executePrepared
Re-check market state, simulate as the wallet, send the prepared call, and wait for a typed receipt.
Sends a frozen PreparedAction. This is the write path for trades and other SDK actions.
Internally this is the viem pattern: simulateContract as the wallet account, then sendTransaction. It does not rewrite calldata. If the market moved, you get StaleStateError instead of a silent re-quote.
Floor actions (raiseIfEligible, raiseManyIfEligible) skip that market-stale check because prepared.to is the controller or Multicall3, not the FloorMarket. Use raiseIfEligible or sv3.transactions.sendPrepared for those.
Import
import { createSv3Client } from "@repo/contract-client";
Usage
const prepared = await sv3.trade.prepareBuyForReserveBudget({
market,
amount: parseUsdc("1"),
slippageBps: 100n,
});
const pending = await sv3.transactions.executePrepared(prepared);
const confirmed = await pending.wait();
confirmed.hash;
confirmed.events;
Flow:
- Confirm
walletClientand thataccountmatchesprepared.account. - Re-read
stateNonceandmarketStateHash. On mismatch throwStaleStateError. simulateContractwith the wallet account.sendTransaction.waitconfirms and decodes protocol events.
acceptStale: true skips the nonce check but still re-simulates and never rewrites calldata.
Return Value
Promise<PendingProtocolTransaction>
| Field | Meaning |
|---|---|
hash | Transaction hash |
request | The simulated request that was sent |
simulation | simulateContract result |
wait() | See wait |
wait() returns { hash, receipt, events }.
Parameters
prepared
- Type:
PreparedAction
From sv3.trade.prepare*. Frozen: to, data, functionName, args, deadline, constraints.
await sv3.transactions.executePrepared(prepared);
options.confirmations (optional)
- Type:
number
Passed through to wait.
await sv3.transactions.executePrepared(prepared, { confirmations: 2 });
options.acceptStale (optional)
- Type:
boolean - Default:
false
await sv3.transactions.executePrepared(prepared, { acceptStale: true });
options.permit (optional)
- Type:
PermitData
Pass a collected EIP-2612 signature. getRequirements never sends approve itself.
await sv3.transactions.executePrepared(prepared, { permit });
Error
| Error | When |
|---|---|
WalletClientRequiredError | No wallet |
AccountMismatchError | Prepared account ≠ wallet |
StaleStateError | Nonce or state hash moved |
SimulationFailedError | simulateContract reverted; cause is ProtocolRevertError |
TransactionRejectedError | Wallet rejected the send |
TransactionRevertedError | Mined revert; cause is decoded when possible |
See Errors.
Tips
- Always simulate as the connected account. Simulating as the zero address misses allowance and pause checks the wallet will hit.
- If you already have a hash (for example a wallet that sent outside the SDK), confirm with
sv3.transactions.wait(hash)instead.