Documentation
¶
Overview ¶
Package sdk provides the official Go client for the Nitrolite Clearnode API.
The SDK offers a unified interface for interacting with Clearnode payment channels, supporting both high-level state operations and low-level RPC access. It simplifies the process of managing channel states, performing off-chain transactions, and settling on-chain when necessary.
Key Features ¶
- Unified Client: A single `Client` struct for all operations.
- State Operations: High-level methods (`Deposit`, `Withdraw`, `Transfer`, `CloseHomeChannel`, `Acknowledge`) to build and co-sign channel states off-chain.
- Blockchain Settlement: A single `Checkpoint` method to settle the latest state on-chain (creating channels, depositing, withdrawing, or finalizing).
- Low-Level Access: Direct access to Clearnode RPC methods for advanced use cases (e.g., querying node config, balances, channel info).
- App Sessions: Comprehensive support for creating and managing application sessions.
- Session Keys: Support for registering and using session keys for delegated signing.
Usage ¶
To use the SDK, create a `Client` instance with your Clearnode WebSocket URL and signers. You can configure blockchain RPCs for on-chain operations.
package main
import (
"context"
"log"
"time"
"github.com/layer-3/nitrolite/pkg/sign"
sdk "github.com/layer-3/nitrolite/sdk/go"
"github.com/shopspring/decimal"
)
func main() {
// Initialize signers
privateKeyHex := "YOUR_PRIVATE_KEY_HEX"
stateSigner, err := sign.NewEthereumMsgSigner(privateKeyHex)
if err != nil {
log.Fatal(err)
}
txSigner, err := sign.NewEthereumRawSigner(privateKeyHex)
if err != nil {
log.Fatal(err)
}
// Create Client
client, err := sdk.NewClient(
"wss://clearnode-sandbox.yellow.org/v1/ws",
stateSigner,
txSigner,
sdk.WithBlockchainRPC(80002, "https://rpc-endpoint.example.com"),
sdk.WithHandshakeTimeout(10*time.Second),
)
if err != nil {
log.Fatal(err)
}
defer client.Close()
ctx := context.Background()
// 1. Deposit (Off-chain state preparation)
// This creates a new state reflecting the deposit intent.
state, err := client.Deposit(ctx, 80002, "usdc", decimal.NewFromInt(100))
if err != nil {
log.Fatal(err)
}
log.Printf("Deposit prepared. New state version: %d", state.Version)
// 2. Settlement (On-chain execution)
// This submits the transaction to the blockchain to create the channel or deposit funds.
txHash, err := client.Checkpoint(ctx, "usdc")
if err != nil {
log.Fatal(err)
}
log.Printf("On-chain transaction hash: %s", txHash)
// 3. Transfer (Off-chain transaction)
// Transfers are instant and don't require immediate on-chain settlement.
_, err = client.Transfer(ctx, "0xRecipientAddress...", "usdc", decimal.NewFromInt(50))
if err != nil {
log.Fatal(err)
}
log.Println("Transfer completed off-chain")
}
Client Configuration ¶
The `NewClient` function accepts variadic `ClientOption` functions to customize behavior:
- `WithBlockchainRPC(chainID, url)`: Registers an RPC endpoint for on-chain settlement.
- `WithHandshakeTimeout(duration)`: Sets the timeout for the initial WebSocket handshake.
- `WithPingInterval(duration)`: Sets the interval for WebSocket ping/pong keepalives.
- `WithErrorHandler(func(error))`: Sets a callback for handling background connection errors.
Error Handling ¶
The SDK methods return standard Go errors. Common errors to check for include connection issues, insufficient balances, or invalid state transitions. Errors from RPC calls often contain detailed messages from the Clearnode server.
Index ¶
- Constants
- Variables
- type Client
- func (c *Client) Acknowledge(ctx context.Context, asset string) (*core.State, error)
- func (c *Client) ApproveSecurityToken(ctx context.Context, chainID uint64, amount decimal.Decimal) (string, error)
- func (c *Client) ApproveToken(ctx context.Context, chainID uint64, asset string, amount decimal.Decimal) (string, error)
- func (c *Client) CancelSecurityTokensWithdrawal(ctx context.Context, blockchainID uint64) (string, error)
- func (c *Client) Challenge(ctx context.Context, state core.State) (string, error)
- func (c *Client) Checkpoint(ctx context.Context, asset string) (string, error)
- func (c *Client) Close() error
- func (c *Client) CloseHomeChannel(ctx context.Context, asset string) (*core.State, error)
- func (c *Client) CreateAppSession(ctx context.Context, definition app.AppDefinitionV1, sessionData string, ...) (string, string, string, error)
- func (c *Client) Deposit(ctx context.Context, blockchainID uint64, asset string, amount decimal.Decimal) (*core.State, error)
- func (c *Client) EscrowSecurityTokens(ctx context.Context, targetWalletAddress string, blockchainID uint64, ...) (string, error)
- func (c *Client) GetActionAllowances(ctx context.Context, wallet string) ([]core.ActionAllowance, error)
- func (c *Client) GetAppDefinition(ctx context.Context, appSessionID string) (*app.AppDefinitionV1, error)
- func (c *Client) GetAppSessions(ctx context.Context, opts *GetAppSessionsOptions) ([]app.AppSessionInfoV1, core.PaginationMetadata, error)
- func (c *Client) GetApps(ctx context.Context, opts *GetAppsOptions) ([]app.AppInfoV1, core.PaginationMetadata, error)
- func (c *Client) GetAssets(ctx context.Context, blockchainID *uint64) ([]core.Asset, error)
- func (c *Client) GetBalances(ctx context.Context, wallet string) ([]core.BalanceEntry, error)
- func (c *Client) GetBlockchains(ctx context.Context) ([]core.Blockchain, error)
- func (c *Client) GetConfig(ctx context.Context) (*core.NodeConfig, error)
- func (c *Client) GetEscrowChannel(ctx context.Context, escrowChannelID string) (*core.Channel, error)
- func (c *Client) GetHomeChannel(ctx context.Context, wallet, asset string) (*core.Channel, error)
- func (c *Client) GetLastAppKeyStates(ctx context.Context, userAddress string, opts *GetLastKeyStatesOptions) ([]app.AppSessionKeyStateV1, error)
- func (c *Client) GetLastChannelKeyStates(ctx context.Context, userAddress string, opts *GetLastChannelKeyStatesOptions) ([]core.ChannelSessionKeyStateV1, error)
- func (c *Client) GetLatestState(ctx context.Context, wallet, asset string, onlySigned bool) (*core.State, error)
- func (c *Client) GetLockedBalance(ctx context.Context, chainID uint64, wallet string) (decimal.Decimal, error)
- func (c *Client) GetOnChainBalance(ctx context.Context, chainID uint64, asset string, wallet string) (decimal.Decimal, error)
- func (c *Client) GetTransactions(ctx context.Context, wallet string, opts *GetTransactionsOptions) ([]core.Transaction, core.PaginationMetadata, error)
- func (c *Client) GetUserAddress() string
- func (c *Client) InitiateSecurityTokensWithdrawal(ctx context.Context, blockchainID uint64) (string, error)
- func (c *Client) Ping(ctx context.Context) error
- func (c *Client) RebalanceAppSessions(ctx context.Context, signedUpdates []app.SignedAppStateUpdateV1) (string, error)
- func (c *Client) RegisterApp(ctx context.Context, appID string, metadata string, ...) error
- func (c *Client) SetHomeBlockchain(asset string, blockchainId uint64) error
- func (c *Client) SignChannelSessionKeyState(state core.ChannelSessionKeyStateV1) (string, error)
- func (c *Client) SignSessionKeyState(state app.AppSessionKeyStateV1) (string, error)
- func (c *Client) SignState(state *core.State) (string, error)
- func (c *Client) SubmitAppSessionDeposit(ctx context.Context, appStateUpdate app.AppStateUpdateV1, quorumSigs []string, ...) (string, error)
- func (c *Client) SubmitAppSessionKeyState(ctx context.Context, state app.AppSessionKeyStateV1) error
- func (c *Client) SubmitAppState(ctx context.Context, appStateUpdate app.AppStateUpdateV1, quorumSigs []string) error
- func (c *Client) SubmitChannelSessionKeyState(ctx context.Context, state core.ChannelSessionKeyStateV1) error
- func (c *Client) Transfer(ctx context.Context, recipientWallet string, asset string, ...) (*core.State, error)
- func (c *Client) WaitCh() <-chan struct{}
- func (c *Client) Withdraw(ctx context.Context, blockchainID uint64, asset string, amount decimal.Decimal) (*core.State, error)
- func (c *Client) WithdrawSecurityTokens(ctx context.Context, blockchainID uint64, destinationWalletAddress string) (string, error)
- type Config
- type CreateAppSessionOptions
- type GetAppSessionsOptions
- type GetAppsOptions
- type GetLastChannelKeyStatesOptions
- type GetLastKeyStatesOptions
- type GetTransactionsOptions
- type Option
Constants ¶
const (
// DefaultChallengePeriod is the default challenge period for channels (1 day in seconds)
DefaultChallengePeriod = 86400
)
Variables ¶
var DefaultConfig = Config{ HandshakeTimeout: 5 * time.Second, PingTimeout: 15 * time.Second, ErrorHandler: defaultErrorHandler, }
DefaultConfig returns the default configuration with sensible defaults.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client provides a unified interface for interacting with Clearnode. It combines state-building operations (Deposit, Withdraw, Transfer) with a single Checkpoint method for blockchain settlement, plus low-level RPC access for advanced use cases.
The two-step pattern for blockchain operations:
- Build and co-sign the state off-chain (Deposit, Withdraw, CloseHomeChannel, etc.)
- Settle on-chain via Checkpoint
High-level example:
stateSigner, _ := sign.NewEthereumMsgSigner(privateKeyHex)
txSigner, _ := sign.NewEthereumRawSigner(privateKeyHex)
client, _ := sdk.NewClient(
"wss://clearnode-sandbox.yellow.org/v1/ws",
stateSigner,
txSigner,
sdk.WithBlockchainRPC(80002, "https://polygon-amoy.alchemy.com/v2/KEY"),
)
defer client.Close()
// Deposit: build state, then settle on-chain
state, _ := client.Deposit(ctx, 80002, "usdc", decimal.NewFromInt(100))
txHash, _ := client.Checkpoint(ctx, "usdc")
// Transfer: off-chain only, no Checkpoint needed for existing channels
state, _ = client.Transfer(ctx, "0xRecipient...", "usdc", decimal.NewFromInt(50))
// Low-level operations
config, _ := client.GetConfig(ctx)
balances, _ := client.GetBalances(ctx, walletAddress)
func NewClient ¶
func NewClient(wsURL string, stateSigner core.ChannelSigner, rawSigner sign.Signer, opts ...Option) (*Client, error)
NewClient creates a new Clearnode client with both high-level and low-level methods. This is the recommended constructor for most use cases.
Parameters:
- wsURL: WebSocket URL of the Clearnode server (e.g., "wss://clearnode-sandbox.yellow.org/v1/ws")
- stateSigner: core.ChannelSigner for signing channel states (use sign.NewEthereumMsgSigner)
- txSigner: sign.Signer for signing blockchain transactions (use sign.NewEthereumRawSigner)
- opts: Optional configuration (WithBlockchainRPC, WithHandshakeTimeout, etc.)
Returns:
- Configured Client ready for operations
- Error if connection or initialization fails
Example:
stateSigner, _ := sign.NewEthereumMsgSigner(privateKeyHex)
txSigner, _ := sign.NewEthereumRawSigner(privateKeyHex)
client, err := sdk.NewClient(
"wss://clearnode-sandbox.yellow.org/v1/ws",
stateSigner,
txSigner,
sdk.WithBlockchainRPC(80002, "https://polygon-amoy.alchemy.com/v2/KEY"),
)
func (*Client) Acknowledge ¶
Acknowledge prepares an acknowledgement state for the given asset. This is used when a user receives a transfer but hasn't yet acknowledged the state, or to acknowledge channel creation without a deposit.
This method handles two scenarios automatically:
- If no channel exists: Creates a new channel with the acknowledgement transition
- If channel exists: Advances the state with an acknowledgement transition
The returned state is signed by both the user and the node.
Parameters:
- ctx: Context for the operation
- asset: The asset symbol to acknowledge (e.g., "usdc")
Returns:
- The co-signed state with the acknowledgement transition applied
- Error if the operation fails
Requirements:
- Home blockchain must be set for the asset (use SetHomeBlockchain) when no channel exists
Example:
state, err := client.Acknowledge(ctx, "usdc")
func (*Client) ApproveSecurityToken ¶
func (c *Client) ApproveSecurityToken(ctx context.Context, chainID uint64, amount decimal.Decimal) (string, error)
ApproveSecurityToken approves the Locking contract to spend tokens on behalf of the caller. This must be called before Lock Security Tokens.
Parameters:
- ctx: Context for the operation
- chainID: The blockchain network ID
- amount: The amount of tokens to approve
Returns:
- Transaction hash
- Error if the operation fails
func (*Client) ApproveToken ¶
func (c *Client) ApproveToken(ctx context.Context, chainID uint64, asset string, amount decimal.Decimal) (string, error)
ApproveToken approves the ChannelHub contract to spend tokens on behalf of the user. This is required before depositing ERC-20 tokens. Native tokens (e.g., ETH) do not require approval and will return an error if attempted.
Parameters:
- ctx: Context for the operation
- chainID: The blockchain network ID (e.g., 11155111 for Sepolia)
- asset: The asset symbol to approve (e.g., "usdc")
- amount: The amount to approve for spending
Returns:
- Transaction hash of the approval transaction
- Error if the operation fails or the asset is a native token
func (*Client) CancelSecurityTokensWithdrawal ¶
func (c *Client) CancelSecurityTokensWithdrawal(ctx context.Context, blockchainID uint64) (string, error)
CancelSecurityTokensWithdrawal re-locks tokens that are currently in the unlocking state, cancelling the pending unlock and returning them to the locked state.
Parameters:
- ctx: Context for the operation
- blockchainID: The blockchain network ID
Returns:
- Transaction hash
- Error if the operation fails
func (*Client) Challenge ¶
Challenge submits an on-chain challenge for a channel using a co-signed state. The state must have both user and node signatures, which are validated before the challenge transaction is submitted.
A challenge initiates a dispute period on-chain. If the counterparty does not respond with a higher-versioned state before the challenge period expires, the channel can be closed with the challenged state.
Parameters:
- ctx: Context for the operation
- state: A co-signed state (both UserSig and NodeSig must be present)
Returns:
- Transaction hash of the on-chain challenge transaction
- Error if validation or submission fails
Requirements:
- Blockchain RPC must be configured for the chain (use WithBlockchainRPC)
- State must have both user and node signatures
- State must have a HomeChannelID
Example:
state, err := client.GetLatestState(ctx, wallet, "usdc", true)
txHash, err := client.Challenge(ctx, *state)
fmt.Printf("Challenge transaction: %s\n", txHash)
func (*Client) Checkpoint ¶
Checkpoint executes the blockchain transaction for the latest signed state. It fetches the latest co-signed state and, based on the transition type and on-chain channel status, calls the appropriate blockchain method.
This is the only method that interacts with the blockchain. It should be called after any state-building method (Deposit, Withdraw, CloseHomeChannel, etc.) to settle the state on-chain. It can also be used as a recovery mechanism if a previous blockchain transaction failed (e.g., due to gas issues or network problems).
Blockchain method mapping:
- Channel not yet on-chain (status Void): Creates the channel via blockchainClient.Create
- HomeDeposit/HomeWithdrawal on existing channel: Checkpoints via blockchainClient.Checkpoint
- Finalize: Closes the channel via blockchainClient.Close
Parameters:
- ctx: Context for the operation
- asset: The asset symbol (e.g., "usdc")
Returns:
- Transaction hash of the blockchain transaction
- Error if the operation fails or no blockchain operation is needed
Requirements:
- Blockchain RPC must be configured for the chain (use WithBlockchainRPC)
- A co-signed state must exist (call Deposit, Withdraw, etc. first)
Example:
state, err := client.Deposit(ctx, 80002, "usdc", decimal.NewFromInt(100))
txHash, err := client.Checkpoint(ctx, "usdc")
fmt.Printf("On-chain transaction: %s\n", txHash)
func (*Client) Close ¶
Close cleanly shuts down the client connection. It's recommended to defer this call after creating the client.
Example:
client, err := NewClient(...)
if err != nil {
log.Fatal(err)
}
defer client.Close()
func (*Client) CloseHomeChannel ¶
CloseHomeChannel prepares a finalize state to close the user's channel for a specific asset. This creates a final state with zero user balance and submits it to the node.
The returned state is signed by both the user and the node, but has not yet been submitted to the blockchain. Use Checkpoint to execute the on-chain close.
Parameters:
- ctx: Context for the operation
- asset: The asset symbol to close (e.g., "usdc")
Returns:
- The co-signed finalize state ready for on-chain close
- Error if the operation fails
Errors:
- Returns error if no channel exists for the asset
- Returns error if state signing or submission fails
Example:
state, err := client.CloseHomeChannel(ctx, "usdc")
txHash, err := client.Checkpoint(ctx, "usdc")
fmt.Printf("Close transaction: %s\n", txHash)
func (*Client) CreateAppSession ¶
func (c *Client) CreateAppSession(ctx context.Context, definition app.AppDefinitionV1, sessionData string, quorumSigs []string, opts ...CreateAppSessionOptions) (string, string, string, error)
CreateAppSession creates a new application session between participants.
Parameters:
- definition: The app definition with participants, quorum, application ID
- sessionData: Optional JSON stringified session data
- quorumSigs: Participant signatures for the app session creation
- opts: Optional parameters (owner signature for apps requiring approval)
Returns:
- AppSessionID of the created session
- Initial version of the session
- Status of the session
- Error if the request fails
Example:
def := app.AppDefinitionV1{
Application: "chess-v1",
Participants: []app.AppParticipantV1{...},
Quorum: 2,
Nonce: 1,
}
sessionID, version, status, err := client.CreateAppSession(ctx, def, "{}", []string{"sig1", "sig2"})
func (*Client) Deposit ¶
func (c *Client) Deposit(ctx context.Context, blockchainID uint64, asset string, amount decimal.Decimal) (*core.State, error)
Deposit prepares a deposit state for the user's channel. This method handles two scenarios automatically:
- If no channel exists: Creates a new channel with the initial deposit
- If channel exists: Advances the state with a deposit transition
The returned state is signed by both the user and the node, but has not yet been submitted to the blockchain. Use Checkpoint to execute the on-chain transaction.
Parameters:
- ctx: Context for the operation
- blockchainID: The blockchain network ID (e.g., 80002 for Polygon Amoy)
- asset: The asset symbol to deposit (e.g., "usdc")
- amount: The amount to deposit
Returns:
- The co-signed state ready for on-chain checkpoint
- Error if the operation fails
Example:
state, err := client.Deposit(ctx, 80002, "usdc", decimal.NewFromInt(100))
txHash, err := client.Checkpoint(ctx, "usdc")
fmt.Printf("Deposit transaction: %s\n", txHash)
func (*Client) EscrowSecurityTokens ¶
func (c *Client) EscrowSecurityTokens(ctx context.Context, targetWalletAddress string, blockchainID uint64, amount decimal.Decimal) (string, error)
EscrowSecurityTokens locks tokens into the Locking contract on the specified blockchain. The tokens are locked for the caller's own address. Before calling this method, you must approve the Locking to spend your tokens using ApproveSecurityToken.
Parameters:
- ctx: Context for the operation
- destinationWalletAddress: The Ethereum address to lock tokens for
- blockchainID: The blockchain network ID
- amount: The amount of tokens to lock (in human-readable decimals, e.g., 100.5 USDC)
Returns:
- Transaction hash
- Error if the operation fails
func (*Client) GetActionAllowances ¶
func (c *Client) GetActionAllowances(ctx context.Context, wallet string) ([]core.ActionAllowance, error)
GetActionAllowances retrieves the action allowances for a user based on their staking level.
Parameters:
- wallet: The user's wallet address
Returns:
- Slice of ActionAllowance containing allowance information per gated action
- Error if the request fails
func (*Client) GetAppDefinition ¶
func (c *Client) GetAppDefinition(ctx context.Context, appSessionID string) (*app.AppDefinitionV1, error)
GetAppDefinition retrieves the definition for a specific app session.
Parameters:
- appSessionID: The application session ID
Returns:
- app.AppDefinitionV1 with participants, quorum, and application info
- Error if the request fails
Example:
def, err := client.GetAppDefinition(ctx, "session123")
fmt.Printf("App: %s, Quorum: %d\n", def.Application, def.Quorum)
func (*Client) GetAppSessions ¶
func (c *Client) GetAppSessions(ctx context.Context, opts *GetAppSessionsOptions) ([]app.AppSessionInfoV1, core.PaginationMetadata, error)
GetAppSessions retrieves application sessions with optional filtering.
Parameters:
- opts: Optional filters (pass nil for no filters)
Returns:
- Slice of AppSession
- core.PaginationMetadata with pagination information
- Error if the request fails
Example:
sessions, meta, err := client.GetAppSessions(ctx, nil)
for _, session := range sessions {
fmt.Printf("Session %s: %d participants\n", session.AppSessionID, len(session.Participants))
}
func (*Client) GetApps ¶
func (c *Client) GetApps(ctx context.Context, opts *GetAppsOptions) ([]app.AppInfoV1, core.PaginationMetadata, error)
GetApps retrieves registered applications with optional filtering.
Parameters:
- opts: Optional filters (pass nil for no filters)
Returns:
- Slice of AppInfoV1 with application information
- core.PaginationMetadata with pagination information
- Error if the request fails
Example:
apps, meta, err := client.GetApps(ctx, nil)
for _, a := range apps {
fmt.Printf("App %s owned by %s\n", a.App.ID, a.App.OwnerWallet)
}
func (*Client) GetAssets ¶
GetAssets retrieves all supported assets with optional blockchain filter.
Parameters:
- blockchainID: Optional blockchain ID to filter assets (pass nil for all assets)
Returns:
- Slice of Asset containing asset information and token implementations
- Error if the request fails
Example:
assets, err := client.GetAssets(ctx, nil)
for _, asset := range assets {
fmt.Printf("%s (%s): %d tokens\n", asset.Name, asset.Symbol, len(asset.Tokens))
}
func (*Client) GetBalances ¶
GetBalances retrieves the balance information for a user.
Parameters:
- wallet: The user's wallet address
Returns:
- Slice of Balance containing asset balances
- Error if the request fails
Example:
balances, err := client.GetBalances(ctx, "0x1234567890abcdef...")
for _, balance := range balances {
fmt.Printf("%s: %s\n", balance.Asset, balance.Balance)
}
func (*Client) GetBlockchains ¶
GetBlockchains retrieves the list of supported blockchain networks. This is a convenience method that calls GetConfig and extracts the blockchains list.
Returns:
- Slice of Blockchain containing name, chain ID, and contract address for each network
- Error if the request fails
Example:
blockchains, err := client.GetBlockchains(ctx)
for _, bc := range blockchains {
fmt.Printf("%s: %s\n", bc.Name, bc.ChannelHubAddress)
}
func (*Client) GetConfig ¶
GetConfig retrieves the clearnode configuration including node identity and supported blockchains.
Returns:
- NodeConfig containing the node address, version, and list of supported blockchain networks
- Error if the request fails
Example:
config, err := client.GetConfig(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Node: %s (v%s)\n", config.NodeAddress, config.NodeVersion)
func (*Client) GetEscrowChannel ¶
func (c *Client) GetEscrowChannel(ctx context.Context, escrowChannelID string) (*core.Channel, error)
GetEscrowChannel retrieves escrow channel information for a specific channel ID.
Parameters:
- escrowChannelID: The escrow channel ID to query
Returns:
- Channel information for the escrow channel
- Error if the request fails
Example:
channel, err := client.GetEscrowChannel(ctx, "0x1234...")
fmt.Printf("Escrow Channel: %s (Version: %d)\n", channel.ChannelID, channel.StateVersion)
func (*Client) GetHomeChannel ¶
GetHomeChannel retrieves home channel information for a user's asset.
Parameters:
- wallet: The user's wallet address
- asset: The asset symbol
Returns:
- Channel information for the home channel
- Error if the request fails
Example:
channel, err := client.GetHomeChannel(ctx, "0x1234...", "usdc")
fmt.Printf("Home Channel: %s (Version: %d)\n", channel.ChannelID, channel.StateVersion)
func (*Client) GetLastAppKeyStates ¶
func (c *Client) GetLastAppKeyStates(ctx context.Context, userAddress string, opts *GetLastKeyStatesOptions) ([]app.AppSessionKeyStateV1, error)
GetLastAppKeyStates retrieves the latest session key states for a user.
Parameters:
- userAddress: The user's wallet address
- opts: Optional filters (pass nil for no filters)
Returns:
- Slice of AppSessionKeyStateV1 with the latest non-expired session key states
- Error if the request fails
Example:
states, err := client.GetLastAppKeyStates(ctx, "0x1234...", nil)
for _, state := range states {
fmt.Printf("Session key %s expires at %s\n", state.SessionKey, state.ExpiresAt)
}
func (*Client) GetLastChannelKeyStates ¶
func (c *Client) GetLastChannelKeyStates(ctx context.Context, userAddress string, opts *GetLastChannelKeyStatesOptions) ([]core.ChannelSessionKeyStateV1, error)
GetLastChannelKeyStates retrieves the latest channel session key states for a user.
Parameters:
- userAddress: The user's wallet address
- opts: Optional filters (pass nil for no filters)
Returns:
- Slice of ChannelSessionKeyStateV1 with the latest non-expired session key states
- Error if the request fails
Example:
states, err := client.GetLastChannelKeyStates(ctx, "0x1234...", nil)
for _, state := range states {
fmt.Printf("Session key %s expires at %s\n", state.SessionKey, state.ExpiresAt)
}
func (*Client) GetLatestState ¶
func (c *Client) GetLatestState(ctx context.Context, wallet, asset string, onlySigned bool) (*core.State, error)
GetLatestState retrieves the latest state for a user's asset.
Parameters:
- wallet: The user's wallet address
- asset: The asset symbol (e.g., "usdc")
- onlySigned: If true, returns only the latest signed state
Returns:
- core.State containing all state information
- Error if the request fails
Example:
state, err := client.GetLatestState(ctx, "0x1234...", "usdc", false)
fmt.Printf("State Version: %d, Balance: %s\n", state.Version, state.HomeLedger.UserBalance)
func (*Client) GetLockedBalance ¶
func (c *Client) GetLockedBalance(ctx context.Context, chainID uint64, wallet string) (decimal.Decimal, error)
GetLockedBalance returns the locked balance of a user in the Locking contract.
Parameters:
- ctx: Context for the operation
- chainID: The blockchain network ID
- wallet: The Ethereum address to check
Returns:
- The locked balance as a decimal (adjusted for token decimals)
- Error if the query fails
func (*Client) GetOnChainBalance ¶
func (c *Client) GetOnChainBalance(ctx context.Context, chainID uint64, asset string, wallet string) (decimal.Decimal, error)
GetOnChainBalance queries the on-chain token balance (ERC-20 or native ETH) for a wallet on a specific blockchain.
Parameters:
- ctx: Context for the operation
- chainID: The blockchain ID to query (e.g., 80002 for Polygon Amoy)
- asset: The asset symbol (e.g., "usdc", "weth")
- wallet: The Ethereum address to check the balance for
Returns:
- The token balance as a decimal (already adjusted for token decimals)
- Error if the query fails
Requirements:
- Blockchain RPC must be configured for the chain (use WithBlockchainRPC)
func (*Client) GetTransactions ¶
func (c *Client) GetTransactions(ctx context.Context, wallet string, opts *GetTransactionsOptions) ([]core.Transaction, core.PaginationMetadata, error)
GetTransactions retrieves transaction history for a user with optional filtering.
Parameters:
- wallet: The user's wallet address
- opts: Optional filters (pass nil for no filters)
Returns:
- Slice of Transaction
- core.PaginationMetadata with pagination information
- Error if the request fails
Example:
txs, meta, err := client.GetTransactions(ctx, "0x1234...", nil)
for _, tx := range txs {
fmt.Printf("%s: %s → %s (%s %s)\n", tx.TxType, tx.FromAccount, tx.ToAccount, tx.Amount, tx.Asset)
}
func (*Client) GetUserAddress ¶
GetUserAddress returns the Ethereum address associated with the signer. This is useful for identifying the current user's wallet address.
func (*Client) InitiateSecurityTokensWithdrawal ¶
func (c *Client) InitiateSecurityTokensWithdrawal(ctx context.Context, blockchainID uint64) (string, error)
InitiateSecurityTokensWithdrawal initiates the unlock process for locked tokens in the Locking contract. After the unlock period elapses, Withdraw Security Tokens can be called to retrieve the tokens.
Parameters:
- ctx: Context for the operation
- blockchainID: The blockchain network ID
Returns:
- Transaction hash
- Error if the operation fails
func (*Client) Ping ¶
Ping checks connectivity to the clearnode server. This is useful for health checks and verifying the connection is active.
Example:
if err := client.Ping(ctx); err != nil {
log.Printf("Server is unreachable: %v", err)
}
func (*Client) RebalanceAppSessions ¶
func (c *Client) RebalanceAppSessions(ctx context.Context, signedUpdates []app.SignedAppStateUpdateV1) (string, error)
RebalanceAppSessions rebalances multiple application sessions atomically.
This method performs atomic rebalancing across multiple app sessions, ensuring that funds are redistributed consistently without the risk of partial updates.
Parameters:
- signedUpdates: Slice of signed app state updates to apply atomically
Returns:
- BatchID for tracking the rebalancing operation
- Error if the request fails
Example:
updates := []app.SignedAppStateUpdateV1{...}
batchID, err := client.RebalanceAppSessions(ctx, updates)
fmt.Printf("Rebalance batch ID: %s\n", batchID)
func (*Client) RegisterApp ¶
func (c *Client) RegisterApp(ctx context.Context, appID string, metadata string, creationApprovalNotRequired bool) error
RegisterApp registers a new application in the app registry. Currently only version 1 (creation) is supported.
The method builds the app definition from the provided parameters, using the client's signer address as the owner wallet and version 1. It then packs and signs the definition automatically.
Session key signers are not allowed to perform this action; the main wallet signer must be used.
Parameters:
- appID: The application identifier
- metadata: The application metadata
- creationApprovalNotRequired: Whether sessions can be created without owner approval
Returns:
- Error if the request fails
Example:
err := client.RegisterApp(ctx, "my-app", `{"name": "My App"}`, false)
func (*Client) SetHomeBlockchain ¶
SetHomeBlockchain configures the primary blockchain network for a specific asset. This is required for operations like Transfer which may trigger channel creation but do not accept a blockchain ID as a parameter.
Validation:
- Checks if the asset is actually supported on the specified blockchain.
- Verifies that a home blockchain hasn't already been set for this asset.
Constraints:
- This mapping is immutable once set for the client instance.
- To move an asset to a different blockchain, use the Migrate() method instead.
Parameters:
- asset: The asset symbol (e.g., "usdc")
- blockchainId: The chain ID to associate with the asset (e.g., 80002)
Example:
// Set USDC to settle on Polygon Amoy
if err := client.SetHomeBlockchain("usdc", 80002); err != nil {
log.Fatal(err)
}
func (*Client) SignChannelSessionKeyState ¶
func (c *Client) SignChannelSessionKeyState(state core.ChannelSessionKeyStateV1) (string, error)
SignChannelSessionKeyState signs a channel session key state using the client's state signer. This creates a properly formatted signature that can be set on the state's UserSig field before submitting via SubmitChannelSessionKeyState.
Parameters:
- state: The channel session key state to sign (UserSig field is excluded from signing)
Returns:
- The hex-encoded signature string
- Error if signing fails
Example:
state := core.ChannelSessionKeyStateV1{
UserAddress: client.GetUserAddress(),
SessionKey: "0xabcd...",
Version: 1,
Assets: []string{"usdc"},
ExpiresAt: time.Now().Add(24 * time.Hour),
}
sig, err := client.SignChannelSessionKeyState(state)
state.UserSig = sig
err = client.SubmitChannelSessionKeyState(ctx, state)
func (*Client) SignSessionKeyState ¶
func (c *Client) SignSessionKeyState(state app.AppSessionKeyStateV1) (string, error)
SignSessionKeyState signs a session key state using the client's state signer. This creates a properly formatted signature that can be set on the state's UserSig field before submitting via SubmitSessionKeyState.
Parameters:
- state: The session key state to sign (UserSig field is excluded from signing)
Returns:
- The hex-encoded signature string
- Error if signing fails
Example:
state := app.AppSessionKeyStateV1{
UserAddress: client.GetUserAddress(),
SessionKey: "0xabcd...",
Version: 1,
ApplicationIDs: []string{},
AppSessionIDs: []string{},
ExpiresAt: time.Now().Add(24 * time.Hour),
}
sig, err := client.SignSessionKeyState(state)
state.UserSig = sig
err = client.SubmitSessionKeyState(ctx, state)
func (*Client) SignState ¶
SignState signs a channel state by packing it, hashing it, and signing the hash. Returns the signature as a hex-encoded string (with 0x prefix).
This is a low-level method exposed for advanced users who want to manually construct and sign states. Most users should use the high-level methods like Transfer, Deposit, and Withdraw instead.
func (*Client) SubmitAppSessionDeposit ¶
func (c *Client) SubmitAppSessionDeposit(ctx context.Context, appStateUpdate app.AppStateUpdateV1, quorumSigs []string, asset string, depositAmount decimal.Decimal) (string, error)
SubmitAppSessionDeposit submits a deposit to an app session. This updates both the app session state and the user's channel state.
Parameters:
- appStateUpdate: The app state update with deposit intent
- quorumSigs: Participant signatures for the app state update
- userState: The user's updated channel state
Returns:
- Node's signature for the state
- Error if the request fails
Example:
appUpdate := app.AppStateUpdateV1{
AppSessionID: "session123",
Intent: app.AppStateUpdateIntentDeposit,
Version: 2,
Allocations: []app.AppAllocationV1{...},
}
nodeSig, err := client.SubmitAppSessionDeposit(ctx, appUpdate, []string{"sig1"}, userState)
func (*Client) SubmitAppSessionKeyState ¶
func (c *Client) SubmitAppSessionKeyState(ctx context.Context, state app.AppSessionKeyStateV1) error
SubmitAppSessionKeyState submits a session key state for registration or update. The state must be signed by the user's wallet to authorize the session key delegation.
Parameters:
- state: The session key state containing delegation information
Returns:
- Error if the request fails
Example:
state := app.AppSessionKeyStateV1{
UserAddress: "0x1234...",
SessionKey: "0xabcd...",
Version: 1,
ApplicationIDs: []string{"app1"},
AppSessionIDs: []string{},
ExpiresAt: time.Now().Add(24 * time.Hour),
UserSig: "0x...",
}
err := client.SubmitAppSessionKeyState(ctx, state)
func (*Client) SubmitAppState ¶
func (c *Client) SubmitAppState(ctx context.Context, appStateUpdate app.AppStateUpdateV1, quorumSigs []string) error
SubmitAppState submits an app session state update. This method handles operate, withdraw, and close intents. For deposits, use SubmitAppSessionDeposit instead.
Parameters:
- appStateUpdate: The app state update (intent: operate, withdraw, or close)
- quorumSigs: Participant signatures for the app state update
Returns:
- Error if the request fails
Example:
appUpdate := app.AppStateUpdateV1{
AppSessionID: "session123",
Intent: app.AppStateUpdateIntentOperate,
Version: 3,
Allocations: []app.AppAllocationV1{...},
}
err := client.SubmitAppState(ctx, appUpdate, []string{"sig1", "sig2"})
func (*Client) SubmitChannelSessionKeyState ¶
func (c *Client) SubmitChannelSessionKeyState(ctx context.Context, state core.ChannelSessionKeyStateV1) error
SubmitChannelSessionKeyState submits a channel session key state for registration or update. The state must be signed by the user's wallet to authorize the session key delegation.
Parameters:
- state: The channel session key state containing delegation information
Returns:
- Error if the request fails
Example:
state := core.ChannelSessionKeyStateV1{
UserAddress: "0x1234...",
SessionKey: "0xabcd...",
Version: 1,
Assets: []string{"usdc", "weth"},
ExpiresAt: time.Now().Add(24 * time.Hour),
UserSig: "0x...",
}
err := client.SubmitChannelSessionKeyState(ctx, state)
func (*Client) Transfer ¶
func (c *Client) Transfer(ctx context.Context, recipientWallet string, asset string, amount decimal.Decimal) (*core.State, error)
Transfer prepares a transfer state to send funds to another wallet address. This method handles two scenarios automatically:
- If no channel exists: Creates a new channel with the transfer transition
- If channel exists: Advances the state with a transfer send transition
The returned state is signed by both the user and the node. For existing channels, no blockchain interaction is needed. For new channels, use Checkpoint to create the channel on-chain.
Parameters:
- ctx: Context for the operation
- recipientWallet: The recipient's wallet address (e.g., "0x1234...")
- asset: The asset symbol to transfer (e.g., "usdc")
- amount: The amount to transfer
Returns:
- The co-signed state with the transfer transition applied
- Error if the operation fails
Example:
state, err := client.Transfer(ctx, "0xRecipient...", "usdc", decimal.NewFromInt(50))
fmt.Printf("Transfer tx ID: %s\n", state.Transition.TxID)
func (*Client) WaitCh ¶
func (c *Client) WaitCh() <-chan struct{}
WaitCh returns a channel that closes when the connection is lost or closed. This is useful for monitoring connection health in long-running applications.
Example:
go func() {
<-client.WaitCh()
log.Println("Connection closed")
}()
func (*Client) Withdraw ¶
func (c *Client) Withdraw(ctx context.Context, blockchainID uint64, asset string, amount decimal.Decimal) (*core.State, error)
Withdraw prepares a withdrawal state to remove funds from the user's channel. This operation handles two scenarios automatically:
- If no channel exists: Creates a new channel with the withdrawal transition
- If channel exists: Advances the state with a withdrawal transition
The returned state is signed by both the user and the node, but has not yet been submitted to the blockchain. Use Checkpoint to execute the on-chain transaction.
Parameters:
- ctx: Context for the operation
- blockchainID: The blockchain network ID (e.g., 80002 for Polygon Amoy)
- asset: The asset symbol to withdraw (e.g., "usdc")
- amount: The amount to withdraw
Returns:
- The co-signed state ready for on-chain checkpoint
- Error if the operation fails
Example:
state, err := client.Withdraw(ctx, 80002, "usdc", decimal.NewFromInt(25))
txHash, err := client.Checkpoint(ctx, "usdc")
fmt.Printf("Withdrawal transaction: %s\n", txHash)
func (*Client) WithdrawSecurityTokens ¶
func (c *Client) WithdrawSecurityTokens(ctx context.Context, blockchainID uint64, destinationWalletAddress string) (string, error)
WithdrawSecurityTokens withdraws unlocked tokens from the Locking contract to the specified destination. Can only be called after the unlock period has fully elapsed.
Parameters:
- ctx: Context for the operation
- blockchainID: The blockchain network ID
- destinationWalletAddress: The Ethereum address to receive the withdrawn tokens
Returns:
- Transaction hash
- Error if the operation fails
type Config ¶
type Config struct {
// URL is the WebSocket URL of the clearnode server
URL string
// HandshakeTimeout is the maximum time to wait for initial connection
HandshakeTimeout time.Duration
// PingTimeout is how long to wait for a ping from the server before considering the connection dead.
// The server sends periodic pings to detect dead clients.
PingTimeout time.Duration
// ErrorHandler is called when connection errors occur
ErrorHandler func(error)
// BlockchainRPCs maps blockchain IDs to their RPC endpoints
// Used by SDKClient for on-chain operations
BlockchainRPCs map[uint64]string
}
Config holds the configuration options for the Clearnode client.
type CreateAppSessionOptions ¶
type CreateAppSessionOptions struct {
// OwnerSig is the app owner's signature approving session creation.
// Required when the app's CreationApprovalNotRequired is false.
OwnerSig string
}
CreateAppSessionOptions contains optional parameters for CreateAppSession.
type GetAppSessionsOptions ¶
type GetAppSessionsOptions struct {
// AppSessionID filters by application session ID
AppSessionID *string
// Participant filters by participant wallet address
Participant *string
// Status filters by status ("open" or "closed")
Status *string
// Pagination parameters
Pagination *core.PaginationParams
}
GetAppSessionsOptions contains optional filters for GetAppSessions.
type GetAppsOptions ¶
type GetAppsOptions struct {
// AppID filters by application ID
AppID *string
// OwnerWallet filters by owner wallet address
OwnerWallet *string
// Pagination parameters
Pagination *core.PaginationParams
}
GetAppsOptions contains optional filters for GetApps.
type GetLastChannelKeyStatesOptions ¶
type GetLastChannelKeyStatesOptions struct {
// SessionKey filters by a specific session key address
SessionKey *string
}
GetLastChannelKeyStatesOptions contains optional filters for GetLastChannelKeyStates.
type GetLastKeyStatesOptions ¶
type GetLastKeyStatesOptions struct {
// SessionKey filters by a specific session key address
SessionKey *string
}
GetLastKeyStatesOptions contains optional filters for GetLastKeyStates.
type GetTransactionsOptions ¶
type GetTransactionsOptions struct {
// Asset filters by asset symbol
Asset *string
// Pagination parameters
Pagination *core.PaginationParams
}
GetTransactionsOptions contains optional filters for GetTransactions.
type Option ¶
type Option func(*Config)
Option is a functional option for configuring the Client.
func WithBlockchainRPC ¶
WithBlockchainRPC returns an Option that configures a blockchain RPC client for a specific chain. This is required for the Checkpoint method which settles states on-chain.
Parameters:
- chainID: The blockchain network ID (e.g., 80002 for Polygon Amoy testnet)
- rpcURL: The RPC endpoint URL (e.g., "https://polygon-amoy.alchemy.com/v2/KEY")
Example:
client, err := sdk.NewClient(
wsURL,
stateSigner,
txSigner,
sdk.WithBlockchainRPC(80002, "https://polygon-amoy.alchemy.com/v2/KEY"),
sdk.WithBlockchainRPC(84532, "https://base-sepolia.alchemy.com/v2/KEY"),
)
func WithErrorHandler ¶
WithErrorHandler sets a custom error handler for connection errors. The handler is called when the connection encounters an error or is closed.
func WithHandshakeTimeout ¶
WithHandshakeTimeout sets the maximum time to wait for initial connection.
func WithPingTimeout ¶
WithPingTimeout sets how long to wait for a ping from the server before considering the connection dead.