# Connection

Establish a connection to NextBlock's gRPC API from Go.

This page shows the connection pattern and API-key credentials wiring. Replace the generated client import and constructor with the client generated from [`nextblock-proto`](https://github.com/nextblock-ag/nextblock-proto).

## Prerequisites

```bash
go mod init nextblock-example
go get google.golang.org/grpc
go get github.com/gagliardetto/solana-go

# Clone the proto specs and generate the Go client
git clone https://github.com/nextblock-ag/nextblock-proto
# Follow the Go generation instructions in that repository
```

## Example

```go
package main

import (
	"context"
	"crypto/x509"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/keepalive"
)

type ApiKeyCredentials struct {
	apiKey     string
	requireTLS bool
}

func NewApiKeyCredentials(apiKey string, requireTLS bool) *ApiKeyCredentials {
	return &ApiKeyCredentials{
		apiKey:     apiKey,
		requireTLS: requireTLS,
	}
}

func (a *ApiKeyCredentials) RequireTransportSecurity() bool {
	return a.requireTLS
}

func (a *ApiKeyCredentials) GetRequestMetadata(context.Context, ...string) (map[string]string, error) {
	return map[string]string{
		"authorization": a.apiKey,
	}, nil
}

var keepAliveParams = keepalive.ClientParameters{
	Time:                time.Minute,
	Timeout:             15 * time.Second,
	PermitWithoutStream: true,
}

func ConnectToNextblock(address string, apiKey string, useTLS bool) (*grpc.ClientConn, error) {
	var opts []grpc.DialOption

	if useTLS {
		pool, err := x509.SystemCertPool()
		if err != nil {
			return nil, err
		}

		creds := credentials.NewClientTLSFromCert(pool, "")
		opts = append(opts, grpc.WithTransportCredentials(creds))
	} else {
		opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
	}

	opts = append(opts, grpc.WithKeepaliveParams(keepAliveParams))
	opts = append(opts, grpc.WithPerRPCCredentials(NewApiKeyCredentials(apiKey, useTLS)))

	return grpc.NewClient(address, opts...)
}
```

## Usage Example

```go
func main() {
	const FrankfurtEndpoint = "frankfurt.nextblock.io:443"

	apiKey := "<your-api-key-here>"

	// Prefer TLS by default.
	conn, err := ConnectToNextblock(FrankfurtEndpoint, apiKey, true)
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	// Replace this with your generated client type.
	// nextblockApiClient := api.NewApiClient(conn)

	// You can now use the generated client for API calls.
}
```

## Connection Best Practices

1. **Use TLS by default**: prefer `useTLS: true` unless you intentionally operate in a trusted internal environment
2. **Keep connections alive**: reuse a single gRPC connection for multiple requests
3. **Handle errors gracefully**: implement retry logic around transient network failures
4. **Close connections cleanly**: use `defer conn.Close()` when the process exits
5. **Choose the closest endpoint**: lower network latency usually improves performance

## Available Endpoints

* **Frankfurt**: `frankfurt.nextblock.io:443` (Europe)
* **Amsterdam**: `amsterdam.nextblock.io:443` (Europe)
* **London**: `london.nextblock.io:443` (Europe)
* **Singapore**: `singapore.nextblock.io:443` (Asia)
* **Tokyo**: `tokyo.nextblock.io:443` (Asia)
* **New York**: `ny.nextblock.io:443` (US East)
* **Salt Lake City**: `slc.nextblock.io:443` (US West)
* **Dublin**: `dublin.nextblock.io:443` (Europe)
* **Vilnius**: `vilnius.nextblock.io:443` (Europe)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.nextblock.io/api/examples/golang/connection.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
