Deposit
Move funds into a Native Core Pool earning balance, from an EVM chain or from an existing Native Core balance.
Two routes lead into the same earn_balance. Choose the route by where the funds are now.
You send
deposit() on the vault contract
A signed transfer action
Signed with
An EVM transaction
EIP-712 typed data
Minimum
Worth at least 10 USD
None
Settles in
Minutes
About one Core block
deposit_type
bridge_deposit
direct_transfer
Neither route can be cancelled or reversed once the first transaction lands.
Read Native Core Pool first for the base URL, the response envelope, and discovery.
Which assets you can deposit
An asset accepts deposits when it appears in config.assets[] with deposit_enabled: true.
curl -sS "$POOL_API_URL/api/v3/earn" \
-H 'content-type: application/json' \
-d '{"type":"config"}'From an EVM chain
This is the Native Core deposit flow, with one argument changed. Follow Deposit: check whether the account exists, size the activation fee, validate the amount, approve and call the vault, then read the deposit nonce from the receipt. Every rule on that page applies here.
Deposit at least 10 USD, and carry the activation fee as msg.value on a first deposit.
Break either rule and the funds will not be credited.
actionFlag is that argument, and it also decides where the deposit lands and where you confirm it:
actionFlag
0
1
Credited to
The Native Core trading balance
earn_balance
Confirmed with
POST /info deposits
Pool deposits, below
depositFor carries the same argument, so a wallet or custodian depositing on a user's behalf passes actionFlag: 1 the same way.
Confirm the credit
Poll the Pool's deposits and match your source transaction hash.
status: "credited" means the amount is in earn_balance and earning. status: "rejected" means the amount is not credited and the funds require manual recovery from Native.
amount is in the asset's 8-decimal balance_decimals, rescaled from the token's own decimals: 100000000 sent as 6-decimal USDT arrives as 10000000000.
The deposit becomes visible when it is credited, and not before. Hold your own record between submitting the transaction and seeing it appear, because the record does not exist until it reaches credited or rejected. A deposit that has not appeared long after the source transaction confirmed should be reported with its source transaction hash rather than retried.
From a Native Core balance
This route moves an existing Native Core balance into the Pool with one signed action. No EVM chain is involved and there is no minimum.
1. Read the vault address
vault_address from config is the recipient. Read it at runtime; a transfer to a superseded address is not credited.
2. Sign and submit the transfer
transfer is a Native Core action, submitted to the Native Core API rather than to the Pool API. It is an owner action: sign it with the main wallet, never with an API wallet.
The domain carries no chainId, so a wallet signs it while connected to any EVM chain. The chain is bound inside the message as nativeChainId. authKind is 1 and authScope is 0; a transfer has no multi-signature or agent-key path.
A typed-data struct that does not match the definition above recovers a different signer, so a mistake there surfaces as an unknown account rather than as a signature error.
The transfer action goes to Native Core's /trade, which returns the Native Core envelope rather than the Pool envelope. Branch on submission_status and treat timeout as unresolved rather than failed. That endpoint is metered per IP, not per user_address, at 1 request per second. See POST /trade, Transaction Signing, Rate limits & errors, and Handle outcomes & timeouts.
3. Wait for the credit
An accepted transfer debits the Core balance immediately. The Pool credit lands about one Core block later. Treat that as typical latency rather than a guarantee, and poll for the deposit.
The deposit appears in deposits with deposit_type: "direct_transfer" and no transaction hashes — the Pool does not record one for this route. Match on the asset, the amount, and core_event_timestamp_ms, then use operation_id as the key from that point on. operation_id is assigned when the event is ingested and cannot be computed before you submit; your cloid is the handle until it appears.
Reading the deposit list
One query covers both routes and the full credited history.
user_address
—
Required
asset_id
all
Optional filter
limit
50
Over 200 the request fails, it is not clamped
before_id
—
Cursor from the previous page's next_before_id
status only ever reads credited or rejected. The list is filtered by user_address, and ownership is only established at credit time, so nothing in flight is visible.
Three trace fields are absent as keys rather than null when they do not apply, so test with if (row.src_tx_hash):
src_chain_id
bridge_deposit
src_tx_hash
bridge_deposit
core_tx_hash
bridge_deposit
Paging returns next_before_id whenever a page comes back exactly limit long, so the last full page still carries a cursor. One extra request returning an empty page is what confirms the end.
What can go wrong
Deposit mined, never appears
actionFlag was not 1, so it credited the trading balance instead
Check the balance on Native Core; the funds are not lost
Deposit mined, never appears, actionFlag was 1
The amount was below the 10 USD minimum, or the amount or activation fee broke another rule on the Native Core deposit page
See What can go wrong there
status: "rejected"
The asset is not listed for the Pool, or has deposit_enabled: false
Read config before building the transaction
Transfer returns MissingCloid or InvalidCloid
cloid omitted, or not 16 bytes
Send a 16-byte cloid and sign with cloidPresent: true
Transfer rejected for its signing scheme
The binary scheme was used; transfer accepts only auth_scheme: "eip712"
Sign the typed data above and post the 65-byte signature
Transfer returns a parse error
The action carried a field not listed above
Send only type, to, asset_id, amount and cloid
Transfer accepted, nothing in deposits
The asset is not deposit-enabled for the Pool
Nothing will appear; report it with the Core transaction hash
code: 131004 limit exceeds max 200
limit above the cap
The request failed entirely; resend with limit at most 200
Next steps
YieldWithdrawLast updated