imToken DApp 开发指引

学习如何开发 DApp 并连接到 imToken。

介绍

本文档将以最简单易懂的方式指导你从头开始创建 DApp,并将你的 DApp 与 imToken 应用程序相连接。本文所使用的示例项目托管于 GitHub (token-getting-started),你可以 安装 imToken 应用 打开项目以预览开发过程中的变化。

imToken 应用在宿主环境与 DApp 之间的通信遵循 EIP-1102 协议,也完全兼容于 MetaMask。你也可以使用 MetaMask 调试自己的 DApp。

想要了解更多的 RPC 接口,请看 RPC 接口文档

假设

此文档假设你已经拥有基础的 Web 开发知识,如 HTML / CSS / JavaScript 等,作为最佳实践,示例项目是基于 React 创建。

如果你完全不需要任何项目框架,仅想使用纯 JavaScript 开发,请参考我们的 入门示例

创建项目

输入 npx create-next-app 以创建基础的 React 项目,这是我们非常熟悉的最简化结构的 Web 应用,虽然,我们需要下载与安装一些 DApp 相关的依赖。

npm i @ethersproject/providers @web3-react/core @web3-react/injected-connector

web3-react 是适用于 React 框架的高层封装库,这可以帮我们屏蔽更多 RPC 接口的实现细节,仅以最简单的方式调用函数,同时还为我们提供了非常丰富的类型支持。

对于 Web3 与之相关类库的解释:

DApp 的具体实现与你选择的类库是无关的,只要类库遵循 EIP 标准即可。imToken 环境内也不会为你注入类似于 web3.js 或是 ethersjs 等第三方库 (出于安全考量),仅会添加用于连接的 Provider 信息。

如果你需要任何其他第三方库,请确保已将依赖已经安装并最终会打包至 Web App 的输出文件中。

现在我们只需要初始化 Provider 即可在组件中使用 Hooks 调用相关 RPC 接口。

增加 Provider 组件 (实际上这是 React Context) 到你的 React 项目根组件中,并添加 getLibrary 方法进行连接。

pages/_app.tsx
import { Web3ReactProvider } from '@web3-react/core'
import { Web3Provider } from '@ethersproject/providers'

const getLibrary = () => {
  const provider = (window as any).web3.currentProvider
  return new Web3Provider(provider)
}

<Web3ReactProvider getLibrary={getLibrary}>
  <Component {...pageProps} />
</Web3ReactProvider>

上述代码可以在 pages/_app.tsx 文件中找到。

我们还在示例项目中添加了基础的 UI 布局,这是为了保证用户预览时有较好的体验。如果不需要,你完全可以忽略它们。

连接到节点

当我们创建 Provider 后,可以尝试在页面中开始连接到节点:

const injected = new InjectedConnector({
  supportedChainIds: [
    1, // Mainet
    3, // Ropsten
    4, // Rinkeby
    5, // Goerli
    42, // Kovan
  ],
})

const { activate, active, account } = useWeb3React<Web3Provider>()

const clickHandler = async () => {
  try {
    if (active) return alert('Already linked')
    await activate(injected, walletError => {
      if (walletError.message.includes('user_canceled')) {
        return alert('You canceled the operation, please refresh and try to reauthorize.')
      }
      alert(`Failed to connect: ${walletError.message}`)
    })
  } catch (err) {
    console.log(err)
    alert('Failed to connect Wallet.')
  }
}

调用activate 方法 (异步) 可以开始尝试连接,如果连接失败会抛出相关的错误信息,在用户接受响应后,连接将会被保存,同时 account 数据也会被自动更新,我们将会得到用户的账户地址。

你可以在 supportedChainIds 中指定可支持的链 ID。上述代码可以在 connector.tsx 文件中找到。

请求签名

请求签名是 DApp 开发中非常关键的一部分,但通常你只需要学习了解请求签名方式中的一种,其他对于不同信息体的签名也能以此类推。在这里作为一个最简单的示例,我们尝试让用户签名一个文本信息 (text message),如果我们成功将会得到一个由用户私钥签名的结果 (字符串)。

在任何时候,你都可以通过签名结果来确认信息是否来自某个地址,这是签名的主要作用。

const [result, setResult] = useState<string>('')
const { active, account, library } = useWeb3React<Web3Provider>()
const isConnected = useMemo(() => active && account, [account, active])

const clickHandler = async () => {
  if (!isConnected) return
  const signer = library.getSigner(account)
  try {
    const result = await signer.signMessage(MESSAGE)
    setResult(result)
  } catch (err) {
    if (err?.errorCode === 1001) {
      return alert('You canceled the operation.')
    }
    alert(err.message)
  }
}

我们可以通过 accountactive 来确认当前是否已连接并已获取到用户的地址 (如果没有,重复上一步),一旦连接确认,我们可以使用准备好的 signMessage 方法请求用户签名。

imToken 应用 (或其他兼容 EIP RPC 的钱包) 都会监听来自外部符合 EIP 规范的 RPC 调用,在这里我们使用 signMessage 方法屏蔽了 RPC 接口的调用细节,你可以粗略将此方法理解为 Web 应用中常见的 HTTP 上层封装,异步调用,返回 Promise 类型。

示例代码中核心内容很简单,只有 signer.signMessage 一句,其他均是处理错误相关信息。对于上诉所有示例代码,你可以在 sign.tsx 文件中找到。

其他

直接 Clone 项目

如果你按文档指引查看代码仍旧感到困惑,可以直接将示例项目 Clone 到本地调试:

git clone git@github.com:consenlabs/token-getting-started.git

在本地调试代码并尝试连接到钱包将有助于你理解 DApp 的工作原理。

直接预览项目

作为更简单的方式,你可以直接在 imToken 应用中打开 https://token-example-react.vercel.app/ 预览此项目,或是使用 imToken 应用扫描下方二维码。

帮助

遇到示例项目代码过时或是其他难以解决的技术问题?请在开发者社区中 创建一个讨论

最后更新于