DEX 집계 및 크로스체인 스왑을 EVM DApp에 통합할 준비가 되셨나요? 이 튜토리얼에서는 OKX DEX API와 상호 작용하여 단일 체인 내에서 그리고 Avalanche C-Chain의 다양한 블록체인에서 토큰 교환을 수행하는 방법을 보여줍니다. 구현에서는 Web3.js 및 OKX DEX API를 사용하여 견적, 승인 및 스왑 실행을 강력하게 처리합니다. 기본적으로 이 구현은 다음을 보여줍니다.
이 튜토리얼에서는 OKX DEX API와 상호작용하는 데 필요한 모든 기능이 포함된 유틸리티 파일인 dexUtils.js를 구현하는 데 중점을 둡니다. 이 파일은 다음을 처리합니다.
시작하기 전에 다음이 필요합니다.
시작하는 데는 두 가지 옵션이 있습니다.
git clone https://github.com/Julian-dev28/okx-os-evm-swap-app.git cd okx-os-evm-swap-app git checkout avalanche-demo
npm install
REACT_APP_API_KEY=your_api_key REACT_APP_SECRET_KEY=your_secret_key REACT_APP_API_PASSPHRASE=your_passphrase REACT_APP_PROJECT_ID=your_project_id REACT_APP_USER_ADDRESS=your_wallet_address REACT_APP_PRIVATE_KEY=your_private_key
Replit 프로젝트 포크:
OKX OS Avalanche 스왑 앱
Replit Secrets 탭(도구 패널에 있음)에서 환경 변수를 추가하세요.
개발 환경을 시작하려면 "실행"을 클릭하세요
이 섹션에서는 Avalanche C-Chain에서 OKX DEX와 상호 작용하는 데 필요한 네트워크 구성 및 토큰 주소를 설정하는 방법을 보여줍니다.
import Web3 from "web3"; import cryptoJS from "crypto-js"; // RPC endpoint for Avalanche C-Chain const avalancheCMainnet = "https://avalanche-c-chain-rpc.publicnode.com"; // OKX DEX contract address on Avalanche // Used to show token allowance const okxDexAddress = "0x40aA958dd87FC8305b97f2BA922CDdCa374bcD7f"; // Standard token addresses // baseTokenAddress represents the native token (ETH/AVAX) across chains const baseTokenAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; // WAVAX token address on Avalanche const wavaxTokenAddress = "0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7"; // Initialize Web3 instance with Avalanche RPC const web3 = new Web3(avalancheCMainnet); // Base URL for API requests const apiBaseUrl = "https://www.okx.com/api/v5/dex/aggregator"; /** * Helper function for constructing API URLs * @param {string} methodName - API endpoint path * @param {Object} queryParams - URL parameters * @returns {string} Complete API URL */ function getAggregatorRequestUrl(methodName, queryParams) { return ( apiBaseUrl + methodName + "?" + new URLSearchParams(queryParams).toString() ); }
견적 기능은 현재 가격과 교환 경로를 검색합니다. 구현은 다음과 같습니다.
git clone https://github.com/Julian-dev28/okx-os-evm-swap-app.git cd okx-os-evm-swap-app git checkout avalanche-demo
npm install
교환하기 전에 ERC20 토큰에 대해 다음 승인 기능을 구현하세요.
REACT_APP_API_KEY=your_api_key REACT_APP_SECRET_KEY=your_secret_key REACT_APP_API_PASSPHRASE=your_passphrase REACT_APP_PROJECT_ID=your_project_id REACT_APP_USER_ADDRESS=your_wallet_address REACT_APP_PRIVATE_KEY=your_private_key
import Web3 from "web3"; import cryptoJS from "crypto-js"; // RPC endpoint for Avalanche C-Chain const avalancheCMainnet = "https://avalanche-c-chain-rpc.publicnode.com"; // OKX DEX contract address on Avalanche // Used to show token allowance const okxDexAddress = "0x40aA958dd87FC8305b97f2BA922CDdCa374bcD7f"; // Standard token addresses // baseTokenAddress represents the native token (ETH/AVAX) across chains const baseTokenAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; // WAVAX token address on Avalanche const wavaxTokenAddress = "0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7"; // Initialize Web3 instance with Avalanche RPC const web3 = new Web3(avalancheCMainnet); // Base URL for API requests const apiBaseUrl = "https://www.okx.com/api/v5/dex/aggregator"; /** * Helper function for constructing API URLs * @param {string} methodName - API endpoint path * @param {Object} queryParams - URL parameters * @returns {string} Complete API URL */ function getAggregatorRequestUrl(methodName, queryParams) { return ( apiBaseUrl + methodName + "?" + new URLSearchParams(queryParams).toString() ); }
다음 구현에서는 동일한 체인 내에서 특히 Avalanche C-Chain의 AVAX에서 WAVAX로 스왑을 실행하는 방법을 보여줍니다.
/** * Generates headers required for OKX DEX quote API calls * Headers include timestamp, signature, and API credentials * * @param {Object} quoteParams - Parameters for the quote request * @returns {Object} Headers object with required authentication */ function getQuoteHeaders(quoteParams) { const date = new Date(); const timestamp = date.toISOString(); // Create signature string following OKX API requirements const stringToSign = timestamp + "GET" + "/api/v5/dex/aggregator/quote?" + new URLSearchParams(quoteParams).toString(); // Return headers with HMAC signature return { "Content-Type": "application/json", "OK-ACCESS-KEY": apiKey, "OK-ACCESS-SIGN": cryptoJS.enc.Base64.stringify( cryptoJS.HmacSHA256(stringToSign, secretKey) ), "OK-ACCESS-TIMESTAMP": timestamp, "OK-ACCESS-PASSPHRASE": apiPassphrase, }; }
다음 구현에서는 견적 검색 및 트랜잭션 실행을 포함하여 AVAX(Avalanche C-Chain)에서 MATIC(Polygon)으로 크로스 체인 스왑을 실행하는 방법을 보여줍니다.
/** * Fetches a quote from the OKX DEX Aggregator * Used to get current prices and optimal swap routes * * @param {Object} quoteParams - Parameters including tokens, amount, and chain * @returns {Promise<Object>} Quote data including price and route information */ async function getQuote(quoteParams) { const apiRequestUrl = `${apiBaseUrl}/quote?${new URLSearchParams(quoteParams)}`; const response = await fetch(apiRequestUrl, { method: "GET", headers: getQuoteHeaders(quoteParams), }); if (!response.ok) { throw new Error("Network response was not ok"); } return response.json(); }
sendSignedTransaction 메소드는 사용자의 지갑 개인 키를 사용하여 거래에 서명하고 전송합니다
/** * Generates headers required for OKX DEX approve transaction API calls * Headers include timestamp, signature, and API credentials * * @param {Object} params - Parameters for the approve transaction * @returns {Promise<Object>} Headers object with required authentication */ function getApproveTransactionHeaders(params) { const date = new Date(); const timestamp = date.toISOString(); const stringToSign = timestamp + "GET" + "/api/v5/dex/aggregator/approve-transaction?" + new URLSearchParams(params).toString(); // Check if required environment variables are present if (!projectId || !apiKey || !secretKey || !apiPassphrase) { throw new Error( "Missing required environment variables for API authentication" ); } return { "Content-Type": "application/json", "OK-PROJECT-ID": projectId, "OK-ACCESS-KEY": apiKey, "OK-ACCESS-SIGN": cryptoJS.enc.Base64.stringify( cryptoJS.HmacSHA256(stringToSign, secretKey) ), "OK-ACCESS-TIMESTAMP": timestamp, "OK-ACCESS-PASSPHRASE": apiPassphrase, }; }
애플리케이션의 유연성은 Params 객체, swapParams 및 quoteParams를 통해 입증됩니다. 이러한 개체는 구성 지점 역할을 하여 사용자가 특정 요구 사항에 따라 견적 요청 및 교환을 맞춤 설정할 수 있습니다.
예를 들어 swapParams 객체 내에서 다음 속성을 찾을 수 있습니다.
// ABI for ERC20 token allowance function // This minimal ABI only includes the allowance function needed for checking token approvals // Full ERC20 ABI not needed since we're only checking allowances const tokenABI = [ { constant: true, inputs: [ { name: "_owner", type: "address", }, { name: "_spender", type: "address", }, ], name: "allowance", outputs: [ { name: "", type: "uint256", }, ], payable: false, stateMutability: "view", type: "function", }, ]; /** * Checks the current allowance for a token * Used to determine if approval is needed before swap * * @param {string} ownerAddress - Address of token owner * @param {string} spenderAddress - Address of spender (DEX contract) * @param {string} tokenAddress - Address of token contract * @returns {Promise<number>} Current allowance amount */ async function getAllowance(ownerAddress, spenderAddress, tokenAddress) { const tokenContract = new web3.eth.Contract(tokenABI, tokenAddress); try { const allowance = await tokenContract.methods .allowance(ownerAddress, spenderAddress) .call(); return parseFloat(allowance); } catch (error) { console.error("Failed to query allowance:", error); throw error; } } /** * Gets approval transaction data from the API * * @param {string} chainId - Network chain ID * @param {string} tokenContractAddress - Token to approve * @param {string} approveAmount - Amount to approve * @returns {Promise<Object>} Approval transaction data */ async function approveTransaction(chainId, tokenContractAddress, approveAmount) { if (!chainId || !tokenContractAddress || !approveAmount) { throw new Error("Missing required parameters for approval"); } const params = { chainId, tokenContractAddress, approveAmount }; const apiRequestUrl = getAggregatorRequestUrl("/approve-transaction", params); const headersParams = getApproveTransactionHeaders(params); try { const response = await fetch(apiRequestUrl, { method: "GET", headers: headersParams, }); if (!response.ok) { const errorData = await response.json().catch(() => null); throw new Error( `API request failed: ${response.status} ${response.statusText}${ errorData ? ` - ${JSON.stringify(errorData)}` : "" }` ); } const data = await response.json(); // Validate the response data if (!data || !data.data || !Array.isArray(data.data) || data.data.length === 0) { throw new Error("Invalid response format from approval API"); } return data; } catch (error) { console.error("Approval request failed:", error); throw error; } } /** * Handles the approval transaction if needed * Checks current allowance and submits approval transaction if necessary * * @param {string} approveAmount - Amount to approve for spending * @returns {Promise<Object|null>} Transaction receipt or null if approval not needed */ async function sendApproveTx(approveAmount) { // Skip approval for native tokens (ETH/AVAX) if (fromTokenAddress.toLowerCase() === baseTokenAddress.toLowerCase()) { return null; } const allowanceAmount = await getAllowance( user, spenderAddress, fromTokenAddress ); // Only approve if current allowance is insufficient if (BigInt(allowanceAmount) < BigInt(approveAmount)) { const approvalResult = await approveTransaction( chainId, fromTokenAddress, approveAmount ); // Prepare approval transaction with safety margins for gas const txObject = { nonce: await web3.eth.getTransactionCount(user), to: fromTokenAddress, gasLimit: BigInt(approvalResult.data[0].gasLimit) * BigInt(2), gasPrice: (BigInt(await web3.eth.getGasPrice()) * BigInt(3)) / BigInt(2), data: approvalResult.data[0].data, value: "0", }; return sendSignedTransaction(txObject); } return null; }
여기에서 chainId(사용하려는 블록체인 네트워크), fromTokenAddress 및 toTokenAddress(스왑하려는 토큰), 스왑하려는 토큰 양, 허용 가능한 슬리피지 비율 및 자신의 고유한 슬리피지 비율을 지정할 수 있습니다. userWalletAddress.
dexUtils.js 객체의 quoteParams를 사용하면 소스 및 대상 블록체인 네트워크를 구성할 수 있습니다.
/** * Helper function to get headers for swap API calls * @param {Object} swapParams - Swap parameters * @returns {Object} Headers with authentication */ function getSwapHeaders(swapParams) { const date = new Date(); const timestamp = date.toISOString(); const stringToSign = timestamp + "GET" + "/api/v5/dex/aggregator/swap?" + new URLSearchParams(swapParams).toString(); return { "Content-Type": "application/json", "OK-ACCESS-KEY": apiKey, "OK-ACCESS-SIGN": cryptoJS.enc.Base64.stringify( cryptoJS.HmacSHA256(stringToSign, secretKey) ), "OK-ACCESS-TIMESTAMP": timestamp, "OK-ACCESS-PASSPHRASE": apiPassphrase, }; } /** * Helper function to get swap data from API * @param {Object} swapParams - Swap parameters * @returns {Promise<Object>} Swap transaction data */ async function getSwapData(swapParams) { const apiRequestUrl = getAggregatorRequestUrl("/swap", swapParams); const response = await fetch(apiRequestUrl, { method: "GET", headers: getSwapHeaders(swapParams), }); if (!response.ok) { throw new Error("Network response was not ok"); } return response.json(); } /** * Executes a single-chain token swap * Handles the main swap transaction after approval * * @param {Object} swapParams - Parameters for the swap * @returns {Promise<Object>} Transaction receipt */ async function sendSwapTx(swapParams) { // Get swap transaction data from API const { data: swapData } = await getSwapData(swapParams); // Validate swap data if (!swapData || swapData.length === 0 || !swapData[0].tx) { throw new Error("Invalid swap data received"); } const swapDataTxInfo = swapData[0].tx; const nonce = await web3.eth.getTransactionCount(user, "latest"); // Prepare transaction with adjusted gas parameters for safety const signTransactionParams = { data: swapDataTxInfo.data, gasPrice: BigInt(swapDataTxInfo.gasPrice) * BigInt(ratio), to: swapDataTxInfo.to, value: swapDataTxInfo.value, gas: BigInt(swapDataTxInfo.gas) * BigInt(ratio), nonce, }; return sendSignedTransaction(signTransactionParams); }
이 예에서는 fromChainId(시작할 블록체인 네트워크), toChainId(교환하려는 블록체인 네트워크), fromTokenAddress 및 toTokenAddress를 지정할 수 있습니다. 이를 통해 Avalanche에서 Polygon까지 다양한 블록체인 생태계에서 토큰을 쉽게 이동할 수 있습니다.
추가로, receiveAddress를 설정하여 교환된 토큰을 보낼 위치를 지정하고, 미끄러짐 허용 범위를 조정하고, 심지어 불리한 가격 변동으로부터 보호하기 위해 가격ImpactProtectionPercentage를 구성할 수도 있습니다.
이러한 구성 옵션을 노출하면 애플리케이션의 적응성이 높아져 빌더가 사용자의 특정 요구 사항에 맞게 앱을 맞춤화할 수 있습니다.
예제 React 애플리케이션을 확인하면 이러한 기능이 구성 요소에서 구현되고 앱에 통합되는 방법에 대한 실제 예를 찾을 수 있습니다.
시간을 내어 이 튜토리얼을 확인해 주셔서 감사합니다! 제공된 정보가 자신의 프로젝트에서 OKX DEX Aggregator API의 기능을 활용하는 방법을 이해하는 데 도움이 되었기를 바랍니다.
이 정보가 도움이 되었나요? 상용구 코드 및 문서를 포함하여 기사 시작 부분에 있는 리소스를 확인하는 것을 잊지 마십시오. OKX OS 커뮤니티에 가입하여 다른 개발자들과 소통하고, 더 많은 Web3 개발 콘텐츠를 보려면 Twitter에서 Julian을 팔로우하세요!
이 콘텐츠는 정보 제공의 목적으로만 제공되며 해당 지역에서 판매되지 않는 제품이 포함될 수도 있습니다. 이는 작성자의 견해를 나타내며 OKX의 견해를 나타내지 않습니다. (i) 투자 조언이나 투자 추천을 제공하기 위한 것이 아닙니다. (ii) 디지털 자산을 구매, 판매 또는 보유하기 위한 제안 또는 권유, 또는 (iii) 재무, 회계, 법률 또는 세금 관련 조언. 스테이블 코인 및 NFT를 포함한 디지털 자산 보유는 높은 수준의 위험을 수반하며 크게 변동될 수 있습니다. 귀하의 재정 상태를 고려하여 디지털 자산을 거래하거나 보유하는 것이 귀하에게 적합한지 신중하게 고려해야 합니다. 귀하의 특정 상황에 대한 질문이 있는 경우 법률/세무/투자 전문가에게 문의하시기 바랍니다. 본 게시물에 게재된 정보(시장 데이터 및 통계 정보 포함)는 일반 정보 제공 목적으로만 사용됩니다. 이 데이터와 그래프를 준비하는 데 모든 합리적인 주의를 기울였으나 여기에 표현된 사실의 오류나 누락에 대해 어떠한 책임도 지지 않습니다. OKX Web3 Wallet과 OKX NFT Marketplace에는 모두 www.okx.com의 별도 서비스 약관이 적용됩니다.
© 2024 OKX. 이 기사는 전체를 복제하거나 배포할 수 있으며, 비상업적인 용도로 사용하는 경우 이 기사의 100단어 이하의 발췌문을 사용할 수 있습니다. 전체 기사를 복제하거나 배포하려면 "이 기사는 © 2024 OKX이며 허가를 받아 사용됩니다."라는 문구도 눈에 띄게 명시해야 합니다. 허용되는 발췌문에는 기사 이름을 인용하고 속성을 포함해야 합니다(예: "단 30분 만에 OKX DEX 위젯 통합, Julian Martinez, © 2024 OKX"). 이 기사의 파생물이나 다른 용도는 허용되지 않습니다.
위 내용은 OKX DEX API 필수 사항: Avalanche C-체인의 단일 및 교차 체인 스왑의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!