EVM Provider

The Tomo Telegram SDK implements the Ethereum provider, allowing seamless integration with existing Ethereum-compatible DApps.

To use the EVM provider in your application, you need to first install the SDK and get the wallet provider:

// get provider 
const ethereum = window.ethereum;

Below are methods that developers can use with our EVM provider.

Wallet Connect

Before using the provider, the user needs to log in to the wallet through the modal by eth_requestAccounts method. The isConnected method returns a boolean value indicating whether the wallet is connected or not.

  ethereum.isConnected(): boolean

Query Methods

The request method is used to make an RPC request to the connected wallet. For detailed information on JSON-RPC methods, refer to:

We provide some frequently used methods as below:

Get accounts address

Connects to the wallet and returns the address of the connected wallet. In Tomo, the return value is the first address in the response.


const accounts = await ethereum.request({
    method: 'eth_requestAccounts',
    params: [], 
});

Or you can use the eth_accounts method to fetch the previous read address from the cache. If missed, it will return an empty array; use it with care!

const accounts = await ethereum.request({
     method: 'eth_accounts',
     params: [], 
});

Get chain ID

Returns the chain ID of the connected wallet.

const chainId = await ethereum.request({ method: 'eth_chainId' });

Get balance

Returns the mainnet balance of ETH in wei of hex format.

// eth_getBalance
const hexAmount= await window.ethereum.request({
  method: 'eth_getBalance',
  params: [addr, 'latest'],
});


const weiAmount = BigInt(hexAmount);

// const ethAmount = weiAmount / BigInt(10 ** 18);
const ethDecimal = Number(weiAmount) / 1e18;
const weiString = weiAmount.toString();

Sign Message

The Tomo Telegram SDK supports signing messages through the request method under the Metamask standard:

  • personal_sign

  • eth_signTypedData

  • eth_signTypedData_v3

  • eth_signTypedData_v4

The return value is the signature data. For detailed usage, refer to:

Example of⁣personal_sign:

const accounts = await ethereum.request({ method: 'eth_accounts' });
const chainId =  await ethereum.request({ method: 'eth_chainId' });

const signature = await ethereum.request({
  method: 'personal_sign',
  params: ['Hello, Tomo!', accounts[0]]
});

Example of⁣eth_signTypedData_v4:


const  accounts = await ethereum.request({ method: 'eth_accounts' });
const  chainId  =  await ethereum.request({ method: 'eth_chainId' });

const  msgParams = {
    "domain": {
        "chainId": chainId,
        "name": "Ether Mail",
        "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
        "version": "1"
    },
    "message": {
        "contents": "Hello, Bob!",
        "from": {
            "name": "Cow",
            "wallets": [
                "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
                "0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF"
            ]
        },
        "to": [
            {
                "name": "Bob",
                "wallets": [
                    "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
                    "0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57",
                    "0xB0B0b0b0b0b0B000000000000000000000000000"
                ]
            }
        ],
        "attachment": "0x"
    },
    ...
}

const signatureV4 = await ethereum.request({
  method: 'eth_signTypedData_v4',
  params: [
    accounts[0], 
    JSON.stringify(msgParams)
  ]
});

Sign Transaction

eth_signTransaction method will return a response with a signed transaction. Or you can use eth_sendTransaction it to send the signed transaction directly to the RPC node you specified in the provider. If you specify the chainId in params, the transaction will be sent to that network. Otherwise, it will be sent to the network you switched to using wallet_switchEthereumChain the method.

For users to verify the transaction contents, we only support passing parameters to the SDK and letting the user decide whether to sign the created transaction.

Transfer transaction

// simple transfer transaction
const response1 = await ethereum.request({
      method: 'eth_signTransaction', // or eth_sendTransaction
      params: [
        {
          from: addr,
          to: toAddr1,
          value: hexString,
          gas: hexString,
          gasPrice: hexString,
          nonce: hexString,
          chainId: hexString,
        },
      ],
    });

Contract call transaction

// transaction call contract 
const response2 = await ethereum.request({
      method: 'eth_signETHTransaction', // or eth_sendTransactio
      params: [
        {
          from: addr,
          to: contractAddr,
          value: int,
          chainId: hexString,
          data: hexData,
        },
      ],
    });

For example, below is the demo for sending ERC20 tokens:

import { ethers } from 'ethers';

// Example of ERC20 transfer 
const abi = [
 
  {
    inputs: [
      {
        internalType: 'address',
        name: 'to',
        type: 'address',
      },
      {
        internalType: 'uint256',
        name: 'amount',
        type: 'uint256',
      },
    ],
    name: 'transfer',
    outputs: [
      {
        internalType: 'bool',
        name: '',
        type: 'bool',
      },
    ],
    stateMutability: 'nonpayable',
    type: 'function',
  }];

// check the decimal of the ERC20 token, assume 6 for usdt
const val = Number(amount) * 10 ** 6
const iface = new ethers.utils.Interface(abi);
const data = iface.encodeFunctionData("transfer", [to, val.toString()]);
const response = await ethereum.request({
      method: 'eth_signETHTransaction', // or eth_sendTransactio
      params: [
        {
          from: from,
          to: contract_address,
          value: 0,
          chainId: chainId,
          data: data,
        },
      ],
    });

Check this doc for more usages.

Send Signed Transaction

To send a signed transaction, the user must use another library, like

const provider = new Web3.providers.HttpProvider(
  `url for rpc nodes`
);
const web3 = new Web3(provider);
try {
  const res = await web3.eth.sendSignedTransaction(serializedTx);
  console.log('result:', res);
} catch (error) {
  console.log(error);
  return;
}

Switch Ethereum Chain​

Switches the connected wallet to the specified chain ID.

try {
  await ethereum.request({
    method: 'wallet_switchEthereumChain',
    params: [{ chainId: '0xf00' }],
  });
} catch (switchError) {
  // error handle
}

Event Listeners

The SDK emits events for account and network changes.

accountsChanged

ethereum.on('accountsChanged', (accounts) => {//error handle };

chainChanged

ethereum.on('chainChanged', (chainId) => {//error handle });

To remove listeners:

ethereum.removeListener('accountsChanged', handleAccountsChanged);
// or remove all listeners
ethereum.removeAllListeners();

Last updated