Polyester separates Funding balances from Trading balances. The correct integration path depends on where the assets are now, where they need to go, and who is authorized to submit the operation.
Choose by source
- Create or retrieve the account's deposit address through
DepositAddressService. - Send the asset to that address on the source chain.
- Follow the resulting deposit lifecycle until the balance is settled.
Deposit-address creation is available through REST at POST /v1/chain/deposit-addresses and through
ConnectRPC. The external-chain transaction remains a user or wallet action. Depending on the
account's configured route, the credited assets can remain in Funding or continue to Trading.
- Funding โ Trading: submit the TradingGateway deposit on-chain.
- Funding โ Funding: submit a FundingAccount transfer on-chain, or use an enabled delegated route.
- Funding โ external chain: call
FundingAccount.withdrawToChainon-chain. FundingAccount invokes Zipper within that transaction. An enabled delegated route can submit the same supported action.
Funding is chain-visible. Polyester's general REST and ConnectRPC APIs do not replace the account's on-chain authorization for these mutations.
- Trading โ Funding: use the Trading withdraw API with action
TO_FUNDING. - Trading โ external chain: use the Trading withdraw API with action
TO_EXTERNAL_CHAIN. - Trading โ Trading: use
InternalTransferServicefor an off-chain internal transfer.
Trading withdrawals support API-key authorization for server-side integrations and wallet authorization for interactive sessions. Internal transfers and withdrawals require stable idempotency keys.
Validate a Funding withdrawal destination
Use POST /v1/chain/withdraws:validate-destination or the ConnectRPC ValidateWithdrawDestination method to validate an external destination before constructing a
Funding withdrawal transaction. This authenticated request checks the selected network, canonical
address format, Polyester account and contract addresses, and destination safety restrictions. It
does not create or submit a withdrawal.
{
"destinationChainId": "1",
"destinationAddress": "0x1111111111111111111111111111111111111111"
} The response returns VALID, INVALID_ADDRESS, UNSUPPORTED_CHAIN, POLYESTER_SMART_ACCOUNT, TOKEN_CONTRACT, or DENYLISTED_ADDRESS. The accompanying message
explains how to correct the destination without exposing internal denylist notes. A denylisted
address applies across every network that shares the same address family, such as all EVM networks.
Choose an interface and authority path
Use REST when you want HTTP and JSON tooling. Public REST paths cover:
- creating and listing deposit addresses
- validating external destinations for Funding withdrawals
- API-key withdrawals from Trading to Funding or an external chain
- Trading-to-Trading internal transfers
- reading balances, transfer history, configuration, and lifecycle state
Wallet-authorized Trading withdrawals are available at POST /v1/chain/trading-withdraws:wallet; they require the same session, fresh step-up proof, and
wallet signature as the ConnectRPC method.
REST money-movement amounts are exact decimal strings. For example, a Trading-to-Trading request uses:
{
"destinationSmartAccountAddress": "0x2222222222222222222222222222222222222222",
"assetId": 1,
"amount": "0.5",
"idempotencyKey": "transfer-2026-07-16-0001"
}The response also exposes amount as a decimal string.
See REST getting started.
Use ConnectRPC for typed unary methods and official SDK integrations. It covers deposit addresses,
Funding withdraw destination validation, Trading-to-Trading internal transfers, Trading withdrawals,
and funds-related reads. Canonical money amounts remain U128 amount_e18 fields on this transport.
Use realtime channels to monitor lifecycle, balance, and transfer updates after submission. Realtime does not initiate deposits, withdrawals, or transfers.
Use WebSocket JSON where the required channel has a JSON variant, or WebSocket Protobuf for typed channels and official SDK clients.
Use a wallet or smart-account transaction for:
- moving assets from Funding to Trading
- transferring assets between Funding accounts
- withdrawing from Funding
- managing external and internal whitelist state
- enabling or revoking delegated Funding access
The live on-chain fee and contract validation are authoritative. An API estimate or saved destination does not override them.
For TypeScript integrations, see Deposits & withdrawals for the smart-account transaction helpers.
A Funding account can grant delegated access on-chain when Polyester has enabled it for the account and integration. The delegated integration can then submit supported Funding withdrawals and Funding-to-Funding transfers.
Delegated Funding does not authorize Trading operations, whitelist changes, or unrestricted account actions.
After submission
Retry backend APIs safely
For a backend API retry, keep the signed business payload, account scope, destination, amount, nonce, deadline, and idempotency value stable for one logical operation. For an API-key retry, create a fresh timestamp and HTTP request signature.
Track the lifecycle
Store the identifiers returned by the intake or chain transaction. Use lifecycle read methods and realtime channels to correlate later updates.
Wait for settlement
An accepted API request or successful on-chain submission does not necessarily mean the destination balance is settled. For a successful balance move, wait for ledger settlement. Failed, dropped, and refunded lifecycle states are terminal without settlement.
Security boundaries
See Withdraw from Trading for the Trading withdrawal payloads.