mechanisms/svm
import "github.com/x402-foundation/x402/go/v2/mechanisms/svm"
Constants
Source: mechanisms/svm/constants.go:11
const (
// SchemeExact is the scheme identifier for exact payments
SchemeExact = "exact"
// DefaultDecimals is the default token decimals for USDC
DefaultDecimals = 6
// DefaultComputeUnitPriceMicrolamports is the default compute unit price in microlamports
DefaultComputeUnitPriceMicrolamports = 1
// MaxComputeUnitPriceMicrolamports is the maximum compute unit price in microlamports (facilitator validation limit)
// 5 lamports = 5,000,000 microlamports
MaxComputeUnitPriceMicrolamports = 5_000_000
// DefaultComputeUnitLimit is the default compute unit limit for transactions
// Set to 20000 to accommodate: transfer (~6200 CUs) + memo (~8500 CUs without signer) + budget instructions (~300 CUs) + headroom
DefaultComputeUnitLimit uint32 = 20000
// MaxMemoBytes is the maximum byte length for seller-defined memo data (extra.memo)
MaxMemoBytes = 256
// LighthouseProgramAddress is the Phantom/Solflare Lighthouse program address
// Phantom and Solflare wallets inject Lighthouse instructions for user protection on mainnet transactions.
// - Phantom adds 1 Lighthouse instruction (4th instruction)
// - Solflare adds 2 Lighthouse instructions (4th and 5th instructions)
// We allow these as optional instructions to support these wallets.
// See: https://github.com/x402-foundation/x402/issues/828
LighthouseProgramAddress = "L2TExMFKdjpN9kozasaurPirfHy9P8sbXoAN1qA3S95"
// MemoProgramAddress is the SPL Memo program address
MemoProgramAddress = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"
// DefaultCommitment is the default commitment level for transactions
DefaultCommitment = rpc.CommitmentConfirmed
// MaxConfirmAttempts is the maximum number of confirmation attempts
MaxConfirmAttempts = 30
// ConfirmRetryDelay is the base delay between confirmation attempts
ConfirmRetryDelay = 1 * time.Second
// SettlementTTL is how long a transaction is held in the duplicate settlement cache.
// Covers the Solana blockhash lifetime (~60-90s) with margin.
SettlementTTL = 120 * time.Second
// CAIP-2 network identifiers (V2)
SolanaMainnetCAIP2 = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
SolanaDevnetCAIP2 = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"
SolanaTestnetCAIP2 = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z"
// V1 network names
SolanaMainnetV1 = "solana"
SolanaDevnetV1 = "solana-devnet"
SolanaTestnetV1 = "solana-testnet"
// USDC mint addresses
USDCMainnetAddress = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
USDCDevnetAddress = "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"
USDCTestnetAddress = "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" // Same as devnet
)Variables
Source: mechanisms/svm/constants.go:73
var (
// NetworkConfigs maps CAIP-2 identifiers to network configurations
// See DEFAULT_ASSETS.md for guidelines on adding new networks
NetworkConfigs = map[string]NetworkConfig{
SolanaMainnetCAIP2: {
Name: "Solana Mainnet",
CAIP2: SolanaMainnetCAIP2,
RPCURL: "https://api.mainnet-beta.solana.com",
DefaultAsset: AssetInfo{
Address: USDCMainnetAddress,
Symbol: "USDC",
Decimals: DefaultDecimals,
},
},
SolanaDevnetCAIP2: {
Name: "Solana Devnet",
CAIP2: SolanaDevnetCAIP2,
RPCURL: "https://api.devnet.solana.com",
DefaultAsset: AssetInfo{
Address: USDCDevnetAddress,
Symbol: "USDC",
Decimals: DefaultDecimals,
},
},
SolanaTestnetCAIP2: {
Name: "Solana Testnet",
CAIP2: SolanaTestnetCAIP2,
RPCURL: "https://api.testnet.solana.com",
DefaultAsset: AssetInfo{
Address: USDCTestnetAddress,
Symbol: "USDC",
Decimals: DefaultDecimals,
},
},
}
// V1ToV2NetworkMap maps V1 network names to CAIP-2 identifiers
V1ToV2NetworkMap = map[string]string{
SolanaMainnetV1: SolanaMainnetCAIP2,
SolanaDevnetV1: SolanaDevnetCAIP2,
SolanaTestnetV1: SolanaTestnetCAIP2,
}
)Source: mechanisms/svm/mint_cache.go:16
var (
ErrMintAccountNotFound = errors.New("mint account not found")
ErrUnknownMintTokenProgram = errors.New("unknown token program")
ErrFailedToDecodeMintData = errors.New("failed to decode mint data")
)Functions
func DecodeTransaction(base64Tx string) (*solana.Transaction, error)
Source: mechanisms/svm/utils.go:173
DecodeTransaction decodes a base64 encoded Solana transaction
func EncodeTransaction(tx *solana.Transaction) (string, error)
Source: mechanisms/svm/utils.go:227
EncodeTransaction encodes a Solana transaction to base64
func FormatAmount(amount uint64, decimals int) string
Source: mechanisms/svm/utils.go:136
FormatAmount converts an amount in smallest units to a decimal string
func GetAssetInfo(network string, assetSymbolOrAddress string) (*AssetInfo, error)
Source: mechanisms/svm/utils.go:58
GetAssetInfo returns information about an asset on a network
func GetNetworkConfig(network string) (*NetworkConfig, error)
Source: mechanisms/svm/utils.go:42
GetNetworkConfig returns the configuration for a network
func GetTokenPayerFromTransaction(tx *solana.Transaction) (string, error)
Source: mechanisms/svm/utils.go:191
GetTokenPayerFromTransaction extracts the token payer (owner) address from a transaction This looks for the TransferChecked instruction and returns the owner/authority address
func IsValidNetwork(network string) bool
Source: mechanisms/svm/types.go:111
IsValidNetwork checks if the network is supported for Solana
func MessageHash(tx *solana.Transaction) (string, error)
Source: mechanisms/svm/utils.go:163
MessageHash returns a stable, immutable cache key for a transaction by hashing its message bytes. The fee-payer signature (slot 0) is mutable - the facilitator overwrites it before broadcast - so keying on the full wire bytes would let an attacker bypass deduplication by randomizing those bytes. The message is what every signer commits to, so its hash uniquely and immutably identifies a payment.
func NewMintMetadataCache() *MintMetadataCache
func NewSettlementCache() *SettlementCache
Source: mechanisms/svm/settlement_cache.go:18
NewSettlementCache creates a new, empty SettlementCache.
func NormalizeNetwork(network string) (string, error)
Source: mechanisms/svm/utils.go:23
NormalizeNetwork converts V1 network names to CAIP-2 format
func ParseAmount(amount string, decimals int) (uint64, error)
Source: mechanisms/svm/utils.go:95
ParseAmount converts a decimal string amount to token smallest units
func PayloadFromMap(data map[string]interface{}) (*ExactSvmPayload, error)
Source: mechanisms/svm/types.go:91
PayloadFromMap creates an ExactSvmPayload from a map
func ValidateSolanaAddress(address string) bool
Source: mechanisms/svm/utils.go:84
ValidateSolanaAddress checks if a string is a valid Solana address
Types
type AssetInfo
Source: mechanisms/svm/types.go:58
AssetInfo contains information about a SPL token
type AssetInfo struct {
Address string // Mint address
Symbol string // Token symbol (e.g., "USDC")
Decimals int // Token decimals
}Fields
Address stringMint address
Symbol stringToken symbol (e.g., "USDC")
Decimals intToken decimals
type ClientConfig
Source: mechanisms/svm/types.go:74
ClientConfig contains optional client configuration
type ClientConfig struct {
RPCURL string // Custom RPC URL
}Fields
RPCURL stringCustom RPC URL
type ClientSvmSigner
Source: mechanisms/svm/types.go:23
ClientSvmSigner defines client-side operations
type ClientSvmSigner interface {
// Address returns the signer's Solana address (base58)
Address() solana.PublicKey
// SignTransaction signs a Solana transaction
SignTransaction(ctx context.Context, tx *solana.Transaction) error
}Methods
Address func() solana.PublicKeyAddress returns the signer's Solana address (base58)
SignTransaction func(ctx context.Context, tx *solana.Transaction) errorSignTransaction signs a Solana transaction
type ExactSvmPayload
Source: mechanisms/svm/types.go:12
ExactSvmPayload represents a SVM (Solana) payment payload
type ExactSvmPayload struct {
Transaction string `json:"transaction"` // Base64 encoded Solana transaction
}Fields
Transaction string`json:"transaction"`Base64 encoded Solana transaction
func ToMap() map[string]interface{}
Source: mechanisms/svm/types.go:84
ToMap converts an ExactSvmPayload to a map for JSON marshaling
type ExactSvmPayloadV1
Source: mechanisms/svm/types.go:17
ExactSvmPayloadV1 - alias for v1 compatibility
type ExactSvmPayloadV1 = ExactSvmPayloadtype ExactSvmPayloadV2
Source: mechanisms/svm/types.go:20
ExactSvmPayloadV2 - alias for v2 (currently identical, reserved for future)
type ExactSvmPayloadV2 = ExactSvmPayloadtype FacilitatorSvmSigner
Source: mechanisms/svm/types.go:34
FacilitatorSvmSigner defines facilitator operations for SVM Supports multiple signers for load balancing, key rotation, and high availability All implementation details (RPC clients, key management) are hidden
type FacilitatorSvmSigner interface {
// GetAddresses returns all addresses this facilitator can use as fee payers for a network
// Enables dynamic address selection for load balancing and key rotation
GetAddresses(ctx context.Context, network string) []solana.PublicKey
// SignTransaction signs a transaction with the signer matching feePayer
// Transaction is modified in-place to add the facilitator's signature
// Returns error if no signer exists for feePayer or signing fails
SignTransaction(ctx context.Context, tx *solana.Transaction, feePayer solana.PublicKey, network string) error
// SimulateTransaction simulates a signed transaction to verify it would succeed
// Returns error if simulation fails
SimulateTransaction(ctx context.Context, tx *solana.Transaction, network string) error
// SendTransaction sends a signed transaction to the network
// Returns transaction signature or error if send fails
SendTransaction(ctx context.Context, tx *solana.Transaction, network string) (solana.Signature, error)
// ConfirmTransaction waits for transaction confirmation
// Returns error if confirmation fails or times out
ConfirmTransaction(ctx context.Context, signature solana.Signature, network string) error
}Methods
GetAddresses func(ctx context.Context, network string) []solana.PublicKeyGetAddresses returns all addresses this facilitator can use as fee payers for a network Enables dynamic address selection for load balancing and key rotation
SignTransaction func(ctx context.Context, tx *solana.Transaction, feePayer solana.PublicKey, network string) errorSignTransaction signs a transaction with the signer matching feePayer Transaction is modified in-place to add the facilitator's signature Returns error if no signer exists for feePayer or signing fails
SimulateTransaction func(ctx context.Context, tx *solana.Transaction, network string) errorSimulateTransaction simulates a signed transaction to verify it would succeed Returns error if simulation fails
SendTransaction func(ctx context.Context, tx *solana.Transaction, network string) (solana.Signature, error)SendTransaction sends a signed transaction to the network Returns transaction signature or error if send fails
ConfirmTransaction func(ctx context.Context, signature solana.Signature, network string) errorConfirmTransaction waits for transaction confirmation Returns error if confirmation fails or times out
type MintMetadata
Source: mechanisms/svm/mint_cache.go:22
MintMetadata contains the stable fields clients need to build SPL transfers.
type MintMetadata struct {
TokenProgramID solana.PublicKey
Decimals uint8
}Fields
TokenProgramID solana.PublicKeyDecimals uint8
type MintMetadataCache
Source: mechanisms/svm/mint_cache.go:28
MintMetadataCache caches mint owner and decimals for one client instance.
type MintMetadataCache struct {
// contains filtered or unexported fields
}func GetOrFetch( ctx context.Context, rpcClient *rpc.Client, network string, mint solana.PublicKey, ) (MintMetadata, error)
type NetworkConfig
Source: mechanisms/svm/types.go:66
NetworkConfig contains network-specific configuration See DEFAULT_ASSETS.md for guidelines on adding new chains
type NetworkConfig struct {
Name string // Network name
CAIP2 string // CAIP-2 identifier
RPCURL string // Default RPC URL
DefaultAsset AssetInfo // Default stablecoin
}Fields
Name stringNetwork name
CAIP2 stringCAIP-2 identifier
RPCURL stringDefault RPC URL
DefaultAsset AssetInfoDefault stablecoin
type ServerConfig
Source: mechanisms/svm/types.go:79
ServerConfig contains optional server configuration.
type ServerConfig struct {
RPCURL string // Custom RPC URL for challenge enrichment
}Fields
RPCURL stringCustom RPC URL for challenge enrichment
type SettlementCache
Source: mechanisms/svm/settlement_cache.go:12
SettlementCache is a thread-safe in-memory cache for deduplicating concurrent settlement requests. A single instance should be shared across V1 and V2 facilitator scheme instances so that a transaction submitted through one protocol version is also blocked on the other.
type SettlementCache struct {
// contains filtered or unexported fields
}func Entries() map[string]time.Time
Source: mechanisms/svm/settlement_cache.go:41
Entries returns a snapshot of the underlying map - use only in tests.
func IsDuplicate(key string) bool
Source: mechanisms/svm/settlement_cache.go:27
IsDuplicate returns true if key is already pending settlement (duplicate). Otherwise it records the key as newly pending and returns false. Callers should reject the settlement when this returns true.
func Mu() *sync.Mutex
Source: mechanisms/svm/settlement_cache.go:46
Mu returns the mutex - use only in tests.
