Skip to main content
The Monaco vault is the bridge between a user’s Sei wallet and Monaco account balances. Deposits move assets into Monaco for trading. Withdrawals move available balances back on-chain. Trading inside Monaco is gasless, but deposits and withdrawals are on-chain wallet transactions. Users still need SEI gas for those settlement actions.

Surface Map

Mental Model

Wallet assets are not tradable until they enter Monaco. Deposits move assets from the connected wallet into Monaco’s vault. Spot orders reserve balances from the user’s Monaco spot account. Perps trades use collateral held in the user’s perps account. Withdrawals move available balances back out of Monaco. Funds locked by open orders, pending operations, or required as perps collateral cannot be withdrawn until they are released.

Deposit Flow

1

Authenticate the wallet

Create a Monaco session for the connected wallet before calling vault methods.
2

Resolve the asset ID

Monaco vault methods use asset UUIDs. The easiest way to find an asset ID is from a trading pair’s baseAssetId or quoteAssetId.
3

Approve the vault

Check whether approval is needed, then approve Monaco’s vault contract to spend the ERC20 token if required.
4

Deposit into Monaco

Deposit to the spot account by default, or route directly to margin collateral when the integration is funding perps.
Allowances are wallet-side ERC20 approvals for Monaco’s vault contract. They are not Monaco account balances, but they determine whether a deposit needs an approval transaction before the deposit transaction.

Deposit Directly to Perps Collateral

By default, vault.deposit() credits the user’s spot account. Pass "margin" as the target when you want to route the on-chain deposit directly into perps collateral.
If margin routing is unavailable for the asset or account, Monaco falls back to spot. Keep this visible in your UI by refreshing both account balances and perps collateral after the transaction.

Registered Deposit Addresses

Instead of prompting a wallet through the approve → deposit flow, you can give a user a stable, deterministic deposit address and have deposits of the watched assets swept into Monaco automatically — the transfer indexer filters to the token addresses getChains() lists, so an unlisted ERC20 sent there is not swept. Every (application, user, deposit target) triple maps to one such address; sdk.sweeper.register({ depositTarget? }) (POST /api/v1/sweeper/register; gRPC SweeperService.Register) registers it so the backend monitors the address and sweeps a watched asset once its accumulated balance reaches that asset’s minimum, crediting the user — no per-deposit signature or transaction from your app. A deposit that leaves the balance below the minimum stays on the address until a later one brings it up. The call is authenticated and carries no identity of its own: the application and the credited address both come from the session, so each user registers through their own client. It is idempotent and returns the derived address immediately, so you can display and fund it before any contract exists there. depositTarget: "margin" asks for swept deposits to land in the parent margin account’s collateral; because the target is part of the derivation, spot and margin have two different deposit addresses. As with a direct deposit, margin routing that is unavailable for the asset or account falls back to spot, so refresh both balances rather than treating a margin address as proof of collateral credit. One registration covers every chain the sweeper watches: the derived address is identical on all of them and is monitored on all of them, so the request carries no chain. sdk.sweeper.getChains() (GET /api/v1/sweeper/chains; gRPC SweeperService.GetChains) lists that set — per chain its EVM chain id, name, whether it is the settlement hub deposits are bridged into, and the swept assets with their token addresses, decimals, and minimum sweep amounts in raw base units. It is public, so a deposit page can show where a user may send before they have a session; a balance below an asset’s minimum waits on the address until a later deposit brings the total up to it (the sweep skips a balance strictly below the minimum, so an exact-minimum total sweeps). See the Vault SDK guide for the full request/response shape and error cases.

Withdrawal Flow

1

Authenticate the wallet

The user must be signed in before requesting a vault withdrawal.
2

Resolve the asset ID

Use a trading pair or an existing balance row to find the Monaco asset UUID.
3

Check available balance

Compare the requested amount against availableBalanceRaw, not total balance. Locked funds are not withdrawable.
4

Withdraw to the wallet

Submit the withdrawal and wait for the on-chain transaction result.

Asset IDs

Monaco uses asset UUIDs for vault operations instead of symbols or token addresses. This prevents ambiguity when assets share symbols, appear in multiple products, or map to different contracts across networks. Trading pairs expose the asset IDs most builders need:
Balance rows also include assetId for assets the user already holds.

Builder Checklist

  • Explain that deposits and withdrawals require wallet confirmations and SEI gas.
  • Use asset IDs for vault operations; do not pass token symbols to deposit or withdrawal methods.
  • Refresh balances after approval, deposit, withdrawal, or retry.
  • Disable withdrawals for balances locked by open orders, pending operations, or perps margin requirements.