# 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();
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tomo.inc/tomo-sdk/tomo-telegram-sdk/wallet-provider/evm-provider.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
