Conditional transactions API (eth_sendRawTransactionConditional) on Robinhood Chain
Last updated:
Conditional or plain send?
Use the conditional method when a late or stale inclusion is worse than no inclusion:
- a bot or backend that priced an action against a block and must not execute it many blocks later;
- a quote or order that expires at a wall-clock time;
- a transaction built against specific storage values (a pool reserve, a nonce slot, an allowance) that must not run if those values change first;
- account-abstraction bundlers: ERC-7796 names the ERC-4337 use case as one the method makes workable.
Use plain eth_sendRawTransaction when the transaction is valid whenever it lands — a transfer, a deposit. A condition you do not need is only one more way for a good transaction to be refused.
One request
curl https://triport.io/rpc/robinhood -X POST \
-H 'Content-Type: application/json' -H "x-token: $TRIPORT_API_KEY" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_sendRawTransactionConditional",
"params":["0x<signed tx>",{
"blockNumberMax":"0x<parent-chain block>",
"timestampMax":"0x<unix seconds>",
"knownAccounts":{"0x<20-byte address>":{"0x<32-byte slot>":"0x<32-byte value>"}}
}]}'
# -32602 "invalid conditional options: ..." -> Triport rejected the shape; nothing was sent
# "result":"0x<tx hash>" -> routed; confirm with eth_getTransactionReceiptFive options are accepted. Anything else is rejected, not ignored:
| Option | Compared with (Arbitrum Nitro) | Shape Triport accepts |
|---|---|---|
blockNumberMin, blockNumberMax | The parent-chain block number (l1BlockNumber in a Robinhood Chain block), inclusive | Non-negative hex or decimal number (send hex, the JSON-RPC convention) |
timestampMin, timestampMax | The Robinhood Chain block timestamp, inclusive | Non-negative hex or decimal number (send hex) |
knownAccounts | Each account's storage root, or individual storage slot values | 20-byte address → 32-byte root hash, or → object of 32-byte slot → 32-byte value |
The block-number trap
On the Arbitrum Nitro stack that Robinhood Chain runs on, blockNumberMin and blockNumberMax are checked against the parent-chain block number, not against the Robinhood Chain block number that eth_blockNumber returns. The two are far apart: Robinhood Chain block 56,782,442 carried l1BlockNumber 25,925,047 (Triport's eth_getBlockByNumber example, 7 September 2026).
- A
blockNumberMaxcomputed frometh_blockNumbersits tens of millions of blocks above the parent chain, so it never expires: the deadline you think you set does nothing. - A
blockNumberMincomputed the same way is never reached, so every submission is refused.
Read the current block with eth_getBlockByNumber("latest", false), take its l1BlockNumber, and add your margin to that. Several Robinhood Chain blocks share one parent-chain number, so this bound is coarse; when the deadline is really about time, use timestampMax.
What comes back, and what to do
| Response | Who answered | What to do |
|---|---|---|
-32602 invalid conditional options: <field>: <reason> | Triport, before any upstream call | Fix the named field. Nothing was sent and no gas was spent. See invalid conditional options. |
-32003 with a message such as BlockNumberMax condition not met | The chain's node, relayed with its code | The condition already failed. Re-read the state, rebuild and re-sign; resending the same bytes fails again. |
-32000 upstream unavailable (HTTP 503) | Triport: no submission target answered | Nothing was accepted. Resend the same signed transaction after a pause; the hash does not change. |
"result": "0x…" (transaction hash) | The first submission target to answer | Routed, not included. Poll eth_getTransactionReceipt by hash. |
No receipt after your blockNumberMax or timestampMax | Nobody: the bound has passed, so the chain can no longer include it | Close the attempt. Rebuild against fresh state if the action is still worth taking. |
Triport validates option names and shapes and never evaluates the conditions. The messages it returns name the field, for example blockNumberMax: must be a non-negative hex or decimal number, paysCoinbase: unknown field or knownAccounts: 0x…: address must be 20-byte hex. In a JSON-RPC batch each conditional element is dispatched on its own, so one malformed element gets its own -32602 and the rest go ahead.
One method name, three rule sets
The method is written up as ERC-7796, “Conditional send transaction RPC”, and the OP Stack sequencer implements it too. Code written against the ERC or another stack's documentation does not carry over unchanged:
| Behaviour | ERC-7796 (draft text) | OP Stack sequencer | Robinhood Chain via Triport |
|---|---|---|---|
| Options | The five above, plus paysCoinbase; knownAccounts may also pin balance, code, nonce | The five above | The five above; the extra ERC-7796 fields are refused with -32602 |
| Block bounds checked against | Block number; the stack is not specified | Checked against the parent of the latest block | The parent-chain block number (l1BlockNumber) |
| Condition failed | -32003 transaction rejected | -32003 | -32003 … condition not met, relayed by Triport |
| Cost or rate cap | -32005 limit exceeded | -32005; per-conditional cost capped, off by default on the node | The plan's robinhood_send_tx budget (below) |
| Malformed options | Not specified | Not described | -32602 from Triport, nothing sent |
Plans
eth_sendRawTransactionConditional and eth_sendRawTransaction share one per-second budget, robinhood_send_tx, from tier-matrix.yaml — the same source as RPC pricing. A batch of N submissions costs N. The key needs the robinhood:rpc scope.
| What | Free trial (7 days) | Basic $20/mo | Pro $249/mo | Business $499/mo | Enterprise from $999/mo |
|---|---|---|---|---|---|
| Transaction submission | 3 RPS sustained · up to 6 burst | 5 RPS sustained · up to 10 burst | 30 RPS sustained · up to 60 burst | 80 RPS sustained · up to 160 burst | No per-category cap |
A flat monthly price, no credits or overage. These budgets are configured plan limits, not measured capacity — see Robinhood Chain limits.
What it does not do
- Not private orderflow. The transaction goes to the sequencer like any other.
- Not a queue advantage. Robinhood Chain sequencing is first-come, first-served; a condition does not move a transaction forward.
- Not proof of inclusion. A returned hash means routed. Only a receipt shows the outcome.
- Not evaluated by Triport. Triport checks names and shapes; the chain checks the conditions.
- Not a substitute for on-chain checks. A condition narrows the window for stale execution; keep the checks your contract needs anyway.
FAQ
- What does a conditional transaction protect me from?
- From your transaction executing against a world it was not built for: after a deadline, outside a time window, or after a storage slot you depend on has changed. Instead of landing and reverting (and paying for it), the transaction is refused.
- Does Triport check whether my conditions hold?
- No. Triport checks the option names and value shapes and answers -32602 locally when they are wrong. Whether the conditions hold is decided by the chain's own nodes when they check the transaction.
- Which block number do blockNumberMin and blockNumberMax compare against?
- On the Arbitrum Nitro stack, which Robinhood Chain runs on, against the parent-chain block number that each Robinhood Chain block carries as l1BlockNumber, not against eth_blockNumber. Timestamps are compared with the Robinhood Chain block timestamp.
- I got a transaction hash. Is my transaction included?
- No. A hash means a submission target accepted the request. Inclusion is proven only by a receipt from eth_getTransactionReceipt. Stop polling once your own deadline has passed.
- Is a conditional send private or faster?
- No. It is not private orderflow and it does not move a transaction forward in the queue. Robinhood Chain sequencing is first-come, first-served; conditions only decide whether the transaction may still be included.
- Which plan do I need?
- Every plan, including the 7-day trial: the method shares the robinhood_send_tx budget with eth_sendRawTransaction. The key needs the robinhood:rpc scope.
Sources
- Triport, Conditional transaction submission and the step-by-step guide: accepted options, local validation, per-item batches.
- Arbitrum Nitro source, checked 13 October 2026: arbitrum_types/txoptions.go (block bounds against the parent-chain block number, timestamps against the L2 block,
-32003messages) and execution/gethexec/tx_pre_checker.go (conditions checked when the transaction is pre-checked, and again when it is sequenced). - ERC-7796: Conditional send transaction RPC, checked 13 October 2026.
- OP Stack: SendRawTransactionConditional, checked 13 October 2026.
- Triport
tier-matrix.yaml, categoryrobinhood_send_tx.