blockrun

package module
v0.0.0-...-719287e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 13, 2026 License: MIT Imports: 20 Imported by: 0

README

BlockRun LLM Go SDK

Go SDK for BlockRun - access multiple LLM providers (OpenAI, Anthropic, Google, etc.) with automatic x402 micropayments on Base chain.

Installation

go get github.com/BlockRunAI/blockrun-llm-go

Quick Start

package main

import (
    "fmt"
    "log"

    blockrun "github.com/blockrun/blockrun-llm-go"
)

func main() {
    // Create client (uses BASE_CHAIN_WALLET_KEY env var)
    client, err := blockrun.NewLLMClient("")
    if err != nil {
        log.Fatal(err)
    }

    // Simple 1-line chat
    response, err := client.Chat("openai/gpt-4o", "What is 2+2?")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(response)
}

Security

Your private key NEVER leaves your machine.

Here's what happens when you make a request:

  1. Your key stays local - only used to sign an EIP-712 typed data message
  2. Only the SIGNATURE is sent in the PAYMENT-SIGNATURE header
  3. BlockRun verifies the signature on-chain via Coinbase CDP facilitator
  4. Your actual private key is NEVER transmitted to any server

This is the same security model as:

  • Signing a MetaMask transaction
  • Any on-chain swap or trade
  • Standard EIP-3009 TransferWithAuthorization

Usage

Initialize Client
// From environment variable (BASE_CHAIN_WALLET_KEY)
client, err := blockrun.NewLLMClient("")

// Or pass private key directly
client, err := blockrun.NewLLMClient("0x...")

// With custom timeout (default: 60s)
client, err := blockrun.NewLLMClient("0x...",
    blockrun.WithTimeout(120 * time.Second),
)
Simple Chat
// Basic chat
response, err := client.Chat("openai/gpt-4o", "What is the capital of France?")

// Chat with system prompt
response, err := client.ChatWithSystem(
    "openai/gpt-4o",
    "Tell me a joke",
    "You are a comedian.",
)
Full Chat Completion (OpenAI-compatible)
messages := []blockrun.ChatMessage{
    {Role: "system", Content: "You are a helpful assistant."},
    {Role: "user", Content: "Hello!"},
}

result, err := client.ChatCompletion("openai/gpt-4o", messages, &blockrun.ChatCompletionOptions{
    MaxTokens:   1024,
    Temperature: 0.7,
    TopP:        0.9,
})

fmt.Println(result.Choices[0].Message.Content)
fmt.Printf("Tokens: %d\n", result.Usage.TotalTokens)
List Available Models
models, err := client.ListModels()
for _, model := range models {
    fmt.Printf("%s: $%.4f/$%.4f per 1M tokens\n",
        model.ID, model.InputPrice, model.OutputPrice)
}
Get Wallet Address
address := client.GetWalletAddress()
fmt.Printf("Wallet: %s\n", address)

Available Models

BlockRun provides access to models from multiple providers:

Provider Models
OpenAI gpt-4o, gpt-4o-mini, o1, o1-mini
Anthropic claude-sonnet-4, claude-haiku-4
Google gemini-2.5-pro, gemini-2.5-flash
DeepSeek deepseek-chat, deepseek-reasoner
xAI grok-3, grok-3-mini

Use client.ListModels() for the full list with current pricing.

How x402 Works

  1. You make an API request
  2. Server returns 402 Payment Required with payment details
  3. SDK signs an EIP-712 message locally (key never sent)
  4. SDK retries with PAYMENT-SIGNATURE header
  5. Server verifies signature, settles payment on-chain
  6. Server returns the AI response

All this happens automatically - you just call Chat() or ChatCompletion().

Environment Variables

Variable Description Default
BASE_CHAIN_WALLET_KEY Your Base chain wallet private key Required
BLOCKRUN_API_URL Custom API endpoint https://blockrun.ai/api

Error Handling

response, err := client.Chat("openai/gpt-4o", "Hello")
if err != nil {
    switch e := err.(type) {
    case *blockrun.ValidationError:
        fmt.Printf("Invalid input: %s - %s\n", e.Field, e.Message)
    case *blockrun.PaymentError:
        fmt.Printf("Payment failed: %s\n", e.Message)
    case *blockrun.APIError:
        fmt.Printf("API error %d: %s\n", e.StatusCode, e.Message)
    default:
        fmt.Printf("Error: %v\n", err)
    }
}

Requirements

  • Go 1.21+
  • A wallet with USDC on Base chain

License

MIT

Documentation

Overview

Package blockrun provides a Go SDK for BlockRun's x402-powered LLM gateway.

SECURITY NOTE - Private Key Handling: Your private key NEVER leaves your machine. Here's what happens: 1. Key stays local - only used to sign an EIP-712 typed data message 2. Only the SIGNATURE is sent in the PAYMENT-SIGNATURE header 3. BlockRun verifies the signature on-chain via Coinbase CDP facilitator 4. Your actual private key is NEVER transmitted to any server

Index

Constants

View Source
const (
	// DefaultAPIURL is the default BlockRun API endpoint.
	DefaultAPIURL = "https://blockrun.ai/api"

	// DefaultMaxTokens is the default max tokens for chat completions.
	DefaultMaxTokens = 1024

	// DefaultTimeout is the default HTTP timeout.
	DefaultTimeout = 60 * time.Second
)
View Source
const (
	// DefaultImageModel is the default image generation model.
	DefaultImageModel = "google/nano-banana"

	// DefaultImageSize is the default image size.
	DefaultImageSize = "1024x1024"

	// DefaultImageTimeout is the default timeout for image generation (images take longer).
	DefaultImageTimeout = 120 * time.Second
)
View Source
const (
	// USDCBaseContract is the USDC contract address on Base chain.
	USDCBaseContract = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"

	// BaseChainIDStr is the Base chain ID as string.
	BaseChainIDStr = "8453"
)
View Source
const (
	// BaseChainID is the chain ID for Base mainnet
	BaseChainID = 8453

	// USDCBase is the USDC contract address on Base
	USDCBase = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
)

Variables

View Source
var (
	// WalletDir is the directory where wallet files are stored.
	WalletDir = filepath.Join(os.Getenv("HOME"), ".blockrun")

	// WalletFile is the path to the wallet key file.
	WalletFile = filepath.Join(WalletDir, ".session")
)

Functions

func CreatePaymentPayload

func CreatePaymentPayload(
	privateKey *ecdsa.PrivateKey,
	recipient string,
	amount string,
	network string,
	resourceURL string,
	resourceDescription string,
	maxTimeoutSeconds int,
	extra map[string]any,
	extensions map[string]any,
) (string, error)

CreatePaymentPayload creates a signed x402 v2 payment payload.

This uses EIP-712 typed data signing to create a payment authorization that the CDP facilitator can verify and settle.

SECURITY: The private key is used ONLY for local signing. Only the signature is sent to the server - the key NEVER leaves your machine.

func CreateWallet

func CreateWallet() (address string, privateKey string, err error)

CreateWallet creates a new Ethereum wallet.

func FormatFundingMessageCompact

func FormatFundingMessageCompact(address string) string

FormatFundingMessageCompact returns a compact funding message.

func FormatNeedsFundingMessage

func FormatNeedsFundingMessage(address string) string

FormatNeedsFundingMessage formats the message shown when wallet needs more funds.

func FormatWalletCreatedMessage

func FormatWalletCreatedMessage(address string) string

FormatWalletCreatedMessage formats the message shown when a new wallet is created.

func GetAddressFromKey

func GetAddressFromKey(privateKey string) (string, error)

GetAddressFromKey derives the Ethereum address from a private key.

func GetEIP681URI

func GetEIP681URI(address string, amountUSDC float64) string

GetEIP681URI generates an EIP-681 URI for USDC transfer on Base.

func GetPrivateKeyFromHex

func GetPrivateKeyFromHex(privateKey string) (*ecdsa.PrivateKey, error)

GetPrivateKeyFromHex parses a hex private key string into an ECDSA private key.

func GetWalletAddressFromEnvOrFile

func GetWalletAddressFromEnvOrFile() (string, error)

GetWalletAddressFromEnvOrFile gets the wallet address without exposing the private key.

func LoadWallet

func LoadWallet() (string, error)

LoadWallet loads the wallet private key from file.

func SaveWallet

func SaveWallet(privateKey string) (string, error)

SaveWallet saves the wallet private key to ~/.blockrun/.session

func ValidateAPIURL

func ValidateAPIURL(apiURL string) error

ValidateAPIURL validates the API URL format.

func ValidateMaxTokens

func ValidateMaxTokens(maxTokens int) error

ValidateMaxTokens validates the max_tokens parameter.

func ValidateModel

func ValidateModel(model string) error

ValidateModel validates the model ID format.

func ValidatePrivateKey

func ValidatePrivateKey(key string) error

ValidatePrivateKey validates the format of a private key.

func ValidateResourceURL

func ValidateResourceURL(resourceURL, expectedBase string) (string, error)

ValidateResourceURL validates that a resource URL is safe.

func ValidateTemperature

func ValidateTemperature(temperature float64) error

ValidateTemperature validates the temperature parameter.

func ValidateTopP

func ValidateTopP(topP float64) error

ValidateTopP validates the top_p parameter.

Types

type APIError

type APIError struct {
	StatusCode int
	Message    string
	Body       map[string]any
}

APIError represents an error from the BlockRun API.

func (*APIError) Error

func (e *APIError) Error() string

type AllModel

type AllModel struct {
	ID       string `json:"id"`
	Name     string `json:"name"`
	Provider string `json:"provider"`
	Type     string `json:"type"` // "llm" or "image"
	// LLM-specific fields
	InputPrice   float64 `json:"inputPrice,omitempty"`
	OutputPrice  float64 `json:"outputPrice,omitempty"`
	ContextLimit int     `json:"contextLimit,omitempty"`
	// Image-specific fields
	PricePerImage  float64  `json:"pricePerImage,omitempty"`
	SupportedSizes []string `json:"supportedSizes,omitempty"`
}

AllModel represents a model from either LLM or image generation. Used by ListAllModels() to return a unified list.

type ChatCompletionOptions

type ChatCompletionOptions struct {
	MaxTokens        int               `json:"max_tokens,omitempty"`
	Temperature      float64           `json:"temperature,omitempty"`
	TopP             float64           `json:"top_p,omitempty"`
	Search           bool              `json:"-"` // Enable xAI Live Search (shortcut)
	SearchParameters *SearchParameters `json:"search_parameters,omitempty"`
}

ChatCompletionOptions contains optional parameters for chat completion.

type ChatMessage

type ChatMessage struct {
	Role    string `json:"role"`    // "system", "user", or "assistant"
	Content string `json:"content"` // Message content
}

ChatMessage represents a message in the conversation.

type ChatResponse

type ChatResponse struct {
	ID        string   `json:"id"`
	Object    string   `json:"object"`
	Created   int64    `json:"created"`
	Model     string   `json:"model"`
	Choices   []Choice `json:"choices"`
	Usage     Usage    `json:"usage"`
	Citations []string `json:"citations,omitempty"` // xAI Live Search citation URLs
}

ChatResponse represents the API response for chat completions.

type Choice

type Choice struct {
	Index        int         `json:"index"`
	Message      ChatMessage `json:"message"`
	FinishReason string      `json:"finish_reason"`
}

Choice represents a single completion choice.

type ClientOption

type ClientOption func(*LLMClient)

ClientOption is a function that configures an LLMClient.

func WithAPIURL

func WithAPIURL(url string) ClientOption

WithAPIURL sets a custom API URL.

func WithHTTPClient

func WithHTTPClient(client *http.Client) ClientOption

WithHTTPClient sets a custom HTTP client.

func WithTimeout

func WithTimeout(timeout time.Duration) ClientOption

WithTimeout sets the HTTP timeout.

type ImageClient

type ImageClient struct {
	// contains filtered or unexported fields
}

ImageClient is the BlockRun Image Generation client.

SECURITY: Your private key is used ONLY for local EIP-712 signing. The key NEVER leaves your machine - only signatures are transmitted.

func NewImageClient

func NewImageClient(privateKey string, opts ...ImageClientOption) (*ImageClient, error)

NewImageClient creates a new BlockRun Image client.

If privateKey is empty, it will be read from the BLOCKRUN_WALLET_KEY or BASE_CHAIN_WALLET_KEY environment variable.

func (*ImageClient) Generate

func (c *ImageClient) Generate(prompt string, opts *ImageGenerateOptions) (*ImageResponse, error)

Generate generates an image from a text prompt.

func (*ImageClient) GetSpending

func (c *ImageClient) GetSpending() Spending

GetSpending returns session spending information.

func (*ImageClient) GetWalletAddress

func (c *ImageClient) GetWalletAddress() string

GetWalletAddress returns the wallet address being used for payments.

func (*ImageClient) ListImageModels

func (c *ImageClient) ListImageModels() ([]ImageModel, error)

ListImageModels returns the list of available image models with pricing.

type ImageClientOption

type ImageClientOption func(*ImageClient)

ImageClientOption is a function that configures an ImageClient.

func WithImageAPIURL

func WithImageAPIURL(url string) ImageClientOption

WithImageAPIURL sets a custom API URL for the image client.

func WithImageHTTPClient

func WithImageHTTPClient(client *http.Client) ImageClientOption

WithImageHTTPClient sets a custom HTTP client for the image client.

func WithImageTimeout

func WithImageTimeout(timeout time.Duration) ImageClientOption

WithImageTimeout sets the HTTP timeout for the image client.

type ImageData

type ImageData struct {
	URL           string `json:"url"`
	RevisedPrompt string `json:"revised_prompt,omitempty"`
	B64JSON       string `json:"b64_json,omitempty"`
}

ImageData represents a single generated image.

type ImageGenerateOptions

type ImageGenerateOptions struct {
	Model   string `json:"model,omitempty"`
	Size    string `json:"size,omitempty"`
	N       int    `json:"n,omitempty"`
	Quality string `json:"quality,omitempty"`
}

ImageGenerateOptions contains optional parameters for image generation.

type ImageModel

type ImageModel struct {
	ID              string   `json:"id"`
	Name            string   `json:"name"`
	Provider        string   `json:"provider"`
	Description     string   `json:"description"`
	PricePerImage   float64  `json:"pricePerImage"`
	SupportedSizes  []string `json:"supportedSizes,omitempty"`
	MaxPromptLength int      `json:"maxPromptLength,omitempty"`
	Available       bool     `json:"available"`
}

ImageModel represents an available image model from the API.

type ImageResponse

type ImageResponse struct {
	Created int64       `json:"created"`
	Data    []ImageData `json:"data"`
}

ImageResponse represents the API response for image generation.

type LLMClient

type LLMClient struct {
	// contains filtered or unexported fields
}

LLMClient is the BlockRun LLM gateway client.

SECURITY: Your private key is used ONLY for local EIP-712 signing. The key NEVER leaves your machine - only signatures are transmitted.

func NewLLMClient

func NewLLMClient(privateKey string, opts ...ClientOption) (*LLMClient, error)

NewLLMClient creates a new BlockRun LLM client.

If privateKey is empty, it will be read from the BASE_CHAIN_WALLET_KEY environment variable.

SECURITY: Your private key is used ONLY for local EIP-712 signing. The key NEVER leaves your machine - only signatures are transmitted.

func (*LLMClient) Chat

func (c *LLMClient) Chat(model, prompt string) (string, error)

Chat sends a simple 1-line chat request.

This is a convenience method that wraps ChatCompletion for simple use cases.

func (*LLMClient) ChatCompletion

func (c *LLMClient) ChatCompletion(model string, messages []ChatMessage, opts *ChatCompletionOptions) (*ChatResponse, error)

ChatCompletion sends a full chat completion request (OpenAI-compatible).

func (*LLMClient) ChatWithSystem

func (c *LLMClient) ChatWithSystem(model, prompt, system string) (string, error)

ChatWithSystem sends a chat request with an optional system prompt.

func (*LLMClient) GetSpending

func (c *LLMClient) GetSpending() Spending

GetSpending returns session spending information.

func (*LLMClient) GetWalletAddress

func (c *LLMClient) GetWalletAddress() string

GetWalletAddress returns the wallet address being used for payments.

func (*LLMClient) ListAllModels

func (c *LLMClient) ListAllModels() ([]AllModel, error)

ListAllModels returns a unified list of all available models (LLM and image).

func (*LLMClient) ListImageModels

func (c *LLMClient) ListImageModels() ([]ImageModel, error)

ListImageModels returns the list of available image models with pricing.

func (*LLMClient) ListModels

func (c *LLMClient) ListModels() ([]Model, error)

ListModels returns the list of available models with pricing.

type Model

type Model struct {
	ID           string  `json:"id"`
	Name         string  `json:"name"`
	Provider     string  `json:"provider"`
	InputPrice   float64 `json:"inputPrice"`     // per 1M tokens
	OutputPrice  float64 `json:"outputPrice"`    // per 1M tokens
	ContextLimit int     `json:"contextLimit"`   // max tokens
	Type         string  `json:"type,omitempty"` // "llm" or "image" (for listAllModels)
}

Model represents an available model from the API.

type PaymentData

type PaymentData struct {
	Signature     string                `json:"signature"`
	Authorization TransferAuthorization `json:"authorization"`
}

PaymentData contains the signature and authorization data.

type PaymentError

type PaymentError struct {
	Message string
}

PaymentError represents an error during payment processing.

func (*PaymentError) Error

func (e *PaymentError) Error() string

type PaymentLinksInfo

type PaymentLinksInfo struct {
	Basescan   string
	WalletLink string
	Ethereum   string
	Blockrun   string
}

PaymentLinksInfo contains various payment links for a wallet.

func GetPaymentLinks(address string) *PaymentLinksInfo

GetPaymentLinks generates payment links for the wallet address.

type PaymentOption

type PaymentOption struct {
	Scheme            string         `json:"scheme"`
	Network           string         `json:"network"`
	Amount            string         `json:"amount"`
	Asset             string         `json:"asset"`
	PayTo             string         `json:"payTo"`
	MaxTimeoutSeconds int            `json:"maxTimeoutSeconds"`
	Extra             map[string]any `json:"extra,omitempty"`
}

PaymentOption represents a single payment option.

func ExtractPaymentDetails

func ExtractPaymentDetails(req *PaymentRequirement) (*PaymentOption, error)

ExtractPaymentDetails extracts payment details from a PaymentRequirement. Returns the first payment option if multiple are available.

type PaymentPayload

type PaymentPayload struct {
	X402Version int            `json:"x402Version"`
	Resource    ResourceInfo   `json:"resource"`
	Accepted    PaymentOption  `json:"accepted"`
	Payload     PaymentData    `json:"payload"`
	Extensions  map[string]any `json:"extensions,omitempty"`
}

PaymentPayload represents the signed payment payload sent to the server.

type PaymentRequirement

type PaymentRequirement struct {
	X402Version int             `json:"x402Version"`
	Accepts     []PaymentOption `json:"accepts"`
	Resource    ResourceInfo    `json:"resource"`
	Extensions  map[string]any  `json:"extensions,omitempty"`
}

PaymentRequirement represents the x402 payment requirements from a 402 response.

func ParsePaymentRequired

func ParsePaymentRequired(headerValue string) (*PaymentRequirement, error)

ParsePaymentRequired parses the payment-required header from a 402 response.

type ResourceInfo

type ResourceInfo struct {
	URL         string `json:"url"`
	Description string `json:"description"`
	MimeType    string `json:"mimeType"`
}

ResourceInfo represents information about the resource being accessed.

type SearchParameters

type SearchParameters struct {
	Mode             string         `json:"mode,omitempty"` // "off", "auto", "on"
	Sources          []SearchSource `json:"sources,omitempty"`
	ReturnCitations  bool           `json:"return_citations,omitempty"`
	FromDate         string         `json:"from_date,omitempty"` // YYYY-MM-DD
	ToDate           string         `json:"to_date,omitempty"`   // YYYY-MM-DD
	MaxSearchResults int            `json:"max_search_results,omitempty"`
}

SearchParameters contains xAI Live Search configuration.

type SearchSource

type SearchSource struct {
	Type             string   `json:"type"` // "web", "x", "news", "rss"
	Country          string   `json:"country,omitempty"`
	ExcludedWebsites []string `json:"excluded_websites,omitempty"`
	AllowedWebsites  []string `json:"allowed_websites,omitempty"`
	SafeSearch       bool     `json:"safe_search,omitempty"`
	// X-specific fields
	IncludedXHandles  []string `json:"included_x_handles,omitempty"`
	ExcludedXHandles  []string `json:"excluded_x_handles,omitempty"`
	PostFavoriteCount int      `json:"post_favorite_count,omitempty"`
	PostViewCount     int      `json:"post_view_count,omitempty"`
	// RSS-specific fields
	Links []string `json:"links,omitempty"`
}

SearchSource represents a search source configuration.

type Spending

type Spending struct {
	TotalUSD float64
	Calls    int
}

Spending represents session spending information.

type TransferAuthorization

type TransferAuthorization struct {
	From        string `json:"from"`
	To          string `json:"to"`
	Value       string `json:"value"`
	ValidAfter  string `json:"validAfter"`
	ValidBefore string `json:"validBefore"`
	Nonce       string `json:"nonce"`
}

TransferAuthorization contains the EIP-3009 TransferWithAuthorization parameters.

type Usage

type Usage struct {
	PromptTokens     int `json:"prompt_tokens"`
	CompletionTokens int `json:"completion_tokens"`
	TotalTokens      int `json:"total_tokens"`
	NumSourcesUsed   int `json:"num_sources_used,omitempty"` // xAI Live Search sources used
}

Usage represents token usage information.

type ValidationError

type ValidationError struct {
	Field   string
	Message string
}

ValidationError represents an input validation error.

func (*ValidationError) Error

func (e *ValidationError) Error() string

type WalletInfo

type WalletInfo struct {
	PrivateKey string
	Address    string
	IsNew      bool
}

WalletInfo contains information about a wallet.

func GetOrCreateWallet

func GetOrCreateWallet() (*WalletInfo, error)

GetOrCreateWallet gets an existing wallet or creates a new one.

Priority: 1. BLOCKRUN_WALLET_KEY environment variable 2. BASE_CHAIN_WALLET_KEY environment variable 3. ~/.blockrun/.session file 4. ~/.blockrun/wallet.key file (legacy) 5. Create new wallet

Directories

Path Synopsis
examples
basic command
Example usage of the BlockRun LLM Go SDK.
Example usage of the BlockRun LLM Go SDK.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL