接入钱包
Provider API

Provider API#

什么是 Injected provider API?#

欧易 Injected providers API 是一个 JavaScript API,欧易将其注入用户访问的网站。您的 DApp 可以使用此 API 请求用户帐户,从用户连接的区块链读取数据,帮助用户签署消息和交易。

连接账户#

eth_requestAccounts

EIP-1102
此方法由 EIP-1102 指定。 在底层逻辑上,它调用 wallet_requestPermissions 以获得 eth_accounts 权限。由于目前来说 eth_accounts 是唯一的权限,所以你现在仅需此方法。

描述

此方法请求用户提供一个以太坊地址来识别。返回值为一个解析为单个以太坊地址字符串数组的 Promise。如果用户拒绝该请求,Promise 将被拒绝并返回 4001 错误。

该请求会导致一个欧易的弹窗出现。你应该只在响应用户操作时请求账户,比如一个用户在单击按钮的时候。在请求仍处于待处理状态时,你应该始终禁用导致请求被分派的按钮。

如果你无法检索用户的账户,你应该鼓励用户发起账户请求。

返回值

string[] - 单个十六进制以太坊地址字符串的数组。

例子

codeopen中打开。

HTML
JavaScript
<button class="connectEthereumButton">Connect Ethereum</button>
const connectEthereumButton = document.querySelector('.connectEthereumButton');

connectEthereumButton.addEventListener('click', () => {
  //Will Start the OKX extension
  okxwallet.request({ method: 'eth_requestAccounts' });
});

签名信息#

eth_sign

描述

sign 方法计算以太坊特定的签名:sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)))

通过在消息中添加前缀,可以将计算出的签名识别为以太坊特定的签名。 这可以防止恶意去中心化应用程序可以签署任意数据(例如交易)并使用签名冒充受害者的滥用行为。

注意:要签名的地址必须已解锁。

参数

  1. DATA,20 字节 - 地址
  2. DATA,N 字节 - 要签名的消息
{
  params:["0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", "0xdeadbeaf"],
}

返回值

DATA:签名

{
  result: "0xa3f20717a250c2b0b729b7e5becbff67fdaef7e0699da4de7ca5895b02a170a12d887fd3b17bfdce3481f10bea41f45ba9f709d39ce8325427b57afcfc994cee1b"
}

例子

codeopen中打开。

HTML
JavaScript
<button class="connectEthereumButton btn">Connect Ethereum</button>
<button class="signMessageButton btn">Sign Message</button>
const connectEthereumButton = document.querySelector('.connectEthereumButton');
const signMessageButton = document.querySelector('.signMessageButton');

let accounts = [];

signMessageButton.addEventListener('click', () => {
  okxwallet
    .request({
      method: 'eth_sign',
      params: [account[0], "0xdeadbeaf"],
    })
    .then((res) => console.log(res))
    .catch((error) => console.error);
});

connectEthereumButton.addEventListener('click', () => {
  getAccount();
});

async function getAccount() {
  try{
    accounts = await okxwallet.request({ method: 'eth_requestAccounts' });
  }catch(error){
    console.log(error);
  }
}

添加代币#

Note: 该功能仅在欧易 Web3 钱包插件端支持。

wallet_watchAsset#

EIP-747
此方法由 EIP-747 指定。

描述

此方法请求用户在欧易中关注某代币。返回一个布尔值,这个布尔值代表着代币是否已成功添加。

大多数以太坊钱包都支持关注一组代币,这些代币通常来自集中管理的代币注册表。 wallet_watchAsset 让 Web3 应用程序开发人员能够在运行时询问他们的用户去关注他们钱包中的代币。新添加的代币与通过原始方法(例如集中式注册表)添加的代币没有任何区别。

参数

  • WatchAssetParams - 要关注的资产的元数据。
interface WatchAssetParams {
  type: 'ERC20'; // In the future, other standards will be supported
  options: {
    address: string; // The address of the token contract
    'symbol': string; // A ticker symbol or shorthand, up to 11 characters
    decimals: number; // The number of token decimals
    image: string; // A string url of the token logo
  };
}

返回值

boolean - 如果添加了代币为 true,否则为 false

例子

codeopen中打开。

HTML
JavaScript
<button class="connectEthereumButton btn">Connect Ethereum</button>
<button class="addTokenButton btn">Add Token</button>
const ethereumButton = document.querySelector('.connectEthereumButton');
const addTokenButton = document.querySelector('.addTokenButton');

addTokenButton.addEventListener('click', () => {
  okxwallet
    .request({
      method: 'wallet_watchAsset',
      params: {
        type: 'ERC20',
        options: {
          address: '0xb60e8dd61c5d32be8058bb8eb970870f07233155',
          symbol: 'FOO',
          decimals: 18,
          image: 'https://foo.io/token-image.svg',
        },
      },
    })
    .then((success) => {
      if (success) {
        console.log('FOO successfully added to wallet!');
      } else {
        throw new Error('Something went wrong.');
      }
    })
    .catch(console.error);
});

ethereumButton.addEventListener('click', () => {
  getAccount();
});

function getAccount() {
  okxwallet.request({ method: 'eth_requestAccounts' }).catch((error)=>{
    console.log(error);
  });
}

事件#

欧易提供者实现了 Node.js EventEmitter API。 本节详细介绍了通过该 API 发出的事件。 网络上有其他各式各样的 EventEmitter 指南可供参考,本指南列出了如下一些事件:

okxwallet.on('accountsChanged', (accounts) => {
  // Handle the new accounts, or lack thereof.
  // "accounts" will always be an array, but it can be empty.
});

okxwallet.on('chainChanged', (chainId) => {
  // Handle the new chain.
  // Correctly handling chain changes can be complicated.
  // We recommend reloading the page unless you have a very good reason not to.
  window.location.reload();
});

另外,一旦你使用完监听器,请不要忘记将其删除(例如在 React 中卸载组件时):

function handleAccountsChanged(accounts) {
  // ...
}

okxwallet.on('accountsChanged', handleAccountsChanged);

// Later
okxwallet.removeListener('accountsChanged', handleAccountsChanged);

okxwallet.removeListener 的第一个参数是事件名称,第二个参数是对已传递给第一个参数中提到的事件名称的 okxwallet.on 的同一函数的引用。

connect

interface ConnectInfo {
  chainId: string;
}

okxwallet.on('connect', handler: (connectInfo: ConnectInfo) => void);

欧易提供者会在第一次能够向链提交 RPC 请求时发出此事件。我们建议使用 connect 事件处理程序和 okxwallet.isConnected() 方法来确定欧易提供者的连接状态和连接时间。

disconnect

okxwallet.on('disconnect', handler: (error: ProviderRpcError) => void);

如果欧易提供者无法向任何链提交 RPC 请求,则会发出此事件。通常,这只会发生在网络连接问题或某些其他不可预见的错误状态下。

一旦发出 disconnect,提供者直到重新建立与链的连接之前将不会接受任何新请求,建立新连接需要重新加载页面。你还可以使用 okxwallet.isConnected() 方法来确定提供程序是否已断开连接。

accountsChanged

okxwallet.on('accountsChanged', handler: (accounts: Array<string>) => void);

每当 eth_accounts RPC 方法的返回值发生变化时,欧易提供程序都会发出此事件。 eth_accounts 会返回一个为空或包含单个账户地址的数组。返回的地址(如果存在)即为允许调用者访问的最近使用的账户地址。由于调用者由其 URL origin 标识,所以具有相同来源(origin)的站点会持有相同的权限。

只要用户公开的账户地址发生变化,就会发出 accountsChanged.

提示
我们计划在不久的将来允许 eth_accounts 数组能够包含多个地址。

chainChanged

提示
欧易的默认链及其链 ID 请参见 Chain IDs section

当前连接的链发生变化时,欧易提供者会发出此事件。

所有的 RPC 请求都提交到当前连接的链上。因此,通过侦听此事件来跟踪当前链 ID 是至关重要的。

我们强烈建议在链更改时重新加载页面,当然你也可以通过需求自行选择。

okxwallet.on('chainChanged', (_chainId) => window.location.reload());

message

interface ProviderMessage {
  type: string;
  data: unknown;
}

okxwallet.on('message', handler: (message: ProviderMessage) => void);

欧易提供者在有需要通知消费者的消息时发出此事件。消息的种类由 type 字符串标识。

RPC 订阅更新是 message 事件的常见用例。 例如,如果你使用 eth_subscribe 创建订阅,则每个订阅更新都将作为 message 事件发出,其 typeeth_subscription

例子

codeopen中打开。

HTML
JavaScript
<button class="connectEthereumButton btn">Connect Ethereum</button>
<button class="switchChainButton btn">Switch Chain</button>
const ethereumButton = document.querySelector(".connectEthereumButton");
const switchChainButton = document.querySelector(".switchChainButton");

window.okxwallet.on("chainChanged", (_chainId) => {
  console.log(`on chainChanged, current chainId: ${_chainId}`);
});

switchChainButton.addEventListener("click", async () => {
  try {
    await okxwallet.request({
      method: "wallet_switchEthereumChain",
      params: [{ chainId: okxwallet.chainId === "0x42" ? "0x38" : "0x42" }]
    });
  } catch (error) {
    // handle other "switch" errors
    console.log(error);
  }
});

ethereumButton.addEventListener("click", () => {
  getAccount();
});

async function getAccount() {
  await okxwallet.request({ method: "eth_requestAccounts" });
}