DApp 通过 WalletConnect 接入 ATON

简介

ATON 1.1.0 版本已经支持了 WalletConnect 协议。用户可以在保持私钥不离开移动设备,不暴露给 DApp 的前提下,实现与 DApp 的连接和交易签名。

什么是 WalletConnect

WalletConnect 是一种开放协议,用于在 DApps 和钱包之间进行安全通信。该协议在两个应用程序和/或设备之间建立远程配对,通过 Bridge server 来传递实际数据。两个对等方共享秘钥,对数据进行对称加密。配对由显示二维码或带有标准 WalletConnect URI 地址的一方发起,并在对方同意此配对请求时建立。

作为 DApp 开发者,您需要了解有关 WalletConnect 集成的基础知识。然后可以根据本教程,让用户在 DApp 生成待签名的交易请求,通过 WalletConnect 发送给 ATON 钱包后进行签名。

如何开发

首先需要在 DApp 里提供连接 WalletConnect 和 sendTransaction 两个按钮,用于建立连接和发送交易。

本教程的示例代码可参考 PlatON WalletConnect Example

1. DApp 集成 WalletConnect 协议

在 DApp 中,首先需要生成标准 WalletConnect URI 格式(EIP-1328)的二维码,以便后续供 ATON 钱包扫码连接(相关的 UI 组件 WalletConnect 官方库已经提供)。

DApp 点击按钮会建立连接,执行 walletConnectInit 方法

安装

  • yarn
yarn add @walletconnect/client @walletconnect/qrcode-modal
  • npm
npm install @walletconnect/client @walletconnect/qrcode-modal

建议开发者关注 walletconnect-monorepo 的官方更新,以便 DApp 可以具备最新的功能和性能提升。

WalletConnect 按钮

<SButtonContainer>
  <SConnectButton left onClick={this.walletConnectInit} fetching={fetching}>
    {"Connect to WalletConnect"}
  </SConnectButton>
</SButtonContainer>

建立 WalletConnect 连接

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

walletConnectInit = async () => {
  // bridge url
  const bridge = "https://bridge.walletconnect.org";

  // create new connector
  const connector = new WalletConnect({ bridge, qrcodeModal: QRCodeModal });

  await this.setState({ connector });

  // check if already connected
  if (!connector.connected) {
    // create new session
    await connector.createSession();
  }

  // subscribe to events
  this.subscribeToEvents();
};

subscribeToEvents 会对 walletConnectInit 定义好的 connector 进行相关的事件监听。connector API

subscribeToEvents = () => {
  const { connector } = this.state;

  if (!connector) {
    return;
  }

  // 当DApp连接上钱包后,若钱包的信息发生变化(大部分情况是 chainId 或者 address),会触发 session_update 的回调
  connector.on("session_update", async (error, payload) => {
    console.log(`connector.on("session_update")`, payload);

    if (error) {
      throw error;
    }

    const { chainId, accounts } = payload.params[0];

    // 通过 payload.params 拿到 accounts 和 chainId,对 DApp 的 state 进行更新
    this.onSessionUpdate(accounts, chainId);
  });

  connector.on("connect", (error, payload) => {
    console.log(`connector.on("connect")`, payload);

    if (error) {
      throw error;
    }

    this.onConnect(payload);
  });

  connector.on("disconnect", (error, payload) => {
    console.log(`connector.on("disconnect")`, payload);

    if (error) {
      throw error;
    }

    this.onDisconnect();
  });

  // 如果已经连接,则 walletConnectInit 执行后不会唤起二维码弹框,只需进行 DApp 的 state更新
  if (connector.connected) {
    const { chainId, accounts } = connector;
    const address = accounts[0];
    this.setState({
      connected: true,
      chainId,
      accounts,
      address,
    });
    this.onSessionUpdate(accounts, chainId);
  }

  this.setState({ connector });
};

注:示例没有使用 react hook,所以代码中的await this.setState() 如果要转换成 hook,需要开发者对于 DApp 的 state 和更新逻辑进行梳理。

2. 和 ATON 建立连接

  • 通过步骤 1,ATON 钱包已经可以扫描 WalletConnect URI 格式的二维码建立连接,读取 URI 后,将立即接收并解密连接的请求数据。然后,钱包将向用户显示 Dapp 提供的请求详细信息。如下:

Initiate Connection

  • 用户将批准或拒绝连接。

如果被拒绝,ATON 发起拒绝请求,DApp 会进入 disconnect 事件,将立即与桥接服务器断开连接,可根据 payload 的 message 进行错误处理和提示

payload: {
  event: "disconnect";
  params: [{ message: "Session update rejected" }];
}

如果获得批准,ATON 会展示连接成功的信息,DApp 会进入 connect 事件,将从钱包返回的 payload 收到提供的帐户和 ChainID。

Approve Connection

payload: {
  event: "connect"
  params: [
    accounts: ['0xdc8c0f103dc8523c82d38064f746dda9fa28bf7f']
    chainId: 210309
    peerId: "BC246E88-ACC0-4FD6-BF10-DEF314EF42BE"
    peerMeta: {description: "hello,i'm Platon.", icons: Array(0), name: 'ATON', url: 'https://safe.gnosis.io'}
  ]
}

3. 交易签名

建立连接后,DApp 将能够发送任何由钱包处理的 JSON-RPC 调用请求,以从其节点读取数据或为交易或消息发出签名请求。

发送按钮

<Button onClick={this.send}>Send</Button>

生成交易签名请求

sendTransaction = async () => {
  const tx = {
    from,
    to,
    nonce,
    gasPrice,
    gasLimit,
    value,
    data,
  };

  // send transaction
  const result = await connector.sendTransaction(tx);

  console.log("connector.sendTransaction result txHash: ", result);
};

交易结果展示

获取到 txHash,可在 DApp 提供浏览器链接和交易详情展示

// format displayed result
const formattedResult = {
  method: "eth_sendTransaction",
  txHash: result,
  from: address,
  to: address,
  value: "0 ETH",
};

// display result
this.setState({
  connector,
  result: formattedResult || null,
});

Confirm Transaction

Transaction Success@3x

总结

按照这三个步骤,就可以在 DApp 里和 ATON 建立连接,并通过 WalletConnect 提供的 sendTransaction 发送交易签名请求。

视频 Demo


5 个赞

赞赞,学习了 :tada: :tada: :tada: :tada: :tada:

1 个赞

666,超棒的教程!