Classifies failures from sendAndConfirmTransaction so callers can decide
whether to retry (transient, e.g. chained-transfer funds not yet settled) or
fail fast (deterministic program error).
Insufficient funds reaches us two ways, and both must be recognised:
Thrown at preflight by HeliusRpcClient.sendTransaction — a plain
Error whose message embeds the RPC error JSON and program logs, e.g.
Solana RPC sendTransaction returned error -32002: …custom program error: 0x1 {"err":{"InstructionError":[3,{"Custom":1}]},"logs":[…"Program log: Error: insufficient funds"…]}
Nothing here keys off that prefix — the signals are the logs and the
error code embedded in the message, so the wording is free to change.
Returned from confirmation by getSignatureStatuses as the structured
status.err, e.g. { InstructionError: [n, { Custom: 1 }] } — an object
with NO substring and NO logs.
SPL Token's InsufficientFunds is custom error code 1 (0x1). Our mintfx
programs CPI the Token program and propagate that code, so a Custom: 1 at
the failing instruction means insufficient funds in the transfer/redeem flows.
Other custom codes (e.g. 3012 AccountNotInitialized, 3002 discriminator
mismatch) are deterministic and must not be retried.
A fee payer out of SOL is a different failure that reads almost the same:
InsufficientFundsForRent renders as "…with insufficient funds for rent",
which matches the token substring below. It is classified first and
separately, because the remedy is topping up PAYER, not waiting.
Classifies failures from
sendAndConfirmTransactionso callers can decide whether to retry (transient, e.g. chained-transfer funds not yet settled) or fail fast (deterministic program error).Insufficient funds reaches us two ways, and both must be recognised:
Thrown at preflight by
HeliusRpcClient.sendTransaction— a plainErrorwhose message embeds the RPC error JSON and program logs, e.g.Solana RPC sendTransaction returned error -32002: …custom program error: 0x1 {"err":{"InstructionError":[3,{"Custom":1}]},"logs":[…"Program log: Error: insufficient funds"…]}Nothing here keys off that prefix — the signals are the logs and the error code embedded in the message, so the wording is free to change.
Returned from confirmation by
getSignatureStatusesas the structuredstatus.err, e.g.{ InstructionError: [n, { Custom: 1 }] }— an object with NO substring and NO logs.SPL Token's
InsufficientFundsis custom error code1(0x1). Our mintfx programs CPI the Token program and propagate that code, so aCustom: 1at the failing instruction means insufficient funds in the transfer/redeem flows. Other custom codes (e.g.3012AccountNotInitialized,3002discriminator mismatch) are deterministic and must not be retried.A fee payer out of SOL is a different failure that reads almost the same:
InsufficientFundsForRentrenders as "…with insufficient funds for rent", which matches the token substring below. It is classified first and separately, because the remedy is topping upPAYER, not waiting.