Skip to content

WalletConnect

Bitget 移动端钱包已支持 WalletConnect。

WalletConnect 是一个链接钱包和 DApps(Web3 应用程序)的开放协议,它使用一个桥梁服务器在两个应用程序和/或设备之间建立远程链接,扫描 QR 码建立链接并开始通信。

  • WalletConnect 官方支持的链:Cosmos、Ethereum、Solana、Near、Startnet
    更多:WalletConnect Multi-Chain
  • Bitget Wallet 已支持:Ethereum、Cosmos

集成步骤

  1. 注册开通 wallet connect 服务
  2. 前端安装 wallet connect sdk
  3. 参数配置及初始化
  4. 钱包 App 扫码验证

开发示例

js
import WalletConnect from '@walletconnect/client';
import QRCodeModal from '@walletconnect/qrcode-modal';

class WalletConnectQrcodeDemo extends React.Component {
  connector = null;
  state = {
    connector: null,
    connected: false,
    chainId: 1,
    selectedAddress: "",
  };
  connect = async () => {
    // bridge url

    const bridge = "https://bridge.walletconnect.org";

    // create new connector
    const connector = new WalletConnect({ bridge, qrcodeModal: QRCodeModal });
    // check if already connected
    if (!connector.connected) {
      // create new session
      await connector.createSession();
    } else {
      const { chainId, accounts } = connector;
      this.setState({
        selectedAddress: accounts[0],
        chainId: chainId,
      });
    }
    this.connector = connector;
    // subscribe to events
    await this.initEvent();
  };
  initEvent() {
    this.connector.on("connect", (error, payload) => {
      console.log(`connector.on("connect")`);
      alert("connected");
      if (error) {
        throw error;
      }
      // Get provided accounts and chainId
      const { accounts, chainId } = payload.params[0];
      this.setState({
        selectedAddress: accounts[0],
        chainId: chainId,
      });
    });
    this.connector.on("session_update", (error, payload) => {
      console.log(`connector.on("session_update")`);
      alert("session_update");
      if (error) {
        throw error;
      }

      const { accounts, chainId } = payload.params[0];
      this.setState({
        selectedAddress: accounts[0],
        chainId: chainId,
      });
    });

    this.connector.on("disconnect", (error, payload) => {
      console.log(`connector.on("disconnect")`);
      alert("disconnect");
      if (error) {
        throw error;
      }
      this.setState({
        selectedAddress: "",
        chainId: 1,
      });
    });
  }
  disconnected() {
    if (this.connector) {
      this.connector.killSession();
      this.setState({
        selectedAddress: "",
        chainId: 1,
      });
    }
  }
  async sendTransaction() {
    // Draft transaction
    const tx = {
      from: this.state.selectedAddress, // Required
      to: document.querySelector("#to").value, // Required (for non contract deployments)
      data: "0x", // Required
      gasPrice: "0x02540be400", // Optional
      gas: "0x9c40", // Optional
      value: String(document.querySelector("#amount").value * 10 ** Number(18)), // Optional
      // nonce: "0x0114", // Optional
    };

    // Send transaction
    return this.connector.sendTransaction(tx);
  }
  render() {
    const { selectedAddress, chainId } = this.state;
    return (
      <>
        <div className="testdemo">
          <div>
            <h1>connect</h1>

            {<button disabled={selectedAddress} data-method="connect" onClick={this.connect.bind(this)}>connect</button>}
            {<button  data-method="disconnected"  onClick={this.disconnected.bind(this)}>disconnected</button>}
            <div>
              selectedAddress: <span id="account">{selectedAddress}</span>
            </div>
            <div>
              chainId : <span id="chainId">{chainId}</span>
            </div>
          </div>

          <div>
            <h1>transfer EVM</h1>
            from:
            <input id="from" type="text"  value={selectedAddress} disabled/>
            to:
            <input id="to" type="text"  value="0x1da770d53eBe21c79cebD9cb0C9ce885BeD251DC"/>
            amount:
            <input id="amount" type="number" />
            <button data-method="sendTransaction" onClick={this.sendTransaction.bind(this)}>sendTranstion</button>
          </div>
        </div>
      </>
    );
  }
}
import WalletConnect from '@walletconnect/client';
import QRCodeModal from '@walletconnect/qrcode-modal';

class WalletConnectQrcodeDemo extends React.Component {
  connector = null;
  state = {
    connector: null,
    connected: false,
    chainId: 1,
    selectedAddress: "",
  };
  connect = async () => {
    // bridge url

    const bridge = "https://bridge.walletconnect.org";

    // create new connector
    const connector = new WalletConnect({ bridge, qrcodeModal: QRCodeModal });
    // check if already connected
    if (!connector.connected) {
      // create new session
      await connector.createSession();
    } else {
      const { chainId, accounts } = connector;
      this.setState({
        selectedAddress: accounts[0],
        chainId: chainId,
      });
    }
    this.connector = connector;
    // subscribe to events
    await this.initEvent();
  };
  initEvent() {
    this.connector.on("connect", (error, payload) => {
      console.log(`connector.on("connect")`);
      alert("connected");
      if (error) {
        throw error;
      }
      // Get provided accounts and chainId
      const { accounts, chainId } = payload.params[0];
      this.setState({
        selectedAddress: accounts[0],
        chainId: chainId,
      });
    });
    this.connector.on("session_update", (error, payload) => {
      console.log(`connector.on("session_update")`);
      alert("session_update");
      if (error) {
        throw error;
      }

      const { accounts, chainId } = payload.params[0];
      this.setState({
        selectedAddress: accounts[0],
        chainId: chainId,
      });
    });

    this.connector.on("disconnect", (error, payload) => {
      console.log(`connector.on("disconnect")`);
      alert("disconnect");
      if (error) {
        throw error;
      }
      this.setState({
        selectedAddress: "",
        chainId: 1,
      });
    });
  }
  disconnected() {
    if (this.connector) {
      this.connector.killSession();
      this.setState({
        selectedAddress: "",
        chainId: 1,
      });
    }
  }
  async sendTransaction() {
    // Draft transaction
    const tx = {
      from: this.state.selectedAddress, // Required
      to: document.querySelector("#to").value, // Required (for non contract deployments)
      data: "0x", // Required
      gasPrice: "0x02540be400", // Optional
      gas: "0x9c40", // Optional
      value: String(document.querySelector("#amount").value * 10 ** Number(18)), // Optional
      // nonce: "0x0114", // Optional
    };

    // Send transaction
    return this.connector.sendTransaction(tx);
  }
  render() {
    const { selectedAddress, chainId } = this.state;
    return (
      <>
        <div className="testdemo">
          <div>
            <h1>connect</h1>

            {<button disabled={selectedAddress} data-method="connect" onClick={this.connect.bind(this)}>connect</button>}
            {<button  data-method="disconnected"  onClick={this.disconnected.bind(this)}>disconnected</button>}
            <div>
              selectedAddress: <span id="account">{selectedAddress}</span>
            </div>
            <div>
              chainId : <span id="chainId">{chainId}</span>
            </div>
          </div>

          <div>
            <h1>transfer EVM</h1>
            from:
            <input id="from" type="text"  value={selectedAddress} disabled/>
            to:
            <input id="to" type="text"  value="0x1da770d53eBe21c79cebD9cb0C9ce885BeD251DC"/>
            amount:
            <input id="amount" type="number" />
            <button data-method="sendTransaction" onClick={this.sendTransaction.bind(this)}>sendTranstion</button>
          </div>
        </div>
      </>
    );
  }
}

自定义配置钱包信息

js
import { createWeb3Modal, defaultConfig } from "@web3modal/ethers/react";

// 1. Get projectId
const projectId = "YOUR_PROJECT_ID";

// 2. Set chains
const mainnet = {
  chainId: 1,
  name: "Ethereum",
  currency: "ETH",
  explorerUrl: "https://etherscan.io",
  rpcUrl: "https://cloudflare-eth.com",
};

// 3. Create a metadata object
const metadata = {
  name: "My Website",
  description: "My Website description",
  url: "https://mywebsite.com", // origin must match your domain & subdomain
  icons: ["https://avatars.mywebsite.com/"],
};

// 4. Create Ethers config
const ethersConfig = defaultConfig({
  /*Required*/
  metadata,

  /*Optional*/
  enableEIP6963: true, // true by default
  enableInjected: true, // true by default
  enableCoinbase: true, // true by default
  rpcUrl: "...", // used for the Coinbase SDK
  defaultChainId: 1, // used for the Coinbase SDK
});

// 5. Create a Web3Modal instance

createWeb3Modal({
  ethersConfig,
  chains: [mainnet],
  projectId,
  enableAnalytics: true, // Optional - defaults to your Cloud configuration
  featuredWalletIds: [
    //Select wallets that are going to be shown on the modal's main view. Default wallets are MetaMask and Trust Wallet. Array of wallet ids defined will be prioritized (order is respected). These wallets will also show up first in All Wallets view. You can find the wallets ids in https://explorer.walletconnect.com/?type=wallet
    "id1",
    "id2",
    "...",
  ],
});

export default function App() {
  return <YourApp />;
}
import { createWeb3Modal, defaultConfig } from "@web3modal/ethers/react";

// 1. Get projectId
const projectId = "YOUR_PROJECT_ID";

// 2. Set chains
const mainnet = {
  chainId: 1,
  name: "Ethereum",
  currency: "ETH",
  explorerUrl: "https://etherscan.io",
  rpcUrl: "https://cloudflare-eth.com",
};

// 3. Create a metadata object
const metadata = {
  name: "My Website",
  description: "My Website description",
  url: "https://mywebsite.com", // origin must match your domain & subdomain
  icons: ["https://avatars.mywebsite.com/"],
};

// 4. Create Ethers config
const ethersConfig = defaultConfig({
  /*Required*/
  metadata,

  /*Optional*/
  enableEIP6963: true, // true by default
  enableInjected: true, // true by default
  enableCoinbase: true, // true by default
  rpcUrl: "...", // used for the Coinbase SDK
  defaultChainId: 1, // used for the Coinbase SDK
});

// 5. Create a Web3Modal instance

createWeb3Modal({
  ethersConfig,
  chains: [mainnet],
  projectId,
  enableAnalytics: true, // Optional - defaults to your Cloud configuration
  featuredWalletIds: [
    //Select wallets that are going to be shown on the modal's main view. Default wallets are MetaMask and Trust Wallet. Array of wallet ids defined will be prioritized (order is respected). These wallets will also show up first in All Wallets view. You can find the wallets ids in https://explorer.walletconnect.com/?type=wallet
    "id1",
    "id2",
    "...",
  ],
});

export default function App() {
  return <YourApp />;
}

*有关 featuredWalletIds 配置的 Bug:featuredWalletIds option is broken, starting from v4.2.2

扩展阅读