SingularityDocs
Integrations

Integrations · Reference

RPC, WebSocket, and SDK contracts

The RPC layer translates client requests into reads, simulations, unsigned instruction plans, or transaction admission. Consensus executes admitted transactions later. Build around that separation: retain the transaction identity, wait for a receipt, inspect its execution result, and monitor node health before treating the endpoint as an available service.

This reference describes the inspected checkout. Published client versions and deployed behavior are scoped separately in compatibility and availability. For an ordered diagnosis, use Inspect a transaction.

Use the CLI guide for shell tasks, quickstart for a verified first transaction artifact, HILSA interfaces for foreign evidence, and edge routing for proxy/cache behavior.

The basic HTTP contract

The node's configured RPC listener defaults to port 8899 and loopback binding. HTTP JSON-RPC errors ordinarily retain HTTP 200; inspect the error member. Invalid JSON is -32700, missing method is -32600, unknown method is -32601, and malformed parameters commonly produce -32602.

The transport bounds headers to 32 KiB and request bodies to 2 MiB, with header/body read deadlines. JSON-RPC batches default to 256 items through SVM_RPC_MAX_BATCH; invalid or zero overrides restore a bounded default. Batch members execute serially through dispatch and share the request's authorization header. The HTTP accept loop itself does not provide the WebSocket listener's connection semaphore; use the public proxy's connection/rate policy. Transport and batch handling, batch dispatcher.

Many Solana-shaped methods use positional arrays. HILSA often expects an object directly. The dispatcher passes params through without globally converting one form into the other. This matters when using SDK methods that always construct arrays.

Core read and submission shapes

MethodParametersResult and boundary
getHealth[]"ok" or -32005; detects halted persistence drain and configurable height stall
getSlot, getBlockHeight[]Current reported height
getGenesisHash, getVersion[]Chain identity or build information, not a health guarantee
getBalance[base58Pubkey, config?]{context:{slot},value:lamports}
getAccountInfo[base58Pubkey, {encoding:"base64"}]Context and account or null; account includes owner, lamports, executable flag, and encoded data
getLatestBlockhash[config?]Context and blockhash/last-valid-height fields used to build a transaction
sendTransaction[encodedTransaction,{encoding:"base64"}]First transaction signature after ingest acknowledgement
getSignatureStatuses[[signature,...],config?]Context and per-signature null or receipt-backed status
getTransaction[signature,config?]Detailed SVM transaction/receipt or null
eto_getTransaction[signatureOrEvmHash]Unified explorer receipt; ecosystem-specific missing-result behavior
eth_sendRawTransaction[0xSignedRlp]EVM hash when admitted, subject to the source checkout's sponsored-envelope gate
eth_getTransactionReceipt[0xHash]EVM receipt or null; inspect status, not merely existence

A built-in program may receive a synthesized loader account when no committed account exists at its address. Static discovery fields such as mining/hashrate or empty account lists are compatibility responses, not evidence of those subsystems. Use compatibility and availability for those distinctions.

getHealth is an operational check. A halted persistence drain always fails it; ETO_HEALTH_STALL_SECS defaults to 30, while zero disables only the stall check. GET /health expresses the same failure as HTTP 503 for a load balancer. The earlier public check reported a halted drain and slot 431998. At 01:44 UTC on 8 September 2026, the refreshed health request instead returned -32000 with Upstream error (HTTP 521); it did not expose the node's own health verdict. Health verdict.

Submission checks are not full preflight execution

sendTransaction accepts explicit base64 or base58 encoding. Without an encoding it tries the historical accepted encodings; specifying one removes ambiguity. It checks the decoded transaction size before deserialization. The default admission ceiling is 1 MiB, capped by the decoder's 4 MiB hard maximum.

It then resolves version-0 lookup tables for the next execution slot, validates required-signature count and nonzero signatures, verifies signatures, and checks recent blockhash or valid durable nonce. Public Solana legacy/v0 bytes remain the signed wire form; lookup-table addresses are re-resolved from authoritative state before execution. Historical native Borsh transactions are also decoded. The internal ETOV0TX1 envelope is not a public submission format. Submission admission, decoder policy.

An externally submitted transaction cannot use the built-in faucet as its fee payer. Embedded EVM instructions receive additional chain-ID, recovered-sender, and nonce validation. The handler tracks sequential nonce consumption within a multi-instruction bundle, so N,N+1 and N,N are not treated identically.

Forwarding succeeds only when ingest returns HTTP 200 with accepted >= 1. Connection failure, an unparseable response, or zero accepted entries becomes an RPC error. Even that positive acknowledgement precedes proposal inclusion, execution, finality, and local durable drain. EVM checks and forwarding, ingest acknowledgement.

The handler does not run the full simulation endpoint before forwarding. Client skipPreflight terminology must not be interpreted as an option to skip server signature, nonce, or blockhash checks.

Interpret receipt status precisely

ObservationMeaning
Builder returned an instructionA candidate is encoded; it has not been submitted
sendTransaction returned a signatureAdmission and ingest acknowledgement passed
Status entry is nullThis node has no receipt for that signature; the reason is not determined
Status is present with err:nullThe node has a receipt recording successful execution
Status is present with non-null errFinalized execution failure; retain the receipt for diagnosis
A client timed outIts observation deadline expired; this does not establish rejection

The source getSignatureStatuses handler returns every found receipt as confirmationStatus:"finalized" and confirmations:null, alongside slot, err, and legacy status. These fixed fields do not independently check consensus proofs or disk durability. The handler does not expose a progression through processed and confirmed. Malformed signature entries also map to null. Status handler.

Receipt visibility and power-loss durability are different boundaries: finalized results may precede the asynchronous persistent-store drain. Applications requiring restart guarantees must also understand unified persistence and durability recovery.

The explorer's missing SVM transaction can be an RPC error where the EVM path returns null. The typed EtoRpc.getTransaction wrapper normalizes its expected transaction-not-found case to null. Do not generalize that behavior to arbitrary errors or assume a missing receipt proves the signed bytes are safe to replace.

Simulation request and result

Use:

simulateTransaction [
  encodedTransaction,
  {encoding:"base64", sigVerify:false, replaceRecentBlockhash:false}
]

The two booleans default to false. Simulation resolves lookups, checks compute-budget instructions, optionally verifies signatures, and checks blockhash validity unless replacement was requested. It runs against the next execution slot with a disposable simulation executor.

The result contains context plus execution error, logs, units consumed, and return data. Return data, when present, identifies its program and base64 bytes. A successful simulation is a prediction for that state and execution profile, not a reservation of balances, accounts, blockhash validity, or future inclusion. Unsupported paths that cannot preserve simulation isolation must fail rather than mutate real state. Simulation handler, isolated execution.

eth_call and estimation also need their selected engine and native integration to be available. Source support for a method does not imply CPU fallback when CuEVM is missing.

Builders, sponsorship, and administration

Prefer unsigned builders such as eto_buildWorkflow and the durable HILSA builders when the client should retain signing authority. They return programId, ordered account metas, instruction bytes, and required signers. Preserve each leg's narrower account permissions when assembling a workflow; a union of outer writable accounts must not silently widen a child call's permissions. Workflow builder.

Several legacy convenience calls instead create operator-funded envelopes. eto_crossVmCall, eto_moveExecute, eto_deployWasm, and eto_deployMove require ETO_RPC_SPONSORED_WRITES=1. Raw EVM submission in this checkout uses a different ETO_RPC_FAUCET_SIGN=1 gate after recovering the ECDSA signer and validating chain 17743 and nonce. Enabling one switch does not enable the other. These are development-oriented source paths, not a public sponsorship promise. Sponsored call gate, raw EVM envelope.

Administrative mutations such as eto_addValidator and eto_validatorVote require a nonempty configured ETO_ADMIN_TOKEN and matching credential. Prefer Authorization: Bearer …; the source retains deprecated parameter-based authentication. Denial is -32004 Unauthorized, not method-not-found. Read-only membership calls and unsigned registration builders do not all share the same mutation semantics. Admin authorization.

Faucet requests are separate capped operations. The SDK helper defaults to requesting 2 SING and waits for status; server policy controls grants, per-request limits, per-recipient/day limits, and the global budget. Do not blindly retry a faucet call after an ambiguous response. No faucet request was executed for this documentation run.

WebSocket subscriptions and recovery

The node exposes Ethereum eth_subscribe types newHeads, logs, and newPendingTransactions. Solana-shaped subscriptions include accounts, programs, logs, signatures, slots, and roots. blockSubscribe is off by default and requires ETO_WS_ENABLE_BLOCK_SUBSCRIPTION; voteSubscribe is absent.

Solana subscription IDs are numeric; Ethereum IDs are strings. Their notifications use the corresponding ecosystem method names. A signature subscription is one-shot: after sending the finalized receipt outcome, the server removes it.

The internal broadcast channel has 4,096 slots. Ordinary event streams can lose events when a subscriber lags. Signature subscriptions have extra protection: installation-time receipt lookup and lag reconciliation consult receipt state so a dropped one-shot event is not the only chance to observe completion. These protections do not make every log/account stream a durable queue. After disconnect, recreate subscriptions and reconcile from authoritative reads or indexed history. Notification formats and receipt lookup, lag handling.

Defaults include 8,192 concurrent WebSocket connections and 256 subscriptions per socket. Handshake/write/idle deadlines bound stalled peers. A full connection semaphore returns HTTP 503 with retry guidance; exceeding the subscription cap produces a resource error. Quiet connections receive a ping before being reaped. WebSocket limits, operator overrides.

SDK layers and their limits

The source package provides three client styles:

ClientAppropriate use
Upstream-compatible ConnectionSolana-shaped calls, transactions, subscriptions
EtoRpcTyped extension wrappers and HTTP transport with custom headers/fetch
SingularityRpcManifest-derived namespace methods returning caller-selected/unknown types

SingularityRpc builds positional arrays from function arguments. Its manifest coverage tests prove mapping to listed method names, not compatibility with each current server schema. For object-parameter HILSA handlers, a namespace call such as chainHead({chain:2}) sends [{chain:2}], which this checkout's handler does not unwrap. Use direct JSON-RPC with object params, or an explicitly adapted transport, until the client and server contracts agree. Builders that accept a one-element array are a separate case. Namespace transport, dispatcher parameter handling.

Bombil remains under legacy onebook / eto_oneBook* names in the SDK manifest. Their presence does not establish runtime handlers or a released Bombil service. See Bombil's exact names and activation contracts and VM explanation.

sendAndConfirm(connection, transaction, signers, options) fills a missing blockhash, signs when signers are supplied, sends once, then polls at a default 200 ms interval for up to 30 seconds. It accepts any present error-free status because the expected server reports finalized receipts directly. It does not independently require confirmationStatus === "finalized"; use it only against the intended chain contract. Errors retain the submitted signature and, for an execution failure, the transaction error. The CLI's confirmation loop separately checks confirmed/finalized status. SDK confirmation.

serializeUnchecked bypasses the upstream total-wire 1,232-byte check while retaining the wire layout. It does not bypass every upstream codec limit or verify signatures for you. The upstream message encoder still has a bounded instruction section and one-byte account indices. packInstructions preserves instruction order, splits at encodable boundaries, and returns transactions plus maximum measured size. It infers a payer from the first signer only when you omit one; a sizing blockhash is cleared before return unless a real one was supplied. A multi-transaction pack is not one atomic transaction. Serializer and packing, packing options.

The executed SDK 0.2.0 offline example signed two transfers, serialized 264 bytes, decoded both instructions, verified signatures, and rejected a modified amount. It sent nothing to the chain. Quickstart provides the reproducible example and its exact success output.

Bounded queries and integration tests

Split large reads: getMultipleAccounts is capped at 100 addresses, getProgramAccounts rejects result sets over 1,000, and log/filter queries have range, result, address, and topic bounds. EVM filter IDs are process-local with expiration; retain an independent application cursor if you need restart recovery. Fees and limits owns the numerical limits.

High-value source tests exercise malformed framing, signature and nonce rejection, lookup resolution, simulation isolation, receipt error shapes, subscription reconciliation, builder account permissions, and SDK transport mapping. The run used focused read-only and offline checks, without compiling the full Cargo graph or claiming end-to-end RPC execution on the halted public node.

Updated Sep 8, 2026View source

On this page