Overview
The CDP Go SDK provides a client for interacting with the Coinbase Developer Platform API. The client handles JWT-based authentication, request signing, and automatic header management.
Installation
Install the SDK using Go modules:
go get github.com/coinbase/cdp-sdk/go
Package Import
import (
"github.com/coinbase/cdp-sdk/go"
"github.com/coinbase/cdp-sdk/go/openapi"
)
ClientOptions
Configuration options for creating a CDP client:
type ClientOptions struct {
// API key ID
APIKeyID string
// API key secret (EC PEM or Ed25519 base64)
APIKeySecret string
// Wallet secret for signing transactions
WalletSecret string
// Enable debug logging
Debugging bool
// Base URL (defaults to production)
BasePath string
// JWT expiration time in seconds (defaults to 120)
ExpiresIn int64
// Host override for internal use
HostOverride string
}
Field Descriptions
Your CDP API key secret. Supports EC PEM keys and Ed25519 base64-encoded keys
Wallet secret for signing transactions (base64-encoded EC DER private key)
Enable debug logging for requests and responses
BasePath
string
default:"https://api.cdp.coinbase.com/platform"
Base URL for the CDP API
JWT expiration time in seconds
Override the host used for request routing (internal use only)
Creating a Client
Basic Client Creation
Create a new CDP client with API credentials:
package main
import (
"context"
"fmt"
"log"
"github.com/coinbase/cdp-sdk/go"
)
func main() {
// Create client options
options := cdp.ClientOptions{
APIKeyID: "your-api-key-id",
APIKeySecret: "your-api-key-secret",
WalletSecret: "your-wallet-secret",
}
// Create client
client, err := cdp.NewClient(options)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
// Use the client
ctx := context.Background()
resp, err := client.ListEvmAccountsWithResponse(ctx, &openapi.ListEvmAccountsParams{})
if err != nil {
log.Fatalf("Request failed: %v", err)
}
fmt.Printf("Status: %d\n", resp.StatusCode())
}
Client from Environment Variables
Load credentials from environment variables:
package main
import (
"os"
"log"
"github.com/coinbase/cdp-sdk/go"
)
func main() {
options := cdp.ClientOptions{
APIKeyID: os.Getenv("CDP_API_KEY_ID"),
APIKeySecret: os.Getenv("CDP_API_KEY_SECRET"),
WalletSecret: os.Getenv("CDP_WALLET_SECRET"),
}
client, err := cdp.NewClient(options)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
// Use client...
}
Client with Custom Configuration
Configure additional options:
options := cdp.ClientOptions{
APIKeyID: "your-api-key-id",
APIKeySecret: "your-api-key-secret",
WalletSecret: "your-wallet-secret",
Debugging: true,
ExpiresIn: 300, // 5 minutes
BasePath: "https://api.cdp.coinbase.com/platform",
}
client, err := cdp.NewClient(options)
Making API Requests
The client provides methods for all CDP API operations:
List EVM Accounts
ctx := context.Background()
params := &openapi.ListEvmAccountsParams{
PageSize: openapi.NewOptional(10),
}
resp, err := client.ListEvmAccountsWithResponse(ctx, params)
if err != nil {
log.Fatalf("Request failed: %v", err)
}
if resp.JSON200 != nil {
for _, account := range resp.JSON200.Accounts {
fmt.Printf("Account: %s\n", account.Address)
}
}
Create EVM Account
ctx := context.Background()
body := openapi.CreateEvmAccountJSONRequestBody{
Name: openapi.NewOptional("my-account"),
}
headers := openapi.CreateEvmAccountParams{
XWalletAuth: "", // Automatically set by client
XIdempotencyKey: "unique-request-id",
}
resp, err := client.CreateEvmAccountWithResponse(ctx, &headers, body)
if err != nil {
log.Fatalf("Request failed: %v", err)
}
if resp.JSON201 != nil {
fmt.Printf("Created account: %s\n", resp.JSON201.Address)
}
Get EVM Account
ctx := context.Background()
address := "0x1234567890123456789012345678901234567890"
resp, err := client.GetEvmAccountWithResponse(ctx, address)
if err != nil {
log.Fatalf("Request failed: %v", err)
}
if resp.JSON200 != nil {
fmt.Printf("Account: %+v\n", resp.JSON200)
}
Update EVM Account
ctx := context.Background()
address := "0x1234567890123456789012345678901234567890"
body := openapi.UpdateEvmAccountJSONRequestBody{
Name: openapi.NewOptional("updated-name"),
}
resp, err := client.UpdateEvmAccountWithResponse(ctx, address, body)
if err != nil {
log.Fatalf("Request failed: %v", err)
}
if resp.JSON200 != nil {
fmt.Printf("Updated account: %+v\n", resp.JSON200)
}
Authentication
The client automatically handles authentication using JWT tokens:
API Key Authentication
- All requests include an
Authorization: Bearer <token> header
- JWT is automatically generated with the request method, host, and path
- Supports both EC (ES256) and Ed25519 (EdDSA) key formats
Wallet Authentication
- POST and DELETE requests to
/accounts and /spend-permissions include X-Wallet-Auth header
- Wallet JWT includes a hash of the request body for integrity
- Uses ES256 signing with the wallet secret
Error Handling
Handle errors and check response status codes:
ctx := context.Background()
resp, err := client.GetEvmAccountWithResponse(ctx, "0x...")
if err != nil {
log.Fatalf("Request failed: %v", err)
}
switch resp.StatusCode() {
case 200:
fmt.Printf("Success: %+v\n", resp.JSON200)
case 404:
fmt.Println("Account not found")
case 401:
fmt.Println("Authentication failed")
default:
fmt.Printf("Unexpected status: %d\n", resp.StatusCode())
}
Context and Cancellation
Use context for timeout and cancellation:
import "time"
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
resp, err := client.ListEvmAccountsWithResponse(ctx, &openapi.ListEvmAccountsParams{})
if err != nil {
log.Fatalf("Request failed: %v", err)
}
Handle paginated responses:
ctx := context.Background()
var allAccounts []openapi.EvmAccount
var pageToken *string
for {
params := &openapi.ListEvmAccountsParams{
PageSize: openapi.NewOptional(50),
PageToken: pageToken,
}
resp, err := client.ListEvmAccountsWithResponse(ctx, params)
if err != nil {
log.Fatalf("Request failed: %v", err)
}
if resp.JSON200 != nil {
allAccounts = append(allAccounts, resp.JSON200.Accounts...)
if resp.JSON200.NextPageToken == nil {
break
}
pageToken = resp.JSON200.NextPageToken
} else {
break
}
}
fmt.Printf("Total accounts: %d\n", len(allAccounts))
Complete Example
Full example with error handling:
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/coinbase/cdp-sdk/go"
"github.com/coinbase/cdp-sdk/go/openapi"
)
func main() {
// Load credentials from environment
options := cdp.ClientOptions{
APIKeyID: os.Getenv("CDP_API_KEY_ID"),
APIKeySecret: os.Getenv("CDP_API_KEY_SECRET"),
WalletSecret: os.Getenv("CDP_WALLET_SECRET"),
}
// Create client
client, err := cdp.NewClient(options)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
ctx := context.Background()
// List accounts
listResp, err := client.ListEvmAccountsWithResponse(ctx, &openapi.ListEvmAccountsParams{
PageSize: openapi.NewOptional(10),
})
if err != nil {
log.Fatalf("Failed to list accounts: %v", err)
}
if listResp.JSON200 != nil {
fmt.Printf("Found %d accounts\n", len(listResp.JSON200.Accounts))
for _, account := range listResp.JSON200.Accounts {
fmt.Printf(" - %s\n", account.Address)
}
}
}
See Also