# Introduction

Introduction to Sender

**Sender Wallet** is a web3 wallet that is compatible with [NEAR](https://near.org/) and [Ethereum](https://ethereum.org/), allowing you to control your cryptocurrency, NFTs, DeFi activities, and digital assets.

### Why use Sender Wallet as your web3 browser and cryptocurrency wallet?

* Security and reliability: A truly decentralized wallet that allows you to have complete control over your cryptocurrency, keys, and data.
* Multi-chain support: Supports Ethereum, NEAR, and all Ethereum-compatible blockchains such as Avalanche, Polygon, BNB Chain, Optimism, Arbitrum, Scroll, and more.
* Send: Send cryptocurrency to anyone, regardless of geographical restrictions.
* Receive: Receive cryptocurrency directly into your wallet when other users pay in cryptocurrency.
* Swap: Convert your cryptocurrency using decentralized exchanges (DEX).
* Track: Stay up to date with price trends, top tokens, trending assets, and more.

**Sender** can help you master the future of cryptocurrency. Welcome to the world of cryptocurrency!

Any issues or feedback? Please contact us via in-app/website live chat or <support@sender.org>

#### Join our community:

Website: [https://sender.org](https://sender.org/)

Twitter: <https://twitter.com/SenderWallet>

Developer docs: [http://docs.senderwallet.io](http://docs.senderwallet.io/)

Discord: <https://discord.com/invite/9WhejkkbZF>

Blog: <https://medium.com/@senderlabs>


# Getting Started

Getting Started with Sender Wallet

To build with Sender, install Sender in your preferred browser. [Download here](https://senderwallet.io/)

Once Sender is installed and running, you will find that newly opened browser tabs have a `window.near` or `window.sender` object available in the developer console. Your website now can interact with Sender via the object.

## Sender Detection <a href="#web3-browser-detection" id="web3-browser-detection"></a>

### For version 1.11.7 and below

To verify if the browser has installed Sender Wallet for Near chain, you can copy and paste the code snippet below in the developer console of your web browser:

```javascript
// For near chain
if (typeof window.near !== 'undefined' && window.near.isSender) {
  console.log('Sender is installed!');
}
```

You can review the full API for the `window.near` object [here](/api-reference/near/near-provider-api).

#### Integration Examples

* Example: <https://github.com/SenderWallet/sender-wallet-dapp-example>&#x20;
* Guest Book: coming soon

### For version 2.0.0 and above

To verify if the browser has installed Sender Wallet for above version 2.0.0, you can copy and paste the code snippet below in the developer console of your web browser:

```javascript
// For version 2.0.0 and above, you can use window.sender.near to interact with near chain,
// but you can still use window.near api to connect near chain.
if (typeof window.sender !== 'undefined' && window.sender.near) {
    console.log('Sender is installed!');
}

// For ethereum chain
if (typeof window.sender !== 'undefined' && window.sender.ethereum) {
    console.log('Sender is installed!');
}
```

You can review the full API for the `window.sender.ethereum` object [here](/api-reference/ethereum/ethereum-provider-api).

#### Integration Examples

* Example: <https://metamask.github.io/test-dapp/>


# Sign in Applications

[Sign in Application in Near](/guide/sign-in-applications/sign-in-applications-in-near)

[Sign in Application in Ethereum](/guide/sign-in-applications/sign-in-applications-in-ethereum)


# Sign in Applications in Near

Once you have Sender installed, you'll be able to sign in and interact with the applications in Near chain.

### Sign In

To interact with smart contracts, users need to sign in the application and request one function call key for the contract. Once sign in, the application will be authorized to call the change methods defined in the scope. &#x20;

```javascript
// Sender will show a popup dialog to ask user to authorize your dApp
// This creates an access key that will be stored in Sender's storage
// The access key can then be used to connect to NEAR and sign transactions

await window.near.requestSignIn({
  contractId: "guest-book.testnet", // contract requesting access
});

// Or add `methodNames` if you only allow the key to call some of the methods

await window.near.requestSignIn({
  contractId: "guest-book.testnet", // contract requesting access
  methodNames: ["addMessage"]       // (optional) changed methods the app allowed to use
});

window.near.isSignedIn()   // true
```

### Sign Out

You may want to remove the generated function access key from browser extension storage if you don't want to use the application any more.&#x20;

<pre class="language-javascript"><code class="lang-javascript">// For version 1.11.7 and below
window.near.signOut();    // true
window.near.isSignedIn();   // false
<strong>
</strong><strong>// For version 2.0.0 and above
</strong>window.sender.near.signOut();    // true
window.sender.near.isSignedIn();   // false
</code></pre>


# Sign in Applications in Ethereum

Once you have Sender installed, you'll be able to sign in and interact with the applications in Ethereum chain.&#x20;

### Sign In

To interact with smart contracts, users need to sign in the application. Once sign in, the application will be authorized to call the change methods defined in the scope. &#x20;

```javascript
// Sender will show a popup dialog to ask user to authorize your dApp
// This method will give you an accounts array which is from Sender wallet extension. 
// window.sender.ethereum.isConnected will be true.
await window.sender.ethereum.requestAccounts(); 
```

#### Disconnect

```javascript
window.sender.ethereum._handleDisconnect(); // true
```


# Access Accounts

[Access Accounts in Near](/guide/access-accounts/access-accounts-in-near)

[Access Accounts in Ethereum](/guide/access-accounts/access-account-in-ethereum)


# Access Accounts in Near

User accounts are used in a variety of contexts in NEAR, including as identifiers and for signing transactions. Once login successfully, you'll be able to access to the `accountId` and `account` instance. &#x20;

### Current Account ID

You can get the logged in account ID via the `getAccountId()` method in **Near** chain

```javascript
// For version 1.11.7 and below
const accountId = window.near.getAccountId();

// For version 2.0.0 and above
const accountId = window.sender.near.getAccountId();
```

### Use Account Instance in Near Chain

***\[Work In-Progress]*** You can also get access to the current account, and use its interface directly. The account is an instance of the `account` object in [near-api-js](http://github.com/near/near-api-js) . The usage can be found in the [documentation here](https://docs.near.org/docs/api/naj-quick-reference#account).&#x20;

```javascript
const account = window.near.account();
await account.sendMoney(
  "receiver-account.testnet", // receiver account
  "1000000000000000000000000" // amount in yoctoNEAR
);
```


# Access Account in Ethereum

User accounts are used in a variety of contexts in Ethereum, including as identifiers and for [signing transactions](/api-reference/ethereum/sign-data). To request a signature from a user or have a user approve a transaction, your dapp must access the user's accounts using the [`eth_requestAccounts`](/api-reference/ethereum/ethereum-provider-api#eth_requestaccounts) RPC method.

When accessing a user's accounts:

* **Only** initiate a connection request in response to direct user action, such as selecting a connect button.
* **Always** disable the connect button while the connection request is pending.
* **Never** initiate a connection request on page load.

### Create a connect button <a href="#create-a-connect-button" id="create-a-connect-button"></a>

We recommend providing a button to allow users to connect **Sender** to your dapp. Selecting this button should call [`eth_requestAccounts`](/api-reference/ethereum/ethereum-provider-api#eth_requestaccounts) to access the user's account.


# Send Transactions

Send Transactions

[Send Transactions on Near](/guide/send-transactions/send-transactions-in-near)

[Send Transactions on Ethereum](/guide/send-transactions/send-transactions-in-ethereum)


# Send Transactions in Near

Transactions are a formal action on a blockchain. They can be initiated in Sender with a call to NEAR's RPC node. They can be a simple sending of $NEAR, may result in sending fungible tokens, creating a new account, or changing state on the blockchain in any number of ways. They are always initiated by a signature from an NEAR account, usually with [a function call key or full access key](https://docs.near.org/docs/concepts/account#access-keys).&#x20;

### Sign and Send a Single Transaction

With Sender, you could sign and send a single transaction with one or multiple actions.&#x20;

```javascript
// Call wNEAR contract method 
// Register the 'xxx.testnet' account to wNEAR on testnet (wrap.testnet)
const tx = {
  receiverId: 'wrap.testnet',
  actions: [
    { 
      methodName: 'storage_deposit',
      args: {
        account_id: 'alice.testnet',
        registration_only: true,
      },
      gas: parseNearAmount('0.003'),
      deposit: parseNearAmount('0.00125'),
    },
  ],
}
const res = await window.near.signAndSendTransaction(tx);
```

```javascript
// Call multiple methods from wNEAR contract
// Swap NEAR to wNEAR, then transfer wNEAR to others
const tx = {
  receiverId: 'wrap.testnet',
  actions: [
    {
      methodName: 'near_deposit',
      args: {},
      deposit: parseNearAmount('1'),
    },
    { 
      methodName: 'storage_deposit',
      args: {
        account_id: 'bob.testnet',
        registration_only: true,
      },
      gas: parseNearAmount('0.003'),
      deposit: parseNearAmount('0.00125'),
    },
    {
      methodName: 'ft_transfer',
      args: {
        received_id: 'bob.testnet',
        amount: '1000000000000000000',
      },
      gas: parseNearAmount('0.003')
    }
  ]
}
const res = await window.near.signAndSendTransaction(tx);
```

### Sign and Send Multiple Transactions

Sender also supports sign and send multiple transactions when needed.

```javascript
const transactions = [
  {
    receiverId: wNearContractId,
    actions: [
      {
        methodName: 'near_deposit',
        args: {},
        amount: '100000000000000000000000',
      },
    ]
  },
  {
    receiverId: RefFinanceContractId,
    actions: [
      {
        methodName: 'add_liquidity',
        args: {
          tokens_ids: ['wrap.testnet', 'token.paras.testnet'],
          amounts: ['1000000000000000000', '1000000000000000000'],
        },
      }
    ]
  }
];

const res = await window.near.requestSignTransactions({ transactions });

console.log('Swap and Send wNEAR with requestSignTransactions response: ', res);
```


# Send Transactions in Ethereum

You can send a transaction in **Sender** using the [`eth_sendTransaction`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendtransaction) RPC method.

For example, the following JavaScript gets the user's accounts and sends a transaction when they select each button, and the following HTML displays the buttons.

{% tabs %}
{% tab title="Javascript" %}

```javascript
const ethereumButton = document.querySelector('.enableEthereumButton');
const sendEthButton = document.querySelector('.sendEthButton');

let accounts = [];

// Send Ethereum to an address
sendEthButton.addEventListener('click', () => {
  sender.ethereum
    .request({
      method: 'eth_sendTransaction',
      params: [
        {
          from: accounts[0], // The user's active address.
          to: '0x2f318C334780961FB129D2a6c30D0763d9a5C970', // Required except during contract publications.
          value: '0x29a2241af62c0000', // Only required to send ether to the recipient from the initiating external account.
          gasPrice: '0x09184e72a000', // Customizable by the user during MetaMask confirmation.
          gas: '0x2710', // Customizable by the user during MetaMask confirmation.
        },
      ],
    })
    .then((txHash) => console.log(txHash))
    .catch((error) => console.error(error));
});

ethereumButton.addEventListener('click', () => {
  getAccount();
});

async function getAccount() {
  accounts = await sender.ethereum.request({ method: 'eth_requestAccounts' });
}
```

{% endtab %}

{% tab title="HTML" %}

```html
<button class="enableEthereumButton btn">Enable Ethereum</button>
<button class="sendEthButton btn">Send ETH</button>
```

{% endtab %}
{% endtabs %}


# Near


# NEAR Provider API

## Properties

### near.isSender

`true` if the user has Sender installed.

## Methods

### near.**requestSignIn()**&#x20;

```javascript
/**
* request signin the contract, with the view and change methods provided, return the access key
* @param {*} contractId contract account id
* @param {*} methodNames the method names on the contract that should be allowed to be called. Pass null for no method names and '' or [] for any method names.
* @param {*} createNew if need create new access key, set createNew = true. Default is false
* @returns { accessKey } signed in access key
*/
near.requestSignIn({ contractId, methodNames, createNew = false }): Promise<Result>
```

Request sign in with the contract, given the needed view and change methods, return the access key (The response might be changed in future version).

```javascript
const contractId = 'guest-book.testnet';
const methodNames = ['addMessage'];
const res = await window.near.requestSignIn({ contractId, methodNames });
```

### near.signOut()

```
/**
* @param {*} contractId contract account id (options)
*/
near.signOut({ contractId }): Promise<Result>;
```

Sign out  the access key from this account and then clean the signed in access key from the storage. Must need to pass the specific contractId if one dapp has multiple contractId.

### near.isSignedIn()

```javascript
/**
* @param {*} contractId contract account id (options)
*/
near.isSignedIn({ contractId }): boolean;
```

Check whether the current account has signed in. Must need to pass the specific contractId if one dapp has multiple contractId.

### near.getAccountId()

```javascript
near.getAccountId(): string;
```

The current selected NEAR account ID

### <mark style="color:blue;">\[Work-In Progress]</mark> near.account()

```
near.account(): Account;
```

Return an instance of the `account` object in [near-api-js](http://github.com/near/near-api-js) . The usage can be found in the [documentation here](https://docs.near.org/docs/api/naj-quick-reference#account).&#x20;

### near.**signAndSendTransaction()**

```
near.signAndSendTransaction({ receiverId: string, actions: Action}): Response;
```

Send one single transaction

### **near.requestSignTransactions()**

```
near.requestSignTransactions(options: SignAndSendTransactionOptions): void;
```

Send multiple transactions in batch

### near.request()

```
near.request(method: string, params: Object): Object;
```

Use `request` to submit [RPC requests](https://docs.near.org/docs/api/rpc) to NEAR blockchain via Sender.&#x20;

## Events

### signIn

An account has signed in

```javascript
near.on("signIn", (() => {
  // TODO if account has signed in
});
```

### signOut

The current account has signed out

```javascript
near.on("signOut", (() => {
  // TODO if account has been signed out
});
```

### **accountChanged**

Listen to the current account changed

```javascript
near.on("accountChanged", ((changedAccountId) => {
  // TODO if account has changed
});
```

### rpcChanged

Listen to the current RPC URL changed

```javascript
near.on("rpcChanged", ((response) => {
  // TODO if rpc has changed
});
```


# Deprecated APIs

Here are some deprecated APIs that we may not support in future versions.

## Methods

### \[deprecated] near.connect()

Similar to `requestSignIn()`, connect user to the current application

### \[deprecated] near.disconnect()

Similar to `signOut()`, disconnect user from the current application

### \[deprecated] near.isConnected()

Returns `true` if the provider is connected to the current chain, and `false` otherwise.

### \[deprecated] **near.sendMoney()**

Send $NEAR to others

```javascript
const res = await window.near.sendMoney({
  receiverId: 'xxx.testnet',
  amount: parseNearAmount('1'),
})

console.log('send near res: ', res);
```

### \[deprecated] near.viewFunction()

View function call with current RPC


# Ethereum


# Sign Data

You can use the following RPC methods to request cryptographic signatures from users:

* [`eth_signTypedData_v4`](#use-eth_signtypeddata_v4) - Use this method to request the most human-readable signatures that are efficient to process on-chain. We recommend this for most use cases.
* [`eth_sign`](#use-personal_sign) - Use this method for the easiest way to request human-readable signatures that don't need to be efficiently processed on-chain.

### Use eth\_signTypedData\_v4 <a href="#use-eth_signtypeddata_v4" id="use-eth_signtypeddata_v4"></a>

[`eth_signTypedData_v4`](https://metamask.github.io/api-playground/api-documentation/#eth_signTypedData_v4) provides the most human-readable signatures that are efficient to process on-chain. It follows the [EIP-712](https://eips.ethereum.org/EIPS/eip-712) specification to allow users to sign typed structured data that can be verified on-chain. It renders the structured data as usefully as possible to the user (for example, displaying known account names in place of addresses).

An `eth_signTypedData_v4` payload uses a standard format of encoding structs, but has a different format for the top-level struct that is signed, which includes some metadata about the verifying contract to provide replay protection of these signatures between different contract instances.

We recommend using [`eth-sig-util`](https://github.com/MetaMask/eth-sig-util) to generate and validate signatures. You can use [`eip712-codegen`](https://github.com/danfinlay/eip712-codegen#readme) to generate most of the Solidity required to verify these signatures on-chain. It currently doesn't generate the top-level struct verification code, so you must write that part manually.&#x20;

{% hint style="info" %}
**CAUTION**

Since the top-level struct type's name and the `domain.name` are presented to the user prominently in the confirmation, consider your contract name, the top-level struct name, and the struct keys to be a user-facing security interface. Ensure your contract is as readable as possible to the user.
{% endhint %}

#### Example

{% tabs %}
{% tab title="Javascript" %}

```javascript
signTypedDataV4Button.addEventListener('click', async function (event) {
  event.preventDefault();

  const msgParams = JSON.stringify({
    domain: {
      // This defines the network, in this case, Mainnet.
      chainId: 1,
      // Give a user-friendly name to the specific contract you're signing for.
      name: 'Ether Mail',
      // Add a verifying contract to make sure you're establishing contracts with the proper entity.
      verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
      // This identifies the latest version.
      version: '1',
    },

    // This defines the message you're proposing the user to sign, is dapp-specific, and contains
    // anything you want. There are no required fields. Be as explicit as possible when building out
    // the message schema.
    message: {
      contents: 'Hello, Bob!',
      attachedMoneyInEth: 4.2,
      from: {
        name: 'Cow',
        wallets: [
          '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
          '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF',
        ],
      },
      to: [
        {
          name: 'Bob',
          wallets: [
            '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
            '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
            '0xB0B0b0b0b0b0B000000000000000000000000000',
          ],
        },
      ],
    },
    // This refers to the keys of the following types object.
    primaryType: 'Mail',
    types: {
      // This refers to the domain the contract is hosted on.
      EIP712Domain: [
        { name: 'name', type: 'string' },
        { name: 'version', type: 'string' },
        { name: 'chainId', type: 'uint256' },
        { name: 'verifyingContract', type: 'address' },
      ],
      // Not an EIP712Domain definition.
      Group: [
        { name: 'name', type: 'string' },
        { name: 'members', type: 'Person[]' },
      ],
      // Refer to primaryType.
      Mail: [
        { name: 'from', type: 'Person' },
        { name: 'to', type: 'Person[]' },
        { name: 'contents', type: 'string' },
      ],
      // Not an EIP712Domain definition.
      Person: [
        { name: 'name', type: 'string' },
        { name: 'wallets', type: 'address[]' },
      ],
    },
  });

  var from = await web3.eth.getAccounts();

  var params = [from[0], msgParams];
  var method = 'eth_signTypedData_v4';

  web3.currentProvider.sendAsync(
    {
      method,
      params,
      from: from[0],
    },
    function (err, result) {
      if (err) return console.dir(err);
      
      if (result.error) {
        alert(result.error.message);
      }
      
      if (result.error) return console.error('ERROR', result);
      
      console.log('TYPED SIGNED:' + JSON.stringify(result.result));

      const recovered = sigUtil.recoverTypedSignature_v4({
        data: JSON.parse(msgParams),
        sig: result.result,
      });

      if (
        ethUtil.toChecksumAddress(recovered) === ethUtil.toChecksumAddress(from)
      ) {
        alert('Successfully recovered signer as ' + from);
      } else {
        alert(
          'Failed to verify signer when comparing ' + result + ' to ' + from
        );
      }
    }
  );
});
```

{% endtab %}

{% tab title="HTML" %}

```html
<h3>Sign typed data v4</h3>
<button type="button" id="signTypedDataV4Button">eth_signTypedData_v4</button>
```

{% endtab %}
{% endtabs %}

### Use eth\_sign <a href="#use-personal_sign" id="use-personal_sign"></a>

[`eth_sign`](https://metamask.github.io/api-playground/api-documentation/#personal_sign) is the easiest way to request human-readable signatures that don't need to be efficiently processed on-chain. It's often used for signature challenges that are authenticated on a web server, such as [Sign-In with Ethereum](https://login.xyz/).

{% hint style="info" %}
**IMPORTANT**

* Don't use this method to display binary data, because the user wouldn't be able to understand what they're agreeing to.
* If using this method for a signature challenge, think about what would prevent a phisher from reusing the same challenge and impersonating your site. Add text referring to your domain, or the current time, so the user can easily verify if this challenge is legitimate.
  {% endhint %}

#### Example

The following is an example of using `eth_sign` with **Sender.**

{% tabs %}
{% tab title="Javascript" %}

```javascript
ethSignButton.addEventListener('click', async function (event) {
  event.preventDefault();
  const exampleMessage = 'Example `eth_sign` message.';

  try {
    const from = accounts[0];
    // For historical reasons, you must submit the message to sign in hex-encoded UTF-8.
    // This uses a Node.js-style buffer shim in the browser.
    const msg = `0x${Buffer.from(exampleMessage, 'utf8').toString('hex')}`;
    const sign = await sender.ethereum.request({
      method: 'eth_sign',
      params: [msg, from, 'Example password'],
    });

    personalSignResult.innerHTML = sign;
    personalSignVerify.disabled = false;
  } catch (err) {
    console.error(err);
    personalSign.innerHTML = `Error: ${err.message}`;
  }
});
```

{% endtab %}

{% tab title="HTML" %}

```html
<h3>Personal sign</h3>
<button type="button" id="personalSignButton">eth_sign</button>
```

{% endtab %}
{% endtabs %}


# Ethereum Provider API

Sender injects a global JavaScript API into websites visited by its users using the `window.sender.ethereum` provider object. This API allows websites to request users' Ethereum accounts, read data from blockchains the user is connected to, and suggest that the user sign messages and transactions.

### Properties <a href="#properties" id="properties"></a>

#### window\.sender.ethereum.isSender <a href="#windowethereumismetamask" id="windowethereumismetamask"></a>

This property is `true` if the user has Sender installed.

### Methods <a href="#properties" id="properties"></a>

#### eth\_requestAccounts <a href="#eth_requestaccounts" id="eth_requestaccounts"></a>

Requests that the user provide an Ethereum address to be identified by. Use this method to [access a user's accounts](https://docs.metamask.io/wallet/get-started/access-accounts). This method is specified by [EIP-1102](https://eips.ethereum.org/EIPS/eip-1102).

Example:

```javascript
// eth_requestAccounts code snippet
document.getElementById('connectButton', connect);

function connect() {
  sender.ethereum
    .request({ method: 'eth_requestAccounts' })
    .then(handleAccountsChanged)
    .catch((error) => {
      if (error.code === 4001) {
        // EIP-1193 userRejectedRequest error
        console.log('Please connect to MetaMask.');
      } else {
        console.error(error);
      }
    });
}
```

#### wallet\_getPermissions <a href="#wallet_getpermissions" id="wallet_getpermissions"></a>

Gets the caller's current [permissions](https://docs.metamask.io/wallet/#restricted-methods). This method returns an array of the caller's permission objects. If the caller has no permissions, the array is empty.

#### wallet\_requestPermissions <a href="#wallet_requestpermissions" id="wallet_requestpermissions"></a>

Requests [permissions](https://docs.metamask.io/wallet/#restricted-methods) from the user. The request causes a Sender popup to appear. You should only request permissions in response to a direct user action, such as a button click.

Example:

```javascript
// wallet_requestPermissions code snippet

document.getElementById('requestPermissionsButton', requestPermissions);

function requestPermissions() {
  sender.ethereum
    .request({
      method: 'wallet_requestPermissions',
      params: [{ eth_accounts: {} }],
    })
    .then((permissions) => {
      const accountsPermission = permissions.find(
        (permission) => permission.parentCapability === 'eth_accounts'
      );
      if (accountsPermission) {
        console.log('eth_accounts permission successfully requested!');
      }
    })
    .catch((error) => {
      if (error.code === 4001) {
        // EIP-1193 userRejectedRequest error
        console.log('Permissions needed to continue.');
      } else {
        console.error(error);
      }
    });
}
```

#### window\.sender.ethereum.request(args) <a href="#windowethereumrequestargs" id="windowethereumrequestargs"></a>

```javascript
// RequestArguments interface
interface RequestArguments {
  method: string;
  params?: unknown[] | object;
}

window.sender.ethereum.request(args: RequestArguments): Promise<unknown>;
```

Use this method to submit [RPC API](https://docs.metamask.io/wallet/reference/rpc-api) requests to Ethereum using Sender It returns a promise that resolves to the result of the RPC method call.

The following is an example of using `window.sender.ethereum.request(args)` to call [`eth_sendTransaction`](https://metamask.github.io/api-playground/api-documentation/#eth_sendTransaction):

```javascript
// Using window.sender.ethereum.request(args) to call eth_sendTransaction example
params: [
  {
    from: '0xb60e8dd61c5d32be8058bb8eb970870f07233155',
    to: '0xd46e8dd67c5d32be8058bb8eb970870f07244567',
    gas: '0x76c0', // 30400
    gasPrice: '0x9184e72a000', // 10000000000000
    value: '0x9184e72a', // 2441406250
    data:
      '0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675',
  },
];

sender.ethereum
  .request({ method: 'eth_sendTransaction', params })
  .then((result) => {
    // The result varies by RPC method.
    // For example, this method returns a transaction hash hexadecimal string upon success.
  })
  .catch((error) => {
    // If the request fails, the Promise rejects with an error.
  });
```

### Events <a href="#events" id="events"></a>

The Sender provider emits events using the Node.js [`EventEmitter`](https://nodejs.org/api/events.html) API. The following is an example of listening to the [`accountsChanged`](https://docs.metamask.io/wallet/#accountschanged) event. You should remove listeners once you're done listening to an event (for example, on component unmount in React).

```javascript
// handle accounts changed
function handleAccountsChanged(accounts) {
  // Handle new accounts, or lack thereof.
}

window.sender.ethereum.on('accountsChanged', handleAccountsChanged);

// Later
window.sender.ethereum.removeListener('accountsChanged', handleAccountsChanged);
```

The first argument of `window.sender.ethereum.removeListener` is the event name, and the second argument is a reference to the function passed to `window.sender.ethereum.on` for the event.

#### accountsChanged <a href="#accountschanged" id="accountschanged"></a>

```javascript
window.sender.ethereum.on('accountsChanged', handler: (accounts: Array<string>) => void);
```

The Sender provider emits this event when the return value of the [`eth_accounts`](https://metamask.github.io/api-playground/api-documentation/#eth_accounts) RPC method changes. `eth_accounts` returns either an empty array, or an array that contains the address of the most recently used account the caller is permitted to access. Callers are identified by their URL origin, which means that all sites with the same origin share the same permissions.

This means that the provider emits `accountsChanged` when the user's exposed account address changes. Listen to this event to [handle accounts](https://docs.metamask.io/wallet/get-started/access-accounts#handle-accounts).

#### chainChanged <a href="#chainchanged" id="chainchanged"></a>

```
window.sender.ethereum.on('chainChanged', handler: (chainId: string) => void);
```

The provider emits this event when the currently connected chain changes. Listen to this event to [detect a user's network](https://docs.metamask.io/wallet/get-started/detect-network).

#### connect <a href="#connect" id="connect"></a>

```
interface ConnectInfo {
  chainId: string;
}

window.sender.ethereum.on('connect', handler: (connectInfo: ConnectInfo) => void);
```

The provider emits this event when it's first able to submit RPC requests to a chain.

#### disconnect <a href="#disconnect" id="disconnect"></a>

```
window.sender.ethereum.on('disconnect', handler: (error: ProviderRpcError) => void);
```

The provider emits this event if it becomes unable to submit RPC requests to a chain. In general, this only happens due to network connectivity issues or some unforeseen error.

#### message <a href="#message" id="message"></a>

```
interface ProviderMessage {
  type: string;
  data: unknown;
}

window.sender.ethereum.on('message', handler: (message: ProviderMessage) => void);
```

The provider emits this event when it receives a message that the user should be notified of. The `type` property identifies the kind of message.


# Ton


# Mobile Dapp Provider

Sender injects a global JavaScript API into websites visited by its users using the `window.sender.ton` provider object. This API allows websites to request users' Ton accounts, read data from blockchains the user is connected to, and suggest that the user sign messages and transactions.

### Properties <a href="#properties" id="properties"></a>

**deviceInfo**

Developer can get deviceInfo from `window.sender.ton` object.

```typescript
// Some code
export declare interface DeviceInfo {
  platform: 'iphone' | 'ipad' | 'android' | 'windows' | 'mac' | 'linux' | 'browser';
  appName: string;
  appVersion: string;
  maxProtocolVersion: number;
  features: Feature[];
}
```

**protocolVersion**

This is protocol version number, and current protocol version is `2`

**isWalletBrowser**

Check current Provider API if it's wallet browser, the default value is `true`

### Methods

**connect**

```typescript
// Connect method
interface TonAddressItem {
  name: 'ton_addr';
}

interface TonProofItem {
  name: 'ton_proof';
  payload: string;
}

type ConnectItem = TonAddressItem | TonProofItem;

interface ConnectEventError {
    event: 'connect_error';
    id: number;
    payload: {
        code: CONNECT_EVENT_ERROR_CODES;
        message: string;
    };
}

interface ConnectEventSuccess {
    event: 'connect';
    id: number;
    payload: {
        items: ConnectItemReply[];
        device: DeviceInfo;
    };
}

type ConnectEvent = ConnectEventSuccess | ConnectEventError;

export declare interface ConnectRequest {
  manifestUrl: string;
  items: ConnectItem[];
}

const protocolVersion = 2;

const request = {
  items: [{ name: 'ton_addr' }],
  manifestUrl: 'https://megaton.fi/tonconnect-manifest.json?v=1',
};

await window.sender.ton.connect(protocolVersion, request);
```

The third dapp can use `connect` method to connect Sender Wallet. And this method will respond a `ConnectEvent` object.&#x20;

**restoreConnection**

```typescript
// Example
await window.sender.ton.restoreConnection();
```

This method can restore app connection automatically if dapp is connected before, so that user don't need to connect dapp again. And this method will respond a `ConnectEvent` object.&#x20;

**disconnect**

```typescript
// Disconnect dapp
await window.sender.ton.disconnect();
```

**send**

```typescript
// Send transaction by wallet
interface SendTransactionRpcRequest {
  method: 'sendTransaction';
  params: [string];
  id: string;
}

interface SignDataRpcRequest {
  method: 'signData';
  params: [
    {
      schema_crc: number;
      cell: string;
    }
  ];
  id: string;
}

interface DisconnectRpcRequest {
  method: 'disconnect';
  params: [];
  id: string;
}

type RpcRequests = {
  sendTransaction: SendTransactionRpcRequest;
  signData: SignDataRpcRequest;
  disconnect: DisconnectRpcRequest;
};

type RpcMethod = 'disconnect' | 'sendTransaction' | 'signData';

const request = {
  sendTransaction: { ... },
  signData: { ... },
  disconnect: { ... },
}

await window.sender.ton.send(request);
```

This method can be used as `sendTransaction` or `signData` method, and dapp can use `send` method to send transaction or sign data.


# Define App's Icon

To Be Added soon


