使用 Widget#
本文将告诉你如何将功能强大的欧易 Widget 与你的产品进行整合,让你只需 30 分钟即可搭建一个高效交易界面!
安装#
yarn add @okxweb3/dex-widget
// or
npm install @okxweb3/dex-widget
// or
pnpm add @okxweb3/dex-widget
快速开始#
下方的例子将向你演示如何在一个 React 项目中使用 @okxweb3/dex-widget。你还可以通过此链接查看更多例子。
实际 Demo:https://okx.github.io/dex-widget/
import React, { useRef, useEffect } from 'react';
import ReactDOM from 'react-dom/client';
import { createOkxSwapWidget } from '@okxweb3/dex-widget';
function App() {
  const widgetRef = useRef();
  useEffect(() => {
    const params = {
      width: 375,
      providerType: 'EVM',
    };
    const provider = window.ethereum;
    const listeners = [
      {
        event: 'ON_CONNECT_WALLET',
        handler: () => {
          provider.enable();
        },
      },
    ];
    const instance = createOkxSwapWidget(widgetRef.current, {
      params,
      provider,
      listeners,
    });
    return () => {
      instance.destroy();
    };
  }, []);
  return <div ref={widgetRef} />;
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
钱包提供方#
如果需要连接钱包,你可以从你的应用中传递钱包提供方信息。同时添加 ON_CONNECT_WALLET 事件,即可无缝连接并使用 Widget。
- 如果提供方是在 Ethereum 或其他 EVM 网络上,它必须要符合 EIP-1193 才能创建交易界面。
- 如果提供方是在 Solana 网络上,它必须从你的应用中传递钱包提供方的信息。
import { createOkxSwapWidget, ProviderType } from '@okxweb3/dex-widget';
const widgetEthInstance = createOkxSwapWidget(
  document.getElementById('widget'),
  {
    params: {
      providerType: ProviderType.EVM,
    },
    provider: window.ethereum, // e.g. window.okexchain
  }
);
const widgetSolanaInstance = createOkxSwapWidget(
  document.getElementById('widget'),
  {
    params: {
      providerType: ProviderType.SOLANA,
    },
    provider: window.solana, // window.okexchain.solana
  }
);
Rainbow 连接钱包组件的示例可参考这个链接。
参数#
下方表格内是对 Params 的描述。
| 参数 | 类型 | 默认值 | 描述 | 
|---|---|---|---|
| width | number | 450 | 用 css 值 (px) 表示的 Widget 宽度。如果未设置宽度,则宽度的展示样式为:>767px 显示为 450 px, <768 px 显示为 100%, < 375 px 则显示为 375 px。 | 
| theme | THEME | light | 兑换 Widget 提供默认的日间、夜间主题选项。你可以按下方示例来切换 Widget 的主题。 | 
| lang | string | en_us | 你可以调整 Widget 所使用的语言,请在多语言配置部分了解更多细节信息。 | 
| tradeType | TradeType | auto | 交易的类型,可以是“swap”、“bridge”,或“auto”。注意:“自动”包含“swap”和“bridge”。 | 
| chainIds | Array<string> | [] | 承载单链兑换的区块链的 ID,请在 ChainId 配置部分查看你可选的所有网络。 | 
| tokenPair | ITokenPair | {} | 你所设定使用的兑换默认代币对,请在默认币对配置部分了解详情。 | 
| bridgeTokenPair | ITokenPair | {} | 你所设定使用的跨链默认代币对,请在默认币对配置部分了解详情。 | 
| providerType | ProviderType | ' ' | ProviderType 是和提供方一致的类型参数,例如,如果提供方是 Solana,那么 providerType 就会是 SOLANA。 | 
| defaultTab | TradeTab     | 'swap' | 可设定默认打开为单链、跨链。1.3.16版本及后续版本支持; | 
| walletName | string | ' ' | 连接的钱包名称,该参数帮助 DEX widget 持续改进产品和服务,来提供更好的交互体验。1.3.16版本及后续版本支持; | 
类型描述#
interface ITokenPair {
    fromChain: string | number;
    toChain: string | number;
    fromToken?: string;
    toToken?: string;
}
enum ProviderType {
    EVM = 'EVM',
    SOLANA = 'SOLANA',
    WALLET_CONNECT = 'WALLET_CONNECT',
}
enum TradeType {
    SWAP = 'swap',
    BRIDGE = 'bridge',
    AUTO = 'auto',
}
enum THEME {
    LIGHT = 'light',
    DARK = 'dark',
}
多语言配置#
| lang | 描述 | 
|---|---|
| en_us | English,默认 | 
| zh_cn | 简体中文 | 
| zh_tw | 繁體中文 | 
| fr_fr | Français (Afrique) | 
| id_id | Bahasa Indonesia | 
| ru_ru | Русский | 
| tr_tr | Türkçe | 
| vi_vn | Tiếng Việt | 
| de_de | Deutsch | 
| it_it | Italiano | 
| pl_pl | Polski | 
| pt_pt | Português (Portugal) | 
| es_es | Español (España) | 
| pt_br | Português (Brasil) | 
| es_419 | Español (Latinoamérica) | 
| cs_cz | Čeština | 
| ro_ro | Română | 
| uk_ua | Українська | 
| ar_eh | العربية | 
| nl_nl | Nederlands | 
ChainId 配置#
| 网络 | ChainId | 主网币合约地址 | 
|---|---|---|
| Ethereum | 1 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| Solana | 501 | 11111111111111111111111111111111 | 
| Arbitrum | 42161 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| Base | 8453 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| Sonic | 146 | 0x4Efa4b8545a3a77D80Da3ECC8F81EdB1a4bda783 | 
| Optimism | 10 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| zkSync Era | 324 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| BNB Chain | 56 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| Linea | 59144 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| Polygon | 137 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| Avalanche C | 43114 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| Mantle | 5000 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| Scroll | 534352 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| X layer | 196 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
| Blast | 81457 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 
默认币对配置#
tokenPair: 如果没有配置,则单链兑换将默认设置在 Ethereum 网络,且 fromToken 为 ETH,toToken 为 USDC。
bridgeTokenPair: 如果没有配置,则跨链兑换将默认设置为从 Ethereum 跨链至 BNB Chain,且 fromToken 为 ETH,toToken 为 BNB。
import React, { useEffect, useRef } from 'react';
import {
  OkxSwapWidgetParams,
  ProviderType,
  TradeType,
} from '@okxweb3/dex-widget';
const provider = window.ethereum;
export function EvmWidget() {
  const widgetRef = useRef();
  const params = {
    chainIds: ['1', '10'],
    lang: 'zh_cn',
    providerType: ProviderType.EVM,
    theme: 'dark',
    tradeType: TradeType.AUTO,
    tokenPair: {
      fromChain: 1, //ETH
      toChain: 1, // ETH
      fromToken: '0xdac17f958d2ee523a2206206994597c13d831ec7', // USDT
      toToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // ETH
    },
    bridgeTokenPair: {
      fromChain: 1, //ETH
      toChain: 56, // BNB
      fromToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // ETH
      toToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // BNB
    },
  };
  const initialConfig = {
    params,
    provider,
    listeners: [
      {
        event: 'ON_CONNECT_WALLET',
        handler: (token, preToken) => {
          provider.enable();
        },
      },
    ],
  };
  useEffect(() => {
    const widgetHandler = createOkxSwapWidget(widgetRef.current, initialConfig);
    return () => {
      widgetHandler?.destroy();
    };
  }, []);
  return <div ref={widgetRef} />;
}
| 参数 | 类型 | 描述 | 
|---|---|---|
| fromChain | String | fromToken 所属的源链 ID (例如,1:Ethereum,可在 ChainId 配置部分查看所有已支持的网络和对应的链 ID)。 | 
| fromToken | String | 试图卖出的代币的合约地址,例如 ETH:0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE。如果 fromToken 是某一区块链的主网币,请查看链 ID 以获取合约地址。 | 
| toChain | String | toToken 所属的目标链 ID (例如,1:Ethereum,可在 ChainId 配置部分查看所有已支持的网络和对应的链 ID)。 | 
| toToken | String | 试图卖出的代币的合约地址,例如 USDC:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48。如果 toToken 是某一区块链的主网币,请查看链 ID 以获取合约地址。 | 
Widget 更新#
updateParams#
可更新的属性:theme、lang、width
// 1. Create and initialize the widget
const widgetHandler = createOkxSwapWidget(container, initialConfig);
// 2. Update the widget's parameters (e.g., change theme or size)
widgetHandler.updateParams({
  width: 700,
  theme: 'light',
  lang: 'tr_tr',
});
updateProvider#
Widget 支持 EVM 和 Solana。当从 EVM 切换到 Solana 时,请记得更新相应的 Widget 提供方,反之亦然。
如果首次渲染时没有传递提供方信息,并想要 Widget 响应钱包绑定,就需要调用 updateProvider。
更新provider可同时增加walletName参数,用来识别用户所连接的插件钱包;
// 3. Update the provider if the user connects a different wallet, EVM => SOLANA
const walletName = 'phantom';
widgetHandler.updateProvider(window.solana, ProviderType.SOLANA, walletName);
// SOLANA => EVM
// widgetHandler.updateProvider(window.ethereum, ProviderType.EVM);
updateListeners#
你可以更新 Widget 监听的事件。
// 4. Modify event listeners to handle new types of events
widgetHandler.updateListeners([
  {
    event: OkxEvents.ON_FROM_CHAIN_CHANGE,
    handler: (payload) => {
      //
    },
  },
]);
- Listeners 主要用于监听 Widget 向外部暴露的接口,通过不同事件进行定制化处理。而 updateListeners 则用于在切换链后更新定制化处理。
- 通过添加事件监听器,可以捕获并处理从 iframe 中传递出来的事件数据。这些数据通常是 iframe 内部发生的事件或状态变化,并通过事件传递到外部页面。
- 接收到的数据可以根据需求进行灵活处理和操作。这意味着你可以根据传递的数据类型或内容,执行不同的逻辑或更新界面元素。
- 通过 updateListeners 方法,你可以为不同类型的事件 (如 OkxEvents.ON_FROM_CHAIN_CHANGE) 添加处理函数。当事件触发时,处理函数会接收到相关的 payload 数据,以便你进一步操作。
destroy#
当清除 Widget 模块时,调用此方法
const widgetHandler = createOkxSwapWidget(container, initialConfig);
widgetHandler.destory();
注意:#
- 每当你刷新和更新时,请确保调用 destroy 方法来清除先前绑定的事件,以避免出现重复订单请求。
事件监听#
Widget 为 ON_CONNECT_WALLET 和 ON_FROM_CHAIN_CHANGE 提供事件监听。
- ON_CONNECT_WALLET:当 Widget 未连接钱包并点击了连接钱包按钮时触发此事件。
- ON_FROM_CHAIN_CHANGE: 当 fromChain 发生变化时会触发此事件。
- ON_SUBMIT_TX:当交易完成后触发此事件,返回该交易的 txHash 以及 chainId;1.3.16版本后支持;
使用方法如下:
import {createOkxSwapWidget, OkxSwapWidgetParams, OkxEventListeners, OkxEvents} from '@okxweb3/dex-widget'
const params: OkxSwapWidgetParams = {
    // ...
}
const listeners: OkxEventListeners = [
    {
        event: OkxEvents.ON_CONNECT_WALLET,
        handler: () => {
            // open connect wallet method, eg openConnectModal of the rainbow kit.
            window.ethereum.enable()
        }
    },
    {
        event: OkxEvents.ON_FROM_CHAIN_CHANGE,
        handler: (token) => {
            //
        }
    },
    {
        event: OkxEvents.ON_SUBMIT_TX,
        handler: (res) => {
            console.log(`Transaction submitted successfully, txHash: ${res.data.txHash}`);
        }
    },
]
const { updateListeners } = createOkxSwapWidget(container, { params, listeners, provider })
