ホームページ >ウェブフロントエンド >jsチュートリアル >OKX DEX API Essentials: Avalanche C チェーンでのシングルチェーンおよびクロスチェーンのスワップ
DEX アグリゲーションとクロスチェーン スワップを EVM DApp に統合する準備はできましたか?このチュートリアルでは、OKX DEX API を操作して、単一チェーン内と Avalanche C チェーンの異なるブロックチェーン間でトークン スワップを実行する方法を説明します。実装では Web3.js と OKX DEX API を使用して、見積もり、承認、スワップ実行の堅牢な処理を作成します。デフォルトでは、この実装は以下を示します:
このチュートリアルは、OKX DEX API と対話するために必要なすべての関数を含むユーティリティ ファイルである dexUtils.js の実装に焦点を当てています。このファイルは以下を処理します:
始める前に以下が必要です:
開始するには 2 つのオプションがあります:
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 チェーン上の 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 チェーン上の 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); }
この例では、fromTokenAddress と toTokenAddress に加えて、fromChainId (開始元のブロックチェーン ネットワーク) と toChainId (スワップ先のブロックチェーン ネットワーク) を指定できます。これにより、Avalanche から Polygon など、さまざまなブロックチェーン エコシステム間でトークンを簡単に移動できます。
さらに、receiveAddress を設定してスワップされたトークンの送信先を指定したり、スリッページ許容値を調整したり、不利な価格変動を防ぐために PriceImpactProtectionPercentage を設定したりすることもできます。
これらの構成オプションを公開することで、アプリケーションの適応性が高まり、ビルダーがユーザー固有のニーズに合わせてアプリケーションを調整できるようになります。
React アプリケーションのサンプルを確認すると、これらの関数がどのようにコンポーネントに実装され、アプリに統合されるかの実例がわかります。
このチュートリアルをご覧いただきありがとうございます。提供された情報が、独自のプロジェクト内で OKX DEX Aggregator API の機能を活用する方法を理解するのに役立つことを願っています。
これは役に立ちましたか?定型コードやドキュメントなど、記事の冒頭にあるリソースを忘れずにチェックしてください。 OKX OS コミュニティに参加して他の開発者とつながり、Twitter で Julian をフォローして Web3 開発コンテンツをさらにご覧ください!
このコンテンツは情報提供のみを目的として提供されており、お住まいの地域では利用できない製品が含まれている場合があります。これは著者の見解を表すものであり、OKX の見解を表すものではありません。これは、(i) 投資アドバイスまたは投資推奨を提供することを目的としたものではありません。 (ii) デジタル資産の購入、販売、または保有の申し出または勧誘、または (iii) 財務、会計、法律、税務上のアドバイス。ステーブルコインやNFTを含むデジタル資産の保有には高いリスクが伴い、大きく変動する可能性があります。自分の財務状況を考慮して、デジタル資産の取引または保有が自分に適しているかどうかを慎重に検討する必要があります。特定の状況に関する質問については、法律/税務/投資の専門家にご相談ください。この投稿に掲載されている情報 (市場データや統計情報が存在する場合) は、一般的な情報提供のみを目的としています。このデータとグラフを作成する際にはあらゆる合理的な注意が払われていますが、ここに記載されている事実の誤りまたは省略については、いかなる責任も負いません。 OKX Web3 ウォレットと OKX NFT マーケットプレイスの両方には、www.okx.com での個別の利用規約が適用されます。
© 2024 OKX.この記事は、非営利目的であれば、その全体を複製または配布することも、100 ワード以下の抜粋を使用することもできます。 記事全体を複製または配布する場合は、「この記事は © 2024 OKX であり、許可を得て使用されています。」と目立つように明記する必要があります。 許可される抜粋では、記事名を引用し、帰属を含める必要があります。たとえば、「OKX DEX ウィジェットをわずか 30 分で統合、Julian Martinez、© 2024 OKX」などです。 この記事の二次的著作物やその他の使用は許可されません。
以上がOKX DEX API Essentials: Avalanche C チェーンでのシングルチェーンおよびクロスチェーンのスワップの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。