Skip to content

ETH

在 Bitget Wallet App 及安装 Chrome Extension 的 Chrome 浏览器中运行 DApp 时,可获得全局对象 window.bitkeep.ethereum 并进行后续的 API 调用。

js
const provider = window.bitkeep.ethereum;
const provider = window.bitkeep.ethereum;

注入对象的属性和方法

  • enable - () => Promise:连接方法,返回账户信息
  • isConnected - () => Boolean:获取连接状态
  • addCurrency - () => Promise:添加代币
  • switchChain - (method, data) => Promise:切换链
  • disconnect - () => Promise:断开连接
  • signPersonalMessage - (data) => Promise:签署消息
  • signTypedMessage - (data) => Promise:签署消息
  • request - (payload, callback) => Promise:即 Eth Call 方法,payload.method 可取值 eth_sign、personal_sign、eth_sendTransaction、eth_accounts 等方法获取不同的链上信息;callback 为调用方法之后的回调函数

请求账户信息

EIP-1102 该方法由EIP-1102指定。

在系统内部,调用 wallet_requestPermissions 的 eth_accounts 权限。

返回值

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

描述

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

这个请求会弹出 Bitget Wallet 钱包窗口,通常用按钮来触发,在该请求未有响应时,应禁止用户点击按钮。

在获得用户账户信息之前,应该提示用户点击按钮发起请求。

  • eth_accounts
    • 获取 user
  • eth_chainId
    • 获取 chainId(十六进制)
js
const Provider = getProvider();

function connect() {
  Provider.request({ method: 'eth_requestAccounts' })
    .then(handleAccountsChainChanged) // address or chainId changed
    .catch((error) => {
      if (error.code === 4001) {
        // EIP-1193 userRejectedRequest error
        console.log('Please connect to Bitkeep.');
      } else {
        console.error(error);
      }
    });
}

//if used injected
const accounts = await Provider.request({ method: 'eth_requestAccounts' });

handleAccountsChainChanged(); // updated address or chainID,refer to accountsChanged/chainChanged(events)

const [address] = await Provider.request({ method: 'eth_accounts' }); // [0x1e805A9aB0FB007B4b9D44d598C6404cE292F20D]
const chainId = await Provider.request({ method: 'eth_chainId' }); // 0x1

//if used web3
import Web3 from 'web3';
const accounts = await Provider.request({ method: 'eth_requestAccounts' });
//  [0x1e805A9aB0FB007B4b9D44d598C6404cE292F20D]

const web3 = new Web3(Provider);

handleAccountsChainChanged(); // updated address or chainID, refer to accountsChanged/chainChanged(events)

const accounts = await web3.eth.getAccounts(); // [0x1e805A9aB0FB007B4b9D44d598C6404cE292F20D]
const chainId = await web3.eth.getChainId(); // 0x1
const Provider = getProvider();

function connect() {
  Provider.request({ method: 'eth_requestAccounts' })
    .then(handleAccountsChainChanged) // address or chainId changed
    .catch((error) => {
      if (error.code === 4001) {
        // EIP-1193 userRejectedRequest error
        console.log('Please connect to Bitkeep.');
      } else {
        console.error(error);
      }
    });
}

//if used injected
const accounts = await Provider.request({ method: 'eth_requestAccounts' });

handleAccountsChainChanged(); // updated address or chainID,refer to accountsChanged/chainChanged(events)

const [address] = await Provider.request({ method: 'eth_accounts' }); // [0x1e805A9aB0FB007B4b9D44d598C6404cE292F20D]
const chainId = await Provider.request({ method: 'eth_chainId' }); // 0x1

//if used web3
import Web3 from 'web3';
const accounts = await Provider.request({ method: 'eth_requestAccounts' });
//  [0x1e805A9aB0FB007B4b9D44d598C6404cE292F20D]

const web3 = new Web3(Provider);

handleAccountsChainChanged(); // updated address or chainID, refer to accountsChanged/chainChanged(events)

const accounts = await web3.eth.getAccounts(); // [0x1e805A9aB0FB007B4b9D44d598C6404cE292F20D]
const chainId = await web3.eth.getChainId(); // 0x1

wallet_watchAsset

EIP-747

由规范EIP-747规定的。

参数

  • WatchAssetParams - 要观察的资产的元数据。
ts
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
  };
}
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

描述

要求用户在 Bitget Wallet 中跟踪代币。返回一个布尔值,表示该代币是否被成功添加。

以太坊钱包都支持一组代币,通常来自集中管理的代币注册表。wallet_watchAsset 使 web3 应用程序开发人员能够在运行时要求他们的用户跟踪他们钱包中的代币。添加后,token 与通过传统方法(例如集中式注册表)添加的 token 无法区分。

ts
provider
  .request({
    method: "wallet_watchAsset",
    params: {
      type: "ERC20",
      options: {
        address: "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
        symbol: "FOO",
        decimals: 18,
        image: "https://xxx.svg",
      },
    },
  })
  .then((success) => {
    if (success) {
      console.log("FOO successfully added to wallet!");
    } else {
      throw new Error("Something went wrong.");
    }
  })
  .catch(console.error);
provider
  .request({
    method: "wallet_watchAsset",
    params: {
      type: "ERC20",
      options: {
        address: "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
        symbol: "FOO",
        decimals: 18,
        image: "https://xxx.svg",
      },
    },
  })
  .then((success) => {
    if (success) {
      console.log("FOO successfully added to wallet!");
    } else {
      throw new Error("Something went wrong.");
    }
  })
  .catch(console.error);

wallet_switchEthereumChain/wallet_addEthereumChain

  • wallet_addEthereumChain

    创建一个确认,要求用户添加指定的链到 Bitget Wallet 。用户可以选择在添加后切换到该链。

    参数:

    对于rpcUrlsblockExplorerUrls数组,至少需要一个元素,并且只使用第一个元素。

    js
    interface AddEthereumChainParameter {
      chainId: string; // A 0x-prefixed hexadecimal string
      chainName: string;
      nativeCurrency: {
        name: string,
        symbol: string, // 2-6 characters long
        decimals: 18,
      };
      rpcUrls: string[];
      blockExplorerUrls?: string[];
      iconUrls?: string[]; // Currently ignored.
    }
    interface AddEthereumChainParameter {
      chainId: string; // A 0x-prefixed hexadecimal string
      chainName: string;
      nativeCurrency: {
        name: string,
        symbol: string, // 2-6 characters long
        decimals: 18,
      };
      rpcUrls: string[];
      blockExplorerUrls?: string[];
      iconUrls?: string[]; // Currently ignored.
    }

    返回值

    null - 如果请求成功,该方法返回 null,否则返回错误。

    与 wallet_switchEthereumChain 一起使用

    Bitget 建议将此方法与 wallet_addEthereumChain 一起使用:

    js
    try {
      await provider.request({
        method: "wallet_switchEthereumChain",
        params: [{ chainId: "0xf00" }],
      });
    } catch (switchError) {
      // This error code indicates that the chain has not been added to Bitkeep.
      if (switchError.code === 4902) {
        try {
          await ethereum.request({
            method: "wallet_addEthereumChain",
            params: [
              {
                chainId: "0xf00",
                chainName: "...",
                rpcUrls: ["https://..."] /* ... */,
              },
            ],
          });
        } catch (addError) {
          // handle "add" error
        }
      }
      // handle other "switch" errors
    }
    try {
      await provider.request({
        method: "wallet_switchEthereumChain",
        params: [{ chainId: "0xf00" }],
      });
    } catch (switchError) {
      // This error code indicates that the chain has not been added to Bitkeep.
      if (switchError.code === 4902) {
        try {
          await ethereum.request({
            method: "wallet_addEthereumChain",
            params: [
              {
                chainId: "0xf00",
                chainName: "...",
                rpcUrls: ["https://..."] /* ... */,
              },
            ],
          });
        } catch (addError) {
          // handle "add" error
        }
      }
      // handle other "switch" errors
    }
  • wallet_switchEthereumChain

    创建一个确认,要求用户切换到指定链 ID 的链上。

    参数:

    对于 rpcUrlsblockExplorerUrls 数组,至少需要一个元素,并且只使用第一个元素。

    js
    interface SwitchEthereumChainParameter {
      chainId: string; // A 0x-prefixed hexadecimal string
    }
    interface SwitchEthereumChainParameter {
      chainId: string; // A 0x-prefixed hexadecimal string
    }

    返回值

    null - 如果请求成功,该方法返回 null,否则返回错误。

    错误代码(error.code)为 4902 时,说明 Bitget Wallet 没有添加所请求的链,可通过wallet_addEthereumChain请求进行添加。

    描述

    与任何导致确认出现的方法一样,wallet_switchEthereumChain 应该只在用户直接操作的情况下被调用,例如点击按钮。

    在以下情况下,Bitget Wallet 将自动拒绝该请求:

    • 如果链 ID 格式错误
    • 如果指定的链 ID 未被添加到 Bitget Wallet

发送交易

js
const transactionParameters = {
  nonce: "0x00", // ignored by Bitkeep
  gasPrice: "0x09184e72a000", // customizable by user during Bitkeep confirmation.
  gas: "0x2710", // customizable by user during Bitkeep confirmation.
  to: "0x0000000000000000000000000000000000000000", // Required except during contract publications.
  from: provider.selectedAddress, // must match user's active address.
  value: "0x00", // Only required to send ether to the recipient from the initiating external account.
  data: "0x7f7465737432000000000000000000000000000000000000000000000000000000600057", // Optional, but used for defining smart contract creation and interaction.
  chainId: "0x3", // Used to prevent transaction reuse across blockchains. Auto-filled by Bitkeep.
};

// txHash is a hex string
// As with any RPC call, it may throw an error
const txHash = await provider.request({
  method: "eth_sendTransaction",
  params: [transactionParameters],
});

// if used web3
const accounts = await provider.request({ method: "eth_requestAccounts" });
const web3 = new Web3(provider);
const result = await web3.eth.sendTransaction({
  from: provider.selectedAddress,
  to: "0x0000000000000000000000000000000000000000",
  value: web3.utils.toWei("1", "ether"),
});
const transactionParameters = {
  nonce: "0x00", // ignored by Bitkeep
  gasPrice: "0x09184e72a000", // customizable by user during Bitkeep confirmation.
  gas: "0x2710", // customizable by user during Bitkeep confirmation.
  to: "0x0000000000000000000000000000000000000000", // Required except during contract publications.
  from: provider.selectedAddress, // must match user's active address.
  value: "0x00", // Only required to send ether to the recipient from the initiating external account.
  data: "0x7f7465737432000000000000000000000000000000000000000000000000000000600057", // Optional, but used for defining smart contract creation and interaction.
  chainId: "0x3", // Used to prevent transaction reuse across blockchains. Auto-filled by Bitkeep.
};

// txHash is a hex string
// As with any RPC call, it may throw an error
const txHash = await provider.request({
  method: "eth_sendTransaction",
  params: [transactionParameters],
});

// if used web3
const accounts = await provider.request({ method: "eth_requestAccounts" });
const web3 = new Web3(provider);
const result = await web3.eth.sendTransaction({
  from: provider.selectedAddress,
  to: "0x0000000000000000000000000000000000000000",
  value: web3.utils.toWei("1", "ether"),
});

以太坊 JSON-RPC 方法

关于以太坊 JSON-RPC API,请参见Ethereum wiki。 如何使用参考API Playground

ts
await provider.request({ method: "eth_accounts", params: [] });
await provider.request({ method: "eth_getBalance", params: [] });
await provider.request({ method: "eth_accounts", params: [] });
await provider.request({ method: "eth_getBalance", params: [] });

事件监听器

当地址和网络改变时通知。使用了eventemitter3

js
// reomove all listeners
provider.removeAllListeners();

function handleAccountsChainChanged() {
  provider.on("accountsChanged", ([address]) => {
    // Handle the new accounts, or lack thereof.
    // "accounts" will always be an array, but it can be empty.
    alert("address changed");
  });
  provider.on("chainChanged", async (chainId) => {
    // Handle the new chain.
    // Correctly handling chain changes can be complicated.
    // We recommend reloading the page unless you have good reason not to.
    alert("chainid changed");
  });
}
// reomove all listeners
provider.removeAllListeners();

function handleAccountsChainChanged() {
  provider.on("accountsChanged", ([address]) => {
    // Handle the new accounts, or lack thereof.
    // "accounts" will always be an array, but it can be empty.
    alert("address changed");
  });
  provider.on("chainChanged", async (chainId) => {
    // Handle the new chain.
    // Correctly handling chain changes can be complicated.
    // We recommend reloading the page unless you have good reason not to.
    alert("chainid changed");
  });
}

另外,一旦开启监听器,监听完后需要及时删除(例如在 React 中的组件卸载)。使用 removeAllListeners 防止多次监听。

js
function handleAccountsChanged(accounts) {
  // ...
}
provider.on("accountsChanged", handleAccountsChanged);

//remove
provider.removeAllListeners(); //remove all
provider.removeListener("accountsChanged", handleAccountsChanged); // only remove accountsChanged
function handleAccountsChanged(accounts) {
  // ...
}
provider.on("accountsChanged", handleAccountsChanged);

//remove
provider.removeAllListeners(); //remove all
provider.removeListener("accountsChanged", handleAccountsChanged); // only remove accountsChanged

accountsChanged

每当 eth_accounts RPC 方法的返回值发生变化时,Bitget Wallet 提供程序都会发出此事件。eth_accounts 返回一个空数组或包含单个帐户地址的数组。返回的地址(如果有)是允许调用者访问的最近使用的帐户的地址。调用者由其 URL 来源标识,这意味着具有相同来源的所有站点共享相同的权限。

这意味着只要用户暴露的账户地址发生变化,就会发出 accountsChanged。

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

chainChanged

当前链接的链发生变化时,BitKeep 提供者会发出这个事件。

所有 RPC 请求都提交给当前链接的链。因此,通过监听这个事件来跟踪当前链的 ID 是非常重要的。

Bitget 强烈建议在链变化时重新加载页面。

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

签署数据

  • eth_sign
  • personal_sign
  • eth_signTypedData
  • eth_signTypedData_v3
  • eth_signTypedData_v4

参考文档

错误

所有由 Bitget Wallet 提供者抛出或返回的错误都遵循这个接口:

ts
interface ProviderRpcError extends Error {
  message: string;
  code: number;
  data?: unknown;
}
interface ProviderRpcError extends Error {
  message: string;
  code: number;
  data?: unknown;
}

ethereum.request(args) 方法会及时的抛出错误。可以使用错误代码属性来确定请求失败的原因。常见的代码及其含义包括:

  • 4001
    • 该请求被用户拒绝
  • -32603
    • 内部错误或参数无效