AccountLayer hooks
React-query wrappers over @symmio/trading-core’s AccountLayer slice.
The page is split into two groups:
- Reads — TanStack
useQuery-shaped hooks. Same call = same cached result. Refetch on invalidation. - Writes — TanStack
useMutation-shaped hooks. Triggermutate/mutateAsync, watchisPending/data/error, and let the hook invalidate the affected reads for you.
Every write also has a paired useSimulateXyz — see Simulate then write.
Reads
useUserSubAccounts
Read a user’s subaccounts. Returns react-query’s full UseQueryResult shape.
import { useUserSubAccounts, useWalletAccount } from "@symmio/trading-react";
const { address } = useWalletAccount();
const { data, isLoading, error, refetch } = useUserSubAccounts({ user: address });
if (!address) return <p>Connect a wallet.</p>;
if (isLoading) return <Spinner />;
if (error) return <ErrorView kind={error.kind} message={error.message} />;
return (
<ul>
{data?.map((sub) => (
<li key={sub.accountAddress}>{sub.name}</li>
))}
</ul>
);Parameters
| Name | Type | Default | Notes |
|---|---|---|---|
user | Address? | undefined | EOA whose subaccounts to fetch. The query is disabled while this is undefined, so you can pass the connected address without a manual enabled guard. |
offset | bigint? | 0n | Pagination offset. |
limit | bigint? | 200n | Pagination cap. |
chainId | number? | config default | Optional chain override. |
query | object? | undefined | TanStack Query overrides, including enabled. |
Return type
UseQueryResult<readonly SubAccountDetail[], SymmioRequestError> — every field react-query exposes, with the SDK error type.
useAccountBalanceOf
Read the account’s available (deallocated) balance — collateral that lives on the account but is not currently allocated to any SubAccount for trading. This is the amount the user can deposit, withdraw, or allocate. Under the hood: balanceOf(account) on the SYMMIO diamond.
import { formatEther } from "viem";
import { useAccountBalanceOf } from "@symmio/trading-react";
const { data, isLoading, error } = useAccountBalanceOf({ account });
if (isLoading) return <Spinner />;
if (error) return <ErrorView kind={error.kind} message={error.message} />;
return <span>{data === undefined ? "-" : formatEther(data)}</span>;Parameters
| Name | Type | Default | Notes |
|---|---|---|---|
account | Address? | undefined | Account address passed to balanceOf. The query is disabled while undefined. |
chainId | number? | config default | Optional chain override. |
query | object? | undefined | TanStack Query overrides. |
config | Config? | provider value | Optional config override. |
Return type
UseQueryResult<bigint, SymmioRequestError>.
The value is in raw collateral token units. Divide by 1e18 / use formatEther when displaying the current deployments’ 18-decimal collateral values.
useAccountBalanceInfo
Read the account’s tradable (allocated) balance info — collateral allocated to this SubAccount for trading, plus the CVA / LF / margin locks currently held against it. Pair with useAccountBalanceOf for the full picture: available on one side, allocated-and-in-play on the other. Under the hood: balanceInfoOfPartyA(account) on the SYMMIO diamond.
import { formatEther } from "viem";
import { useAccountBalanceInfo } from "@symmio/trading-react";
const { data } = useAccountBalanceInfo({ account });
return <span>{data ? formatEther(data.allocatedBalance) : "-"}</span>;Parameters
| Name | Type | Default | Notes |
|---|---|---|---|
account | Address? | undefined | Account address passed as PartyA to balanceInfoOfPartyA. The query is disabled while undefined. |
chainId | number? | config default | Optional chain override. |
query | object? | undefined | TanStack Query overrides. |
config | Config? | provider value | Optional config override. |
Return type
UseQueryResult<AccountBalanceInfo, SymmioRequestError>.
interface AccountBalanceInfo {
allocatedBalance: bigint;
lockedCVA: bigint;
lockedLF: bigint;
lockedPartyAMM: bigint;
lockedPartyBMM: bigint;
pendingLockedCVA: bigint;
pendingLockedLF: bigint;
pendingLockedPartyAMM: bigint;
pendingLockedPartyBMM: bigint;
}All fields are in raw collateral token units.
Writes
Every hook below returns react-query’s UseMutationResult — call mutate(inputs) (or mutateAsync), watch isPending / data / error, and the hook invalidates the reads it affected on your behalf.
useAllocate
Allocate a subaccount’s available balance into its allocated (tradeable) balance.
The call inputs (account, amount) are passed to mutate; amount is in 18 decimals.
import { useAllocate } from "@symmio/trading-react";
const { mutate, isPending, isSuccess, data, error } = useAllocate();
<button onClick={() => mutate({ account: "0xsub...", amount: 1_000000000000000000n })} disabled={isPending}>
{isPending ? "Sending…" : "Allocate"}
</button>;
{
isSuccess && <p>tx: {data.hash}</p>;
}Options
interface UseAllocateParameters {
waitForReceipt?: boolean; // default true — mutation resolves only after the receipt is mined
confirmations?: number; // default 1
}Cache invalidation
On success, the hook invalidates the subaccount’s useAccountBalanceInfo and useAccountBalanceOf queries in the active QueryClient, so allocated and available balances rerender automatically.
Dry run
useSimulateAllocate() runs the same call through simulateContract without sending — useful to surface a would-be revert before prompting the wallet.
useDeallocate
Deallocate a subaccount’s allocated (tradeable) balance back into its available balance — the reverse of useAllocate. The hook fetches a fresh Muon uPnL signature automatically before submitting (the contract requires it to prove the subaccount stays solvent), unless you pass one as upnlSig. amount is in 18 decimals.
import { useDeallocate } from "@symmio/trading-react";
const { mutate, isPending, isSuccess, data, error } = useDeallocate();
<button onClick={() => mutate({ account: "0xsub...", amount: 1_000000000000000000n })} disabled={isPending}>
{isPending ? "Sending…" : "Deallocate"}
</button>;
{
isSuccess && <p>tx: {data.hash}</p>;
}Options
interface UseDeallocateParameters {
waitForReceipt?: boolean; // default true — mutation resolves only after the receipt is mined
confirmations?: number; // default 1
}Cache invalidation
On success, the hook invalidates the subaccount’s useAccountBalanceInfo and useAccountBalanceOf queries in the active QueryClient, so allocated and available balances rerender automatically.
Muon signature & cooldown
The hook calls getDeallocateUpnlSig for you unless you pass a upnlSig variable. Deallocate is subject to the on-chain debounce — submitting too soon after a prior deallocate reverts — and the result must keep the subaccount solvent; both surface as a normalized SymmioRequestError. useSimulateDeallocate() dry-runs the call (supply a upnlSig there — it does not auto-fetch).
useEditAccountName
Submit a rename transaction.
import { useEditAccountName } from "@symmio/trading-react";
const { mutate, isPending, isSuccess, data, error } = useEditAccountName();
<button onClick={() => mutate({ account: "0xsub...", name: "Trading bot" })} disabled={isPending}>
{isPending ? "Sending…" : "Rename"}
</button>;
{
isSuccess && <p>tx: {data.hash}</p>;
}
{
error?.kind === "user-rejected" ? null : error && <p>{error.message}</p>;
}Options
interface UseEditAccountNameOptions {
waitForReceipt?: boolean; // default true — mutation resolves only after the receipt is mined
confirmations?: number; // default 1
}Cache invalidation
On success, the hook invalidates every cached useUserSubAccounts query in the active QueryClient, so mounted lists rerender with the new name automatically. No manual invalidation needed.
Why this hook needs a connected wallet
The hook reads useSymmioWalletClient() under the hood. If the user is disconnected or on the wrong chain, calling mutate throws a SymmioRequestError with kind: "sdk" before any contract call is made. UIs typically gate the button on useWalletAccount().isOnExpectedChain to avoid the error path entirely.