Wallet API

Redemption#

Call this endpoint when a user wants to withdraw assets from a DeFi protocol (redeem) or repay a loan (repay). Key parameters: investmentId, address. Critical note: always pass redeemPercent when redeeming (e.g., "1" for 100%) — otherwise, for tokens with dynamic balances such as aTokens, the on-chain execution may revert due to balance changes between API response and transaction confirmation. For V3 Pool redemptions, tokenId is required.

URL: POST /api/v6/defi/transaction/exit

Request Parameters#

FieldTypeRequiredDefaultExplanation
investmentIdStringYesInvestment product ID
addressStringYesUser wallet address
tokenIdStringNoV3 Pool NFT position token ID. Required for redemption when isV3Pool=true
redeemPercentStringRecommendedRedemption ratio, e.g., "1"=100%, "0.5"=50%. When not provided, the Zap calldata's tokenIn amount uses the exact value from userInputList.coinAmount; when provided, MAX_UINT256 is used to represent the full balance
userInputListArrayNoFor Farm and V2 Pool, input LP Token information; for other cases, input the target receiving token information
> tokenAddressStringNoRequired when userInputList is provided; Token contract address
> chainIndexStringNoRequired when userInputList is provided; Chain ID
> coinAmountStringNoRequired when userInputList is provided; Amount (human-readable, e.g., "0.05")
> tokenSymbolStringNoToken symbol
> tokenPrecisionIntegerNoPrecision
> tokenIdStringNoNFT token ID (V3 Pool scenario)
slippageStringNo"0.01"Transaction slippage (effective for adapter/Zap routing). "0.01"=1%, "0.1"=10%

Key Notes#

redeemPercent is required: When type="REDEEM", if redeemPercent is not provided, the Zap calldata generated by the API will use an exact value for tokenIn.amount (e.g., 60009) instead of MAX_UINT256. For tokens like aToken whose interest grows dynamically, the balance may change between the API response and on-chain execution, causing SafeERC20: low-level call failed. When redeemPercent: "1" is provided, the amount is set to MAX_UINT256, and the contract dynamically retrieves the actual balance.

Request Examples#

Example 1: BSC V3 Pool pure redemption (50%, without userInputList)#

Investment product: PancakeSwapV3 USDT-RIVER (id=1589649169)

Json
{
    "investmentId": "1589649169",
    "address": "0x1ae68a40b9f903a469aed01574f3a9ab6d45c563",
    "tokenId": "6632738",
    "redeemPercent": "0.5"
}

Example 2: Avalanche Aave V3 redemption (redeemPercent="1")#

Investment product: Aave V3 USDC (id=124, chainIndex=43114)

Json
{
    "investmentId": "124",
    "address": "0x1ae68a40b9f903a469aed01574f3a9ab6d45c563",
    "userInputList": [
        {
            "tokenAddress": "0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e",
            "chainIndex": "43114",
            "coinAmount": "0.05"
        }
    ],
    "redeemPercent": "1"
}

Example 3: Sui NAVI redemption#

Investment product: NAVI USDC (id=32202, chainIndex=784)

Json
{
    "investmentId": "32202",
    "address": "0x2791c11545a2fef7d8b3188002c80343bf6dc64130a603914238d8660b3bddde",
    "userInputList": [
        {
            "tokenAddress": "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
            "chainIndex": "784",
            "coinAmount": "0.3"
        }
    ]
}

Example 4: Solana Kamino repayment#

Investment product: Kamino USDC Borrow (id=29130, chainIndex=501)

Json
{
    "investmentId": "29130",
    "address": "4GK2VMnznuPpg8gG9vqD5MM6889pjJ8WS2HqzktaBfSo",
    "userInputList": [
        {
            "tokenAddress": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
            "chainIndex": "501",
            "coinAmount": "0.05"
        }
    ]
}

Response Parameters#

FieldTypeExplanation
data.dataListArrayCalldata result list (execute in order)
> callDataTypeStringOperation type (approve, subscribe, redeem, claim)
> fromStringFrom address (user wallet address)
> toStringTo address (target contract address)
> valueStringTransfer amount (native token quantity). Empty string or "0x0" when no native token transfer is needed
> serializedDataStringSerialized transaction data. EVM: hex calldata (0x prefix); Solana: base58 encoded; Sui: base64 encoded BCS bytes
> originalDataStringAuxiliary metadata (JSON string)
> transactionPayloadStringTransaction template, only returned for Aptos chains
> signatureDataStringSignature data
> gasStringGas limit, only returned for non-EVM chains such as Aptos

Common dataList combinations during redemption:

  • Single step: [WITHDRAW] — pure redemption/repayment
  • Two steps: [APPROVE, WITHDRAW] — requires prior aToken authorization to Zap
  • Two steps: [WITHDRAW, SWAP] — V3 withdraw then swap back to target token (actually combined into a single callDataType=WITHDRAW,SWAP)

Response Example#

EVM chain (Avalanche Aave V3 USDC redemption, APPROVE + WITHDRAW two steps)

Json
{
    "code": 0,
    "msg": "",
    "data": {
        "dataList": [
            {
                "callDataType": "APPROVE",
                "from": "0x1ae68a40b9f903a469aed01574f3a9ab6d45c563",
                "to": "0x625e7708f30ca75bfd92586e17077590c60eb4cd",
                "value": "0x0",
                "serializedData": "0x095ea7b3000000000000000000000000...ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
                "originalData": "{\"callDataType\":\"APPROVE\",\"methodId\":\"0x095ea7b3\",\"methodDefine\":\"approve(address,uint256)\",...}",
                "signatureData": ""
            },
            {
                "callDataType": "WITHDRAW",
                "from": "0x1ae68a40b9f903a469aed01574f3a9ab6d45c563",
                "to": "0x794a61358d6845594f94dc1db02a252b5b4814ad",
                "value": "0x0",
                "serializedData": "0x69328dec000000000000000000000000...0000000000000000000000001ae68a40b9f903a469aed01574f3a9ab6d45c563",
                "originalData": "{\"callDataType\":\"WITHDRAW\",\"methodId\":\"0x69328dec\",\"methodDefine\":\"withdraw(address,uint256,address)\",...}",
                "signatureData": ""
            }
        ]
    }
}

Note: When redeemPercent="1", the amount parameter in serializedData is MAX_UINT256, and the contract dynamically retrieves the actual balance for redemption, avoiding insufficient balance issues caused by aToken interest growth.