Development Guide for imToken DApp

Learn how to develop a DApp and link to imToken.

Introduction

This document will guide you in the simplest way possible to create a DApp from scratch and link your DApp to the imToken application.

The code written in the documentation can be found in sample project token-getting-started. You can install the imToken app to open the project you are developing to preview the changes.

imToken complies with the communication protocol between the DApp and the host environment: EIP-1102, this is fully compatible with metamask. You can also use metamask to debug your own DApps.

Want to learn more about RPC APIs? Browse the RPCs documentation.

Assumptions

This document assumes that you are already familiar with the basics of web development such as basic HTML / CSS / JavaScript, as a best practice, the sample project for the documentation is written based on React.

If you only need Native JavaScript and window.web3 for development and don't want any framework, please refer to our example here.

Create Project

Type npx create-next-app at the command line to create a base React project, which is a very simple minimalist structure for a web application, then we need to install some dependencies related to the DApp.

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

web3-react is a web3 upper layer wrapper library for the React API, it helps us to call the RPC API in a simpler way, very useful type hints are also provided.

Explanation of web3 and the libraries associated with it:

The imToken environment does not provide you with a built-in web3 or ethersjs library, only a basic provider, you just need to install your favorite class library in your project and inject the provider from imToken into it.

Now we need to initialize the Provider so that we can call the RPC API using Hooks in each component, add the Provider Component (which is actually a React Context) to the root component of the React project, and add a method to get the Provider in the imToken environment:

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>

The code for this file can be found here: pages/_app.tsx.

We have added an additional UI library so that you can have a base UI layout for your demo, you can ignore it or just copy the code from this file and try it.

Connect

Once we have created the Provider, we can try to link the host environment:

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.')
  }
}

We call the activate method to start trying to connect, if the connection fails we can get an error message from the host environment, if the user completes the authorization, then the account will be updated.

You can specify the supported chains in supportedChainIds, the detailed code can be found in the connector.tsx file.

Request Sign

Requesting Sign is a very common and important part of DApps, and you only need to learn one of these types of signatures to understand how it works. Here, as an example, we try to ask the user to sign a text message, and if we succeed, we will get the signature result.

At any time, you can run through the signature results to determine if the message came from a certain address.

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)
  }
}

We can simply determine whether the current DApp is connected to the wallet by account or active. Once the connection is confirmed, we can use signMessage to request the user to authorize the signature operation.

The sample code looks simple, and it's nothing special compared to the React App you're familiar with, just remember to handle the relevant errors.

For the above code, you can find it in the sign.tsx file.

Others

Direct clone project

If you think these flows from the code are confusing, try cloning down the entire sample repository:

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

Debugging the sample code of the example step by step will be very helpful for you to understand the running process.

Direct preview example

As a simpler way, you can open link https://token-example-react.vercel.app/ directly in imToken App, here is the online link to the sample project, you can see how it works by previewing the link.

Or use the imToken app to scan the sample project.

Help

Have you found an out-of-date sample code or any problems with it? Please leave your suggestions here: token-getting-started/issues.

Last updated