Back to Ccxt

DeFi Commands

.agents/skills/binance-agentic-wallet/references/defi.md

4.5.6539.1 KB
Original Source

DeFi Commands

Query DeFi protocols, investment opportunities, and the user's DeFi positions. Execute DeFi transactions (deposit, redeem, LP, claim).

Sign-in required: All DeFi commands require an active Agentic Wallet session. If the user is not signed in, ask them to sign in first (auth signin) before running any defi command.

Always preview before executing: Before running any state-changing command (deposit, redeem, lp-add, lp-remove, claim), call defi preview --action <action> ... with the same parameters first. Show the user the estimated fee, balance changes, and any warnings. Only proceed after the user confirms.

Post-trade verification

After a successful state-changing call (deposit / redeem / lp-add / lp-remove / claim), backend data is not immediately consistent — there is a delay before the change reflects in subsequent reads. Follow these rules when the user asks to verify the result:

  1. Set expectations on submit. A returned txHash only means the transaction was submitted — it may still be pending in the mempool, and it could still fail on-chain (revert, run out of gas, be dropped). Tell the user something like "submitted; not yet confirmed on-chain. Data may take a moment to update, ask any time to check." Do NOT claim the deposit / redeem / claim is complete, and do NOT call any verification query immediately after — it will just show stale data.

  2. First verification = normal query, no --refresh. When the user asks to check, call defi position without --refresh. Most of the time data is already updated.

  3. If the data still doesn't look updated after the normal query, you MAY call defi position --refresh once. Do NOT chain multiple --refresh calls back-to-back — --refresh is server-side rate-limited, and refreshes should be spaced at least several minutes apart. This is the only sanctioned exception to the "don't pass --refresh by default" rule.

  4. On rate-limit errors from --refresh:

    • Do NOT surface the raw error to the user.
    • Fall back to a regular query (no --refresh) and present whatever data is available.
    • Tell the user data may still be syncing and to retry after a few minutes.
  5. Never claim "transaction failed" based on a stale read. A txHash is only proof that the tx was submitted — it does NOT prove it succeeded on-chain. Backend position queries also lag behind the chain, so a stale read is not evidence of failure either. If verification queries still show no change, the answer is "syncing — check the block explorer for the tx's on-chain status", not "it failed".

Display Rules (apply to ALL defi commands)

When summarizing or rendering any field below to the user, format to exactly 2 decimal places (round half-up). Do not drop trailing zeros, do not switch to scientific notation, do not omit the unit.

Field kindExamples in JSONRender as
APY / APR (always decimal)apy: "0.0432", apy: "2.12"4.32%, 212.00%
TVL (USD)tvl: "1187356864", tvl: "2851031.25"$1,187,356,864.00, $2,851,031.25
USD valuestokenValue, protocolTotalValue, deFiTotalValue, fdv, valueUsd$57.40, $1,807.99
Health factorhealthRate: "1.85"1.85
Ratios / shares (0–1)ratio: "0.5"50.00%
Slippage (basis points)slippageBps: "100"1.00%

Notes for the model:

  • apy is ALWAYS a decimal fraction — multiply by 100 to get the percentage. "0.04"4.00%, "2.12"212.00%. Values can exceed 1.0 (>100% APY is normal for some LP pools). Never display raw decimal to user.
  • apy is base APY only — it does NOT include earn campaign / promotional APY. Numbers may differ from values shown on the protocol's official website. Mention this if the user asks why the number differs.
  • At the protocol level (defi protocol-list / defi protocol-info), apy is the MAX APY across all the protocol's pools / investments — not every pool yields this rate. When presenting to the user, call it "max APY" or "up to X%" so they don't assume every position under this protocol earns that same rate. To see the per-investment APY, use defi investment-list --defiProtocolId <id>.
  • Token amounts (tokenAmount) keep their original precision (8+ decimals); do not force them to 2 decimals.
  • Numeric IDs (nftId, tickLower, tickUpper, unlockTime, chain IDs) are integers; never reformat.

defi protocol-list

List DeFi protocols with TVL and APY metrics.

Syntax

bash
baw defi protocol-list [--binanceChainId <binanceChainId>] [--investType <investType>] [--sortField <sortField>] [--sortDirection <sortDirection>] [--page <page>] [--size <size>] --json

Parameters

ParameterRequiredDefaultDescription
--binanceChainIdNoFilter by chain ID (e.g., 56 for BSC)
--investTypeNoEarn or LiquidityPool
--sortFieldNotvlSort by apy or tvl
--sortDirectionNoDESCASC or DESC
--pageNo1Page number
--sizeNo200Results per page (max 200)

Example

bash
baw defi protocol-list --binanceChainId 56 --investType Earn --json

Response

json
{
  "success": true,
  "data": {
    "total": 2,
    "list": [
      {
        "defiProtocolId": "protocol_abc",
        "protocolName": "Protocol ABC",
        "description": "...",
        "protocolLogo": "https://...",
        "tvl": "1187356864",
        "apy": "0.29",
        "investType": ["Earn"],
        "supportedChains": ["56"]
      }
    ]
  }
}

defi protocol-info

Get detailed information about a specific DeFi protocol.

Syntax

bash
baw defi protocol-info --defiProtocolId <defiProtocolId> --json

Parameters

ParameterRequiredDescription
--defiProtocolIdYesProtocol ID (e.g., protocol_abc)

Example

bash
baw defi protocol-info --defiProtocolId protocol_abc --json

Response

json
{
  "success": true,
  "data": {
    "defiProtocolId": "protocol_abc",
    "protocolName": "Protocol ABC",
    "protocolLogo": "https://...",
    "description": "...",
    "websiteUrl": "https://...",
    "investType": ["Earn"],
    "supportedChains": ["56"],
    "tvl": "1187356864",
    "tags": ["DeFi", "Lending"],
    "founded": "2020",
    "fdv": "83304822.86",
    "totalFunding": null,
    "socialLinks": { "x": "...", "discord": null, "github": null, "linkedin": null },
    "team": [ { "name": "...", "role": "...", "twitter": "...", "linkedin": "...", "bio": "..." } ],
    "fundRaising": [ { "round": "Seed", "amount": "...", "date": "...", "investors": ["..."] } ],
    "securityScore": "85",
    "dimensionScores": { "codeSecurity": "...", "fundamentalHealth": "..." },
    "highlights": ["..."],
    "faq": [ { "title": "...", "answer": "..." } ]
  }
}

defi investment-list

List DeFi investment opportunities. investType is required.

Syntax

bash
baw defi investment-list --investType <investType> [--defiProtocolId <defiProtocolId>] [--contractAddresses <addresses>] [--binanceChainId <binanceChainId>] [--sortField <sortField>] [--sortDirection <sortDirection>] [--page <page>] [--size <size>] --json

Parameters

ParameterRequiredDefaultDescription
--investTypeYesEarn or LiquidityPool
--defiProtocolIdNoFilter by protocol ID
--contractAddressesNoFilter by token contract addresses (comma-separated, max 2)
--binanceChainIdNoFilter by chain ID
--sortFieldNoapySort by apy or tvl
--sortDirectionNoDESCASC or DESC
--pageNo1Page number
--sizeNo20Results per page (max 100)

Example

bash
baw defi investment-list --investType Earn --defiProtocolId protocol_abc --json

Response

json
{
  "success": true,
  "data": {
    "total": 21,
    "list": [
      {
        "binanceChainId": "56",
        "defiProtocolId": "protocol_abc",
        "protocolName": "Protocol ABC",
        "investmentId": "0e82...",
        "investmentName": "TOKEN_A",
        "investType": "Earn",
        "apyType": "APY",
        "apy": "0.04",
        "tvl": "2851031.25"
      }
    ]
  }
}

defi investment-info

Get full details for a single investment.

Syntax

bash
baw defi investment-info --investmentId <investmentId> --json

Parameters

ParameterRequiredDescription
--investmentIdYesInvestment ID

Example

bash
baw defi investment-info --investmentId 0e82... --json

Response

json
{
  "success": true,
  "data": {
    "binanceChainId": "56",
    "defiProtocolId": "protocol_abc",
    "protocolName": "Protocol ABC",
    "protocolLogo": "https://...",
    "investmentId": "...",
    "investmentName": "TOKEN_A",
    "investType": "Earn",
    "investable": true,
    "apy": "0.04",
    "apyType": "APY",
    "tvl": "2851031.25",
    "poolAddress": null,
    "feeRate": null,
    "assetTokenList": [ { "tokenAddress": "0x4bd1...", "tokenName": "Token A", "tokenSymbol": "TKA" } ],
    "rewardTokenList": [ { "tokenAddress": "0x...", "tokenName": "...", "tokenSymbol": "RWD" } ],
    "lpTokenList": null,
    "borrowTokenList": null
  }
}

Field notes

FieldMeaning
investableBoolean. true → all operations allowed. false → product is delisted; agent MUST refuse new deposit / lp-add requests and tell the user the product is delisted; only redeem / lp-remove / claim remain available.

defi position

Query the user's DeFi positions across all supported protocols. Returns a hierarchical structure: Protocol → Pool → PositionCollection → Position → Token.

Syntax

bash
baw defi position [--address <address>] [--binanceChainId <binanceChainId>] [--defiProtocolId <defiProtocolId>] [--refresh] --json

Parameters

ParameterRequiredDescription
--addressNoQuery by a specific address (defaults to user's wallet address)
--binanceChainIdNoFilter results by chain ID
--defiProtocolIdNoFilter by DeFi protocol ID (e.g., protocol_abc, protocol_xyz)
--refreshNoForce-refresh positions (skip cache; server rate-limited, refreshes should be spaced several minutes apart). Do NOT pass this by default — only include it when the user explicitly asks to refresh / sync / reload / get the latest on-chain positions, OR per the Post-trade verification flow.

Example

bash
# All positions for the connected wallet
baw defi position --json

# Filter by a specific protocol
baw defi position --defiProtocolId protocol_abc --json

# Force refresh — only when the user explicitly asks to refresh / sync / reload positions
baw defi position --refresh --json

Response Structure (4-Layer Hierarchy)

Response
└── deFiTotalValue  (USD total across all protocols)
└── deFiProtocolVOList[]                       ← Protocol layer
    ├── binanceChainId / protocolId / defiProtocolId / protocolName
    ├── protocolTotalValue
    ├── healthRiskThresholds  (JSON string with health-factor color thresholds for Lending)
    └── poolList[]                              ← Pool layer
        ├── bnPoolId / poolCa / poolType / poolTemplateCode
        ├── poolDetail  (feeTier, spokeName, vaultName, etc — varies by poolType)
        └── positionCollectionList[]            ← PositionCollection layer
            ├── positionCollectionId / positionCollectionTotalValue
            ├── positionCollectionDetail  (healthRate for Lending, collectionDisplayName)
            └── positionList[]                   ← Position layer
                ├── positionId / underlyingAssetName / underlyingAssetId
                ├── assetType  (null / "locked" / "farming")
                ├── investmentIds[]
                ├── positionDetail  (nftId, tickLower, tickUpper, unlockTime, ...)
                └── tokenList                    ← Token layer (grouped by type)
                    ├── supply: TokenVO[]
                    ├── borrow: TokenVO[]
                    └── reward: TokenVO[]

Field Reference Guide

LayerKey fieldsWhat they mean
ProtocolprotocolIdChain + version unique (e.g., bsc_protocol_abc, bsc_protocol_xyz)
ProtocoldefiProtocolIdCross-chain protocol group (e.g., protocol_abc, protocol_xyz)
PoolpoolTypeLending / Liquidity Pool / Farming / Locked / Yield / etc.
PoolpoolTemplateCodeDrives client rendering (e.g., Concentrated_Liquidity_V3, Lending_Hub_Spoke)
PositionCollectionpositionCollectionDetail.healthRateLending account health factor (only present for poolType=Lending)
PositionassetTypenull for normal, "locked", or "farming"
PositiontokenList.supply / borrow / rewardTokens grouped by direction
PositionpositionDetail.tickLower/tickUpperLP V3/V4 price range as raw ticks (no auto-conversion)
PositionpositionDetail.unlockTimeLock-end timestamp (seconds) for Staked_Locked pools
PositionpositionDetail.unlockTimeReachedBoolean; whether unlockTime has passed (computed server-side). Use it directly — do not re-compute from current time.
PositionpositionDetail.nftIdNFT-based LP position ID

How to Read the Response (AI Guide)

Different user questions need different layers:

User questionWhere to look
"What's my total DeFi value?"deFiTotalValue
"Which protocols do I use?"deFiProtocolVOList[].protocolName + protocolTotalValue
"What's my lending health factor?"Find protocol with poolType=LendingpositionCollectionDetail.healthRate. Health < 1.5 = high risk.
"Show me my LP positions"Filter pools by poolType="Liquidity Pool". positionDetail.nftId is the NFT ID.
"Are any of my LPs out of range?"positionDetail.active. false means current price is outside tickLower..tickUpper.
"What can I claim?"tokenList.reward[] shows unclaimed rewards / fees
"What am I borrowing?"tokenList.borrow[] (only present for Lending positions)
"Is this protocol supported by Binance Wallet?"See Derived insights → protocol support. Reuse prior defi protocol-list results from the conversation; if none, ask the user to run defi protocol-list first.
"Any redemptions in progress?"See Derived insights → redemption in progress.
"Anything I can claim from redemptions?"See Derived insights → claimable redemption. Suggest defi claim --claimType REDEMPTION ....

Derived insights (compute at render time, not in the response)

Some user-facing concepts are NOT returned directly by defi position — derive them by inspecting the response:

ConceptHow to derive
Protocol supported by Binance WalletReuse defi protocol-list results already in the current conversation context — a position's defiProtocolId ∈ those results → supported. Do NOT auto-invoke defi protocol-list just to check this. If the user has not run defi protocol-list in this session and explicitly asks "is this protocol supported", suggest they run defi protocol-list to get the supported set.
Redemption in progresspoolType="Staked" AND assetType="locked" AND positionDetail.unlockTime is set AND positionDetail.unlockTimeReached=false. Show unlockTime so the user knows when funds will be claimable.
Claimable redemptionpoolType="Staked" AND assetType="locked" AND positionDetail.unlockTime is set AND positionDetail.unlockTimeReached=true. Tell user they can call defi claim --claimType REDEMPTION ....

Display Rules (position-specific)

  • Always show contract addresses alongside token symbols (token symbols can be spoofed).
  • Group by protocolName when summarizing — same defiProtocolId may span multiple protocolIds.
  • Highlight risk: if any Lending collection has healthRate < 1.5, surface a warning. Don't auto-act.
  • Don't fabricate price-range conversions: tickLower/tickUpper are raw ticks. Only convert to USD price if the user explicitly asks.
  • For numeric formatting (USD values, APY/APR, health factor, ratios) follow the global Display Rules at the top of this document.

Example (Abbreviated)

json
{
  "success": true,
  "data": {
    "deFiTotalValue": "1807.99",
    "deFiProtocolVOList": [
      {
        "binanceChainId": "56",
        "protocolId": "bsc_protocol_abc",
        "defiProtocolId": "protocol_abc",
        "protocolName": "Protocol ABC",
        "protocolTotalValue": "57.40",
        "healthRiskThresholds": "{...}",
        "poolList": [
          {
            "poolType": "Lending",
            "poolTemplateCode": "Lending_Hub_Spoke",
            "poolDetail": { "spokeName": "Main Market" },
            "positionCollectionList": [
              {
                "positionCollectionDetail": { "healthRate": "1.85" },
                "positionList": [
                  {
                    "underlyingAssetName": "USDT",
                    "tokenList": {
                      "supply": [
                        { "tokenSymbol": "USDT", "tokenAddress": "0x55d3...", "tokenAmount": "100", "tokenValue": "100.00" }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}

defi deposit

Deposit / stake / supply assets to a DeFi protocol.

Syntax

bash
baw defi deposit --investmentId <investmentId> --tokenAddress <tokenAddress> --amount <amount> [--gasLevel <gasLevel>] --json

Parameters

ParameterRequiredDefaultDescription
--investmentIdYesInvestment product ID (from investment-list)
--tokenAddressYesToken contract address to deposit
--amountYesAmount in human-readable units (e.g., 1.5)
--gasLevelNoMEDIUMLOW / MEDIUM / HIGH

Example

bash
baw defi deposit --investmentId 0e82... --tokenAddress 0x55d398326f99059fF775485246999027B3197955 --amount 1.5 --json

Response

json
{
  "success": true,
  "data": {
    "txHash": "0xabc123..."
  }
}

defi redeem

Redeem / unstake / withdraw assets from a DeFi protocol.

Syntax

bash
baw defi redeem --investmentId <investmentId> --tokenAddress <tokenAddress> [--amount <amount>] [--ratio <ratio>] [--gasLevel <gasLevel>] --json

Parameters

ParameterRequiredDefaultDescription
--investmentIdYesInvestment product ID
--tokenAddressYesToken contract address to redeem
--amountNo*Amount in human-readable units (e.g., 1.5) (mutually exclusive with --ratio)
--ratioNo*Ratio (0, 1] (mutually exclusive with --amount)
--gasLevelNoMEDIUMLOW / MEDIUM / HIGH

*Either --amount or --ratio must be provided.

Response

json
{
  "success": true,
  "data": {
    "txHash": "0xabc123...",
    "redeemDelayDays": ["7", "15"]
  }
}

Field notes

FieldMeaning
redeemDelayDaysOptional List<String>. When empty / absent, the redeem is one-shot — funds credit as soon as the tx confirms. When present and non-empty, the protocol requires a lock-up before funds are claimable. A single value or repeated values mean a fixed wait (e.g. a staking protocol ["7", "7"] = funds mature 7 days after the redeem is submitted); two distinct values are a range (e.g. ["7", "15"] = funds mature somewhere between 7 and 15 days after submission). Tell the user funds will be claimable after that delay, and they must call defi claim --claimType REDEMPTION --redemptionId <id> ... later to actually withdraw.

Two-phase redemption flow

For protocols with non-empty redeemDelayDays (e.g. a staking protocol 7-day unstake):

  1. Phase 1 — submit redeem: user calls defi redeem .... Returns a txHash and redeemDelayDays. The position enters a redemption-in-progress state — see Derived insights → redemption in progress in defi position.
  2. Phase 2 — claim matured redemption: after the delay elapses, the position becomes claimable. User must explicitly call defi claim --claimType REDEMPTION --redemptionId <id> ... to actually receive the unstaked funds.

For protocols with no delay, redeem is single-step — no Phase 2 needed.


defi lp-add

Add liquidity to an LP position (create new or top up existing).

Single-token input only — no auto-swap. An LP position requires both pool tokens, but lp-add only takes one --tokenAddress + --amount. The wallet does not swap the input into the paired token; the user must already hold both tokens in the correct ratio for the chosen price range.

Syntax

bash
baw defi lp-add --investmentId <investmentId> --tokenAddress <tokenAddress> --amount <amount> [--nftId <nftId>] [--priceRange <percent>] [--tickLower <tickLower>] [--tickUpper <tickUpper>] [--slippageBps <slippageBps>] [--gasLevel <gasLevel>] --json

Parameters

ParameterRequiredDefaultDescription
--investmentIdYesLP investment product ID
--tokenAddressYesToken contract address
--amountYesAmount in human-readable units (e.g., 1.5)
--nftIdNo*Position source: top up existing V3/V4 LP NFT tokenId
--priceRangeNo*Position source: new position centered on current pool price; percent, e.g. 5 = ±5%
--tickLowerNo*Position source: new position lower tick (raw int24, aligned to pool tickSpacing)
--tickUpperNo*Position source: new position upper tick (raw int24, aligned to pool tickSpacing)
--slippageBpsNoautoSlippage tolerance in basis points (e.g. 500 = 5%), integer 14999; "auto" uses 1% (100 bps)
--gasLevelNoMEDIUMLOW / MEDIUM / HIGH

*Provide exactly one position source: --nftId, --priceRange, or --tickLower+--tickUpper.

Response

json
{
  "success": true,
  "data": {
    "txHash": "0xabc123..."
  }
}

defi lp-remove

Remove liquidity from an LP position.

Syntax

bash
baw defi lp-remove --investmentId <investmentId> --nftId <nftId> --ratio <ratio> [--slippageBps <slippageBps>] [--gasLevel <gasLevel>] --json

Parameters

ParameterRequiredDefaultDescription
--investmentIdYesLP investment product ID
--nftIdYesLP NFT tokenId
--ratioYesRemoval ratio (0, 1]; "1" removes full position
--slippageBpsNoautoSlippage tolerance in basis points (e.g. 500 = 5%), integer 14999; "auto" uses 1% (100 bps)
--gasLevelNoMEDIUMLOW / MEDIUM / HIGH

Response

json
{
  "success": true,
  "data": {
    "txHash": "0xabc123..."
  }
}

defi claim

Claim LP fees, protocol/investment rewards, or matured redemptions.

Syntax

bash
baw defi claim --claimType <claimType> [--investmentId <investmentId>] [--defiProtocolId <defiProtocolId>] [--nftId <nftId>] [--redemptionId <redemptionId>] [--tokenAddress <tokenAddress>] [--gasLevel <gasLevel>] [--binanceChainId <binanceChainId>] --json

Parameters

ParameterRequiredDefaultDescription
--claimTypeYesREWARD_PROTOCOL / REWARD_INVESTMENT / LP_FEE / REDEMPTION
--investmentIdNo*Investment product ID (required for REWARD_INVESTMENT, LP_FEE and REDEMPTION)
--defiProtocolIdNo*DeFi protocol ID (required for REWARD_PROTOCOL)
--nftIdNo*LP NFT tokenId (required for LP_FEE)
--redemptionIdNo*Redemption record ID (required for REDEMPTION); this is the positionDetail.positionIndex returned by defi position
--tokenAddressNoOptional: limit claim to a specific token
--gasLevelNoMEDIUMLOW / MEDIUM / HIGH
--binanceChainIdNo56Chain ID; only needed when --investmentId is absent (i.e. REWARD_PROTOCOL)

*Required params depend on --claimType.

Response

json
{
  "success": true,
  "data": {
    "txHash": "0xabc123..."
  }
}

defi preview

Preview a DeFi transaction without broadcasting. Returns estimated gas, balance changes, and warnings.

Syntax

bash
baw defi preview --action <action> [--investmentId <investmentId>] [--tokenAddress <tokenAddress>] [--amount <amount>] [--ratio <ratio>] [--nftId <nftId>] [--priceRange <percent>] [--tickLower <tickLower>] [--tickUpper <tickUpper>] [--slippageBps <slippageBps>] [--claimType <claimType>] [--defiProtocolId <defiProtocolId>] [--gasLevel <gasLevel>] [--binanceChainId <binanceChainId>] --json

Parameters

ParameterRequiredDefaultDescription
--actionYesDEPOSIT / REDEEM / LP-ADD / LP-REMOVE / CLAIM.
other paramsSame as the corresponding action command above

Example

bash
baw defi preview --action DEPOSIT --investmentId 0e82... --tokenAddress 0x55d3... --amount 1.5 --json

Response

json
{
  "success": true,
  "data": {
    "balanceChange": [
      { "tokenSymbol": "USDT",  "tokenAddress": "0x55d398...", "amount": "-1.5", "valueUsd": "1.50" },
      { "tokenSymbol": "vUSDT", "tokenAddress": "0xfd5840...", "amount": "1.5",  "valueUsd": "1.50" }
    ],
    "feeAndContract": {
      "estimatedNetworkFee": { "amount": "0.00012", "tokenSymbol": "BNB", "valueUsd": "0.07" },
      "interactWith":        { "address": "0xfD36..." }
    },
    "warnings": []
  }
}

Field notes

FieldMeaning
balanceChange[]Per-token expected balance changes after this tx. amount is signed — positive = inflow to the user, negative = outflow. valueUsd is the absolute USD value (always non-negative). Render to the user as before/after balance impact.
feeAndContract.estimatedNetworkFeeEstimated network gas. amount is in the chain's native gas token (tokenSymbol, e.g. BNB).
feeAndContract.interactWith.addressAddress of the smart contract the main tx will call. Show this for transparency.
warnings[]Non-blocking pre-flight warnings (e.g. health factor warning). Surface ALL warnings to the user before they confirm.