Minimal Solana JSON-RPC calls over an X402.RPC endpoint.
Provides exactly the RPC surface the SVM facilitator engine needs —
getLatestBlockhash, simulateTransaction, sendTransaction, and
getSignatureStatuses — as thin wrappers around the generic
X402.RPC.request/3, unwrapping Solana's %{"context", "value"} response
envelope where present. It is not a general-purpose Solana client: there is
no account fetching, no address-lookup-table resolution, and no WebSocket
subscription support.
{:ok, rpc} =
X402.RPC.new(
rpc_url: "https://api.devnet.solana.com",
finch: MyApp.Finch
)
{:ok, %{blockhash: blockhash}} = X402.Solana.RPC.get_latest_blockhash(rpc)All transport, TLS, and telemetry behaviour is inherited from X402.RPC
(events carry the Solana method name as :method metadata), and errors are
X402.RPC.error/0 values — node-side failures come back as
{:error, {:jsonrpc_error, %{code: _, message: _, data: _}}}.
Summary
Types
The unwrapped getLatestBlockhash value.
One getSignatureStatuses entry: nil for an unknown signature, or the
status with its confirmationStatus ("processed", "confirmed",
"finalized", or nil) and error term.
The unwrapped simulateTransaction value.
Functions
Fetches the latest blockhash via getLatestBlockhash.
Fetches confirmation statuses for Base58 signatures via
getSignatureStatuses.
Broadcasts a Base64-encoded wire transaction via sendTransaction.
Simulates a Base64-encoded wire transaction via simulateTransaction.
Types
@type latest_blockhash() :: %{ blockhash: String.t(), last_valid_block_height: non_neg_integer() }
The unwrapped getLatestBlockhash value.
One getSignatureStatuses entry: nil for an unknown signature, or the
status with its confirmationStatus ("processed", "confirmed",
"finalized", or nil) and error term.
The unwrapped simulateTransaction value.
err is nil when the simulated transaction would succeed; otherwise the
node's error term (a string or a map, passed through as decoded JSON).
Functions
@spec get_latest_blockhash( X402.RPC.t(), keyword() ) :: {:ok, latest_blockhash()} | {:error, X402.RPC.error()}
Fetches the latest blockhash via getLatestBlockhash.
Returns the blockhash (Base58) and the last block height at which a transaction using it is still valid.
Options
:commitment(String.t/0) - The commitment level for the request. The default value is"confirmed".
@spec get_signature_statuses(X402.RPC.t(), [String.t()]) :: {:ok, [signature_status()]} | {:error, X402.RPC.error()}
Fetches confirmation statuses for Base58 signatures via
getSignatureStatuses.
Returns one entry per requested signature, in request order: nil for
a signature the node does not know, or a map with its
confirmation_status and err (non-nil when the transaction was
included but failed on chain).
The request is issued with searchTransactionHistory: true. The node's
in-memory status cache only retains recent signatures, so pending-store
retries that arrive after a confirmed transaction ages out would otherwise
see nil and never observe the successful payment.
@spec send_transaction(X402.RPC.t(), String.t(), keyword()) :: {:ok, String.t()} | {:error, X402.RPC.error()}
Broadcasts a Base64-encoded wire transaction via sendTransaction.
Sends with skipPreflight: true, matching the reference facilitators —
verification already simulated, and a preflight failure here would be
indistinguishable from a node-side rejection. Returns the Base58
transaction signature acknowledged by the node.
Options
:commitment(String.t/0) - The commitment level for the request. The default value is"confirmed".
@spec simulate_transaction(X402.RPC.t(), String.t(), keyword()) :: {:ok, simulation()} | {:error, X402.RPC.error()}
Simulates a Base64-encoded wire transaction via simulateTransaction.
The simulation runs with sigVerify: false and
replaceRecentBlockhash: false, matching the reference facilitators: the
fee-payer slot is unsigned until settlement, so required signatures must be
verified locally instead (see X402.Verify.SVM), and the embedded
blockhash is part of what is being validated.
Returns the node's simulation verdict — err: nil means the transaction
would succeed.
Options
:commitment(String.t/0) - The commitment level for the request. The default value is"confirmed".