Inner balances
The engine holds assets for two kinds of owners: accounts (users) and DEXs. Each owner has an inner balance per asset. Swaps, transfers and DEX calls only move amounts between inner balances. Tokens leave the engine only when they’re withdrawn.
An owner is written as { "Account": "alice.near" } or { "Dex": "slimedragon.near/xyk" } in method arguments.
The near CLI examples on this page run in order, as alice.near after a storage deposit. Together they’re one script.
Register assets
Section titled “Register assets”An owner can only receive an asset that is registered for it. Anything that would credit an unregistered asset fails with Asset <asset> is not registered for Account(<account>). This includes deposits, the output of swaps, and transfers.
near contract call-function as-transaction dex.intear.near register_assets \ json-args '{"asset_ids": ["near", "nep141:usdt.tether-token.near"]}' \ prepaid-gas '30.0 Tgas' attached-deposit '1 yoctoNEAR' \ sign-as alice.near network-config mainnet sign-with-keychain sendAnd for another account:
near contract call-function as-transaction dex.intear.near register_assets \ json-args '{ "asset_ids": ["nep141:usdt.tether-token.near"], "for": {"Account": "bob.near"} }' \ prepaid-gas '30.0 Tgas' attached-deposit '1 yoctoNEAR' \ sign-as alice.near network-config mainnet sign-with-keychain sendforis optional and defaults to you. You can register assets for another account or for a DEX.- The storage is always paid from your storage balance, even when registering for someone else.
- Assets that are already registered are skipped. Registration can’t be undone.
Use are_assets_registered to check, for example before building a transaction:
near contract call-function as-read-only dex.intear.near are_assets_registered \ json-args '{ "asset_ids": ["near", "nep141:usdt.tether-token.near"], "for": {"Account": "alice.near"} }' \ network-config mainnet nowDeposit
Section titled “Deposit”Deposits credit your inner balance. Each kind of asset arrives in its own way:
| Asset | How to deposit | Credited to |
|---|---|---|
near |
deposit_near on the engine, with the NEAR attached |
The caller |
nep141:<contract> |
ft_transfer_call on the token, to dex.intear.near |
sender_id |
nep171:<contract>:<token id> |
nft_transfer_call on the NFT contract, to dex.intear.near |
previous_owner_id |
nep245:<contract>:<token id> |
mt_transfer_call or mt_batch_transfer_call on the contract, to dex.intear.near |
Each previous_owner_id |
Leave msg empty ("") for a plain deposit, and don’t pass operations to deposit_near. Each plain deposit logs a user_deposit event.
near contract call-function as-transaction dex.intear.near deposit_near \ json-args '{}' \ prepaid-gas '30.0 Tgas' attached-deposit '1 NEAR' \ sign-as alice.near network-config mainnet sign-with-keychain sendnear contract call-function as-transaction usdt.tether-token.near ft_transfer_call \ json-args '{"receiver_id": "dex.intear.near", "amount": "5000000", "msg": ""}' \ prepaid-gas '50.0 Tgas' attached-deposit '1 yoctoNEAR' \ sign-as alice.near network-config mainnet sign-with-keychain sendWith a non-empty msg, the deposit doesn’t go to your inner balance: the tokens are used by the operations in msg.
If the deposit fails, for example because the asset isn’t registered for you, the token contract gets the tokens back to you, as NEP-141, NEP-171 and NEP-245 transfers do when the receiver fails.
You can also deposit NEAR with execute_operations: if you attach more than 1 yoctoNEAR, the whole deposit is added to your inner balance before the operations run.
Check balances
Section titled “Check balances”near contract call-function as-read-only dex.intear.near asset_balance_of \ json-args '{"of": {"Account": "alice.near"}, "asset_id": "nep141:usdt.tether-token.near"}' \ network-config mainnet now
near contract call-function as-read-only dex.intear.near registered_assets_of \ json-args '{"account_id": "alice.near", "from_index": 0, "limit": 100}' \ network-config mainnet nowasset_balance_of returns the balance, or null if the asset isn’t registered for the owner.
registered_assets_of returns [[asset_id, balance], ...] for every registered asset, in the order they were registered. Pass dex_id instead of account_id for a DEX. Exactly one of them is required.
Transfer
Section titled “Transfer”transfer_asset moves an amount from your inner balance to another account or DEX inside the engine. The receiver must have the asset registered.
near contract call-function as-transaction dex.intear.near transfer_asset \ json-args '{ "to": {"Account": "bob.near"}, "asset_id": "nep141:usdt.tether-token.near", "amount": "1000000" }' \ prepaid-gas '30.0 Tgas' attached-deposit '1 yoctoNEAR' \ sign-as alice.near network-config mainnet sign-with-keychain sendWithdraw
Section titled “Withdraw”withdraw sends assets from your inner balance out of the engine: NEAR with a transfer, tokens with ft_transfer, nft_transfer or mt_transfer.
A NEP-141 token can only be sent to a wallet that is registered on the token contract. Register bob.near there first, unless they already hold the token:
near contract call-function as-transaction usdt.tether-token.near storage_deposit \ json-args '{"account_id": "bob.near", "registration_only": true}' \ prepaid-gas '30.0 Tgas' attached-deposit '0.00125 NEAR' \ sign-as alice.near network-config mainnet sign-with-keychain sendThen withdraw to them:
near contract call-function as-transaction dex.intear.near withdraw \ json-args '{ "asset_id": "nep141:usdt.tether-token.near", "amount": {"Exact": "2000000"}, "withdraw_to": "bob.near" }' \ prepaid-gas '50.0 Tgas' attached-deposit '1 yoctoNEAR' \ sign-as alice.near network-config mainnet sign-with-keychain send| Argument | Description |
|---|---|
asset_id |
The asset to withdraw |
amount |
{ "Exact": "<amount>" }, or { "Full": { "at_least": "<amount>" } } for the whole balance. Full fails if the balance is lower than at_least. at_least can be null |
withdraw_to |
The wallet to send to. Optional, defaults to you |
The amount leaves your inner balance right away, and the transfer happens in the next receipt. The method returns true if the transfer succeeded, and logs a withdraw event.
If the transfer fails, it returns false and the assets are refunded to an inner balance:
- to the receiver (
withdraw_to), if the asset is registered for them in the engine, - otherwise back to you.
Withdrawing an amount of 0 does nothing and returns true.