Skip to main content
sauce send broadcasts transactions you signed with any signer, waits for each one, and reports what it did.

Synopsis

Description

sauce send takes transactions signed by a hardware wallet, a KMS or another wallet’s tool, typically from a sauce tx plan. It never takes a key. Each operand is one signed transaction:
  • on an EVM chain, the raw 0x… hex a signer returns; the chain and the sender are read from it;
  • on Solana, the base64 wire transaction; every signature is checked against its message.
- reads the transactions from stdin, separated by whitespace. The transactions go out in the order given. Each is simulated as it was signed before it is sent: on an EVM chain an eth_call from its sender with the gas and fees it was signed with, which a program can read, its gas limit held to what that call used; on Solana a simulation that checks the signatures. A transaction that would fail is not sent: the reason is printed, the command exits 1, and nothing after it is sent. Each transaction is confirmed before the next is simulated, so a cook signed after its Pot’s deployment runs on the deployed Pot. On an EVM chain, every cook and Pot deployment among the transactions is first held to the Pot guard, all together: a cook must go to a Pot of this SDK’s release, or to one a transaction before it deploys, and each deployment must put its Pot where the Kitchen says (predictPot, or predictSharedPot for a Shared Pot). A step that fails the guard stops the batch before anything is sent, naming the step, so a transfer into a Pot does not land ahead of a cook that would be refused. A signed Kitchen.deployPot for owner zero is refused the same way, before any funding is sent. For each transaction it prints the hash (a signature on Solana), status and cost, the explorer and trace links, the decoded reason a failure gives, and for a cook what moved and what it left in the Pot; on Solana what main returned.
  • A transaction the chain already has is read back, not sent again. One the chain had, pending, then lost (dropped or reorged out) is reported gone, to sign again.
  • A Solana transaction lands within about a minute of being built, or never: one whose blockhash has expired is refused, to build and sign again. One missing a signature (the fee payer’s, or any its message names) is refused, naming the missing signer.
  • On Arc, a transaction signed with a fee cap below the chain’s minimum base fee of 20 gwei is refused before anything is sent, since it would never be included.
  • A Pot deployment that lands is recorded in the Pot store, as sauce run records it.
A Solana plan. A Solana cook too large for one transaction is a plan of steps: the setup (the Pot, token accounts, the program staged in a code buffer, a lookup table), the cook, then closing the code buffer. sauce tx prints the first step and its cursor. With --cursor, sauce send sends the step’s signed transactions, then prints the next step, built from what the cluster shows, with the cursor for the step after it. --cursor alone builds the next step without sending anything. --signature confirms a transaction of the plan you broadcast another way. --close gives up on the cook and closes the code buffer. A cursor carries no key and no endpoint. Solana covers plans in full. sauce send sends only on a supported chain: Ethereum, Base, Arc and Solana, and the testnets Arc Testnet, Base Sepolia, Ethereum Sepolia, Solana Devnet and Solana Testnet. On a preview chain it is refused before any endpoint is reached, with a message that names the supported chains and how to request the refused one.

Prerequisites

  • Transactions signed by your signer, such as a sauce tx plan.
  • For a cook on an EVM chain, the release’s engine deployed on the chain. sauce pot --chain <chain> --owner <address> reports whether it is.

Options

Output

With --json, stdout carries one object: Exit codes: 0 when every transaction succeeded; 1 when one would fail, reverted or was lost, when the Pot guard refuses the batch, or on a preview chain; 2 for a usage error, including a transaction that is not signed or not a transaction.

Examples

These examples show what sauce send refuses before anything is sent; none broadcasts a transaction. The unsigned transaction is the offline cook from sauce tx, serialized with viem’s serializeTransaction and no signature. A real sauce tx plan, once signed, is sent as sauce send <deployment> <cook>: the Pot’s deployment first, then the cook.

Refuse an unsigned transaction

The command exits 2.

Refuse input that is not a transaction

The command exits 2.

Refuse a preview chain

The same unsigned transaction, serialized with Arbitrum’s chain id:
The chain is read from the transaction, and the refusal comes before the signature is checked. The command exits 1.

Refuse a batch before anything is sent

Two transactions signed for Base: a transfer of 0.001 ETH into an owner’s Pot that has no code yet, then the cook on that Pot from a sauce tx plan, without the plan’s Kitchen.deployPot:
Run on a local fork of Base at block 53157283 with the current contracts. The command exits 1, the transfer is not sent either, and the Pot’s balance stays 0. With the plan’s deployment ahead of the cook, the cook goes to a Pot the batch deploys, which the guard accepts.

Next steps

  • sauce tx: the unsigned transactions to sign.
  • sauce run: sign and send with a wallet or key the command holds.
  • External wallets: signing outside the sauce command.
  • Solana: plans, cursors and code buffers.