> For the complete documentation index, see [llms.txt](https://docs.tomo.inc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tomo.inc/tomo-sdk/tomo-telegram-sdk/wallet-provider/evm-provider.md).

# 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:

```typescript
// get provider 
const ethereum = window.ethereum;
```

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

## Wallet Connect <a href="#isconnected" id="isconnected"></a>

Before using the provider, the user needs to log in to the wallet through the modal by [`eth_requestAccounts` ](#supported-methods)method. The `isConnected` method returns a boolean value indicating whether the wallet is connected or not.

```javascript
ethereum.isConnected(): boolean
```

## Query Methods[​](https://docs.uxuy.com/uxuy-connect/guide/#request-method) <a href="#request-method" id="request-method"></a>

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

* [MetaMask JSON-RPC API](https://docs.metamask.io/wallet/reference/json-rpc-api/)
* [Ethereum.org JSON-RPC API](https://ethereum.org/developers/docs/apis/json-rpc/)

We provide some frequently used methods as below:[​](https://docs.uxuy.com/uxuy-connect/guide/#supported-methods)

### **Get accounts**[**​**](https://docs.uxuy.com/uxuy-connect/guide/#eth_requestaccounts) **address** <a href="#supported-methods" id="supported-methods"></a>

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

{% code overflow="wrap" %}

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

{% endcode %}

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!&#x20;

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

### **Get chain ID**

Returns the chain ID of the connected wallet.

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

### Get balance

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

```typescript
// 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:

* [Signing Data](https://docs.metamask.io/wallet/how-to/sign-data/#signing-data-with-metamask)
* [Signing Transaction](https://docs.metamask.io/wallet/how-to/send-transactions/)
* [eth-sig-util](https://github.com/MetaMask/eth-sig-util)

Example of⁣`personal_sign`:

```javascript
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`:

```javascript
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.&#x20;

### Transfer transaction

```typescript
// 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

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

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

```typescript
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_sendTransaction
  params: [
    {
      from: from,
      to: contract_address,
      value: '0x0', // Value in hexadecimal
      chainId: chainId,
      data: data,
    },
  ],
});
```

Check [this doc](https://docs.ethers.org/v5/api/utils/abi/interface/) for more usages.

## Send Signed Transaction

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

```typescript
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.error('Error:', error);
  return;
}
```

## Switch Ethereum Chain​

Switches the connected wallet to the specified chain ID.&#x20;

```javascript
try {
  await ethereum.request({
    method: 'wallet_switchEthereumChain',
    params: [{ chainId: '0xf00' }],
  });
} catch (switchError) {
  // Handle the error here
  console.error('Error switching Ethereum chain:', switchError);
}
```

## Event Listeners[​](https://docs.uxuy.com/uxuy-connect/guide/#event-listeners) <a href="#event-listeners" id="event-listeners"></a>

The SDK emits events for account and network changes.

### **accountsChanged**[**​**](https://docs.uxuy.com/uxuy-connect/guide/#accountschanged)

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

### **chainChanged**[**​**](https://docs.uxuy.com/uxuy-connect/guide/#chainchanged)

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

To remove listeners:

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