TESTNET
Markets
Trade
Lending Vaults
More
User Docs Developer Docs Sdk API Docs Help
Overview
Overview
Architecture
Authentication
Client configuration
Overview
Environments
Installation
Market data
Market data services
Authentication model
Quickstart
Trading
Trading services
Account services
Catalog & precision
Streaming
Accounts & balances
Funding services
Deposits & withdrawals
Realtime client
Errors
Server-side usage
Error handling
  1. Typescript
  2. /
  3. Deposits & withdrawals

Deposits & withdrawals

What chains and assets are supported?

Zipper is Polyester's deposit/withdraw bridge. Its public configuration lists every supported chain, unified asset, and per-chain route — including network fees and minimums:

const config = await client.zipper.getDepositWithdrawConfig();

The same data is easier to consume through the catalog's zipper reader, which adds lookups and conversions:

await client.catalog.ensureReady();

const chains = client.catalog.zipper.listChains();
const usdc = client.catalog.zipper.requireAssetBySymbol("USDC");
const route = client.catalog.zipper.requireAssetChain("USDC", "ethereum");

Deposits

Create (or fetch) a deposit address for an account on a given chain, then send funds to it:

const address = await client.deposit.createAddress({ chainId });
const addresses = await client.deposit.listAddresses();

Deposit addresses are per-account — pass account to get a subaccount's address.

Tracking with lifecycle flows

Cross-chain operations (deposits, withdrawals) progress through multi-step lifecycle flows. The lifecycle service reads and streams their state, so you can show users exactly where their funds are:

const { flows } = await client.lifecycle.listFlows({
	/* kind/state/account filters */
});
const flow = await client.lifecycle.getFlow({ flowId });

// find the flow for a transaction hash
const byTx = await client.lifecycle.listFlowsByTx({ txHash });

// live progress
const unsubscribe = client.lifecycle.subscribeFlowDetail({
	flowId,
	onEvent: (detail) => updateProgress(detail),
});

subscribeOpenFlows streams summaries of all open flows for an account.

Ledger transfers

Every balance movement is a ledger transfer. List and stream them:

const { transfers, nextPageToken } = await client.transfers.list({ limit: 50 });

const unsubscribe = client.transfers.subscribe({
	accountId,
	onEvent: (transfer) => console.log(transfer),
});

Internal transfers

Move funds between Polyester accounts (root ↔ subaccount, or to another user) without touching a chain:

const result = await client.internalTransfers.create({
	/* destination (root / subaccount / smart account), asset, decimal amount */
});

Destinations can be resolved from user input with client.accounts.resolve(...), and saved ones come from the address book (client.addressBook.listTransferDestinations()). Internal transfer requests are idempotent.

Withdrawals from Trading

Withdrawals out of the Trading venue are signed intents. Two destinations:

// Trading → Funding (stays on Polyester)
await client.tradingWithdraws.createToFunding({
	/* asset, decimal amount, destination, signature or walletSigner */
});

// Trading → an external chain
await client.tradingWithdraws.createToExternalChain({
	/* asset, gross decimal amount, destination network + address, signature or walletSigner */
});

Each intent includes a short deadline (~5 minutes), a nonce, and an idempotency key, and must be signed — either pass a walletSigner for an EIP-712 wallet signature, or a precomputed payloadSignature when signing with API-key infrastructure.

Guard signers
Accounts protected by a guard use client.guardSigner to co-sign protected actions: signProtectedAction / batchSignProtectedActions produce the approval signatures, and createWallet / rotateWallet / exportWallet manage the backend guard wallet itself.

On-chain actions with the smart account

For operations that require sending an actual chain transaction from the user's smart account (rather than an API request), the @polyester/sdk/smart-account subpath wires viem + account-abstraction against the environment's bundler and paymaster:

import {
	createPolyesterSmartAccount,
	createPolyesterSmartAccountClient,
	sendPolyesterUserOperation,
} from "@polyester/sdk/smart-account";

const account = await createPolyesterSmartAccount({ environment, owner });
const smartAccountClient = createPolyesterSmartAccountClient(account, { environment });

await sendPolyesterUserOperation(smartAccountClient, {
	calls: [
		/* ... */
	],
});

sendPolyesterUserOperation estimates gas and applies a safety buffer before submitting. predictPolyesterSmartAccountAddress computes the account address without any RPC calls.

Previous

Funding services

Next

Realtime client

  • What chains and assets are supported?
  • Deposits
  • Tracking with lifecycle flows
  • Ledger transfers
  • Internal transfers
  • Withdrawals from Trading
  • On-chain actions with the smart account