搜索
首页web前端js教程OKX DEX API 要点:Avalanche C 链上的单链和跨链互换

OKX DEX API Essentials: Single and Cross-Chain Swaps on Avalanche C-Chain

准备好将 DEX 聚合和跨链交换集成到您的 EVM DApp 中了吗?本教程向您展示如何与 OKX DEX API 交互,以在单个链内以及 Avalanche C 链的不同区块链之间执行代币交换。您的实施将使用 Web3.js 和 OKX DEX API 来创建对报价、批准和互换执行的强大处理。默认情况下,此实现演示:

  • 单链互换:Avalanche C 链上的 AVAX 到 WAVAX
  • 跨链交换:Avalanche C 链上的 AVAX 到 Polygon 上的 POL

文件结构

本教程重点介绍 dexUtils.js 的实现,这是一个实用程序文件,其中包含与 OKX DEX API 交互所需的所有函数。该文件处理:

  • 网络和令牌配置
  • 标题结构
  • API端点和调用构造
  • 报价检索
  • 代币批准
  • 单链互换
  • 跨链交换

先决条件

开始之前,您需要:

  • 已安装 Node.js(v20 或更高版本)
  • Web3 和区块链概念的基础知识
  • 钱包地址和私钥
  • 来自 OKX 开发者门户的 OKX API 凭证(API 密钥、密钥和密码)
  • 来自 OKX 开发者门户的项目 ID
  • Git 安装在您的计算机上

设置

您有两种开始选择:

选项 1:本地开发

  1. 克隆存储库并切换到演示分支:
git clone https://github.com/Julian-dev28/okx-os-evm-swap-app.git
cd okx-os-evm-swap-app
git checkout avalanche-demo
  1. 安装依赖项:
npm install
  1. 设置环境变量:
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

选项 2:使用 Replit

  1. 分叉 Replit 项目:
    OKX OS Avalanche 交换应用程序

  2. 在 Replit Secrets 选项卡(位于“工具”面板中)中添加环境变量:

    • 点击“秘密”
    • 添加各个环境变量:
      • REACT_APP_API_KEY
      • REACT_APP_SECRET_KEY
      • REACT_APP_API_PASSPHRASE
      • REACT_APP_PROJECT_ID
      • REACT_APP_USER_ADDRESS
      • REACT_APP_PRIVATE_KEY
  3. 单击“运行”启动您的开发环境

初始配置

本节展示如何设置与 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

调用API

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

调用API

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();
}
</object>

签署和发送交易

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,
   };
}
</object>

使用功能

应用程序的灵活性通过 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>} 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) 



<p>在这里,您可以指定chainId(您要使用的区块链网络)、fromTokenAddress和toTokenAddress(您要交换的代币)、您要交换的代币数量、可接受的滑点百分比以及您自己的值用户钱包地址。</p>

<p>dexUtils.js 对象中的 quoteParams 允许您配置源和目标区块链网络:<br>
</p>

<pre class="brush:php;toolbar:false">
/**
 * 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);
}
</object></object>

在此示例中,您可以指定 fromChainId(您起始的区块链网络)和 toChainId(您要交换到的区块链网络),以及 fromTokenAddress 和 toTokenAddress。这使您可以轻松地在不同的区块链生态系统之间移动您的代币,例如从 Avalanche 到 Polygon。

此外,您可以设置 receiveAddress 来指定交换的代币应发送到的位置,调整滑点容差,甚至配置 PriceImpactProtectionPercentage 以防止不利的价格变动。

通过公开这些配置选项,应用程序变得具有高度适应性,使开发人员能够根据用户的特定需求定制应用程序。

通过查看示例 React 应用程序,您可以找到如何在组件中实现这些功能并将其集成到应用程序中的工作示例。

结论

感谢您花时间查看本教程!我希望所提供的信息有助于了解如何在您自己的项目中利用 OKX DEX Aggregator API 的强大功能。

其他资源

  • OKX DEX API 文档
  • Web3.js 文档
  • Avalanche C 链文档

觉得这有帮助吗?不要忘记查看文章开头的资源,包括样板代码和文档。加入 OKX OS 社区与其他开发者联系,并在 Twitter 上关注 Julian 以获取更多 Web3 开发内容!


此内容仅供参考,可能涵盖您所在地区不提供的产品。仅代表作者观点,不代表OKX立场。它无意提供 (i) 投资建议或投资推荐; (ii) 购买、出售或持有数字资产的要约或招揽,或 (iii) 财务、会计、法律或税务建议。数字资产持有量,包括稳定币和 NFT,风险较高,波动较大。您应该根据您的财务状况仔细考虑交易或持有数字资产是否适合您。有关您具体情况的问题,请咨询您的法律/税务/投资专业人士。本文中出现的信息(包括市场数据和统计信息,如果有)仅供一般参考之用。尽管我们在准备这些数据和图表时已采取了所有合理的谨慎措施,但对于此处表达的任何事实错误或遗漏,我们不承担任何责任。 OKX Web3 钱包和 OKX NFT 市场均受 www.okx.com 上单独的服务条款约束。

© 2024 OKX。本文可以全文复制或分发,也可以使用本文 100 字或更少的摘录,前提是此类使用是非商业性的。 任何对整篇文章的复制或分发还必须在显着位置注明:“本文版权所有 © 2024 OKX,经许可使用。” 允许的摘录必须引用文章名称并包含出处,例如“在短短 30 分钟内集成 OKX DEX Widget,Julian Martinez,© 2024 OKX”。 不允许对本文进行衍生作品或其他用途。

以上是OKX DEX API 要点:Avalanche C 链上的单链和跨链互换的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
在JavaScript中替换字符串字符在JavaScript中替换字符串字符Mar 11, 2025 am 12:07 AM

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

jQuery检查日期是否有效jQuery检查日期是否有效Mar 01, 2025 am 08:51 AM

简单JavaScript函数用于检查日期是否有效。 function isValidDate(s) { var bits = s.split('/'); var d = new Date(bits[2] '/' bits[1] '/' bits[0]); return !!(d && (d.getMonth() 1) == bits[1] && d.getDate() == Number(bits[0])); } //测试 var

jQuery获取元素填充/保证金jQuery获取元素填充/保证金Mar 01, 2025 am 08:53 AM

本文探讨如何使用 jQuery 获取和设置 DOM 元素的内边距和外边距值,特别是元素外边距和内边距的具体位置。虽然可以使用 CSS 设置元素的内边距和外边距,但获取准确的值可能会比较棘手。 // 设置 $("div.header").css("margin","10px"); $("div.header").css("padding","10px"); 你可能会认为这段代码很

10个jQuery手风琴选项卡10个jQuery手风琴选项卡Mar 01, 2025 am 01:34 AM

本文探讨了十个特殊的jQuery选项卡和手风琴。 选项卡和手风琴之间的关键区别在于其内容面板的显示和隐藏方式。让我们深入研究这十个示例。 相关文章:10个jQuery选项卡插件

10值得检查jQuery插件10值得检查jQuery插件Mar 01, 2025 am 01:29 AM

发现十个杰出的jQuery插件,以提升您的网站的活力和视觉吸引力!这个精选的收藏品提供了不同的功能,从图像动画到交互式画廊。让我们探索这些强大的工具: 相关文章: 1

HTTP与节点和HTTP-Console调试HTTP与节点和HTTP-Console调试Mar 01, 2025 am 01:37 AM

HTTP-Console是一个节点模块,可为您提供用于执行HTTP命令的命令行接口。不管您是否针对Web服务器,Web Serv

自定义Google搜索API设置教程自定义Google搜索API设置教程Mar 04, 2025 am 01:06 AM

本教程向您展示了如何将自定义的Google搜索API集成到您的博客或网站中,提供了比标准WordPress主题搜索功能更精致的搜索体验。 令人惊讶的是简单!您将能够将搜索限制为Y

jQuery添加卷轴到DivjQuery添加卷轴到DivMar 01, 2025 am 01:30 AM

当div内容超出容器元素区域时,以下jQuery代码片段可用于添加滚动条。 (无演示,请直接复制到Firebug中) //D = document //W = window //$ = jQuery var contentArea = $(this), wintop = contentArea.scrollTop(), docheight = $(D).height(), winheight = $(W).height(), divheight = $('#c

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器