DeFi API
Subscription process

Subscription process#

For the subscription process, please refer to the subscription flow section in the overview.

1. Set up your environment#

Set up your environment. For details, please refer to the Importing Necessary Node.js Libraries.

2. Search for platform information and get investment product details#

2.1 Search for summary information of investment products under a protocol#

Here is an example of a Node.js request. For interface information, refer to here.

Step 1: Define parameters#

Next, define the parameters for querying the summary information of investment products.

const getProtocolListParam = {
  platformName: '',
  platformId: ''
};

Step 2: Define helper function#

Define a helper function to interact with the DeFi API.

const getProtocolListRequestUrl = (api, queryParams) => {
  const path = api + '?' + new URLSearchParams(queryParams).toString();
  return {
    apiRequestUrl: exploreBaseUrl + path,
    path: exploreBasePath + path,
  };
};
const getProtocolListData = async () => {
  const { apiRequestUrl, path } = getProtocolListRequestUrl(
    '/protocol/list',
    getProtocolListParam
  );
  return fetch(apiRequestUrl, {
    method: 'GET',
    headers: headersParams,
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

Step 3: Get the result#

Tip
Get the result. If you need to navigate to the investment product details webpage, use the value of investmentPageUrlPattern in the result and fill in the placeholder with the corresponding investmentId value to form the URL. If you want to query the investment product details API, concatenate the value of investmentApiUrlPattern with the corresponding investmentId value to form the URL.
async function someFunction() {
    const { data: protocolListData } = await getProtocolListData();
    console.log(JSON.stringify(protocolListData));
}
someFunction();

After sending the transaction, you will receive the following response:

{
    "code": 0,
    "msg": "",
    "data":
    [
        {
            "platformId": 294,
            "platformName": "SpaceFi",
            "platformWebSite": "https://spacefi.io/",
            "investmentApiUrlPattern": "https://www.okx.com/api/v5/defi/explore/product/detail?investmentId=",
            "investmentPageUrlPattern": "https://www.okx.com/cn/web3/defi/detail/${investmentId}",
            "platformMinInfos":
            [
                {
                    "investmentId": "21010",
                    "protocolId": "207",
                    "network": "ZKSYNC",
                    "chainId": "1"
                },
                {
                    "investmentId": "21011",
                    "protocolId": "207",
                    "network": "ZKSYNC",
                    "chainId": "1"
                }
            ]
        }
    ]
}

2.2 Search for investment product details#

You can use the investmentApiUrlPattern and investmentId attributes obtained in the previous step to form the URL for investment product details. Refer to the interface information here.

Step 1: Define parameters#

Define the parameters for querying the investment product details.

const getProductDetailParam = {
  investmentId: '21010',
  investmentCategory: ''
};

Step 2: Define helper function#

Define a helper function to interact with the DeFi API.

const getProductDetailRequestUrl = (api, queryParams) => {
  const path = api + '?' + new URLSearchParams(queryParams).toString();
  return {
    apiRequestUrl: exploreBaseUrl + path,
    path: exploreBasePath + path,
  };
};
const getProductDetailData = async () => {
  const { apiRequestUrl, path } = getProductDetailRequestUrl(
    '/product/detail',
    getProductDetailParam
  );
  return fetch(apiRequestUrl, {
    method: 'GET',
    headers: headersParams,
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

Step 3: Get the result#

async function someFunction() {
    const { data: productDetailData } = await getProductDetailData();
    console.log(JSON.stringify(productDetailData));
}
someFunction();

After sending the transaction, you will receive the following response:

{
    "code": 0,
    "msg": "",
    "data":
    {
        "investmentId": "21010",
        "investmentName": "USDC-ETH",
        "chainId": "324",
        "rate": "0.06340",
        "investType": "2",
        "platformName": "SpaceFi",
        "platformId": "491",
        "analysisPlatformId": "294",
        "poolVersion": "1",
        "rateType": "1",
        "tvl": "4464444.45647",
        "underlyingToken":
        [
            {
                "tokenSymbol": "USDC",
                "tokenAddress": "0x3355df6d4c9c3035724fd0e3914de96a5a83aaf4",
                "isBaseToken": false
            },
            {
                "tokenSymbol": "ERA_ETH",
                "tokenAddress": "0x0000000000000000000000000000000000000000",
                "isBaseToken": true
            }
        ],
        "isInvestable": true,
        "earnedToken":
        [
            {
                "tokenSymbol": "USDC",
                "tokenAddress": "0x3355df6d4c9c3035724fd0e3914de96a5a83aaf4",
                "isBaseToken": false
            },
            {
                "tokenSymbol": "ERA_ETH",
                "tokenAddress": "0x0000000000000000000000000000000000000000",
                "isBaseToken": true
            }
        ],
        "lpToken":
        [
            {
                "tokenSymbol": "SLP",
                "tokenAddress": "0xd0ce094412898760c2a5e37abec39b0e785b45ae",
                "isBaseToken": false
            }
        ],
        "subscriptionMethod": "2",
        "redeemMethod": "2"
    }
}

3. Query investment estimated earnings calculation#

Retrieve valid data for an investment product. You can input the desired investment amount to obtain the estimated investment earnings information. Refer to the interface details here.

Step 1: Define parameters#

Next, define the parameters for calculating investment subscription earnings.

const getSubscribeInfoBody = {
  inputAmount: "1",
  inputTokenAddress: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
  investmentId: "21200",
  address: "0x7f****da",
  investmentType: "0",
  tokenDecimal: "18",
  isSingle: false
};

Step 2: Define helper function#

Define a helper function to interact with the DeFi API.

const getSubscribeInfoData = async () => {
  return fetch(calculatorBaseUrl + '/subscribe-info', {
    method: 'POST',
    headers: headersParams,
    body: JSON.stringify(getSubscribeInfoBody),
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

Step 3: Get the result#

async function someFunction() {
    const { data: subscribeInfoData } = await getSubscribeInfoData();
    console.log(subscribeInfoData);
}

someFunction();

After sending the transaction, you will receive the following response:

{
    "code": 0,
    "msg": "",
    "data":
    {
        "investWithTokenList":
        [
            {
                "tokenSymbol": "CORE",
                "tokenName": "Core",
                "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
                "network": "CORE",
                "chainId": "1116",
                "tokenPrecision": "18",
                "isBaseToken": true,
                "coinAmount": "1",
                "currencyAmount": "0.4918"
            }
        ],
        "gainsTokenList":
        [
            {
                "tokenSymbol": "CORE",
                "tokenName": "Core",
                "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
                "network": "CORE",
                "tokenPrecision": "18",
                "coinAmount": "0.00069321843585011",
                "dataType": "0"
            }
        ],
        "approveStatusList":
        [
            {
                "tokenSymbol": "CORE",
                "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
                "network": "CORE",
                "chainId": "1116",
                "tokenPrecision": "18",
                "isNeedApprove": false,
                "approveAddress": "0x0000000000000000000000000000000000001007",
                "orderType": "3"
            }
        ],
        "isSwapInvest": false,
        "estimateGasFee": "99343",
        "isAllowSubscribe": true,
        "validatorName": "OKXEarn"
    }
}

4. Generate call data for subscription transaction#

The subscription process consists of the following steps:

4.1 Subscription authorization#

Here is an example of a Node.js request. Refer to the interface details here.

Step 1: Define parameters#

Define the parameters for authorizing the subscription amount.

const userInputList = [
   {
   "chainId": "56",
   "coinAmount": "10",
   "tokenAddress": "0x526a913a7a4518aa2abc3dcd3c46a9c73f40f94a"
   }
   ];
const getTransactionAuthorizationBody = {
  address: '0x7f****da',
  type: '3',
  investmentId: '6925',
  userInputList: userInputList
};

Step 2: Define helper function#

Define a helper function to interact with the DeFi API.

const getTransactionAuthorizationData = async () => {
  return fetch(transactionBaseUrl + '/authorization', {
    method: 'POST',
    headers: headersParams,
    body: JSON.stringify(getTransactionAuthorizationBody),
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

Step 3: Get the result#

async function someFunction() {
    const { data: transactionAuthorizationData } = await getTransactionAuthorizationData();
    console.log(transactionAuthorizationData);
}

someFunction();

After sending the transaction, you will receive the following response:

{
    "code": 0,
    "msg": "",
    "data":
    {
        "dataList":
        [
            {
                "from": "0x7f4****da",
                "to": "0x52****4a",
                "value": "0x0",
                "serializedData": "0x095ea7b30000000000000000000000002c34a2fb1d0b4f55de51e1d0bdefaddce6b7cdd60000000000000000000000000000000000000000000000008ac7230489e80000",
                "originalData": "{\"methodDefine\":\"approve(address,uint256)\",\"methodId\":\"0x095ea7b3\",\"methodType\":\"METHOD_ID\",\"params\":{\"params\":[\"0x2c34a2fb1d0b4f55de51e1d0bdefaddce6b7cdd6\",\"10000000000000000000\"]},\"useAdapter\":false}",
                "signatureData": "1bca0efbd1c809de94cdd8c924329c7ac79a4d346742de61925e8494f2c84c446bd3cf42b56d690c85ff513beadf46cd18f4e3e74845a92c48451584615f749d1c"
            }
        ]
    }
}

4.2 Subscription transaction#

Here is an example of a Node.js request. For detailed information about the API, refer to here.

Step 1: Define parameters#

Define the parameters for querying subscription investments.

const userInputList = [
   {
   "coinAmount": "0.6"
   }
   ];
const expectOutputList = [
   {
   "coinAmount": "0.6"
   }
   ];
const getTransactionSubscriptionBody = {
  address: '0x7f****da',
  investmentId: '6925',
  userInputList: userInputList,
  expectOutputList: expectOutputList
};

Step 2: Define helper function#

Define a helper function to interact with the DeFi API.

const getTransactionSubscriptionData = async () => {
  return fetch(transactionBaseUrl+'/subscription', {
    method: 'post',
    headers: headersParams,
    body: JSON.stringify(getTransactionSubscriptionBody),
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

Step 3: Get the result#

async function someFunction() {
    const { data: transactionSubscriptionData } = await getTransactionSubscriptionData();
    console.log(transactionSubscriptionData);
}

someFunction();

After sending the transaction, you will receive the following response:

{
    "code": 0,
    "msg": "",
    "data":
    {
        "dataList":
        [
            {
                "from": "0x7f****da",
                "to": "0x72****d2",
                "value": "0x0",
                "serializedData": "0x016cba5f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000526a913a7a4518aa2abc3dcd3c46a9c73f40f94a0000000000000000000000000000000000000000000000000853a0d2313c00000000000000000000000000005569e13b1ec4336d17e8f24d892a4a915fc5da9400000000000000000000000000000000000000000000000000000000000000010000000000000000000000004e38a4ad4f210ad5abb2c8f2598706ae8b4a1ce600000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000005569e13b1ec4336d17e8f24d892a4a915fc5da94000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e4c41a3be800000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e38a4ad4f210ad5abb2c8f2598706ae8b4a1ce60000000000000000000000007f429edeff8afc7bb3a2cf7db832fc86f6fa99da00000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000026f700000000000000000000000000000000000000000000000000000000",
                "originalDataClass": "OriginalDataEntrance",
                "originalData": "{\"hexCallData\":\"0x016cba5f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000526a913a7a4518aa2abc3dcd3c46a9c73f40f94a0000000000000000000000000000000000000000000000000853a0d2313c00000000000000000000000000005569e13b1ec4336d17e8f24d892a4a915fc5da9400000000000000000000000000000000000000000000000000000000000000010000000000000000000000004e38a4ad4f210ad5abb2c8f2598706ae8b4a1ce600000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000005569e13b1ec4336d17e8f24d892a4a915fc5da94000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e4c41a3be800000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e38a4ad4f210ad5abb2c8f2598706ae8b4a1ce60000000000000000000000007f429edeff8afc7bb3a2cf7db832fc86f6fa99da00000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000026f700000000000000000000000000000000000000000000000000000000\",\"methodDefine\":\"{\\n\\t\\\"inputs\\\": [{\\n\\t\\t\\\"components\\\": [{\\n\\t\\t\\t\\\"internalType\\\": \\\"struct TokenInInfo\\\",\\n\\t\\t\\t\\\"name\\\": \\\"tokenIn\\\",\\n\\t\\t\\t\\\"type\\\": \\\"tuple[]\\\",\\n\\t\\t\\t\\\"components\\\": [{\\n\\t\\t\\t\\t\\\"internalType\\\": \\\"address\\\",\\n\\t\\t\\t\\t\\\"name\\\": \\\"token\\\",\\n\\t\\t\\t\\t\\\"type\\\": \\\"address\\\"\\n\\t\\t\\t}, {\\n\\t\\t\\t\\t\\\"internalType\\\": \\\"uint256\\\",\\n\\t\\t\\t\\t\\\"name\\\": \\\"amount\\\",\\n\\t\\t\\t\\t\\\"type\\\": \\\"uint256\\\"\\n\\t\\t\\t}, {\\n\\t\\t\\t\\t\\\"internalType\\\": \\\"address\\\",\\n\\t\\t\\t\\t\\\"name\\\": \\\"to\\\",\\n\\t\\t\\t\\t\\\"type\\\": \\\"address\\\"\\n\\t\\t\\t}]\\n\\t\\t}, {\\n\\t\\t\\t\\\"internalType\\\": \\\"struct TokenAmount\\\",\\n\\t\\t\\t\\\"name\\\": \\\"tokenOut\\\",\\n\\t\\t\\t\\\"type\\\": \\\"tuple[]\\\",\\n\\t\\t\\t\\\"components\\\": [{\\n\\t\\t\\t\\t\\\"internalType\\\": \\\"address\\\",\\n\\t\\t\\t\\t\\\"name\\\": \\\"token\\\",\\n\\t\\t\\t\\t\\\"type\\\": \\\"address\\\"\\n\\t\\t\\t}, {\\n\\t\\t\\t\\t\\\"internalType\\\": \\\"uint256\\\",\\n\\t\\t\\t\\t\\\"name\\\": \\\"amount\\\",\\n\\t\\t\\t\\t\\\"type\\\": \\\"uint256\\\"\\n\\t\\t\\t}]\\n\\t\\t}],\\n\\t\\t\\\"internalType\\\": \\\"struct BaseRequest\\\",\\n\\t\\t\\\"name\\\": \\\"request\\\",\\n\\t\\t\\\"type\\\": \\\"tuple\\\"\\n\\t}, {\\n\\t\\t\\\"components\\\": [{\\n\\t\\t\\t\\\"internalType\\\": \\\"address\\\",\\n\\t\\t\\t\\\"name\\\": \\\"target\\\",\\n\\t\\t\\t\\\"type\\\": \\\"address\\\"\\n\\t\\t}, {\\n\\t\\t\\t\\\"internalType\\\": \\\"bytes\\\",\\n\\t\\t\\t\\\"name\\\": \\\"callData\\\",\\n\\t\\t\\t\\\"type\\\": \\\"bytes\\\"\\n\\t\\t}],\\n\\t\\t\\\"internalType\\\": \\\"struct Call\\\",\\n\\t\\t\\\"name\\\": \\\"calls\\\",\\n\\t\\t\\\"type\\\": \\\"tuple[]\\\"\\n\\t}],\\n\\t\\\"name\\\": \\\"execute\\\",\\n\\t\\\"stateMutability\\\": \\\"payable\\\",\\n\\t\\\"type\\\": \\\"function\\\"\\n}\",\"methodId\":\"\",\"methodType\":\"ABI\",\"params\":{\"baseRequest\":{\"tokenIn\":[{\"amount\":600000000000000000,\"to\":\"0x5569e13b1ec4336d17e8f24d892a4a915fc5da94\",\"token\":\"0x526a913a7a4518aa2abc3dcd3c46a9c73f40f94a\"}],\"tokenOut\":[{\"amount\":500000000000000000,\"token\":\"0x4e38a4ad4f210ad5abb2c8f2598706ae8b4a1ce6\"}]},\"operatorDataList\":[{\"adapterOperate\":true,\"call\":{\"calls\":\"xBo76AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATjikrU8hCtWrssjyWYcGrotKHOYAAAAAAAAAAAAAAAB/Qp7e/4r8e7Oiz324MvyG9vqZ2gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbwW1nTsgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACb3\",\"callsAsString\":\"0xc41a3be800000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e38a4ad4f210ad5abb2c8f2598706ae8b4a1ce60000000000000000000000007f429edeff8afc7bb3a2cf7db832fc86f6fa99da00000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000026f7\",\"target\":\"0x5569e13b1ec4336d17e8f24d892a4a915fc5da94\"},\"hexCallData\":\"0xc41a3be800000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e38a4ad4f210ad5abb2c8f2598706ae8b4a1ce60000000000000000000000007f429edeff8afc7bb3a2cf7db832fc86f6fa99da00000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000026f7\",\"operateType\":\"DEPOSIT\",\"operatorMethodInfo\":{\"methodDefine\":\"{\\n\\t\\\"inputs\\\": [{\\n\\t\\t\\\"internalType\\\": \\\"address\\\",\\n\\t\\t\\\"name\\\": \\\"pool\\\",\\n\\t\\t\\\"type\\\": \\\"address\\\"\\n\\t}, {\\n\\t\\t\\\"internalType\\\": \\\"struct TokenOutInfo\\\",\\n\\t\\t\\\"name\\\": \\\"tokenOut\\\",\\n\\t\\t\\\"type\\\": \\\"tuple\\\",\\n\\t\\t\\\"components\\\": [{\\n\\t\\t\\t\\t\\\"internalType\\\": \\\"address\\\",\\n\\t\\t\\t\\t\\\"name\\\": \\\"token\\\",\\n\\t\\t\\t\\t\\\"type\\\": \\\"address\\\"\\n\\t\\t\\t}, {\\n\\t\\t\\t\\t\\\"internalType\\\": \\\"address\\\",\\n\\t\\t\\t\\t\\\"name\\\": \\\"toAddress\\\",\\n\\t\\t\\t\\t\\\"type\\\": \\\"address\\\"\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\t\\\"internalType\\\": \\\"uint256\\\",\\n\\t\\t\\t\\t\\\"name\\\": \\\"minAmount\\\",\\n\\t\\t\\t\\t\\\"type\\\": \\\"uint256\\\"\\n\\t\\t\\t}\\n\\t\\t]\\n\\t}, {\\n\\t\\t\\\"internalType\\\": \\\"bytes\\\",\\n\\t\\t\\\"name\\\": \\\"data\\\",\\n\\t\\t\\\"type\\\": \\\"bytes\\\"\\n\\n\\t}],\\n\\t\\\"name\\\": \\\"deposit\\\",\\n\\t\\\"stateMutability\\\": \\\"payable\\\",\\n\\t\\\"type\\\": \\\"function\\\"\\n}\",\"params\":{\"data\":\"00000000000000000000000000000000000000000000000000000000000026f7\",\"pool\":\"0x0000000000000000000000000000000000000000\",\"tokenOut\":{\"amount\":500000000000000000,\"toAddress\":\"0x7f429edeff8afc7bb3a2cf7db832fc86f6fa99da\",\"token\":\"0x4e38a4ad4f210ad5abb2c8f2598706ae8b4a1ce6\"}}},\"target\":\"0x5569e13b1ec4336d17e8f24d892a4a915fc5da94\"}]},\"useAdapter\":true}",
                "signatureData": "dbfe682a491b31141c99800913c9a052ee8dee122854cb0c459af85fff9f5d571aaf217b3bbbe10b141247bc0327357c3dde2874333f8a4c031d84d31a41ffec1c"
            }
        ]
    }
}

5. Signature and broadcasting#

During the signing process, you can directly use the serializedData obtained in step 3 as call data, or you can let users assemble callData using originalData for signing and broadcasting. For EVM-based investments, you can refer to the signature example.