# Relayer Integration API (v1.0) OKX proposes replacing frequent status polling by off-chain wallet services with secure callback endpoints that enable relayers to push real‑time status updates. This approach will significantly reduce network traffic, lower update latency, and simplify state synchronization between wallets and relayers. We acknowledge this may require additional effort, and we are aligning the design with applicable EIP standards. ## Authentication Please refer to our official document for REST API authentication: https://web3.okx.com/build/docs/waas/rest-authentication Please provide your Project ID so we can add it to the whitelist. You can locate the Project ID in the [Developer Portal](https://web3.okx.com/build/dev-portal) under Settings. ## Field Mapping from EIP to OKX API This API adapts the Generic Relayer Architecture EIP to OKX's API standards. Key differences: ### Structural Changes - **Array-based**: Both endpoints use top-level arrays instead of wrapped objects - **Flattened objects**: All nested `data` wrappers removed; fields promoted to top level - **Batch limit**: Maximum 100 items per array request ### Field Mappings | EIP Field | OKX API Field | Type Change | Notes | |-----------|---------------|-------------|-------| | **Fee Data (`relayer_getFeeData`)** | | `chainId` | `chainIndex` | - | References [(OKX Wallet API ChainIndex)](https://web3.okx.com/build/docs/waas/walletapi-resources-supported-networks) | | `token.address` | `tokenAddress` | - | Flattened from nested object | | `token.decimals` | `tokenDecimals` | number → string | Flattened and converted to string | | `rate` | `rate` | - | Unchanged | | `minFee` | `minFee` | - | Unchanged (optional) | | `expiry` | `expiry` | number → string | Timestamp as string | | `effectiveGasPrice` | `effectiveGasPrice` | - | Unchanged (hex string) | | `context` | N/A | - | Not required | | **Status (`relayer_getStatus`)** | | N/A | `timestamp` | - | Added for record creation time | | `id` | `requestId` | - | Added for unique entry identification | | N/A (param) | `taskId` | - | Task identifier from `relayer_sendTransaction` | | `chainId` | `chainIndex` | - | References OKX ChainIndex | | `status` | `status` | enum → string | Status codes as string (e.g., "200") | | `receipt.blockHash` | `blockHash` | - | Flattened from nested receipt object | | `receipt.blockNumber` | `blockHeight` | - | Flattened from nested receipt object | | `receipt.gasUsed` | `gasUsed` | - | Flattened from nested receipt object | | `receipt.transactionHash` | `txHash` | - | Flattened and shortened field name | | `message` (error) | `errorMessage` | - | Renamed for clarity | | `data` (error) | `errorData` | - | Renamed for clarity | ## Endpoint: Publish Exchange Rates ### Request - **Method**: POST - **URL**: `https://web3.okx.com/api/v6/wallet/relayer/fee-data` #### Request Body The request body is a top-level array of exchange rate objects. Maximum 100 items per request. ```typescript type FeeDataItem = { timestamp: string; requestId: string; chainIndex: string; tokenAddress: string; tokenDecimals: string; rate: string; minFee?: string; expiry: string; effectiveGasPrice: string; }; type Request = Array<FeeDataItem>; ``` #### Field Descriptions - `timestamp`: Unix timestamp in seconds (string format) - `requestId`: Unique identifier for this fee data entry - `chainIndex`: OKX chain identifier (see ChainIndex section) - `tokenAddress`: Payment token contract address (0x0 for native token) - `tokenDecimals`: Number of decimals for the payment token (string format) - `rate`: Exchange rate as decimal string (token-per-1-native, e.g., "2000.50" for USDC/ETH) - `minFee`: Optional minimum fee in token units (string format) - `expiry`: Unix timestamp when this rate expires (string format) - `effectiveGasPrice`: Gas price for fee calculation in wei (hex string) #### Example Request ```json [ { "timestamp": "1755914000", "requestId": "1", "chainIndex": "1", "tokenAddress": "0x036CbD53842c5426634e7929541eC2318f3dCF7e", "tokenDecimals": "6", "rate": "2000.50", "minFee": "4.5", "expiry": "1755917874", "effectiveGasPrice": "0x4a817c800" }, { "timestamp": "1755914000", "requestId": "2", "chainIndex": "8453", "tokenAddress": "0x0000000000000000000000000000000000000000", "tokenDecimals": "18", "rate": "1", "expiry": "1755917874", "effectiveGasPrice": "0x3b9aca00" } ] ``` ### Response - 200 OK — network success; inspect the `code` field for logical success or failure. - Success example: ```json { "code": 0, "msg": "SUCCESS", "data": [] } ``` - Error example (network OK but logical failure): ```json { "code": 70000, "msg": "SIGNATURE_INVALID", "data": [] } ``` ## Endpoint: Submit Intent Status ### Request - **Method**: POST - **URL**: `https://web3.okx.com/api/v6/wallet/relayer/transaction-status` #### Request Body The request body is a top-level array of transaction status objects. Maximum 100 items per request. For the explanation of the intent status codes, please refer to the EIP [Status Codes](https://hackmd.io/T4TkZYFQQnCupiuW231DYw#Status-Codes). ```typescript type TransactionStatusItem = { timestamp: string; requestid: string; taskId: string; chainIndex: string; status: string; blockHash?: string; blockHeight?: string; gasUsed?: string; txHash?: string; errorMessage?: string; errorData?: string; }; type Request = Array<TransactionStatusItem>; ``` #### Field Descriptions - `timestamp`: Unix timestamp in seconds when status was recorded (string format) - `requestId`: Unique identifier for this status update entry - `taskId`: 32-byte task identifier returned by relayer (from `relayer_sendTransaction`) - `chainIndex`: OKX chain identifier (see ChainIndex section) - `status`: Status code as string (e.g., "100", "110", "200", "400", "500") - `blockHash`: Block hash containing the transaction (required for status 200) - `blockHeight`: Block number in hex format (required for status 200) - `gasUsed`: Gas consumed in hex format (required for status 200) - `txHash`: Transaction hash (required for status 110 and 200) - `errorMessage`: Human-readable error description (required for status 400 and 500) - `errorData`: Additional error data or revert reason (optional for status 400 and 500) #### Example Request ```json [ { "timestamp": "1755914000", "requestId": "1", "taskId": "0x0e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", "chainIndex": "1", "status": "200", "blockHash": "0x6789b0746d84002f2f258129cfd9714d412e78b4d91b8e61608fac9165988baf", "blockHeight": "0x22a1e6e", "gasUsed": "0x9cf2", "txHash": "0xd9b01a72502e7f518fb043bfacd1e13b07f24995f404f8cbb60a1212ca8b4c42" }, { "timestamp": "1755914005", "requestId": "2", "taskId": "0x1f780fc74451881717f66e5c5ca45a2c7c85ff4e5255b11326d1638296e38442", "chainIndex": "8453", "status": "110", "txHash": "0x8abc2d73513ef8541c9dbf16bba89e9eb4a27d6a4e72ef9fb123c5d81a7a8d93" }, { "timestamp": "1755914010", "requestId": "3", "taskId": "0x2g890gd85562992828g77f6d6db56b3d8d96gg5f6366c22437e1749307f49553", "chainIndex": "1", "status": "400", "errorMessage": "Insufficient payment", "errorData": "0x" } ] ``` ### Status Codes Reference: https://hackmd.io/T4TkZYFQQnCupiuW231DYw#Status-Codes ### Response - 200 OK — All validations passed ```json { "code": 0, "msg": "SUCCESS", "data": [] } ``` - 200 OK — Previous state not found ```json { "code": 70001, "msg": "PENDING_PREV_STATUS", "data": [] } ``` - 200 OK — Example error ```json { "code": 70000, "msg": "SIGNATURE_INVALID", "data": [] } ```