Skip to Content
Symmio Frontier — the SDK surface for builders on HyperEVM
CoreAccountLayer

AccountLayer

The AccountLayer contract is where SYMMIO subaccounts live. Each EOA can own multiple subaccounts; each subaccount can route trades into Virtual Accounts (VAs).

This slice also exposes SYMMIO core balance reads for accounts. The account input can be a subaccount or virtual account address depending on what the underlying SYMMIO method accepts.

Reads

getUserSubAccounts

List a user’s subaccounts.

import { getUserSubAccounts } from "@symmio/trading-core"; const subs = await getUserSubAccounts(config, { user: "0xabc...", offset: 0n, limit: 200n, });

Parameters

NameTypeDefaultNotes
userAddressEOA whose subaccounts to list.
offsetbigint0nPagination offset.
limitbigint200nMax number of subaccounts to return. Matches the Explorer Inspector page default.
chainIdnumber?config defaultOptional chain override.

Returnsreadonly SubAccountDetail[].

interface SubAccountDetail { accountAddress: Address; // proxy address on chain owner: Address; // EOA that created this subaccount name: string; // editable via editAccountName isExists: boolean; // false if deleted singleVAMode: boolean; affiliate: Address; symmioCore: Address; metadata: Hex; isolationType: SubAccountIsolationType; }

getAccountBalanceOf

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 transfer, withdraw, or allocate. Read via balanceOf(account) on the SYMMIO diamond.

import { getAccountBalanceOf } from "@symmio/trading-core"; const balance = await getAccountBalanceOf(config, { account: "0xaccount...", });

Parameters

NameTypeDefaultNotes
accountAddressrequiredAccount address passed to balanceOf.
chainIdnumber?config defaultOptional chain override.

Returnsbigint, in raw collateral token units. Use formatUnits(value, 18) / formatEther(value) or the utils package when displaying decimal values.

getAccountBalanceInfo

Read the account’s tradable (allocated) balance info — the collateral that has been allocated to this SubAccount and is available (or locked) for trading, together with the CVA / LF / margin locks currently held against it. Read via balanceInfoOfPartyA(account) on the SYMMIO diamond.

Pair with getAccountBalanceOf for the full picture: balanceOf is the free-to-move pot; balanceInfoOfPartyA is the allocated-and-in-play pot.

import { getAccountBalanceInfo } from "@symmio/trading-core"; const info = await getAccountBalanceInfo(config, { account: "0xaccount...", }); console.log(info.allocatedBalance);

Parameters

NameTypeDefaultNotes
accountAddressrequiredAccount address passed as PartyA to balanceInfoOfPartyA.
chainIdnumber?config defaultOptional chain override.

ReturnsAccountBalanceInfo.

interface AccountBalanceInfo { allocatedBalance: bigint; lockedCVA: bigint; lockedLF: bigint; lockedPartyAMM: bigint; lockedPartyBMM: bigint; pendingLockedCVA: bigint; pendingLockedLF: bigint; pendingLockedPartyAMM: bigint; pendingLockedPartyBMM: bigint; }

All fields are returned in raw collateral token units.

SubAccountIsolationType

enum SubAccountIsolationType { POSITION = 0, // one VA per trade MARKET = 1, // one VA per market MARKET_DIRECTION = 2, // one VA per market + direction CUSTOM = 3, // no automatic VA creation }

Writes

allocate

Move a subaccount’s available balance into its allocated (tradeable) balance — the margin Party A trades against. The call is routed through the AccountLayer _call proxy so the SYMMIO core attributes it to the subaccount; the connected wallet must be the subaccount’s on-chain owner. The subaccount must not be suspended or in liquidation as Party A.

import { allocate } from "@symmio/trading-core"; const hash = await allocate(config, { account: "0xsub...", amount: 1_000000000000000000n, // 18 decimals });

Parameters

NameTypeNotes
accountAddressThe subaccount to allocate into. The signer must equal its on-chain owner.
amountbigintAmount moved into allocated balance, in 18 decimals (not collateral decimals).
chainIdnumber?Optional chain override.
simulateBeforeWriteboolean?Dry-run via simulateContract first (defaults to the config’s setting, itself true by default).

ReturnsHash (the broadcast tx hash).

Dry-run without sending via simulateAllocate(config, params).

deallocate

Move a subaccount’s allocated (tradeable) balance back into its available balance — the reverse of allocate. Routed through the AccountLayer _call proxy; the connected wallet must be the subaccount’s on-chain owner. Requires a fresh Muon uPnL attestation so the contract can verify the subaccount stays solvent, and is subject to the on-chain deallocate debounce.

import { deallocate, getDeallocateUpnlSig } from "@symmio/trading-core"; const upnlSig = await getDeallocateUpnlSig(config, { virtualAccount: "0xsub..." }); const hash = await deallocate(config, { account: "0xsub...", amount: 1_000000000000000000n, // 18 decimals upnlSig, });

Parameters

NameTypeNotes
accountAddressThe subaccount to deallocate from. The signer must equal its on-chain owner.
amountbigintAmount moved back into available balance, in 18 decimals (not collateral decimals).
upnlSigSingleUpnlSigA fresh Muon uPnL attestation — fetch with getDeallocateUpnlSig right before submitting.
chainIdnumber?Optional chain override.
simulateBeforeWriteboolean?Dry-run via simulateContract first (defaults to the config’s setting, itself true by default).

ReturnsHash (the broadcast tx hash).

Dry-run without sending via simulateDeallocate(config, params).

editAccountName

Rename a subaccount.

import { editAccountName } from "@symmio/trading-core"; const hash = await editAccountName(config, { account: "0xsub...", name: "Trading bot", });

Parameters

NameTypeNotes
accountAddressThe subaccount being renamed. The signer must equal the subaccount’s owner on chain.
namestringNew display name.
chainIdnumber?Optional chain override.

ReturnsHash (the broadcast tx hash).

Query options

import { getAccountBalanceInfoQueryOptions, getAccountBalanceOfQueryOptions, getUserSubAccountsQueryOptions, } from "@symmio/trading-core"; useQuery(getAccountBalanceOfQueryOptions(config, { account })); useQuery(getAccountBalanceInfoQueryOptions(config, { account })); useQuery(getUserSubAccountsQueryOptions(config, { user }));

Raw ABI

For consumers that want to call viem directly:

import { accountLayerAbi, symmioAbi } from "@symmio/trading-core"; await publicClient.readContract({ abi: accountLayerAbi, address: accountLayerAddress, functionName: "getUserSubAccounts", args: ["0xabc...", 0n, 200n], }); await publicClient.readContract({ abi: symmioAbi, address: symmioAddress, functionName: "balanceOf", args: ["0xaccount..."], });
Last updated on