Skip to Content
Symmio Trading-SDK — the SDK surface for builders on Arbitrum
ReactTransactions

Transactions

What a write hook does with your variables

Every write hook forwards its mutation variables to the core action verbatim. It defaults only chainId (to the connected chain) and injects the values its own docs name — useDeallocate’s upnlSig when you omit it, useWithdraw’s account and isolationType. Anything a hook takes over is removed from its variables type with Omit<>.

That is the contract, and it is what makes the type honest: a field that type-checks is a field that is honored. So an optional parameter on the core action — gasless, from, simulateBeforeWrite — reaches the action just by being passed to mutate.

from is worth calling out because it plays three roles depending on the path:

  • on a simulation, it is the dry-run msg.sender (the useSimulate* hooks default it to the connected address);
  • on a write, it is a hint handed to config.getWalletClient({ chainId, from }) — write hooks forward it but never default it, so a custom multi-signer resolver keeps whatever default it chose;
  • on a relayed write, the wallet that resolver returns signs the InstantLayer operation, so from selects the EIP-712 signer. That is separate from the billing sub-account, which comes from the action itself or from gasless.account.

Transactions store

A small, opt-in zustand  store for tracking in-flight tx hashes in the UI — the data backing pending-tx badges, post-confirmation toasts, and “view in explorer” links.

The SDK’s mutation hooks (useEditAccountName, future writes) do not populate this store automatically. You wire it up where it makes sense for your app.

API

interface TrackedTx { hash: Hash; chainId: number; label: string; // human-readable: "Rename account" status: "pending" | "confirmed" | "failed"; createdAt: number; // Date.now() at insertion } interface TransactionsStoreState { txs: readonly TrackedTx[]; add: (tx: Omit<TrackedTx, "status" | "createdAt">) => void; markConfirmed: (hash: Hash) => void; markFailed: (hash: Hash) => void; clear: () => void; }

Usage

Subscribe

Standard zustand. Pass a selector for fine-grained subscriptions:

import { useTransactionsStore } from "@symmio/trading-react"; function PendingBadge() { const pendingCount = useTransactionsStore((s) => s.txs.filter((t) => t.status === "pending").length); if (pendingCount === 0) return null; return <span className="badge">{pendingCount} pending</span>; }

Track a tx from a mutation

const { mutateAsync } = useEditAccountName({ waitForReceipt: false }); const add = useTransactionsStore((s) => s.add); const markConfirmed = useTransactionsStore((s) => s.markConfirmed); const markFailed = useTransactionsStore((s) => s.markFailed); async function rename() { const { hash } = await mutateAsync({ account, name }); add({ hash, chainId, label: "Rename account" }); try { await publicClient.waitForTransactionReceipt({ hash }); markConfirmed(hash); } catch { markFailed(hash); } }

If you’d rather have the hook await the receipt for you and skip the store, set waitForReceipt: true (the default) and ignore this whole section.

Why opt-in

Tx tracking is UI plumbing — every app’s needs differ (toast positioning, persistence, deduplication). The store is small enough that you can replace it with your own zustand or Redux slice without changing the hooks that produce tx hashes.

Last updated on