Generate Custody Address
A custody deposit address is assigned to one SoDEX user (an EVM account) on one external chainName. It is the destination for a custody deposit, not a bridge contract. Create or query it through the Deposit Addresses API, then confirm the same value is stored on ValueChain before displaying it or sending funds.
Create or query
Each creation request consumes 200 REST weight from the IP budget. Use GET for polling. See Address creation rate limit.
chain must be the exact chainName from Asset Configuration for a route with custody.allowDeposit equal to true. The path {userAddress} is the receiving user's EVM address on ValueChain.
Query an existing assignment:
curl -sS "https://mainnet-gw.sodex.dev/api/v1/user/YOUR_USER_ADDRESS/deposit-address?chain=TON" \
-H "Accept: application/json"If address and status are empty, request creation for that chain:
curl -sS -X POST "https://mainnet-gw.sodex.dev/api/v1/user/YOUR_USER_ADDRESS/deposit-address" \
-H "Content-Type: application/json" \
--data '{"chain":"TON"}'To start creation for every custody chain available to the user:
curl -sS -X POST "https://mainnet-gw.sodex.dev/api/v1/user/YOUR_USER_ADDRESS/deposit-addresses" \
-H "Content-Type: application/json"Poll GET until status is terminal. Creation is asynchronous; an empty or Processing address is not a deposit destination.
status
Meaning
Empty
No assignment yet. POST to create, then poll.
Processing
Creation in progress. Keep polling.
Enabled
API has an address. Verify it on chain before use.
Suspicious
Do not display or send to this address.
POST does not transfer funds and does not require a private key. A poll timeout is not permission to send.
Verify on ValueChain
The API can return Enabled before you treat the destination as authoritative. Read SoDexTokenCustody on ValueChain Mainnet (0xB37295d1ea21E65b76dCB2E85e035eE0dBFC70CB) and require the API address to appear in the on-chain list for the same account and chain.
accountis the same EVM address used in the API path.chainis the samechainNamestring used in the API (TON, not a chain ID).getDepositWalletListis the list to check against. If the list is empty but a legacy single wallet exists, the contract returns that wallet as a one-element list.getDepositWalletis the legacy single mapping. Do not use it alone when the list can contain more than one destination.
The API address is correct only if it is an exact string in getDepositWalletList. Custody destinations are often non-EVM (for example TON); do not checksum or rewrite the string. An empty list means this account and chain are not stored on chain yet — keep polling the API and the contract; do not send.
Only after this check should the address be shown or used as a deposit destination. Then follow Custody Deposits to transfer from the external network.
Last updated