# Welcome to Etherspot

Etherspot is an Account Abstraction SDK, delivering frictionless Web3 UX.

{% hint style="info" %}
Our most recent version of Etherspot which is fully 4337 compliant (and is highly recommended you use) can be found [here](https://etherspot.fyi/)!

We will not be updating these docs and old SDK as frequently anymore so please use Etherspot Prime on <https://etherspot.fyi/>
{% endhint %}

Etherspot SDK represents a multi-chain self-custody Smart Contract Wallet platform that caters to the needs of decentralized application, game, and wallet developers. The platform offers seamless Web3 UX solutions that enable quick onboarding of new users while simplifying the intricate blockchain operations. The key factors behind such a smooth experience are account abstraction with Smart Contract Wallets and our multi-chain Relayer Infrastructure, which provide a convenient way for developers to abstract away complexities.

## What can you do with Etherspot?

#### Etherspot SDK delivers a Web2 experience in a self-custodial fashion to your (d)App, Wallet or Game.

* <mark style="color:purple;">**Web2 onboarding for Web3**</mark><mark style="color:purple;">:</mark> onboard your web2 users easily through social logins, create counter-factual wallets and enable easy recovery. No seed phrases are required to secure wallets.
* <mark style="color:purple;">**Simple User Interface & Integration:**</mark> leverage our BUIDLER react component to onboard and integrate into your dApp easily. Style it in your way to suit your branding.
* <mark style="color:purple;">**Multi-Chain NFT Support**</mark><mark style="color:purple;">:</mark> exceptional NFT support for the multi-chain reality, allow users to interact with NFTs with ease.&#x20;
* <mark style="color:purple;">**Meta-Transactions**</mark><mark style="color:purple;">:</mark> allow users to pay for gas with ANY token on any chain. Currently, we support DAI, USDC, USDT and BUSD as a gas token. Etherspot SDK can support any token on any chain that has liquidity.
* <mark style="color:purple;">**Seamless Multi-Chain Experience**</mark><mark style="color:purple;">:</mark> users can control their wallets on any chain from any endpoint providing a seamless multi-chain experience. Keep connected to Polygon while executing one-click actions on Optimism.&#x20;
* <mark style="color:purple;">**Sponsored Transactions**</mark><mark style="color:purple;">:</mark> projects can sponsor transactions for their dApp to provide the UX as seamless as Web2.&#x20;
* <mark style="color:purple;">**Transaction Batching / Multi-Call**</mark><mark style="color:purple;">:</mark> abstract the painful experience of signing multiple transactions into a one-click action for your users by composing multiple transactions into a single transaction. Eg: Approve, Deposit, Borrow and Stake in a single transaction.
* <mark style="color:purple;">**Cross-Chain Bridging & Transaction Bundling**</mark> allow your dApp to onboard users from any chain through our BUIDLER react component and execute one-click actions with ease. Go cross-chain without deploying on other chains.
* <mark style="color:purple;">**Fiat on and off Ramp**</mark><mark style="color:purple;">:</mark> let your users buy and sell without KYC (up to 1000 EUR per day) within your dapp or via our BUIDLER React Component.&#x20;

## How does it work?

The Etherspot SDK deploys Smart Contract-based Wallets which are created counterfactually for each user and is the same on every chain providing a superior cross-chain experience. The wallet is deployed upon the first transaction by the user. Etherspot currently subsidises **Polygon** and **Gnosis** deployments for all users.&#x20;

<figure><img src="/files/Ak9PAAbdYSZk7h8scx8T" alt=""><figcaption><p>EOA set up can be done via Metamask and Social Login providers.</p></figcaption></figure>

A smart contract-based wallet is associated with and controlled by each user's EOA (Externally Owned Account). EOA wallets such as Metamask accounts or Rainbow mobile wallets are also known as Key-based Wallets. Social Logins generated accounts are also considered EOA or Key-based accounts. Smart-Contract wallets provide better security to self-custody as they are not dependent on a single private key.

#### Plug & Play with Etherspot BUIDLER React Component

The Etherspot SDK can be initiated and implemented with an easy-to-implement BUIDLER react component, providing plug & play functionality that reduces implementation time and resources for developers significantly. Developers can leverage the power of the SDK with a few lines of code and easily implement powerful functionality like transaction batching without redesigning their UI.  &#x20;

The BUIDLER comes out of the box with Social Logins and Web3 onboarding, and loads assets and balances from Key-Based (EOA, e.g. Metamask) and Smart Contract-based Wallets. Styling adjustments can be made easily to fit your project's branding.\
\
The react component consists currently of blocks: Asset Bridging, Swaps and Send functionality and we plan on adding more protocols. Transaction Batching is completely automated, selecting 2 or more swaps on the same chain will be automatically batched allowing for one-to-many, many-to-one and many-to-many swaps. Multi-Call Transaction Batching allows developers to develop user journeys with assets that are not yet owned by the user (e.g. one-click liquidity farming from a single asset). \
\
Custom Contract interactions can easily be implemented on the BUIDLER as a block to allow for streamlined development with Etherspot SDK. See our Cross-Chain KLIMA DAO Staking block example as a use case.

&#x20;              &#x20;

<figure><img src="/files/nNMF4DKWji8qBB74DTtc" alt=""><figcaption><p>   <em>Building blocks and styling options for the Eherspot BUIDLER.</em> </p></figcaption></figure>

&#x20;                                                                          &#x20;

Ready to poke around? Go over to <https://buidler.etherspot.io/> and try the Etherspot BUIDLER out.&#x20;

**Need to speak to us?**

We're open to hearing from you regarding features, use cases, suggestions and more. You can find us on [Discord. ](https://chat.pillar.fi)Go to our dev-chat channel or open a ticket if your require technical support.


# Chains, Bridges & DEXes

Bringing the EVM-universe together.

Etherspot currently supports the following, chains and bridges either directly via the SDK or through our bridge aggregation partners such as Li.Fi.&#x20;

#### Chains <a href="#chains" id="chains"></a>

<table data-header-hidden><thead><tr><th width="90"></th><th width="68"></th><th></th><th></th><th></th></tr></thead><tbody><tr><td>#</td><td></td><td>Chain</td><td>Chain Key</td><td>Chain ID</td></tr><tr><td>1</td><td>✅</td><td>Ethereum</td><td>ETH</td><td>1</td></tr><tr><td>2</td><td>✅</td><td>Gnosis (xDAI)</td><td>DAI</td><td>100</td></tr><tr><td>3</td><td>✅</td><td>Binance Smart Chain</td><td>BSC</td><td>56</td></tr><tr><td>4</td><td>✅</td><td>Fantom</td><td>FTM</td><td>250</td></tr><tr><td>5</td><td>✅</td><td>Polygon</td><td>POL</td><td>137</td></tr><tr><td>6</td><td>✅</td><td>Aurora</td><td>AUR</td><td>1313161554</td></tr><tr><td>7</td><td>✅</td><td>Avalanche</td><td>AVA</td><td>43114</td></tr><tr><td>8</td><td>✅</td><td>Arbitrum</td><td>ARB</td><td>42161</td></tr><tr><td>9</td><td>✅</td><td>Arbitrum Nova</td><td>ETH</td><td>42170</td></tr><tr><td>10</td><td>✅</td><td>Optimism</td><td>OPT</td><td>10</td></tr><tr><td>11</td><td>✅</td><td>Moonbeam</td><td>MOO</td><td>1284</td></tr><tr><td>12</td><td>✅</td><td>Neon </td><td>NEON</td><td>245022934</td></tr><tr><td>13</td><td>✅</td><td>OKT Chain</td><td>OKTC</td><td>66</td></tr><tr><td>14</td><td>✅</td><td>Klaytn Cypress </td><td>KLAY</td><td>8217</td></tr></tbody></table>

#### Bridges <a href="#bridges" id="bridges"></a>

Bridges are either supported directly on the SDK or through our partner bridge aggregators integrations like (Li.Fi and Socket).

<table data-header-hidden><thead><tr><th width="90"></th><th width="74"></th><th></th><th></th><th></th></tr></thead><tbody><tr><td>#</td><td></td><td>Bridge</td><td>Bridge Key</td><td>Supported Chains</td></tr><tr><td>1</td><td>✅</td><td>Connext</td><td><code>connext</code></td><td>ETH, OPT, BSC, DAI, POL, FTM, ARB, AVA, MOR, CRO</td></tr><tr><td>2</td><td>✅</td><td>Hop</td><td><code>hop</code></td><td>ETH, OPT, DAI, POL, ARB</td></tr><tr><td>3</td><td>✅</td><td>Celer cBridge</td><td><code>cbridge</code></td><td>ETH, AUR, OPT, BSC, POL, FTM, OKT, AVA, ARB</td></tr><tr><td>4</td><td>✅</td><td>Multichain</td><td><code>multichain</code></td><td>ETH, BSC, POL, FTM, ARB, AVA, OKT, DAI, MOR, CEL, CRO...</td></tr><tr><td>5</td><td>✅</td><td>Optimism Gateway</td><td><code>optimism</code></td><td>ETH, OPT</td></tr><tr><td>6</td><td>✅</td><td>Polygon Bridge (PoS)</td><td><code>polygon</code></td><td>ETH, POL</td></tr><tr><td>7</td><td>✅</td><td>AVAX Bridge</td><td><code>avalanche</code></td><td>ETH, AVA</td></tr><tr><td>8</td><td>✅</td><td>Arbitrum Bridge</td><td><code>arbitrum</code></td><td>ETH, ARB</td></tr><tr><td>9</td><td>✅</td><td>Stargate</td><td><code>stargate</code></td><td>ETH, OPT, BSC, POL, FTM, ARB, AVA</td></tr></tbody></table>

#### Exchanges​ <a href="#exchanges" id="exchanges"></a>

Currently, we support the following exchanges.

<table data-header-hidden><thead><tr><th width="83"></th><th width="40"></th><th></th><th></th><th></th></tr></thead><tbody><tr><td>#</td><td></td><td>Exchange</td><td>Exchange Key</td><td>Supported Chains</td></tr><tr><td>1</td><td>✅</td><td>0x</td><td><code>0x</code></td><td>ETH, BSC, POL, FTM, AVA, OPT</td></tr><tr><td>2</td><td>✅</td><td>1inch</td><td><code>1inch</code></td><td>ETH, OPT, BSC, DAI, POL, AVA, FTM, ARB</td></tr><tr><td>3</td><td>✅</td><td>ParaSwap</td><td><code>paraswap</code></td><td>ETH, BSC, POL, AVA, FTM</td></tr><tr><td>4</td><td>✅</td><td>OpenOcean</td><td><code>openocean</code></td><td>ETH, BSC, POL, ARB, AVA, OKT, MOR, AUR, CRO</td></tr><tr><td>5</td><td>✅</td><td>DODO</td><td><code>dodo</code></td><td>ETH, BSC, OKT, OPT, POL, ARB, MOR, AUR, AVA, CRO</td></tr><tr><td>6</td><td>✅</td><td>UniswapV2</td><td><code>uniswap</code></td><td>ETH</td></tr><tr><td>7</td><td>✅</td><td>SushiSwap</td><td><code>sushiswap</code></td><td>ETH, BSC, DAI, POL, FTM, ONE, AVA, ARB, MOR, OKT, FUS, CEL</td></tr><tr><td>8</td><td>✅</td><td>QuickSwap</td><td><code>quickswap</code></td><td>POL</td></tr><tr><td>9</td><td>✅</td><td>HoneySwap</td><td><code>honeyswap</code></td><td>DAI, POL</td></tr><tr><td>10</td><td>✅</td><td>Pancake</td><td><code>pancakeswap</code></td><td>BSC</td></tr><tr><td>11</td><td>✅</td><td>SpiritSwap</td><td><code>spiritswap</code></td><td>FTM</td></tr><tr><td>12</td><td>✅</td><td>SpookySwap</td><td><code>spookyswap</code></td><td>FTM</td></tr><tr><td>13</td><td>​✅​</td><td>SoulSwap</td><td><code>soulswap</code></td><td>FTM</td></tr><tr><td>14</td><td>✅</td><td>Pangolin</td><td><code>pangolin</code></td><td>AVA</td></tr><tr><td>15</td><td>✅</td><td>Solarbeam</td><td><code>solarbeam</code></td><td>MOR</td></tr><tr><td>16</td><td>✅</td><td>StellaSwap</td><td><code>steallaswap</code></td><td>MOO</td></tr><tr><td>17</td><td>✅</td><td>BeamSwap</td><td><code>beamswap</code></td><td>MOO</td></tr><tr><td>18</td><td>✅</td><td>UbeSwap</td><td><code>ubeswap</code></td><td>CEL</td></tr><tr><td>19</td><td>✅</td><td>CronaSwap</td><td><code>cronaswap</code></td><td>CRO</td></tr><tr><td>20</td><td>✅</td><td>Diffusion</td><td><code>diffusion</code></td><td>EVM</td></tr><tr><td>21</td><td>✅</td><td>Cronus</td><td><code>cronus</code></td><td>EVM</td></tr><tr><td>22</td><td>✅</td><td>Evmoswap</td><td><code>evmoswap</code></td><td>EVM</td></tr><tr><td>23</td><td>✅</td><td>OKCSwap</td><td><code>okcswap</code></td><td>OKT</td></tr><tr><td>24</td><td>✅</td><td>JSwap</td><td><code>jswap</code></td><td>OKT</td></tr><tr><td>25</td><td>✅</td><td>Swapr</td><td><code>swapr</code></td><td>DAI</td></tr><tr><td>26</td><td>✅</td><td>Voltage</td><td><code>voltage</code></td><td>FUS</td></tr><tr><td>27</td><td>✅</td><td>Trisolaris</td><td><code>trisolaris</code></td><td>AUR</td></tr><tr><td>28</td><td>✅</td><td>Wagyuswap</td><td><code>wagyuswap</code></td><td>VEL</td></tr></tbody></table>

**Testnets**

While we support these testnets and create wallets for all of them when the SDK is instantiated, it is recommended to test the BUIDLer component using mainnet using Gnosis Chain. Devs can get xdai [here](http://www.gnosisfaucet.com/).

<table><thead><tr><th width="86">#</th><th width="63"> </th><th width="267">Chain </th><th>Chain ID</th></tr></thead><tbody><tr><td>1</td><td>✅</td><td>goerli</td><td>5</td></tr><tr><td>2</td><td>✅</td><td>fuji</td><td>43113</td></tr><tr><td>3</td><td>✅</td><td>sokol</td><td>77</td></tr><tr><td>4</td><td>✅</td><td>bscTest</td><td>97</td></tr><tr><td>5</td><td>✅</td><td>fantomTest</td><td>4002</td></tr><tr><td>6</td><td>✅</td><td>mumbai</td><td>80001</td></tr><tr><td>7</td><td>✅</td><td>auroraTest</td><td>1313161555</td></tr><tr><td>8</td><td>✅</td><td>moonbase</td><td>1287</td></tr><tr><td>9</td><td>✅</td><td>arbitrumNitro</td><td>421613</td></tr><tr><td>10</td><td>✅</td><td>neonDevnet</td><td>245022926</td></tr><tr><td>11</td><td>✅</td><td>optimismGoerli</td><td>420</td></tr><tr><td>12</td><td>✅</td><td>etherspot</td><td>4386</td></tr><tr><td>13</td><td>✅</td><td>OktcTest</td><td>65</td></tr><tr><td>14</td><td>✅</td><td>KlaytnBaobab</td><td>1001</td></tr><tr><td>15</td><td>✅</td><td>Chiado</td><td>10200</td></tr></tbody></table>


# Social Logins

Combining Web3auth with Etherspot for a frictionless Web3 UX.

Etherspot has partnered with Web3Auth, to bring users a frictionless Web3 experience by combining the power of Web3auth's social login onboarding and Etherspot's Smart Wallet infrastructure.&#x20;

With Web3Auth, users handle keys similar to a multi-factor account, where they use their OAuth login, devices and other factors to manage their key pairs. In this example, the user starts by generating a 2 out of 3 (2/3) Shamir Secret Sharing. This gives the user three shares: ShareA, ShareB, and ShareC.

Similar to existing 2FA systems, a user needs to prove ownership of at least 2 out of 3 (2/3) shares, in order to retrieve his private key. This initial setup provides several benefits.

1. **ShareA is stored on the user's device**: Implementation is device and system specific. For example, on mobile devices, the share could be stored in device storage secured via biometrics.
2. **ShareB is managed by a login service via node operators**: This share is further split amongst a network of nodes and retrieved via conventional authentication flows.
3. **ShareC is a recovery share**: An extra share to be kept by the user, possibly kept on a separate device, downloaded or based on user input with enough entropy (eg. password, security questions, hardware device etc.).

<figure><img src="/files/JhtEFuKBPOSQAO1v1Gqx" alt=""><figcaption><p>Web3auth Self-Custody Framework.</p></figcaption></figure>

Using Web3Auth, the user is always in control of ownership and access to their cryptographic key pair. Login services only ever have access to one share, and thus it's not possible for the provider to retrieve the user's private key on their own.

#### Feels like Web 2.0 login flows[​ ](https://web3auth.io/docs/overview/key-management/#feels-like-web-20-login-flows) <a href="#feels-like-web-20-login-flows" id="feels-like-web-20-login-flows"></a>

On a day-to-day basis, Web3Auth allows access to a user key pair through flows indistinguishable from Web2.0 logins, contributing to greatly improving user experience and onboarding

&#x20;                                                  ![](/files/pec50LW3J6imWJGQYUsi)\
&#x20;                                               Social logins on <https://buidler.etherspot.io/>

**Improvements to key recovery and redundancy**[**​**](https://web3auth.io/docs/overview/key-management/#improvements-to-key-recovery-and-redundancy)

In the event of a lost device/share, there is redundancy built into the share threshold such that a user can still recover their key. It is also possible to refresh shares such that lost shares are revoked.

This is an improvement over writing down a seed phrase on a piece of paper, since losing the seed phrase gives complete access to the private key. Losing a share, however, is acceptable as long as the user does not lose more than one share without refreshing his existing shares.

#### Incremental security[​](https://web3auth.io/docs/overview/key-management/#incremental-security) <a href="#incremental-security" id="incremental-security"></a>

Users can increase security on their key by increasing the 2/3 threshold to a higher threshold. For example, a user can increase the threshold from 2/3 to 3/4 and add yet another authentication factor like a hardware device. This might be necessary if the user has high amounts of cryptocurrency on his private key.

#### Chain/platform agnostic via native signatures[​](https://web3auth.io/docs/overview/key-management/#chainplatform-agnostic-via-native-signatures) <a href="#chainplatform-agnostic-via-native-signatures" id="chainplatform-agnostic-via-native-signatures"></a>

areWeb3Auth's resulting interface is a native cryptographic key pair, making it compatible with almost all cryptographic constructs on various platforms and elliptic curves. Secret sharing and share refresh is also done completely off-chain, which makes Web3Auth usable on blockchains with limited smart contract functionality.

#### Censorship resistant[​](https://web3auth.io/docs/overview/key-management/#censorship-resistant) <a href="#censorship-resistant" id="censorship-resistant"></a>

Using a 2/3 threshold also prevents censorship by the Torus nodes. In the case that the nodes refuse to return the share of the user's private key even after the user has authenticated successfully, the user can still reconstruct their private key using ShareA (device share) and ShareC (recovery share).


# Web3 Logins

The Etherspot BUIDLER React Component accepts any provider / provider-like objects returned from a Wallet Connector library.

<figure><img src="/files/MbNFvGLdF4QWB3lEL6lC" alt=""><figcaption></figcaption></figure>


# Introduction

An introduction to TransactionKit

## What is TransactionKit?

We're glad you asked.

Writing code to perform transactions on the blockchain is still difficult. The learning curve is steep and some blockchain knowledge and Web3 development experience is needed.

We have leveraged the power of the Etherspot platform to simplify this into a few React Components and Hooks that can be controlled via your React UI.

**👉 Supports 13 chains and their testnets**

You read that right. TransactionKit is built on top of Etherspot and helps make your app truly multichain. TransactionKit supports Etheruem, Polygon, Gnosis, Binance, Fantom, Aurora, Avalanhe, Optimism, Arbitrum, Moonbean, Celo, Fuse and Arbitrum Nova.

**👉 Transaction Batching out the box**

Organise your transactions into batches to have them execute together. Each batch can be performed on a different blockchain.

**👉 Zero configuration**

You bring the code and design, we'll handle the infrastructure. Built with your productivity and speed in mind. No need to configure infrastructure providers, no signups needed, no credit cards down. Just install the code and start sending transactions.

**👉 Total design freedom**

TransactionKit is a headless collection of React Components and does not impose any existing user interfaces on you. You design and build how you envision your app, and we'll handle all the technical complexity.

## Here's an example

We're going to sent 0.1 ETH to another blockchain account.

```jsx
<EtherspotBatches>
  <EtherspotBatch>
    <EtherspotTransaction
      to={"0x0763d68dd586AB1DD8Be2e00c514B2ac8757453b"}
      value={"0.1"}
    />
  </EtherspotBatch>
</EtherspotBatches>
```

That's all it took!

## Want to try this out for yourself?

Have a look at our [Quick Start](/transaction-kit/quick-start) guide to get going.


# Code Sandboxes

We've built ready-to-go CodeSandboxes to get started quickly.

## Introduction

We want to get you going as fast as possible with TransactionKit. We've built some CodeSandboxes for you, ready to fork mould into your own. Have a look at the options below.

## Ready-to-fork Sandboxes

### Send a native asset

This CodeSandbox allows you to simply send a native asset using TransactionKit, and is built on the Polygon Testing blockchain called Mumbai.

:point\_right: [Open native asset CodeSandbox](https://codesandbox.io/s/brave-darkness-doh5im)

### Staking

This CodeSandbox shows how easy it is to build a staking website with TransactionKit. We have built and deployed a fake token (TKT) minting Smart Contract, and a staking Smart Contract which accepts the aforementioned fake token (TKT) and gives you stkTKT in return.

:point\_right: [Open staking CodeSandbox](https://codesandbox.io/s/staking-example-2pij3n)

:page\_facing\_up: [TxKitToken (TKT) on Polygon Mumbai](https://mumbai.polygonscan.com/token/0x2A9bb3fB4FBF8e536b9a6cBEbA33C4CD18369EaF)

:page\_facing\_up: [Staking Contract on Polygon Mumbai](https://mumbai.polygonscan.com/address/0x0493b9a21dE42546B2E3687Da683D0B7B6ec2180)

### Etherspot Assets hook

We have prebuilt token lists for you to use in your app. We have curated the top 100 popular tokens for every chain. You can see how to use this data in the CodeSandbox below.

:point\_right: [Etherspot Assets hook CodeSandbox](https://codesandbox.io/s/fetch-etherspot-assets-hook-y9ehm9)

### Etherspot NFTs hook

This CodeSandbox shows you how to fetch NFT data for your Etherspot Smart Wallet account.&#x20;

:point\_right: [Etherspot NFTs hook CodeSandbox](https://codesandbox.io/s/fetch-etherspot-nfts-hook-1zrzbv)

### Etherspot Transaction History hook

See how you can fetch the transation history for an Etherspot account, and for different chains.

{% hint style="warning" %}
Remember: transaction history only works with Etherspot Smart Wallet accounts!
{% endhint %}

:point\_right: [Etherspot History hook CodeSandbox](https://codesandbox.io/s/fetch-etherspot-history-hook-09uno6)

## There's more coming!

We're hard at work creating more examples for you to get started quickly. Keep checking back!

Got a suggestion you would like to see? Drop us a message on [Discord](https://discord.com/invite/GAkYj6m5Uh)!


# Quick Start

Get started quickly with TransactionKit

## View or fork now on CodeSandbox

The Quick Start below is available as a well documented, fully functioning live example on CodeSandbox.

:point\_right: [View or fork the Send Native Asset CodeSandbox](https://doh5im.csb.app/)

:book: [View all our CodeSandbox examples](/transaction-kit/code-sandboxes)

Otherwise, please keep following the instructions below.

## Bootstrap a React App

Let's keep it simple and use `create-react-app` here. Run the following command in a directory of your choice:

```bash
npx create-react-app txkit-quickstart
```

The above command will install and bootstrap a basic React App into a directory called `txkit-quickstart.` Once the installation has finished, change directory into your newly bootstrapped React app by typing:

```bash
cd txkit-quickstart
```

## Install Transaction Kit

Next, install TransactionKit and Ethers

```bash
npm i @etherspot/transaction-kit ethers@5.4.0
// or
yarn add @etherspot/transaction-kit ethers@5.4.0
```

## Create a Web3 Provider

A Web3 provider ultimately provides access to blockchain account, also known as a wallet.

For the Quick Start example, we will randomly generate a wallet.

{% code title="index.tsx / index.js" %}

```javascript
import { EtherspotTransactionKit } from '@etherspot/transaction-kit';
import { ethers } from 'ethers';

// ...

const randomWallet = ethers.Wallet.createRandom();
const providerWallet = new ethers.Wallet(randomWallet.privateKey);
```

{% endcode %}

## Wrap your \<App /> with \<EtherspotTransactionKit />

Wrap your React `<App />` tag in the `<EtherspotTransactionKit />` tag. This will turbocharge your React app with the power of Etherspot and everything that the platform can offer.

{% code title="index.tsx / index.js" %}

```jsx
root.render(
  <React.StrictMode>
    <EtherspotTransactionKit
      provider={providerWallet} /* The random wallet we created above */
      chainId={80001} /* Polygon Testnet - Mumbai */
    >
      <App />
    </EtherspotTransactionKit>
  </React.StrictMode>
);
```

{% endcode %}

{% hint style="info" %}
**Get yourself some Polygon Mumbai Testnet funds**

In order to execute a transaction, you need to fund your randomly created account with Test MATIC, the native token on Polygon Mumbai. You can get some for free below.

[https://faucet.polygon.technology](https://faucet.polygon.technology/)
{% endhint %}

## Build a UI

We're going to start with a simple example - sending some MATIC to another address. TransactionKit makes this really, really easy. Have a look at the code below.

{% code title="" %}

```jsx
import {
  EtherspotBatches,
  EtherspotBatch,
  EtherspotTransaction,
  useEtherspotUi,
  useEtherspotAddresses,
} from '@etherspot/transaction-kit';

// In your main function body...

const { estimate, send } = useEtherspotTransactions();
const etherspotAddresses = useEtherspotAddresses();

const [address, setAddress] = useState('0x271Ae6E03257264F0F7cb03506b12A027Ec53B31');
const [amount, setAmount] = useState('0.001');

// In your rendering function...

<EtherspotBatches>
  <EtherspotBatch>
    <EtherspotTransaction
      to={address}
      value={amount}
    >
      {/* The following returns a list of Blockchain
          addresses that are ready to use */}
      {
        etherspotAddresses.map((etherspotAddressObject) =>
          <div>
            <p>Blockchain Name: {etherspotAddressObject.chainName}</p>
            <p>Blockchain ID:{etherspotAddressObject.chainId}</p>
            <p>Address: {etherspotAddressObject.address}</p>
          </div>
        )
      }
      <input
        type="text"
        value={address}
        onChange={(event) => setAddress(event.target.value)}
      />
      <input
        type="text"
        value={amount}
        onChange={(event) => setAmount(event.target.value)}
      />
      <hr />
      <button onClick={() => estimate()}>Estimate</button>
      <button onClick={() => send()}>Send</button>
    </EtherspotTransaction>
  </EtherspotBatch>
</EtherspotBatches>
```

{% endcode %}

{% hint style="warning" %}
**You must always estimate before sending**

Estimating first performs important transaction cost calculations that are required before sending.
{% endhint %}

Once sent - you can check the transaction on the Polygon Mumbai blockchain explorer [here](https://mumbai.polygonscan.com/address/0x271Ae6E03257264F0F7cb03506b12A027Ec53B31).

## :tada: Congratulations!

You've just sent your first transaction using TransactionKit! Wasn't that easy? Why not have a look around the TransactionKit documentation to see what else you can do with TransactionKit!


# React Hooks


# useEtherspotAssets()

A React hook that retuns a list of tokens for developers to use in their project.

## Introduction

As part of any cryptocurrency related app, it's essential to be able to access a list of other cryptocurrencies and their asset data (such as asset logo) to use within your app, otherwise you'll likely need to try and find this yourself.

The `useEtherspotAssets` hook makes this easy for you by allowing you to access our prebuilt list of tokens for every chain.

## Ready-to-fork CodeSandbox available

There is a CodeSandbox available for this hook. Check it out to see the `useEtherspotAssets` hook in action action, and fork it should you want to test or change anything.

:point\_right: [CodeSandbox directory: Etherspot Assets](https://docs.etherspot.io/transaction-kit/code-sandboxes#etherspot-assets-hook)

## How to use

```jsx
import {
  useEtherspotAssets
} from "@etherspot/transaction-kit";

// Later in your component function...

const { getAssets } = useEtherspotAssets();

// When you're ready to fetch the assets...

const tokens = await getAssets();

// `tokens` will look similar to the following...

// [
//   {
//     "address": "0xe3818504c1B32bF1557b16C238B2E01Fd3149C17",
//     "chainId": 1,
//     "decimals": 18,
//     "logoURI": "https://images.prismic.io/pillar-app/83dcf8ff-6459-41d4-8d43-7ec143814b2d_pillar-logo-5.png?auto=compress,format",
//     "name": "Pillar",
//     "symbol": "PLR"
//   },
//   {
//     "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
//     "chainId": 1,
//     "decimals": 6,
//     "logoURI": "https://raw.githubusercontent.com/bnb-chain/tokens-info-v2/master/tokens/usdt/usdt.png",
//     "name": "USDT",
//     "symbol": "USDT"
//   },
//   ...  
// ]
```

## :tada:  Congratulations!

Now you know how to fetch a list of popular assets to use in your app instead of having to find a data source of tokens from somewhere else.


# useEtherspotNfts()

A React hook that returns a list of NFTs for any supported blockchain and address.

## Introduction

Depending on what type of app you are building, NFTs can sometimes form part of your app, or - can even be the main focus of your app entirely. The `useEtherspotNfts` hook will allow you to fetch NFTs per blockchain and by account address.

## Ready-to-fork CodeSandbox available

There is a CodeSandbox available for this hook. Check it out to see the `useEtherspotNfts` hook in action action, and fork it should you want to test or change anything.

:point\_right: [CodeSandbox directory: Etherspot NFTs](https://docs.etherspot.io/transaction-kit/code-sandboxes#etherspot-nfts-hook)

## Hook Parameters

```javascript
/**
 * useEtherspotNfts(chainId?: number)
 */

// useEtherspotNfts takes a chain ID as
// its only parameter. For example, the following
// will fetch your NFTs for your Smart Wallet
// address on Polygon:

const { getAccountNfts } = useEtherspotNfts(137);
//                                           ^
//                                  Note the chain ID

const accountNfts = await getAccountNfts();
// By default, this fetches the NFTs of your own
// Smart Wallet account.

/**
 * getAccountNfts(accountAddress?: string)
 */
 
// The getAccountNfts function takes an account
// address as its only parameter. The function
// will fetch the NFTs for the provided address
// instead of your Smart Wallet address.
const otherAccountNfts = await getAccountNfts(
  '0x0763d68dd586AB1DD8Be2e00c514B2ac8757453b'
);

```

## How to use

```jsx
import {
  useEtherspotNfts
} from "@etherspot/transaction-kit";

// Later in your component function...

const { getAccountNfts } = useEtherspotNfts();

// When you're ready to fetch NFTs...

const nfts = await getAccountNfts();

// `nfts` will look similar to the following...

// [
//   {
//     "contractName": null,
//     "contractSymbol": null,
//     "contractAddress": "0xa07e45a987f19e25176c877d98388878622623fa",
//     "tokenType": "Erc1155",
//     "nftVersion": null,
//     "nftDescription": null,
//     "balance": 1,
//     "items": [
//       {
//         "tokenId": "123",
//         "name": "null #123",
//         "amount": 2,
//         "image": "Dummy ERC1155",
//         "ipfsGateway": null
//       }
//     ]
//   }
// ]
```

## :tada:  Congratulations!

And that is how you fetch NFT data for any of Etherspot's supported blockchains, and for any address.


# useEtherspotHistory()

A React hook that allows you to fetch the transaction history Etherspot addresses.

## Check out the methods below

* [Get account transactions](/transaction-kit/react-hooks/useetherspothistory/getaccounttransactions)
* [Get a single account transaction](/transaction-kit/react-hooks/useetherspothistory/getaccounttransaction)


# getAccountTransactions()

Gets all the transactions for an Etherspot address.

## Introduction

You can fetch the historical transactions for any blockchain address that belongs to the Etherspot ecosystem.

{% hint style="warning" %}
**Etherspot addresses only!**

Please note that this hook works only with Etherspot blockchain addresses. Blockchain addresses that were not created on the Etherspot platform are not supported.
{% endhint %}

## Ready-to-fork CodeSandbox available

There is a CodeSandbox available for this hook. Check it out to see the `useEtherspotHistory` hook in action action, and fork it should you want to test or change anything.

:point\_right: [CodeSandbox directory: Etherspot History](https://docs.etherspot.io/transaction-kit/code-sandboxes#etherspot-transaction-history-hook)

## How to use

To fetch historical transactions for a blockchain address on the Etherspot platform, simply call `getAccountTransactions()` from `useEtherspotHistory().`

```javascript
import {
  useEtherspotHistory,
} from '@etherspot/transaction-kit';

// Later in the main component function...

const { getAccountTransactions } = useEtherspotHistory();

// And when you're ready to fetch your transaction history...

const accountTransactionHistory = await getAccountTransactions(); // This is also a Promise

// accountTransactionHistory will now contain an array of history objects.
```

## :tada:  Congratulations!


# getAccountTransaction()

Gets a single transaction for an Etherspot address by hash.

## Introduction

You can fetch a single historical transaction for any blockchain address that belongs to the Etherspot ecosystem. All you need is the hash you want to look up the history item for.

{% hint style="warning" %}
**Etherspot addresses only!**

Please note that this hook works only with Etherspot blockchain addresses. Blockchain addresses that were not created on the Etherspot platform are not supported.
{% endhint %}

## Ready-to-fork CodeSandbox available

There is a CodeSandbox available for this hook. Check it out to see the `useEtherspotHistory` hook in action action, and fork it should you want to test or change anything.

:point\_right: [CodeSandbox directory: Etherspot History](https://docs.etherspot.io/transaction-kit/code-sandboxes#etherspot-transaction-history-hook)

## How to use

To fetch a historical transaction for a blockchain address on the Etherspot platform, simply call `getAccountTransaction(hash)` from `useEtherspotHistory()`, passing a blockchain hash where `hash` is above.

```javascript
import {
  useEtherspotHistory,
} from '@etherspot/transaction-kit';

// Later in the main component function...

const { getAccountTransaction } = useEtherspotHistory();

// And when you're ready to fetch your transaction history item...

const accountTransactionHistoryItem = await getAccountTransactions(
  '0xdd2f99257393a054588fbfaf7702c293b05aea2ffa034920c0d02f475d6e97d0',
);

// accountTransactionHistoryItem will now return an object containing the history item.
```

## :tada:  Congratulations!


# useEtherspotTransactions()


# estimate()

Estimates all batches and transactions

## Introduction

Any transaction that is intended to be sent to the blockchain **must be estimated** **first**. The estimation function performs several checks including cost estimation and transaction validity. This method **must always be called** before we send, otherwise the send method will return an error.

## How to use

Whenever you add, edit or remove an `<EtherspotBatches>`, `<EtherspotBatch />` or `<EtherspotTransaction />` component - call the `.estimate()` hook.

You simply need to import the hook and call the function as shown below.

```javascript
import {
  useEtherspotTransactions,
} from '@etherspot/transaction-kit';

// Later in the main component function...

const { estimate } = useEtherspotTransactions();

// And when you're ready to perform the estimate...

estimate(); // This is also a Promise

// Now your transactions are ready to send!
```

## :tada: Congratulations!

And that was estimation! Remember: estimation should always be called whenever any of the TransactionKit UI components change.

The next step in this journey is to [`.send()`](/transaction-kit/react-hooks/useetherspottransactions/send)


# send()

Sends all batches and transactions

## Introduction

The `.send()` function simply sends all the `<EtherspotBatches />`, which contain all `<EtherspotBatch />` and `<EtherspotTransaction />` components to the blockchain via the Etherspot platform.

{% hint style="warning" %}
**You must always estimate before sending**

Estimating first performs imporant transaction cost calculations that are required before sending.
{% endhint %}

## How to use

Whenever you are ready to send your transaction to the blockchain, you simply need to call .send() as shown below.

```javascript
import {
  useEtherspotTransactions,
} from '@etherspot/transaction-kit';

// Later in the main component function...

const { send } = useEtherspotTransactions();

// And when you're ready to end your transaction(s)...

send(); // This is also a Promise

// Your transactions are now being sent to the blockchain
```

## :tada: Congratulations

By calling the above function, you have sent the transactions to the Etherspot platform, and we'll take care of it from here to ensure that the transactions are executed on the blockchain.


# useEtherspotAddresses()

A React hook that returns all the blockchain addresses for all the blockchains that the Etherspot platform supports.

## Introduction

The `useEtherspotAddresses()` hook will return an array of objects, of which each object is representative of a supported Etherspot blockchain. Each object in the array will contain the blockchain name, blockchain ID and the Etherspot Smart Wallet address which you can start using immediately.

{% hint style="warning" %}
**A word on these Etherspot Smart Wallet addresses**

These are the **primary addresses** you will be sending and receiving from. Please use these addresses, and not your key wallet address when writing code, sending and receiving from faucets, other accounts or Smart Contracts.
{% endhint %}

## How to use

```javascript
import {
  useEtherspotAddresses,
} from '@etherspot/transaction-kit';

// Later in the main component function...

const etherspotAddresses = useEtherspotAddresses();

// etherspotAddresses will look similar to this:
/**
 * [{
 *   chainId: 137,
 *   chainName: 'matic',
 *   address: '0x0123...'
 * }, {
 *   ...
 * }]
/*
```

## :tada: Congratulations!

It's that easy to fetch your Etherspot Smart Wallet addresses for use on each chain.


# useEtherspotBalances()

A React hook that returns the native balance for a particular blockchain supported by the Etherspot Platform.

## Introduction

The `useEtherspotBalances()` hook will return an object containing the native balance of the Etherspot Smart Wallet address on the blockchain ID being passed to the hook.

## How to use

```javascript
import {
  useEtherspotBalances,
} from '@etherspot/transaction-kit';

// Later in the main component function...
const etherspotBalanceOnMatic = useEtherspotBalances(137);

// etherspotBalanceOnMatic will look similar to this:
/**
 * [
 *  {
 *   "token": null,
 *    "balance": {
 *      "type": "BigNumber",
 *      "hex": "0x00"
 *    },
 *   "superBalance": null
 *  }
 * ]
/*
```

## :tada: Congratulations!

It's that easy to fetch your Etherspot Smart Wallet balances each chain.


# React Components


# \<EtherspotTransactionKit />

The top level component that injects the Etherspot Platform into your React app

## Introduction

In order for us to provide all the power of Etherspot to your app, we need to wrap your app in an `<`EtherspotTransactionKit `/>` tag. This will allow the whole app to access libraries and services provided by TransactionKit.

## How to use

The `<`EtherspotTransactionKit `/>` component will wrap your top level `<App />` tag which is usually found in the React app's `index.js` file. Here is how you would use the `<`EtherspotTransactionKit `/>` tag.

```jsx
// Import the following libraries
import { EtherspotTransactionKit } from '@etherspot/transaction-kit';
// We're importing Ethers here to create a random wallet
import { ethers } from 'ethers';

/**
 * Later in your app's function code...
 */

// Let's create the random wallet for demonstration purposes.
const randomWallet = ethers.Wallet.createRandom();
// Pass the private key into a new ethers.Wallet to return a
// provider. This is the account we pass into EtherspotUi.
const providerWallet = new ethers.Wallet(randomWallet.privateKey);

/**
 * In your app's render function, "wrap" the <App /> tag...
 */

root.render(
  <React.StrictMode>
    <EtherspotTransactionKit provider={providerWallet}> // <-- open here
      <App />
    </EtherspotTransactionKit>                          // <-- close here
  </React.StrictMode>
);
```

## :tada: Congratulations

And that's how we get our TransactionKit journey started. In summary, "wrapping" your `<App />` component injects the powerful features and services of Etherspot into your app. Read on to discover what's next.


# \<EtherspotBatches />

The beginning of a transaction. Indicates that we are creating one or more batches of transactions.

## Introduction

The `<EtherspotBatches />` component is, at its simplest, a way to indicate to TransactionKit that you're about to start defining one or more `<EtherspotBatch />` components which may contain one or more `<EtherspotTransaction />` or `<EtherspotContractTransaction />` components.&#x20;

This tag helps TransactionKit keep itself organised, takes various component props to customise the transactions inside it and returns events when we need to [estimate](/transaction-kit/react-hooks/useetherspottransactions/estimate).

The `<EhterspotBatches />` component takes any child components like taxt, buttons etc.

## Component Properties

<table><thead><tr><th width="182">Property</th><th>Description</th></tr></thead><tbody><tr><td><code>skip</code></td><td>Optional: Takes a boolean value of <code>true</code> or <code>false</code>. Set <code>skip={true}</code> when you would like to skip these batches from being estimated and sent.</td></tr><tr><td><code>id</code></td><td>Optional: An ID (which can be a <code>string</code>, <code>number</code> etc) that allows you to define the ID of this batches group. We will use this ID if you provide it internally, but also allows you to use it to keep track elsewhere within your app.</td></tr><tr><td><code>onEstimated</code></td><td>Optional: Takes a function which accepts a parameter which is an estimation object. This is fired when an transaction cost estimation has been completed of all the contained <code>&#x3C;EtherspotBatch /></code> components. See the code example below to see how this is used.</td></tr></tbody></table>

## How to use

Below is an example of how to use the `<EtherspotBatches />` component.

{% code lineNumbers="true" %}

```jsx
// In your functional component or elsehwere
const onEstimateReceiver = (estimationData) => {
  console.log(
    'This is the cost estimate for all the batches',
    estimationData,
  );
}

// In your render or as a component...
<EtherspotBatches skip={true} onEstimated={onEstimateReceiver}>
  <EtherspotBatch>
    <EtherspotTransaction to={address0} value={amount0} />
  </EtherspotBatch>
  <EtherspotBatch>
    <EtherspotTransaction to={address1} value={amount1} />
    <EtherspotTransaction to={address2} value={amount2} />
  </EtherspotBatch>
</EtherspotBatches>
```

{% endcode %}

## :tada: Congratulations!

You can now see how we us the `<EtherspotBatches />` tag to enclose one or more of  `<EtherspotBatch />` tags.


# \<EtherspotBatch />

Indicates that we are going to add one more blockchain transactions to this batch.

## Introduction

The `<EtherspotBatch />` component allows you to define one or more `<EtherspotTransaction />` components to be sent as part of the `<EtherspotBatch />`.

## Component Properties

<table><thead><tr><th width="211">Property</th><th>Description</th></tr></thead><tbody><tr><td><code>id</code></td><td>Optional: An ID (which can be a <code>string</code>, <code>number</code> etc) that allows you to define the ID of this batch group. We will use this ID if you provide it internally, but also allows you to use it to keep track elsewhere within your app.</td></tr><tr><td><code>chainId</code></td><td>Optional: The blockchain ID that you would like to execute this batch on. Check out our <a href="/pages/-MeAyzR2e2VKsOneDqAi">supported blockchains</a> to check what we support.<br><br>The default is  "1" - Ethereum Mainnet.</td></tr><tr><td><code>gasTokenAddress</code></td><td>Optional: You can choose to pay for for batch of transactions with something else other than the native token for the blockchain you defined in <code>chainId</code> (or Ethereum if none specified).</td></tr></tbody></table>

## How to use

Below is an example of how to use the `<EtherspotBatch />` component.

```jsx
// In your functional component or elsehwere
const onEstimateReceiver = (estimationData) => {
  console.log(
    'This is the cost estimate for all the batches',
    estimationData,
  );
}

// In your render or as a component...
<EtherspotBatches onEstimated={onEstimateReceiver}>
  <EtherspotBatch>
    {/*
      Within the <EtherspotBatch /> component,
      you can add 1 or more <EtherspotTransaction />
      tags to be performed together and at the same
      time (i.e. within the same "batch").
    */}
  </EtherspotBatch>
</EtherspotBatches>
```

## :tada: Congratulations!

And that's how to implement the `<EtherspotBatch />` component. It's worth remembering that this component expects other components like `<EtherspotTransaction />` to live inside it for it to do anything at all.


# \<EtherspotTransaction />

## Introduction

This component allows you to tell TransactionKit that there will be a blockchain transaction performed. This TransactionKit component is likely to be the one you use the most to send a basic transaction, such as sending ETH (or the native token [on any other chain we support](/master/chains-bridges-and-dexes)) to another blockchain address on the same chain.

You can have 1 or many `<EtherspotTransaction />` components inside an `<EtherspotBatch />` component to be sent at the same time (i.e. as part of the same "batch").

## Component Properties

| Property | Description                                                                                                                                                                                                                                                            |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`     | Optional: An ID (which can be a `string`, `number` etc) that allows you to define the ID of this batch group. We will use this ID if you provide it internally, but also allows you to use it to keep track elsewhere within your app.                                 |
| `to`     | The destination blockchain address, on the same chain. For example, if you are sending from the Polygon blockchain, make sure you sent it to another address on the Polygon blockchain.                                                                                |
| `value`  | This can either be a string represented in Ether or as a BigNumber (see example).                                                                                                                                                                                      |
| `data`   | Optional: An optional data object which can be read by the recipient (the `to` address), if it is a Smart Contract, to perform additional functions as part of the transaction (see example), or, to just store an arbitrary piece of data along with the transaction. |

## How to use

Below is an example of how to use the `<EtherspotTransaction />` component. We have given two exampels, one that is a simple transaction and one that calls a method on a Smart Contract.

### Sending some ETH

Sending some ETH (or any other native token for another blockchain) is one of the most common transactions to performed - for example, sending some ETH to a friend. Here is how you can do that.

```jsx
// In your functional component or elsehwere
const onEstimateReceiver = (estimationData) => {
  console.log(
    'This is the cost estimate for all the batches',
    estimationData,
  );
}

// In your render or as a component...
<EtherspotBatches onEstimated={onEstimateReceiver}>
  <EtherspotBatch>
    {/*
    The following <EtherspotTransaction /> will send
    0.01 ETH to 0x0763d68dd586AB1DD8Be2e00c514B2ac8757453b.
    */}
    <EtherspotTransaction
      to={'0x0763d68dd586AB1DD8Be2e00c514B2ac8757453b'}
      value={'0.01'}
    />
    {/*
    You can add 1 or more <EtherspotTransaction />
    components here, and they will all be executed
    together and at the same time (i.e. as part of
    this batch).
     */}
  </EtherspotBatch>
</EtherspotBatches>
```

### Sending a transaction with a data object

Another type of transaction is sending a transaction with some data. Other dapps and services may read this data, or if you're sending some ETH (or other native token) to a Smart Contract, the Smart Contract may use this data to perform additional functions. Here how you can send some arbitrary data along with your transaction.

```jsx
// In your functional component or elsehwere
const onEstimateReceiver = (estimationData) => {
  console.log(
    'This is the cost estimate for all the batches',
    estimationData,
  );
}

// In your render or as a component...
<EtherspotBatches onEstimated={onEstimateReceiver}>
  <EtherspotBatch>
    {/*
    The following <EtherspotTransaction /> will send
    0.01 ETH to 0x0763d68dd586AB1DD8Be2e00c514B2ac8757453b
    and will include a data object containing the the
    message 'i am a teapot'.
    */}
    <EtherspotTransaction
      to={'0x0763d68dd586AB1DD8Be2e00c514B2ac8757453b'}
      value={'0.01'}
      data={'i am a teapot'}
    />
    {/*
    You can add 1 or more <EtherspotTransaction />
    components here, and they will all be executed
    together and at the same time (i.e. as part of
    this batch).
     */}
  </EtherspotBatch>
</EtherspotBatches>
```

## :tada: Congratulations!

You have learned how to send transactions with TransactionKit. Remember to check out our CodeSandbox to see this in action. You can also fork it and try it out yourself!

:point\_right: [View or fork CodeSandbox](https://doh5im.csb.app/)


# \<EtherspotContractTransaction />

## Introduction

This component allows you to tell TransactionKit that there will be a blockchain transaction performed, and it will be against a Smart Contract. This component is specifically tailored to Smart Contracts. If you are looking to send a simple transaction, then [`<EtherspotTransaction />`](/transaction-kit/react-components/less-than-etherspottransaction-greater-than) is what you may be looking for.

You can have 1 or many `<EtherspotContractTransaction />` components inside an `<EtherspotBatch />` component to be sent at the same time (i.e. as part of the same "batch").

## Component Properties

| Property          | Description                                                                                                                                                                                                                            |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`              | Optional: An ID (which can be a `string`, `number` etc) that allows you to define the ID of this batch group. We will use this ID if you provide it internally, but also allows you to use it to keep track elsewhere within your app. |
| `contractAddress` | The destination Smart Contract address  on the blockchain. Every Smart Contract has a unique address, including tokens.                                                                                                                |
| `abi`             | The "Application Binary Interface" of the Smart Contract... in other words, a dictionary of all the things we can do with this Smart Contract, and what data it needs.                                                                 |
| `method`          | The name of the function we want to call on the Smart Contract                                                                                                                                                                         |
| `params`          | The parameter(s), if any, we want to provide to the "method" above.                                                                                                                                                                    |
| `value`           | Optional: The amount of native token we want to send along. This can either be a string represented in Ether or as a BigNumber (see example).                                                                                          |

## How to use

Below is an example of how to use the `<EtherspotContractTransaction />` component.

### Sending a token

Sending a token is a very common practice within the blockchain ecosystem. When you send a token, you are interacting with the Smart Contract for that token. For example - you might want to send 10 USDC to pay for something, or, you might want to send 200 SHIB to a friend. Here's how to do that.

```jsx
// In your functional component or elsehwere
const onEstimateReceiver = (estimationData) => {
  console.log(
    'This is the cost estimate for all the batches',
    estimationData,
  );
}

// In your render or as a component...
<EtherspotBatches onEstimated={onEstimateReceiver}>
  <EtherspotBatch>
    {/*
    The following <EtherspotContractTransaction /> will send
    10 USDC to 0x0763d68dd586AB1DD8Be2e00c514B2ac8757453b by
    instrucing the USDC contract (0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)
    via the "transfer" method, which takes two parameters; the
    address (who to transfer to) and the amount (how much USDC to send).
    Note the "value" is set to 0 here. We do not want to send any of
    our own native asset along with this transaction.
    */}
    <EtherspotContractTransaction
      contractAddress={'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'}
      abi={['function transfer(address, uint)']}
      methodName={'transfer'}
      params={['0x0763d68dd586AB1DD8Be2e00c514B2ac8757453b', '10']}
      value={'0'}
    />
    {/*
    You can add 1 or more <EtherspotContractTransaction />
    components here, and they will all be executed
    together and at the same time (i.e. as part of
    this batch).
     */}
  </EtherspotBatch>
</EtherspotBatches>
```

## :tada: Congratulations!

You have learned how to send transactions that interact with Smart Contract and tokens with TransactionKit.


# \<EtherspotApprovalTransaction />

## Introduction

The `<EtherspotApprovalTransaction />` component authorizes the spending of an asset, owned by yourself, by another Smart Contract. This Smart Contract can serve any purpose, but is usually associated with decentralised finance app (also known as DeFi) such as Uniswap or Gamma.

In other words, it's like giving your friend permission to spend some of your money, up to a certain limit. In this scenario, the friend is the Smart Contract mentioned above.

{% hint style="warning" %}
The `<EtherspotApprovalTransaction />` component assumes that a `transfer` function exists on the Smart Contract being called.
{% endhint %}

## Component Properties

| Property          | Description                                                                                                               |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `tokenAddress`    | The token's Smart Contract address that will be permitted to be moved to the `recieverAddress.`                           |
| `receiverAddress` | The destination blockchain address (on the same chain) permitted for the tokens located at `tokenAddress` to be moved to. |
| `value`           | The maximum value that the token address is allowed to move to the `receiverAddress`.                                     |

## How to use

Below is an example of how to use the `<EtherspotApprovalTransaction />` component.

```jsx
import {
  EtherspotContractTransaction,
  EtherspotApprovalTransaction,
  EtherspotBatches,
  EtherspotBatch,
} from "@etherspot/transaction-kit";
import { utils } from "ethers";

// Later in your render function...

<EtherspotBatches>
  <EtherspotBatch chainId={80001}>
    {/*
    The following block is the first transaction in this batch
    of transactions, and instructs Etherspot to set a spending
    limit for the Smart Contract located at `receiverAddress`
    to be allowed to spend the token located at `tokenAddress`
    up to the amount specified in `value`.
    
    So in summary, using the example below:
    
    Smart Contract: 0x0493b9a21dE42546B2E3687Da683D0B7B6ec2180
    is allowed to spend up to and including 10 of the token
    located at: 0x2A9bb3fB4FBF8e536b9a6cBEbA33C4CD18369EaF.
    */}
    <EtherspotApprovalTransaction
      tokenAddress={"0x2A9bb3fB4FBF8e536b9a6cBEbA33C4CD18369EaF"}
      receiverAddress={"0x0493b9a21dE42546B2E3687Da683D0B7B6ec2180"}
      value={"10"}  
    />
    {/*
    The following block is the second transaction in this batch
    of transactions, and instructs Etherspot to call and execute
    the "stake" function on the Smart Contract located at the
    `contractAddress`. The "stake" function in the Smart Contract
    address located at the `contractAddress` takes 1 parameter
    which is the numbber of tokens to stake.
    
    In the <EtherspotApprovalTransaction /> component above, we
    gave permission for the Smart Contract below to spend 10 tokens
    of the token located at `tokenAddress` above from the Etherspot
    Smart Wallet account.
    */}
    <EtherspotContractTransaction
      contractAddress={"0x0493b9a21dE42546B2E3687Da683D0B7B6ec2180"}
      abi={["function stake(uint)"]}
      methodName={"stake"}
      params={[utils.parseEther("10")]}
    />
  </EtherspotBatch>
</EtherspotBatches>
```

## :tada: Congratulations!

And that is how we give permission for another Smart Contract, which is associated with a blockchain app, to spend your tokens using the `<EtherspotApprovalTransaction />` component up to a certain limit.

{% hint style="warning" %}
**A note on setting the spend limit...**

Sometimes it may seem convenient to set the spending limit to a very high amount, more than what is actually needed. This will result in you not having to call the approval tag again for that Smart Contract.

Whilst no-one is going to stop you doing this, please consider that the Smart Contract you're giving permission to spend your funds may be compromised in the future and could possibly drain all the funds in your account that it has permission to.
{% endhint %}


# \<EtherspotTokenTransferTransaction />

## Introduction

The `<EtherspotTokenTransferTransaction />` React Component helps you facilitate the transfer of an asset (such as PLR. USDC or SHIB) to another account.

You just need to provide the token address, the destination address and the amount of tokens you want to transfer to the destination address, and we'll take it from there.

{% hint style="warning" %}
**About token addresses**

Remember to research the correct token address on the correct blockchain you are sending to. Do not send tokens to another blockchain as it will be lost.

Keep transfers on the same blockchain.
{% endhint %}

{% hint style="warning" %}
The `<EtherspotTokenTransferTransaction />` component assumes that a `transfer` function exists on the Smart Contract being called.
{% endhint %}

## Component Properties

| Property          | Description                                                    |
| ----------------- | -------------------------------------------------------------- |
| `tokenAddress`    | The destination token address                                  |
| `receiverAddress` | The blockchain address that will receive the token             |
| `value`           | How much of the token you want to send to the receiver address |

## How to use

Below is an example of how to use the `<EtherspotTokenTransferTransaction />` component.

```jsx
// In your functional component or elsehwere
const onEstimateReceiver = (estimationData) => {
  console.log(
    'This is the cost estimate for all the batches',
    estimationData,
  );
}

// In your render or as a component...
<EtherspotBatches onEstimated={onEstimateReceiver}>
  <EtherspotBatch>
    {/*
      The following <EtherspotTokenTransferTransaction />
      component will transfer 5 USDC from the built-in
      Etherspot Smart Wallet account to the receiverAddress.
      
      In the example below:
      
      - The tokenAddress is the USDC contract address
        on Ethereum
      - The receiverAddress is the destination of the
        token amount being transferred
      - The value determines how much of the USDC is
        being transferred to the receiverAddress
    */}
    <EtherspotTokenTransferTransaction
      tokenAddress={'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'}
      receiverAddress={'0x0763d68dd586AB1DD8Be2e00c514B2ac8757453b'}
      value={'5'}
    />
    {/*
      You can add more <Etherspot*Transaction />
      components here, and they will all be executed
      together and at the same time (i.e. as part of
      this batch).
    */}
  </EtherspotBatch>
</EtherspotBatches>
```

## :tada: Congratulations!

And that is how we use the `<EtherspotTokenTransferTransaction />` component. Transaction Kit has simplified the whole process of sending tokens to another bblockchain account.

Be sure that the the token address is the correct address for the blockchain you are working on.&#x20;


# Introduction

BUIDLer is a react component that allows plug-and-play integration with the Etherspot SDK, allowing dApps and developers to easily leverage the SDK in a highly customisable fashion.&#x20;

<figure><img src="/files/LjX62aUgLL9NfdC3u1sw" alt=""><figcaption></figcaption></figure>

## In a nutshell

The Etherspot BUIDLER React component allows anyone to implement transfers, contract interactions, swaps, crosschain bridging and more into their own dApp with just a few lines of code.

The BUIDLER component takes care of the technical requirements behind the scenes to provide a great user experience to your users.

## Everything is a "block"

One of the most important concepts to understand is that every **action** that a user can perform is represented as a **block**. Each block can be performed as a batch transaction (where several actions are executed as one transaction) or in a sequence (where each transaction happens one after another).

We've included several blocks that help facilitate actions out the box, and we've created a guide on how to create your own block.

## Take it for a spin, now

Head over to <https://buidler.etherspot.io> to see what you can do before you start the [Installation](/buidler-react-component/installation).

Devs can test on mainnet using Gnosis Chain, and adding funds to their wallet with [this faucet.](http://www.gnosisfaucet.com/)


# Installation

To install the React BUIDLER Component, you can install this in your project via NPM or Yarn:

{% tabs %}
{% tab title="NPM" %}
npm i @etherspot/react-transaction-buidler
{% endtab %}

{% tab title="Yarn" %}
yarn add @etherspot/react-transaction-buidler
{% endtab %}
{% endtabs %}

Once you have installed the package, you can then [Integrate React Component](/buidler-react-component/integrate-react-component).


# Integrate React Component

Get going with the Etherspot BUIDLER React Component

## Get started quickly

Simply copy and paste the code below:

```jsx
import {
  Etherspot,
} from "@etherspot/react-transaction-buidler";

/**
 * This is all that is needed to get started.
 * To customise this, see the possible props
 * you can pass in. the docs.
 */
function RenderEtherspot(props) {
  return <Etherspot />;
}
```

This will render the Etherspot BUIDLER React Component with default options.

### Next Steps

Once you have integrated the `<Etherspot />` component, you can find out how to:

* Use [Shared Sessions](/buidler-react-component/shared-sessions)
* Use [Cross-chain KLIMA DAO Staking](/buidler-react-component/build-your-own-block/cross-chain-klima-dao-staking)


# Shared Sessions

## Introduction

Shared session allow a user to provide a signature just once on one chain, and use the same session when accessing other chains with the same acconnt. This helps streamline  the user experience without them needing constantly provide a signature.

### Implementation

#### When using 1 BUIDLER component

This is handled automatically for you, there's nothing you need to do to enable this feature.

#### When using more than 1 BUIDLER component in your dApp

You need to import the `SessionStorage` export from the `etherspot` package, and pass this to your `<Etherspot />` component using the prop: `etherspotSessionStorage`.&#x20;

See the example below:

```jsx
import {
  SessionStorage,
} from 'etherspot';

import {
  Etherspot,
  TRANSACTION_BLOCK_TYPE,
} from "@etherspot/react-transaction-buidler";

// ...

return (
  <Etherspot
    etherspotSessionStorage={SessionStorage}
    defaultTransactionBlocks={[{ type: TRANSACTION_BLOCK_TYPE.SEND_ASSET }]}
  />
);
```


# Wallet Connectors

The Etherspot BUIDLER React Component accepts any provider / provider-like objects returned from a Wallet Connector library.

```jsx
<Etherspot
  provider={connectedProvider}
/>
```

## Wallet Connector Libraries

We've compiled a short list of libraries that return a provider that can be used with the Etherspot component.

* [Ethers](https://docs.ethers.io/v5/api/providers/)
* [Web3 Onboard](https://onboard.blocknative.com/)
* [Web3Auth](https://web3auth.io/)

Each of the services / libraries above return a provider that can be passed to the Etherspot component.


# Blocks


# Send

## Introduction

The Send block simply sends an asset from your either your key wallet or your smart wallet to another address. This is useful for sending on funds that you have just swapped, for example.

![](/files/okQgamLqbJHgyX734SEg)

The above block will send a small amount of aUSDC to the address in the "Receiver address" box.

![](/files/uYXDnM8uZDOQjKiJzJCK)

Once the user executes this block, the aUSDC will be sent to the address entered in the previous step.

### Implementation

Copy and paste the code below to get started.

```jsx
import {
  Etherspot,
  TRANSACTION_BLOCK_TYPE,
} from "@etherspot/react-transaction-buidler";

// ...

return (
  <Etherspot
    defaultTransactionBlocks={[{ type: TRANSACTION_BLOCK_TYPE.SEND_ASSET }]}
  />
);
```


# Batching Transaction

Batching allows a user to group multiple transactions together as one.

## Introduction

One of the features of Etherspot is the ability to **batch** transactions together to perforum multiple transactions together at the same time. Etherspot handles the execution of this.

Take the example below:

![](/files/A6IkpsBxAR7xnwLTppIr)

As you can see from the image above, there are three blocks being performed, which will be executed as one transaction:

* [Swap](/buidler-react-component/blocks/swaps) block
* Another [swap](/buidler-react-component/blocks/swaps) block
* [Send](/buidler-react-component/blocks/send) block

Once the user has entered their block values, they can proceed to review their blocks on the next screen before they submit the transaction:

![](/files/xigCaRajmtz0fLv4a7Xk)

Once the user presses "Execute", they blocks will be batched into one transaction and sent via the connected provider.

### Implementation

The batching functionality is automatically included as a core feature of the Etherspot BUIDLER component. Clicking on the button below adds another block to the batch:

![](/files/BMAKbdm8ujKkDZTHZdfd)

You will then be given the option of which block you would like to add next:

![](/files/8zfpNvTT37Xx5LUSSAEN)


# Multicall Transaction

## Introduction

Multicall Transactions allows users to perform transactions in sequence one after another. This means that the Etherspot BUIDLER component will wait for one multicall block to finish before moving onto the next one.&#x20;

This is useful if you need to ensure that a block finishes before the next one continues.

Take the following example:

![](/files/shOHzdXOcWWYdfKbPxcb)

Here the swap block has been added to the Etherspot BUIDLER component. Clicking on the "Start multi-call with USDT" button will add another multicall block to the sequence, starting with the destination asset of the last block - in this case, USDT.

When clicking on the multi-call button, you are then given options on which block you would like to continue with:

![](/files/rktMWY8oXVw6WWbkKmby)

You can continue this indefinitley.&#x20;

### Implementation

The multicall  functionality is automatically included as a core feature of the Etherspot BUIDLER component. Clicking on the button below adds another block to the multicall.

![](/files/n5MTLdkvwxYfX0HCjCI1)

You will then be given the option of which block you would like to add next.


# Swaps

## Introduction

The Swaps block allows a user to facilitate asset swaps as part of the BUIDLER component.&#x20;

Users can use assets in their Key Wallet or Smart Wallet to swap assets.&#x20;

![](/files/p2ajJuKJI6b9MaTAgoEI)

Once a user selects their swap pair and amount, they can then choose a swap offer from the list presented.

![](/files/hzPlTw16pmVYqtOmcedj)

Once the user has chosen their offer, they are ready to make the swap.

### Implementation

Copy and paste the code below to get started.

```jsx
import {
  Etherspot,
  TRANSACTION_BLOCK_TYPE,
} from "@etherspot/react-transaction-buidler";

// ...

return (
  <Etherspot
    defaultTransactionBlocks={[{ type: TRANSACTION_BLOCK_TYPE.ASSET_SWAP }]}
  />
);
```


# Bridges

## Introduction

The Etherspot BUIDLER component comes with a built-in block to facilitate swapping assets across chains or Layer 2 chains.

Users can select a source token and amount, and a destination asset on a different chain.

![](/files/6GcP202RGCckf4loxvir)

Etherspot will take care of finding the best route and display it to the user.

![](/files/vZId5Zz2Jyl81FxiNT7i)

Once the user reviews this, they are shown a summary and they can choose whether to execute the transaction.

![](/files/2dEMJGWkYjSrkoKnrEMK)

### Implementation

Copy and paste the code below to get started.

```jsx
import {
  Etherspot,
  TRANSACTION_BLOCK_TYPE,
} from "@etherspot/react-transaction-buidler";

// ...

return (
  <Etherspot
    defaultTransactionBlocks={[{ type: TRANSACTION_BLOCK_TYPE.ASSET_BRIDGE }]}
  />
);
```


# Custom Contract Interactions

See the [Build Your Own Block](/buidler-react-component/build-your-own-block) / [Cross-chain KLIMA DAO Staking](/buidler-react-component/build-your-own-block/cross-chain-klima-dao-staking) to see how to build your own block.


# Styling

The Etherspot BUIDLER React Component can be styled to match your theme. See an example below of a theme object that can be passed to the Etherspot component:

## Example

```javascript
const theme = {
  color: {
    background: {
      main: "#221f33",
      topMenu: "#443d66",
      topMenuButton: "#ff884d",
      card: "#2b2640",
      button: "#ff884d",
      closeButton: "#ff884d",
      selectInputToggleButton: "#ff884d",
      selectInput: "#443d66",
      selectInputExpanded: "#1a1726",
      selectInputImagePlaceholder: "#443d66",
      textInput: "#1a1726",
      switchInput: "#1a1726",
      switchInputActiveTab: "#443d66",
      switchInputInactiveTab: "transparent",
      pill: "#2b2640",
      checkboxInputInactive: "#665c99",
      toDropdownColor: "#F8EFEA",
    },
    text: {
      selectInput: "#ffeee6",
      selectInputOption: "#ffeee6",
      selectInputOptionSecondary: "#ffeee6",
      searchInput: "#998ae6",
      searchInputSecondary: "#998ae6",
      outerLabel: "#998ae6",
      innerLabel: "#998ae6",
      topMenu: "#998ae6",
      main: "#ffeee6",
      topBar: "#998ae6",
      buttonSecondary: "#998ae6",
      card: "#ffeee6",
      cardTitle: "#ffeee6",
      button: "#fff",
      errorMessage: "#ff4d6a",
      textInput: "#ffeee6",
      textInputSecondary: "#ffeee6",
      switchInputActiveTab: "#ffeee6",
      switchInputInactiveTab: "#bbb8cc",
      selectInputImagePlaceholder: "#ffeee6",
      cardDisabled: "#605e5e",
      pill: "#bbb8cc",
      pillValue: "#ffeee6",
    },
  },
};
```

This object can then be passed directly to the Etherspot component:

```jsx
<Etherspot
  themeOverride={theme}
/>
```


# Build Your Own Block


# Cross-chain KLIMA DAO Staking

## Introduction

The KLIMA DAO Staking block is an example custom smart contract interaction to achieve a business specific goal, using the Etherspot BUIDLER Component.

:link: Skip straight to [#building-your-own-block](#building-your-own-block "mention")

In this case, this block allows users to stake directly into sKLIMA from any token on any blockchain. This is achieved by using the built-in functionality that Etherspot provides to fetch crosschain swap routes and execute transactions.

When selecting a new transaction, the user can select the KLIMA Staking block:

![](/files/aJLI4j7KoCvwagCoOS0C)

The user can select any asset they own on any chain, and the following process will take place:

<figure><img src="/files/nmp9iigbqkyNfcjxFgPj" alt=""><figcaption></figcaption></figure>

From the flow above, the following business logic is performed:

1. The user selects a blockchain
2. The owned assets from the selected blockchain are loaded
3. The user selects an amount of their token on their selected blockchain that they would like to use to stake into the KLIMA DAO contract
4. This information is passed to the Etherspot SDK for crosschain offers, and a list of possible crosschain swapping routes are returned
5. The business logic of the KLIMA block is programmed to select the best offer on behalf of the user
6. This crosschain swap transaction is added to the transaction batch
7. A new transaction is programmed to take the swap amount and asset and stake it into the KLIMA DAO staking contract
8. This contract staking action is added to the transaction batch
9. If the user has selected to receieve their staked KLIMA into a key wallet addess:
   1. A new transaction is programmed to send the sKLIMA to the desired address and added to the batch.
10. The batch is executed.

### Implementation

Copy and paste the code below to see the KLIMA Staking Block in action.

```jsx
import {
  Etherspot,
  TRANSACTION_BLOCK_TYPE,
} from "@etherspot/react-transaction-buidler";

// ...

return (
  <Etherspot
    defaultTransactionBlocks={[{ type: TRANSACTION_BLOCK_TYPE.KLIMA_STAKE }]}
  />
);
```

### Building your own block

Have a look at the open-source Etherspot BUIDLER Component repository here.

:link: <https://github.com/etherspot/etherspot-react-transaction-buidler>

See how the KLIMA Staking Block is built here:

:link: <https://github.com/etherspot/etherspot-react-transaction-buidler/blob/develop/src/components/TransactionBlock/KlimaStakingTransactionBlock.tsx>


# Requirements

What's required to run the Etherspot SDK.

The Etherspot SDK runs in any Javascript environment, or any platform that supports a Javascript environment. This includes platforms and technologies such as:

* Web browsers (Chrome, Firefox, Brave, Edge etc)
* Devices (React Native, Ionic etc)
* Server-side applications (Node.js, Deno etc)


# Install Etherspot SDK

You can install the Etherspot SDK from NPM.

{% hint style="warning" %}
**This is the v1 version of Etherspot. We highly recommend using** [**Etherspot Prime**](https://etherspot.fyi) **instead of this SDK, as it is not actively being developed on anymore.**
{% endhint %}

The Etherspot SDK can be installed via NPM or Yarn using the commands below:

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

```bash
npm i etherspot ethers@^5.0.8 reflect-metadata@^0.1.13 rxjs@^6.6.2
npm i ws # node.js only
```

{% endtab %}

{% tab title="YARN" %}

```bash
yarn add etherspot ethers@^5.0.8 reflect-metadata@^0.1.13 rxjs@^6.6.2
yarn add ws # node.js only
```

{% endtab %}
{% endtabs %}

Once you've completed the above, please head on over to the next section: [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), where we show you how to create accounts across our supported Ethereum chains.

:busstop: Here's some helpful links:

* :arrow\_upper\_right: View [Etherspot](https://www.npmjs.com/package/etherspot) on [npmjs.org](https://www.npmjs.com/package/etherspot)


# Bootstrap Etherspot SDK

The bare minimum to get you started.

{% hint style="info" %}
Before you continue, please make sure you've checked the [Requirements](/getting-started/requirements) and performed the steps to [Install Etherspot SDK](/getting-started/install-sdk).
{% endhint %}

As a bare minimum to use Etherspot, we recommend that you implement the following steps within your application.&#x20;

## Create an instance of the Etherspot SDK

This is where it all begins. You can check which EVM chains are supported on our [Chains, Bridges & DEXes page](/master/chains-bridges-and-dexes). Then you can take a look at [Instantiate Etherspot SDK](/getting-started/bootstrap-etherspot-sdk/instantiate-etherspot-sdk) to instantiate the SDK on one or multiple chains.

For the purposes of this guide, we're going to stick with Ethereum Mainnet.

## Create a session

Next up, we create a session with our newly instantiated Etherspot SDK. This is useful for when you would like to authenticate / validate external clients with the Etherspot SDK instance.

```typescript
import { Sdk } from 'etherspot';

const sdk: Sdk; // current sdk instance

async function main() {
  const output = await sdk.createSession();

  console.log('session object', output);
  console.log('session graphql headers', {
    ['x-auth-token']: output.token,
  });
}
```

## Get your Etherspot Ethereum address

The next step is to get your Ethereum address from your Etherspot SDK.

```typescript
import { Sdk } from 'etherspot';

const sdk: Sdk; // current sdk instance

async function main() {
  const output = await sdk.computeContractAccount();

  console.log('contract account', output);
}
```

Running the above code results in the following output:

```
{
  "address": "0x2f95595d9Bca08bA59110adF5e823c94955d82BB",
  "type": "Contract",
  "state": "UnDeployed",
  "store": "PersonalAccountRegistry",
  "createdAt": "[Date] 2021-07-10 00:10:26",
  "updatedAt": "[Date] 2021-07-10 00:10:26",
  "synchronizedAt": "[Date] 2021-07-10 00:10:24"
}
```

The output above shows the Etherspot service returning the state of your Etherspot SDK instance.

| Key       | Meaning                                                                                                   |
| --------- | --------------------------------------------------------------------------------------------------------- |
| `address` | The Ethereum address that is assigned to your SDK instance.                                               |
| `type`    | This should only be `Contract` - and signals that this account is controlled by a Smart Contract.         |
| `state`   | Is either `UnDeployed` or `Deployed`.                                                                     |
| `store`   | Where this data is being stored. If you're using the hosted version of Etherspot, you can disregard this. |

{% hint style="info" %}
Providing that you use the same private key for each SDK instance against different chains, you will always get back the same Ethereum address. This means that your Ethereum address is the same across all chains. This is by design for convenience.
{% endhint %}

You're now ready to start building something with the Etherspot SDK! Why not take a look at the use cases from the navigation menu?

:busstop: Here are some helpful links:

* Got an idea? Prototype it now on the [Etherspot Playground](/getting-started/etherspot-playground)
* Learn how to work with [Multi-chain Transactions](/use-cases/transactions)


# Instantiate Etherspot SDK

## Instantiating on all available chains

{% hint style="info" %}
Use the same private key or authentication method when instantiating an instance of the Etherspot SDK to generate the **same Ethereum address across all chains!**
{% endhint %}

Here we show you a basic example of how you could go about instantiating all the networks we support and make them available via a class.&#x20;

```typescript
import {
  Sdk as EtherspotSdk,
  NetworkNames,
} from 'etherspot';

class EtherspotService {
  instances: { [network: string]: EtherspotSdk } = {};
  
  init(privateKey: string): void {
    /**
    * You can use this space to do anything else
    * you're application may require to run.
    */ 
    
    // Mainnet
    this.instances[NetworkNames.Mainnet] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Mainnet });
      
    // Gnosis Chain (xDai)
    this.instances[NetworkNames.Xdai] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Xdai });
    
    // Binance Smart Chain
    this.instances[NetworkNames.Bsc] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Bsc });
        
    // Polygon, formerly known as Matic
    this.instances[NetworkNames.Matic] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Matic });
      
    // Fantom
    this.instances[NetworkNames.Fantom] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Fantom });
    
    // Aurora
    this.instances[NetworkNames.Aurora] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Aurora });
    
    // Avalanche
    this.instances[NetworkNames.Avalanche] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Avalanche });   
    
    // Arbitrum
    this.instances[NetworkNames.Arbitrum] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Arbitrum });  
    
    // Moonbeam
    this.instances[NetworkNames.Moonbeam] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Moonbeam }); 
      
    // Celo
    this.instances[NetworkNames.Celo] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Celo });
      
    // Fuse
    this.instances[NetworkNames.Fuse] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Fuse });
    
    // ArbitrumNova
    this.instances[NetworkNames.ArbitrumNova] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.ArbitrumNova });
      
    // Optimism
    this.instances[NetworkNames.Optimism] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Optimism });
      
    // Neon
    this.instances[NetworkNames.Neon] =
      new EtherspotSdk(privateKey, { networkName: NetworkNames.Neon });      
  }
}
```

## Instantiating on a single chain

Below is some examples of how you would instantiate an instance on the Etherspot SDK on a single chain.

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

```typescript
import { Sdk, NetworkNames, randomPrivateKey } from 'etherspot';

const privateKey = randomPrivateKey();
let sdk: Sdk

/**
* Replace `privateKey` with your own private key
* or Etherspot Authentication method.
*/
sdk = new Sdk({
  privateKey,
}, {
  networkName: 'mainnet' as NetworkNames,
});

console.info('SDK created');
```

{% endtab %}

{% tab title="Polygon" %}

```typescript
import { Sdk, NetworkNames, randomPrivateKey } from 'etherspot';

const privateKey = randomPrivateKey();
let sdk: Sdk

/**
* Replace `privateKey` with your own private key
* or Etherspot Authentication method.
*/
sdk = new Sdk({
  privateKey,
}, {
  networkName: 'matic' as NetworkNames,
});

console.info('SDK created');
```

{% endtab %}

{% tab title="xDai" %}

```typescript
import { Sdk, NetworkNames, randomPrivateKey } from 'etherspot';

const privateKey = randomPrivateKey();
let sdk: Sdk

/**
* Replace `privateKey` with your own private key
* or Etherspot Authentication method.
*/
sdk = new Sdk({
  privateKey,
}, {
  networkName: 'xdai' as NetworkNames,
});

console.info('SDK created');
```

{% endtab %}

{% tab title="Binance" %}

```typescript
import { Sdk, NetworkNames, randomPrivateKey } from 'etherspot';

const privateKey = randomPrivateKey();
let sdk: Sdk

/**
* Replace `privateKey` with your own private key
* or Etherspot Authentication method.
*/
sdk = new Sdk({
  privateKey,
}, {
  networkName: 'bsc' as NetworkNames,
});

console.info('SDK created');
```

{% endtab %}

{% tab title="Fantom" %}

```typescript
import { Sdk, NetworkNames, randomPrivateKey } from 'etherspot';

const privateKey = randomPrivateKey();
let sdk: Sdk

/**
* Replace `privateKey` with your own private key
* or Etherspot Authentication method.
*/
sdk = new Sdk({
  privateKey,
}, {
  networkName: 'fantom' as NetworkNames,
});

console.info('SDK created');
```

{% endtab %}
{% endtabs %}


# Events

Listen to events from the Etherspot SDK

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

## Getting started

The Etherspot SDK allows developers and users of their SDK instances to receive events as they happen within the Etherspot platform. These event mechanisms allow applications to react to, or, monitor the state of their application actions and perform additional functions or business logic afterwards.

Etherspot currently supports the following events:

| Event Name               | Description                                                                                      |
| ------------------------ | ------------------------------------------------------------------------------------------------ |
| AccountMemberCreated     |                                                                                                  |
| AccountMemberUpdated     |                                                                                                  |
| AccountUpdated           |                                                                                                  |
| ENSNodeCreated           |                                                                                                  |
| ENSNodeUpdated           |                                                                                                  |
| GatewayBatchCreated      |                                                                                                  |
| GatewayBatchUpdated      |                                                                                                  |
| P2PPaymentChannelCreated |                                                                                                  |
| P2PPaymentChannelUpdated |                                                                                                  |
| P2PPaymentDepositCreated |                                                                                                  |
| P2PPaymentDepositUpdated |                                                                                                  |
| PaymentHubBridgeCreated  |                                                                                                  |
| PaymentHubBridgeUpdated  |                                                                                                  |
| PaymentHubCreated        |                                                                                                  |
| PaymentHubDepositCreated |                                                                                                  |
| PaymentHubDepositUpdated |                                                                                                  |
| PaymentHubPaymentCreated |                                                                                                  |
| PaymentHubUpdated        |                                                                                                  |
| TransactionUpdated       | This event type is fired when an update occurs against a transaction made with the ETherspot SDK |

## Listen for all events

The following code below allows an application to listen for all events occurring on the Etherspot SDK.

```typescript
sdk
  .notifications$
  .subscribe(
    eventData => console.log('Event:', eventData)
  );
```


# Etherspot Block Explorer

Etherspot's POA Network Block Explorer

## Test your apps with our Etherspot POA Network

Etherspot has a built-in POA network to assist you in developing your applications quickly and with minimal effort. Etherspot also has a **built-in faucet** on the Etherspot Playground for accounts created on the Etherspot POA network which allows you to top up account addresses or P2P Deposit addresses for testing.

:arrow\_upper\_right: [**Launch Etherspot Block Explorer**](https://explorer.etherspot.dev/)

:busstop: Here are some other helpful links:

* Try the [Etherspot Playground](/getting-started/etherspot-playground)
* Top up accounts created on the Etherspot POA network with the [built-in facet](https://try.etherspot.dev/#TopUpAccount)


# Etherspot Playground

Try Etherspot right now!

## :rocket: Prototype your ideas NOW

Etherspot Playground is a live SDK browser that allows you to try all the SDK methods to see how they behave. It's entirely risk free, and you can throw it away when you're done. Here's some benefits of the Etherspot Playground:

* :rocket: Rapidly prototype ideas and changes
* :chains: Multi-chain ready (see [Supported Ethereum Chains](https://docs.etherspot.dev/master/chains-bridges-and-dexes))
* :cloud: No infrastructure to set up - connected directly to our managed Etherspot service
* :boom: Use the Etherspot Playground to debug application issues
* :wastebasket: Throwaway your Etherspot Playground instance when no longer needed
* :books: Open multiple instances of the Etherspot Playground, simulating one or more Etherspot SDK instances
* :key: Connect with Key (private key), MetaMask, WalletConnect or Torus
* :compass: Use our [Etherspot Block Explorer](/getting-started/etherspot-block-explorer) for accounts created using the Etherspot POA network
* :fuelpump: Use our [built-in faucet](https://try.etherspot.dev/#TopUpAccount) for accounts created on the Etherspot POA network

:arrow\_upper\_right: [**Launch Etherspot Playground**](https://try.etherspot.dev)


# Social Login using Etherspot SDK

Demonstrate how social login work with Etherspot SDK

{% hint style="success" %}
Before we continue, please ensure that you have had a look at [Social Logins](/master/social-logins) to better understand how it works and our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

In this article, we would take a look at how we can implement social logins using our Etherspot SDK to make use of both, the power of social login by creating a wallet with your social account sign-in and the power of Etherspot SDK to make that wallet, an Account Abstracted smart wallet

First, let us create a wallet using Web3Auth for Social Login. For this, we have to sign-up in <https://dashboard.web3auth.io/> for creating an account to create a web3Auth ClientId which is available after you are signed into the dashboard and created a project under 'Plug and Play'. Copy the ClientId shown and keep it ready before continuing.

Install Web3Auth package

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

```
npm install --save @web3auth/modal
```

{% endtab %}

{% tab title="YARN" %}

```
yarn add @web3auth/modal
```

{% endtab %}
{% endtabs %}

Initialising Web3Auth for Social Login using the above created web3Auth ClientId

```javascript
import { Web3AuthCore } from '@web3auth/core'

const web3AuthInstance = new Web3AuthCore({
  clientId: web3AuthClientId, // created in the Web3Auth Dashboard as described above
  chainConfig: {
    chainNamespace: CHAIN_NAMESPACES.EIP155,
    chainId: '0x1', // ChainID in hexadecimal
  },
  storageKey: 'local',
})
```

{% hint style="info" %}
You can view a detailed steps on how to get started with Web3Auth [here](https://web3auth.io/docs/quick-start)
{% endhint %}

Defining the Web3Auth openLogin Adapter which is reponsible for sign-in options. You can see the list of all sign-in options provided [here](https://web3auth.io/docs/custom-authentication/social-providers/).

```javascript
const openLoginAdapter = new OpenloginAdapter({
  adapterSettings: {
    network: 'mainnet',
    clientId: web3AuthClientId,
  },
  loginSettings: {
    mfaLevel: 'none',
  },
})

web3AuthInstance.configureAdapter(openLoginAdapter)

// Listen to events emitted by the Web3Auth Adapter
web3AuthInstance.on(ADAPTER_EVENTS.CONNECTED, () => {
  if (!web3AuthInstance?.provider) {
    return
  }
})

web3AuthInstance.on(ADAPTER_EVENTS.ERRORED, (error) => {
  console.log(error)
})

// Initialise the web3Auth instance after setting up the Adapter Configuration
await web3AuthInstance.init()
```

Initialise the Etherspot SDK with the provider after connecting the web3Auth with valid credentials of any of the above supported social platforms listed.&#x20;

For this Example, Let us take Google as the social platform that we are looking to sign-in

<pre class="language-javascript" data-overflow="wrap"><code class="lang-javascript">try {
<strong>    // login_hint is optional parameter which accepts any string and can be set to null
</strong><strong>    const web3authProvider = await web3Auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, { 'google', login_hint })
</strong><strong>}
</strong>catch (e) {
  console.log(`Failed to login! Reason: ${e instanceof Error &#x26;&#x26; e?.message ? e.message : 'unknown'}.`)
  return
}

if (!web3authProvider) {
  console.log(`Failed to get the provider connected`)
  return
}
// Initialising web3Auth Provider as Web3 Injectable
const web3 = new Web3(web3authProvider as any)
const web3provider = new Web3WalletProvider(web3.currentProvider as any)
// Refresh the web3 Injectable to validate the provider
await web3provider.refresh()
// Initialise the Etherspot SDK
const etherspotSdk = new Sdk(web3provider, { networkName: NetworkNames.Mainnet, env: EnvNames.MainNets, omitWalletProviderNetworkCheck: true })
await etherspotSdk.computeContractAccount()
</code></pre>


# Sponsored Transactions

{% hint style="info" %}
Sponsored transactions are the ability to pay for another user's transaction fees.
{% endhint %}

For instance, any holder of a certain amount of your token can have an amount of their gas fees paid for on transactions that interact with your smart contracts or dapp.

Etherspot offers a simple way to do this using our SDK:

1. A developer can set up an address that they wish to pay for their users transactions.
2. Set up an account with us internally to act as a paymaster.
3. Pay assets into this account to pay for transactions.
4. Integrate the Etherspot SDK into their dapp to enable sponsored transactions using the address/account created above.

To create an account with us internally please [join our Discord](http://discord.etherspot.io/) and open a ticket.

Etherspot members in the Discord will be able to assist in setting up your account and integrating the SDK in a customised way that suits your dapps needs.


# Crosschain Streaming

How to set up Crosschain Streaming using Superfluid with Etherspot

Etherspot have teamed up with Superfluid to allow Crosschain Streaming. This allows you to stream assets to another Etherspot-supported blockchain.

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

## Before we continue...

We're going to need a few things ready to go. For this example. we're going to use two testnets:

* Goerli (Ethereum testnet)
* Mumbai (Polygon tesnet)

... and we're going be using two tokens:

* ETH on Goerli: `0x0000000000000000000000000000000000000000`
* ERC-20 Test Token on Mumbai:  `0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa`

Let's set this up in our code.

```javascript
import {
  Sdk as EtherspotSdk,
  NetworkNames,
  randomPrivateKey,
} from 'etherspot';

// ...

// First, define the tokens
const fromToken = '0x0000000000000000000000000000000000000000';
const toToken = '0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa';

// Next, instantiate our SDKs for each network
const etherspotGoerliSdk = new EtherspotSdk({
  privateKey: randomPrivateKey(),
}, {
  networkName: NetworkNames.Goerli,
});

const etherspotMumbaiSdk = new EtherspotSdk({
  privateKey: randomPrivateKey(),
}, {
  networkName: NetworkNames.Mumbai,
});

// Finally, compute the contract account addresses ahead of time
// The responses will return the account details.
const goerliAccount = await etherspotGoerliSdk.computeContractAccount();
const mumbaiAccount = await etherspotMumbaiSdk.computeContractAccount();
```

Now we have two Etherspot accounts ready to go.

## Supported Chains

Not all chains are supported. We have created an SDK method that allows you to fetch the supported chains. This helps minimise wasted time testing what chains might be supported.

```javascript
import { CrossChainServiceProvider } from 'etherspot';

// Keep this for future use.
const supporteChains = await sdk.getCrossChainBridgeSupportedChains({
  serviceProvider: this.serviceProvider
});
```

{% hint style="info" %}
Be sure to check whatever chains you are working with against the list returned above!
{% endhint %}

## Supported Tokens

As with the Supported Chains above, we also provide a helper SDK method to return the supported list of tokens between two chains. This can save you alot of time and effort.

```javascript
import {
  SocketTokenDirection,
  CrossChainServiceProvider
} from 'etherspot';

const supportedTokens = await sdk.getCrossChainBridgeTokenList({
  fromChainId: 420,
  toChainId: 80001,
  direction: SocketTokenDirection.From,
  serviceProvider: CrossChainServiceProvider.LiFi,
});
```

## Create Superfluid Token Wrapper

We're now going to create a Superfluid Token Wrapper.

```javascript
import { ethers } from 'ethers';
import {
  SuperTokenFactoryContract,
  SuperTokenContract,
} from 'etherspot';

// Build the transaction to create the Superfluid
// ERC20 Super Token
const createSuperERC20Tx = await etherspotMumbaiSdk
  .createSuperERC20WrapperTransactionPayload(
    toToken
  );
  
// Add this to the Etherspot transaction batch
await etherspotMumbaiSdk.batchExecuteAccountTransaction(createSuperERC20Tx);

const txResponse = await this.toWallet.sendTransaction(
  await etherspotMumbaiSdk.encodeGatewayBatch()
);
const txReceipt = await txResponse.wait();
const factoryContract = new SuperTokenFactoryContract();
const factoryCreated = factoryContract
  .parseLogs(txReceipt.logs)
  .find(log => log && log.event === 'SuperTokenCreated');
  
const superTokenAddress = factoryCreated.args[0];
 
await sdk.clearGatewayBatch();

const superTokenContract = new SuperTokenContract(
  this.superTokenAddress
);
```

## Perform necessary transactions

In order to continue, we need to ensure that we can perform the necessary actions. The below code will ensure these are met.

```javascript
const approveReq = erc20TokenContract.encodeApprove(
  superTokenAddress,
  amountToStream // BigNumber
);

await etherspotMumbaiSdk.batchExecuteAccountTransaction(approveReq);

const upgradeReq = superTokenContract.encodeUpgrade(
  amountToStream
);

await etherspotMumbaiSdk.batchExecuteAccountTransaction(upgradeReq);
```

## Start Crosschain Streaming

We're now ready to start the Crosschain Streaming! Lets execute the final set of transactions.

```javascript
const txnData = await etherspotMumbaiSdk.createStreamTransactionPayload({
  tokenAddress: superTokenAddress,
  receiver: destinationAddress,
  amount: flowRate, // amount in wei
  skipBalanceCheck: true,
});
await etherspotMumbaiSdk.batchExecuteAccountTransaction(txnData);
```


# Token Swaps

Use Etherspot to fetch Exchange offers between pairs

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

In this example, we're going to show you how to exchange tokens using the Etherspot Exchange. The Etherspot Exchange gives the ability for your users of your dApp or service to take advantage of swapping tokens and using different tokens as needed.&#x20;

## :octagonal\_sign: Before we continue...

{% hint style="warning" %}
Whilst the Etherspot Exchange service returns exchange offers on multiple chains, the service does not facilitate swaps from one chain to another. For that, you need to use an official "bridge" service.
{% endhint %}

We're going to be using one Etherspot SDK instance here:

* A `mainnet` Etherspot SDK to receive our offers. For the purposes of this guide, we're going to assume the variable is called `mainnetEtherspotSdk`.

{% hint style="info" %}
When using a different network for the SDK like Polygon or Binance Smart Chain - token swap offers will be returned for their respective chains.
{% endhint %}

We also need to ensure that we have the [Ethers library installed](/getting-started/install-sdk) and available to use:

```typescript
import { utils as EthersUtils } from 'ethers';
```

## Supported chains and exchanges

Currently, we support following chains and exchanges.

:chains: **Mainnet**

* 1inch
* Synethetix
* Uniswap
* Sushiswap

:chains: **Polygon**, formerly known as **MATIC**:

* 1inch
* Sushiswap

:chains: **Binance Smart Chain**

* 1inch
* Sushiswap

:chains: **xDai**

* Sushiswap

## Searching for swap offers

To start a search for token swap offers, we need to call the `getExchangeOffers` method with our desired token and amount parameters as illustrated below.

```typescript
// DAI
const fromToken = {
  address: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
  decimals: 18,
}

// USDC
const toToken = {
  address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  decimals: 6,
}

// Amount requested to swap
const fromAmountEthers = EthersUtils
  .parseUnits(
    '1.5', // Amount in ethers
    fromToken.decimals
  );

// Returns an array of offers, if any.
const tokenSwapOffers = await mainnetEtherspotSdk
  .getExchangeOffers({
    fromTokenAddress: fromToken.address,
    toTokenAddress: toToken.address,
    fromAmount: fromAmountEthers
  });
```

When `getExchangeOffers` is executed, you will receive an array of 0 or more offers based on your swap request. For each item in the array, this data object is returned:

| Property        | Meaning                                                |
| --------------- | ------------------------------------------------------ |
| `exchangeRate`  | The rate that is being returned by the exchange        |
| `provider`      | Who is providing this swap offer                       |
| `receiveAmount` | The total amount due to be received                    |
| `transactions`  | An array of required transactions to execute this swap |

You can now execute the [Transactions](/use-cases/transactions) in a chosen exchange offer to perform the desired Token Swap.

## :tada: Finished!


# Transactions

How to send a receive transactions using the Etherspot SDK.

:busstop: Here are some helpful links to get you started:

* [Historical](/use-cases/transactions/historical#getting-started) Transactions
* [Sending](/use-cases/transactions/sending) Transactions


# Historical

Reading transactions using Etherspot

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

## Getting started

The Etherspot SDK makes it really easy for you to send a transaction on any of our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi). The method call is the same for each chain.

## Fetching historical transactions

Fetching transactions using the Etherspot SDK is easy. Just call the `getTransactions` method against the Etherspot SDK instance to fetch all transactions on the account. This is the same method across all chains on the Etherspot SDK.

```typescript
const transactions = await sdk.getTransactions();

console.log('Transactions:', transactions);
```

:zap: [Try this out now on Etherspot Playground](https://try.etherspot.dev/#GetTransactions).

## Fetching a single transaction

Along with fetching all transactions above, you can also simply fetch a single transaction by hash and the data associated with that transaction. This is the same method across all chains on the Etherspot SDK.

```typescript
const singleTransaction = await sdk.getTransaction({
  hash: null, // Replace null with your transaction hash
});

console.log('Transaction:', singleTransaction);
```

:zap: [Try this out now on Etherspot Playground](https://try.etherspot.dev/#GetTransaction).

## :tada: Finished!


# Sending

Batching and sending transactions using Etherspot

![Transaction Batching with Etherspot](/files/-MgH8fLPC4IBTrCOzNqZ)

{% hint style="success" %}

Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

## Getting started

The Etherspot SDK makes it really easy for you to send a transaction on any of our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi). The method call is the same for each chain.

{% hint style="danger" %}
**Do not send assets or native tokens from one chain (like xDai) to an address or contract address on another chain (like Polygon), it will not arrive and the transmitted funds will be lost. This requires the use of** [**Multi-chain Bridges**](/use-cases/multi-chain-bridges)**.**
{% endhint %}

First let's fetch our account object. The `state` object contains all the essential information for the instantiated SDK when we performed the steps at [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). You can see what else resides in.the account class [here](https://sdk.etherspot.dev/classes/account.html).

```typescript
const { account } = sdk.state;
```

## Optional: Setting up a notifications subscription

Next, set up a listener against the SDK's notification subscription method. This will allow us to receive an event when the transaction has been confirmed, or enters any other state for that matter.

```typescript
sdk
  .notifications$
  .subscribe(console.log);
```

## Adding your transaction to a batch

When using Etherspot to send transactions, we first add the transaction to a "batch". A batch can contain many transactions for a more gas-efficient operation, but in this example - we're just going to add one transaction to the batch. It will behave as if we are just sending a single transaction.

```typescript
await sdk.batchExecuteAccountTransaction({
  to: '0x0fd7508903376dab743a02743cadfdc2d92fceb8', // Destination Ethereum address
  value: 100, // This value is in wei
  data: null // Optional contract data payload
}).catch(console.error);
```

To see the full SDK reference for the `batchExecuteAccountTransaction`, click [here](https://sdk.etherspot.dev/classes/executeaccounttransactiondto.html).

Once the above method, `batchExecuteAccountTransaction` has been executed, the instruction to send 100 wer to the Ethereum address `0x0fd7508903376dab743a02743cadfdc2d92fceb8`.has been added into the batch. You can choose to continue adding more transactions to this batch.

## Estimating your batch

At this point, your batch is ready to have the gas cost estimated. This gives you, or your users, the opportunity to see how much this transaction may cost on the chain that you have instantiated the SDK on. You can read more about instantiating the Etherspot SDK on different chains here:[Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi).&#x20;

```typescript
const estimationResponse = await sdk
  .estimateGatewayBatch()
  .catch(console.error);
  
console.log('Gas estimated at:', estimationResponse);
```

If you're happy with the cost, proceed to the next and final step.

## Submitting your batch

The final step is to submit your batch, containing your one or more transactions, to the Etherspot gateway. The Etherspot gateway will queue and manage your batch, and endeavour to do everything it can to get your transaction onto your chosen blockchain.

```typescript
const submissionResponse = await sdk
  .submitGatewayBatch()
  .catch(console.error);
```

If you had previously set up a notification subscription [here](/use-cases/transactions#optional-setting-up-a-notifications-subscription), then this will fire with different events as your batch is queued, processed and eventually sent to the blockchain.

## :tada: Finished!


# Multi-chain Bridges

Learn how to work with Payment Hubs and build Multi-chain Bridges

:busstop: Here are some helpful links to get you started:

* Learn how to build an [ERC20 Bridge](/use-cases/multi-chain-bridges/erc20-bridge)
* Learn how to build a [DAI - xDai Bridge](/use-cases/multi-chain-bridges/dai-xdai) using TokenBridge
* Learn how to build an [xDai - DAI Bridge](/use-cases/multi-chain-bridges/xdai-dai) using TokenBridge
* Learn how to build a [Native Token Bridge](/use-cases/multi-chain-bridges/native-token-bridges)

:busstop: Also might be of interest:

* Learn how to build [Peer-to-Peer Payments](/use-cases/peer-to-peer-payments)


# ERC20 Bridge

Cross chain transfer of erc20 tokens

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

In this example, we're going to show you how to transfer from ERC20 token available on Ropsten Testnet to ERC20 token available on Sokol Testnet.

## :octagonal\_sign: Before we continue...

We're going to be using **four** Etherspot SDK instances here:

* A `ropsten` Etherspot SDK for our user wallet
* A `ropsten` Etherspot SDK for the Payment Hub on this network

:arrow\_upper\_right: We will use this instance to send our DAI from and ETH to pay the gas fees.

* A `sokol` Etherspot SDK for our user wallet
* A `sokol` Etherspot SDK for the Payment Hub on this network

:arrow\_lower\_right: We will use this instance to receive our xDai on the xDai chain.

:warning: Make sure you've checked out [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi) before you continue as we also show you the code to instantiate `ropsten` and `sokol` versions of the SDK. **Remember to use the same private key or authentication for both SDK instances to get the same Ethereum address on both Ropsten Testnet and Sokol Testnet.**

## Getting started

First, let's install a prerequisite NPM package we're going to need. The `erc-20-abi` package will provide us with the ERC20 token interface to interact with.

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

```bash
npm i erc-20-abi
```

{% endtab %}

{% tab title="YARN" %}

```bash
yarn erc-20-abi
```

{% endtab %}
{% endtabs %}

Next, let's retrieve the the `abi` from the `erc-20-abi` package.

```javascript
import { abi } from 'erc-20-abi';
```

We're going to use two of the four instances of the Etherspot SDK as "Payment Hubs".&#x20;

{% hint style="info" %}
Payment Hubs are nothing more than instances of the Etherspot SDK, but exist purely to hold funds for cross-chain transfer.
{% endhint %}

For this guide, we're going to transfer ETH from the `Ropsten` network to the `Sokol` network. To achieve this, we're going to send ETH from our user wallet to the `Ropsten` Payment Hub (which itself is an instance of the Etherspot SDK), and the `Sokol` Payment Hub (which, again, is another instance of the Etherspot SDK) will send the transferred amount back to the user's wallet on the `Sokol` network.

We're going to assume that we're working with the following definitions:

```typescript
/**
* Payment Hubs
* - Network: Ropsten
* - const ropstenEtherspotPaymentHub
*
* - Network: Sokol
* - const sokolEtherspotPaymentHub
*
* User Wallets
* - Network: Ropsten
* - const ropstenEtherspotUser
*
* - Network: Sokol
* - const sokolEtherspotUser
*
* ERC20 Token Address
* - Network: Ropsten
* - const ropstenTopkenAddress
* - Network: Sokol
* - const sokolTokenAddress
*/
```

## Ensure Payment Hubs are funded

For this process to work, we need to make sure that the Payment Hubs have enough liquidity in them to facilitate the bridge transfer. We're going to be working with the `p2pDepositAddress` from the Payment Hub Etherspot SDKs. We can get this address as follows:

```javascript
const { p2pDepositAddress } = ropstenEtherspotPaymentHub.state;
```

The `p2pDepositAddress` exists purely to provide liquidity for other operations. Your `address` is unaffected.

We now need to add Test ETH from the [Ropsten Faucet](https://faucet.ropsten.be/). Please follow the instructions on the [Ropsten Faucet](https://faucet.ropsten.be/) website to receive Test ETH to the `p2pDepositAddress`.

Once you have received the Test ETH and ERC20 tokens to the `p2pDepositAddress` in the `ropstenEtherspotPaymentHub` instance, we need to perform the same set of operations for the `Sokol` Payment Hub Etherspot SDK.

```javascript
const { p2pDepositAddress } = sokolEtherspotPaymentHub.state;
```

We now need to add Test ETH from the [Sokol Faucet](https://www.poa.network/for-developers/getting-tokens-for-tests/sokol-testnet-faucet). Please follow the instructions on the [Sokol Faucet](https://www.poa.network/for-developers/getting-tokens-for-tests/sokol-testnet-faucet) website to receive Test ETH to the `p2pDepositAddress`.

We also need to fund ERC20 tokens to their respective chains. Some Test ERC20 tokens can be minted from their Contract methods or you can itself create ERC20 tokens and deploy on your desired chains.

Once both `p2pDepositAddress` from `Sokol` and `Ropsten` are funded with Test ETH from their respective faucets and ERC20 tokens from minting/deploying, we're ready to move on.

## Add liquidity to the Payment Hubs

Now that our Payment Hubs are funded with Test ETH and ERC20 Tokens to their respective `p2pDepositAddress`, the next step is to update the Payment Hubs with the amount of liquidity we wish to provide from our respective `p2pDepositAddress`.

```typescript
/**
* We're going to add 1 ERC20 Token(18 decimals) of liquidity to the
* Ropsten Payment Hub which is taken from the
* p2pDepositAddress.
*/ 
await ropstenHubSdk.updatePaymentHub({
  liquidity: ethers.utils.parseEther(1), // Token amount
  token: ropstenTokenAddress // erc20 token address you wish to transfer
})
.catch(console.error);

/**
* We're going to add 1 ERC20 Token(18 decimals) of liquidity to the
* Sokol Payment Hub which is taken from the
* p2pDepositAddress.
*/ 
await sokolHubSdk.updatePaymentHub({
  liquidity: ethers.utils.parseEther(1), // Token amount
  token: sokolTokenAddress // erc20 token you wish to withdraw as
})
.catch(console.error);
```

{% hint style="info" %}
Please ensure that the `p2pDepositAddress` has received enough erc20 tokens before adding liquidity using the code above.
{% endhint %}

Once we've completed the liquidity addition operation, we're ready to move on.

## Activate the Payment Hub Bridge

In order to allow transfer from one chain to another, we need to activate the Payment Hub Bridge using the destination Payment Hub SDK instance. Here's how to achieve this:

```javascript
import { NetworkNames } from 'etherspot';

await sokolEtherspotPaymentHub
 .activatePaymentHubBridge({
   acceptedNetworkName: "ropsten" as NetworkNames,
   acceptedToken: ropstenTokenAddress,
   token: sokolTokenAddress
 })
 .catch(console.error);
```

Once the above step is completed, the destination `Sokol` Payment Hub bridged with the `Ropsten` network name and you're ready to move on to the next step.

## Exchanging with the Payment Hubs

From our `Ropsten` user wallet, we first need to transfer the amount of ETH that we want to exchange to ETH on `Sokol` to our `Ropsten` user wallet's `p2pDepositAddress`. We will do this in the normal way that we usually send [Transactions](/use-cases/transactions).

Before we continue, let's clear the `Ropsten` Etherspot SDK Transaction Batch queue. We're keeping the house clean :broom:&#x20;

```javascript
await ropstenEtherspotSdk.clearGatewayBatch();
```

Next, we are going to encode the transaction data with parameters required to transfer the erc20 tokens using the abi method.

```javascript
const erc20Contract = await ropstenHubSdk.registerContract('erc20Contract', abi, ropstenTokenAddress);
const transactionRequest = erc20Contract.encodeTransfer(
  ropstenHubSdk.state.p2pPaymentDepositAddress,
  ethers.utils.parseEther(value), // value you wish to transfer
);
```

We're going to perform a series of steps to:

1. Add the encoded transaction to the batch
2. Estimate the gas required to perform this transaction
3. Send the batch to Etherspot to be processed

```javascript
/**
* Step 1: Add the transaction (which instructs the DAI
* contract to perform a transfer to the Token Bridge
* contract address) to a clean "batch" of transactions.
*
* Note: You can batch many transactions together and
* submit them as one request for a more gas-efficient
* operation. Here, we're just adding 1 transaction to
* this batch.
*/
const batchResponse = await ropstenEtherspotSdk
  .batchExecuteAccountTransaction(transactionRequest)
  .catch(console.error);

/**
* Step 2: Estimate the gas required to perform this
* operation. This is useful for presenting to users
* and allowing them to make a final decision.
*/
const estimateResponse = await ropstenEtherspotSdk
  .estimateGatewayBatch()
  .catch(console.error);

/**
* Step 3: Finally, send this batch to Etherspot for
* processing. We'll manage the transaction, queuing,
* retries and endevour to do whatever it takes to
* get this transaction on the chosen blockchain.
*/
const submissionResponse = await ropstenEtherspotSdk
  .submitGatewayBatch()
  .catch(console.error);
```

{% hint style="info" %}
Make sure to transfer native tokens less than the available liquidity on the Payment Hubs.
{% endhint %}

Once the above batch transaction has been confirmed, we need to perform two steps:

1. Call the `updatePaymentHubDeposit` method on our users `Ropsten` Etherspot SDK with the reference to the `Ropsten` Payment Hub, and the amount we wish to make available from our `p2pDepositAddress` to the `Ropsten` Payment Hub
2. Call the `transferPaymentHubDeposit` method on our users `Ropsten` Etherspot SDK, which will instruct the Payment Hub to move the funds from one Payment Hub to the destination Payment Hub.

```javascript
const exchangeAmount = ethers.utils.parseEther(valueInEth);

await ropstenEtherspotSdk.updatePaymentHubDeposit({
    hub: ropstenEtherspotPaymentHub.state.accountAddress,
    token: ropstenTokenAddress, // token you wish to exchange from
    totalAmount: exchangeAmount
}).catch(console.error);

await ropstenEtherspotSdk.transferPaymentHubDeposit({
    hub: ropstenEtherspotPaymentHub.state.accountAddress,
    token: ropstenTokenAddress, // token you wish to exchange from
    targetToken: sokolTokenAddress, // token you wish to exchange to
    targetHub: sokolEtherspotPaymentHub.state.accountAddress,
    targetNetworkName: "sokol" as NetworkNames,
    value: exchangeAmount,
}).catch(console.error);
```

Once the above has been completed, the internal ledger operations of the Payment Hub mechanisms will move the available liquidity from the source Payment Hub on Ropsten to the destination Payment Hub on `Sokol`. We're now ready to withdraw the funds on the destination Payment Hub on `Sokol`.

## Withdraw from the destination Payment Hub

To be able to withdraw the above `exchangeAmount` from the destination Sokol Payment Hub, we need to perform a few final steps.&#x20;

{% hint style="info" %}
We're now working primarily with the `Sokol` Payment Hub Etherspot SDK and the `Sokol` User Etherspot SDK.
{% endhint %}

First, we need to instruct the Sokol User Etherspot SDK instance that we are going to make a withdrawal by calling the `updatePaymentHubDeposit` method on the `Sokol` Etherspot User's SDK instance.

```javascript
/**
* Note: Setting `totalAmount` to 0 instructs the
* PaymentHub that we want to make a withdrawal.
*/
await sokolEtherspotUser.updatePaymentHubDeposit({
  hub: ropstenEtherspotPaymentHub.state.accountAddress,
  token: sokolTokenAddress, // token address on receiver's chain(sokol)
  totalAmount: 0, // See note above.
}).catch(console.error);
```

Internally a new hash has been created, which we will later find and sign to allow the withdrawal to take place. This process allows Etherspot to make the necessary liquidity checks before allowing the withdrawal to take place.

The next step is to find the transaction hash which needs to be signed from the `Sokol` Payment Hub. We'll  first retrieve a list of uncommitted Payment Hub transaction items.

```javascript
const uncommittedPaymentChannels = await sokolEtherspotPaymentHub
  .getP2PPaymentChannels({
    uncommittedOnly: true, // Filter to return uncommitted Payment channels by the receiver
  })
  .catch(console.error);
```

We then need to find the transaction hash to be signed. For the purposes of this guide, we're going to assume that there is just one uncommitted Payment Channel returned from the `getP2PPaymentChannels` method call.

```javascript
const paymentHubChannel = uncommittedPaymentChannels.items[0];
```

Once we have this information, we're going to perform a basic validation check to check two things:

1. That the `paymentHubChannel.state` is `"Opened"`
2. That the `sokolEtherspotUser.state.accountAddress` and the `paymentHubChannel.recipient` are the same

```javascript
let paymentChannelHash = null;

if (
  paymentHubChannel.state == "Opened" &&
  sokolEtherspotUser.state.accountAddress === paymentHubChannel.recipient
) {
  paymentChannelHash = paymentHubChannel.hash;
}
```

Providing that the two above validation points are true, we can sign the Payment Channel hash and commit the Payment Channel.&#x20;

```javascript
await sokolEtherspotPaymentHub
  .signP2PPaymentChannel({
    paymentChannelHash,
  })
  .catch(console.error);
    
// `paymentChannelHash` has now been signed by the Payment Hub
```

Committing the Payment Channel with with the signed hash from the previous code example moves the `exchangeAmount` to the final destination address.

```javascript
/*
* Remember to clear your batch and keep the house clean!
*/
await sokolEtherspotUser.clearGatewayBatch();

/**
* Next, commit the Payment Channel. The 
* batchCommitP2PPaymentChannel takes an object with two
* properties:
* - paymentChannelHash: the previously signed Payment channel hash
* - deposit: 
* - - true: the exchange amount is transferred to the p2pDepositAddress.
* - - false: the exchange amount is transferred to the accountAddress
*/
await sokolEtherspotUser.batchCommitP2PPaymentChannel({
  paymentChannelHash,
  deposit: false, // See notes above
}).catch(console.error);

/**
* Next, we estimate the cost of the transaction...
*/
await sokolEtherspotUser
 .estimateGatewayBatch();

/**
* And finally we submit this to the ETherspot Gateway.
*/
await sokolEtherspotUser
  .submitGatewayBatch();
```

Once you have finished making one or more transactions against the hubs, we are going to commit the Payment Channels that was created by the sender Payment Hub. This is the last step to be completed with the Payment Hub transactions as there could be many transfers between the Etherspot User SDK and the Payment Hub. The next step will total-up the amount transferred so that just a single, minimal gas fee is paid.

To commit the Payment Channel, we need to get the hash generated for the Payment Channel that was previously created. This can be obtained by calling `getP2PPaymentChannels` on the Etherspot SDK.

Firstly, retrieve a list of uncommitted Payment Hub transaction items.

```javascript
/**
* uncommittedOnly: true - Filter to return uncommitted 
* Payment Channels.
*/
const uncommittedPaymentChannels = await ropstenEtherspotPaymentHub
  .getP2PPaymentChannels({
    uncommittedOnly: true, // See note above
  })
  .catch(console.error);
```

For the purposes of this guide, we're going to assume that there is just one uncommitted Payment Channel returned from the `getP2PPaymentChannels` method call.

```javascript
const paymentHubChannel = uncommittedPaymentChannels.items[0];
```

Once we have this information, we're going to perform a basic validation check to check two things:

1. That the `paymentHubChannel.state` is `"Signed"`
2. That the `ropstenEtherspotUser.state.accountAddress` and the `paymentHubChannel.recipient` are the same

```javascript
let paymentChannelHash = null;

if (
  paymentHubChannel.state == "Signed" &&
  ropstenEtherspotUser.state.accountAddress === paymentHubChannel.recipient
) {
  paymentChannelHash = paymentHubChannel.hash;
}
```

Providing that the two above validation points are true, we can commit the Payment Channel to receive the total amount of funds transferred from your Etherspot SDK `p2pDepositAddress`  to sender's Payment Hub `p2pDepositAddress`.

```javascript
/*
* Remember to clear your batch and keep the house clean!
*/
await ropstenEtherspotUser.clearGatewayBatch();

/**
* Next, commit the Payment Channel. The 
* batchCommitP2PPaymentChannel takes an object with two
* properties:
* - paymentChannelHash: the previously signed Payment channel hash
* - deposit: 
* - - true: the exchange amount is transferred to the p2pDepositAddress.
* - - false: the exchange amount is transferred to the accountAddress
*/
await ropstenEtherspotUser.batchCommitP2PPaymentChannel({
  paymentChannelHash,
  deposit: true, // See notes above
}).catch(console.error);

/**
* Next, we estimate the cost of the transaction...
*/
await ropstenEtherspotUser
 .estimateGatewayBatch();

/**
* And finally we submit this to the ETherspot Gateway.
*/
await ropstenEtherspotUser
  .submitGatewayBatch();
```

## :tada: Finished!


# DAI - xDai Bridge

Transfer of DAI tokens to xDai native tokens using token bridge

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

In this example, we're going to show you how to send DAI to xDai using their TokenBridge and Etherspot.&#x20;

## :octagonal\_sign: Before we continue...

We're going to be using two Etherspot SDK instances here:

* A `mainnet` version

:arrow\_upper\_right: We will use this instance to send our DAI from and ETH to pay the gas fees.

* A `xDai` version

:arrow\_lower\_right: We will use this instance to receive our xDai on the xDai chain.

:warning: Make sure you've checked out [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi) before you continue as we also show you the code to instantiate `mainnet` and `xDai` versions of the SDK. **Remember to use the same private key for both SDK instances to get the same Ethereum address on both mainnet and xDai.**

This example use case is quite simple and straight forward, as the TokenBridge is a managed service in itself, however this example is often a requirement for many bridge services and serves as a building block.

{% hint style="warning" %}
We're using `mainnet` to send assets for this example. For other networks, please ensure that you are using the correct contract addresses for that network.
{% endhint %}

{% hint style="warning" %}
Please make sure your that your `mainnet` Etherspot address is funded with DAI tokens and enough ETH to pay the gas fees required.
{% endhint %}

## :envelope: Sending DAI to TokenBridge

First, let's install a prerequisite NPM package we're going to need. The `erc-20-abi` package will provide us with the ERC20 token interface to interact with.

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

```bash
npm i erc-20-abi
```

{% endtab %}

{% tab title="YARN" %}

```bash
yarn erc-20-abi
```

{% endtab %}
{% endtabs %}

Next, let's retrieve the the `abi` from the `erc-20-abi` package.

```javascript
/**
* Note: Also make sure that your `mainnet` and `xDai`
* instances of the Etherspot SDK are available here.
*
* For the purposes of this demonstration, we're going
* to assume the following:
* 
* The mainnet Etherspot SDK:
* - const mainnetEtherspotSdk
*
* The xDai Etherspot SDK:
* - const xdaiEtherspotsdk
*/

import { abi } from 'erc-20-abi';
```

Next, let's define our essential variables. We need the DAI token contract address and the Token Bridge contract address. Remember, on different networks, the contract address is different! The contract addresses before are for `mainnet`.

```javascript
// WARNING: The following contract addresses are only for mainnet.
const daiContractAddress = "0x6b175474e89094c44da98b954eedeac495271d0f";
const tokenBridgeContractAddress = "0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016";
```

Next up, let's prepare our request to interact with the contract, and calculate the value we want to send.

```javascript
/**
* WARNING! The minimum amount that can be transferred 
* to the Token Bridge is 10 DAI. Please make sure you
* have enough DAI in your Etherspot address.
*/
const daiTransferAmount = ethers.utils.parseEther("10");

// Construct a new token interface that we can talk to...
const tokenAbiInterface = new ethers.utils.Interface(abi); 

// Then create a "transfer" transaction request to the
// Token Bridge...
const transactionRequest = tokenAbiInterface.encodeFunctionData("transfer", [tokenBridgeContractAddress, daiTransferAmount]);
```

Before we continue, let's clear the Etherspot SDK Transaction Batch queue. We're keeping the house clean :broom:&#x20;

```javascript
await mainnetEtherspotSdk.clearGatewayBatch();
```

Finally, we're going to perform a series of steps to:

1. Add the transaction to the batch
2. Estimate the gas required to perform this transaction
3. Send the batch to Etherspot to be processed

```javascript
/**
* Step 1: Add the transaction (which instructs the DAI
* contract to perform a transfer to the Token Bridge
* contract address) to a clean "batch" of transactions.
*
* Note: You can batch many transactions together and
* submit them as one request for a more gas-efficient
* operation. Here, we're just adding 1 transaction to
* this batch.
*/
const batchResponse = await mainnetEtherspotSdk
  .batchExecuteAccountTransaction({
    to: daiContractAddress,
    data: transactionRequest
  })
  .catch(console.error);

/**
* Step 2: Estimate the gas required to perform this
* operation. This is useful for presenting to users
* and allowing them to make a final decision.
*/
const estimateResponse = await mainnetEtherspotSdk
  .estimateGatewayBatch()
  .catch(console.error);

/**
* Step 3: Finally, send this batch to Etherspot for
* processing. We'll manage the transaction, queuing,
* retries and endevour to do whatever it takes to
* get this transaction on the chosen blockchain.
*/
const submissionResponse = await mainnetEtherspotSdk
  .submitGatewayBatch()
  .catch(console.error);
```

### :tada: Finished!

Once this process has completed, the TokenBridge service will send your `xDai` to the same address, but on the `xDai` chain.

Your `xDai` will arrive in the `xDai` version of your Etherspot address, which is accessible via the `xDai` version of your Etherspot SDK which was created earlier:  `xdaiEtherspotSdk`. Did you miss that bit? Check out the "Before we continue" section: [DAI - xDai Bridge](/use-cases/multi-chain-bridges/dai-xdai#before-we-continue).

:busstop: Here are some helpful links:

* Check out the [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi)
* Prototype your ideas now with the [Etherspot Playground](/getting-started/etherspot-playground)


# xDai - DAI Bridge

Transfer xDai on xDai to DAI on Mainnet using Etherspot SDK

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

In this example, we're going to show you how to send xDai to Dai using their TokenBridge and Etherspot.&#x20;

## :octagonal\_sign: Before we continue...

We're going to be using two Etherspot SDK instances here:

* A `mainnet` version

:arrow\_upper\_right: We will use this instance to send our DAI from and ETH to pay the gas fees.

* A `xDai` version

:arrow\_lower\_right: We will use this instance to receive our xDai on the xDai chain.

:warning: Make sure you've checked out [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi) before you continue as we also show you the code to instantiate `mainnet` and `xDai` versions of the SDK. **Remember to use the same private key for both SDK instances to get the same Ethereum address on both mainnet and xDai.**

This example use case is more complex than the previous guide in this series: [DAI - xDai Bridge](/use-cases/multi-chain-bridges/dai-xdai), but completes the cycle of DAI:left\_right\_arrow:xDai.&#x20;

{% hint style="warning" %}
Please make sure your that your `xDai` Etherspot address is funded with enough xDAI to pay the gas fees required.
{% endhint %}

## Sending xDai to TokenBridge

The first step in our journey to change xDai back to DAI is to send our xDai, using the xDai version of the Etherspot SDK, to the xDai TokenBridge.

Let's define our required variables:

```javascript
/**
* Note: Make sure that your `mainnet` and `xDai`
* instances of the Etherspot SDK are available here.
*
* For the purposes of this demonstration, we're going
* to assume the following:
* 
* The mainnet Etherspot SDK:
* - const mainnetEtherspotSdk
*
* The xDai Etherspot SDK:
* - const xdaiEtherspotsdk
*/

import { ethers } from 'etherspot';
const xdaiBridgeAddress = "0x7301CFA0e1756B71869E93d4e4Dca5c7d0eb0AA6";
const xdaiBridgeContract = "0x6A92e97A568f5F58590E8b1f56484e6268CdDC51";
// Visit https://blockscout.com/xdai/mainnet/address/0x6A92e97A568f5F58590E8b1f56484e6268CdDC51/contracts.
// Under the "Code" tab, scroll down to "Contract ABI" 
// and copy the code into a JSON file and import it here.
const xdaiBridgeAbi = require('xDaiBridgeAbi.json');

const daiContractAddress = "0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016";
// Visit https://etherscan.io/address/0x7e7669bdff02f2ee75b68b91fb81c2b38f9228c2#code and scroll down to Contract ABI and copy the whole code and paste it in a JSON file and import it to this variable.
const daiContractAbi = require('daiContractAbi.json');
```

Next, let's specify how much xDai we would like to send.

```javascript
// Note: TokenBridge requires a minimum of 10 xDai
let xdaiTransferAmount = ethers.utils.parseEther("10");
```

:broom: Let's ensure that we have no batches of transactions waiting in the queue to be sent. We like to keep the house clean.

```javascript
await xdaiEtherspotsdk
  .clearGatewayBatch()
  .catch(console.error);
```

Next, we're going to perform a series of steps to:

1. Add the transaction to the batch
2. Estimate the gas required to submit and execute this batch
3. Send the batch to Etherspot to be processed
4. Check to see when the transaction has been sent

```javascript
/**
* Step 1: Add the transaction to a clean
* "batch" of transactions.
*
* Note: You can batch many transactions together and
* submit them as one request for a more gas-efficient
* operation. Here, we're just adding 1 transaction to
* this batch.
*/
const batchResponse = await xdaiEtherspotsdk
  .batchExecuteAccountTransaction({
    to: xdaiBridgeAddress,
    value: xdaiTransferAmount
  })
  .catch(console.error);
  
/**
* Step 2: Estimate the gas required to perform this
* operation. This is useful for presenting to users
* and allowing them to make a final decision.
*/
const estimateResponse = await xdaiEtherspotsdk
  .estimateGatewayBatch()
  .catch(console.error);
  
/**
* Step 3: Next, send this batch to Etherspot for
* processing. We'll manage the transaction, queuing,
* retries and endevour to do whatever it takes to
* get this transaction on the chosen blockchain.
*/
const submitGatewayResponse = await xdaiEtherspotsdk
  .submitGatewayBatch()
  .catch(console.error);
  
/**
* Step 4: Let's keep checking on this batch submission
* to check the status before we move on. Keep calling
* this method below, using an Interval timer for example,
* and move on to the next step when gatewayBatchStatus.state
* is "Sent".
*/
const gatewayBatchStatus = await xdaiEtherspotsdk
  .getGatewaySubmittedBatch({
    hash: submitGatewayResponse.hash,
  })
  .catch(console.error);
```

| gatewayBatchStatus.state | meaning                                                                                       |
| ------------------------ | --------------------------------------------------------------------------------------------- |
| "Sent"                   | The transactions that existed in the batch are due to be confirmed.                           |
| "Sending"                | The transactions that existed in the batch are currently pending broadcast on the blockchain. |
| "Queued"                 | The transactions that existed in the batch are queued by Etherspot to be processed.           |

## Get TokenBridge Signature

Once `gatewayBatchStatus.state` is equal to `"Sent"`, indicating that the transactions in the batch are due to be confirmed, we'll lift the hash of the transaction into its own variable.

```javascript
const xDaiSubmissionHash = gatewayBatchStatus.transaction.hash;
```

Next, we need to construct an instance of the xDai bridge contract from the ethers library. We'll communicate with the contract to fetch the required data to continue.

```javascript
const xDaiTokenBridgeContract = await new ethers.Contract(
  xdaiBridgeContract,
  xdaiBridgeAbi, 
  new ethers.providers.JsonRpcProvider(
    "https://rpc.xdaichain.com/",
  ),
);
```

Next, we're going to perform three steps:

1. Query the contract for a corresponding message hash for xDai amount and the xDai Etherspot address
2. Use the message hash from the previous point to get a message payload from the contract
3. Check if the message payload is valid, and then get the required signature to continue.

```javascript
/**
* Step 1: Query the contract for the corresponding
* message hash
*/
const messageHash = await contract.getMessageHash(
  xdaiEtherspotsdk.state.accountAddress, // Your xDai Etherspot address
  xdaiTransferAmount.toString(),
  xDaiSubmissionHash, 
);

/**
* Step 2: Use the message hash to fetch the
* message payload itself
*/
let messagePayload = await contract.getMessage(messageHash);

/**
* Step 3: Let's do a basic check to ensure that the
* available tokens are still available to withdraw
*/
let signature = null;
if (messagePayload != "0x" && messagePayload != "0x0") {
  signature = await contract
    .getSignatures(
      ethers.utils.keccak256(messagePayload)
    );
} else {
  console.error('Please check the contract payload parameters.');
}
```

Once the transaction above gets confirmed, pass the required parameters along with the hash of the transaction made earlier to the contract methods to get the signature from token bridge.&#x20;

## Withdraw DAI from TokenBridge to Etherspot address

In this final section, we're going to initiate a move from the DAI contract address to our own Etherspot address on mainnet - it's final destination.

First, let's construct a contract interface to communicate with the DAI contract:

```javascript
// First, construct the interface...
const daiInterface = new ethers.utils.Interface(daiContractAbi); 

// Next, encode the required data to perform the withdrawal
let encodedData = await daiInterface.encodeFunctionData(
  "executeSignatures",
  [messagePayload, signature],
);
```

:broom: Let's ensure that we have no batches of transactions waiting in the queue to be sent. We like to keep the house clean.

```javascript
await xdaiEtherspotsdk
  .clearGatewayBatch()
  .catch(console.error);
```

Now, we have completed all the required prerequisites to withdraw the DAI from TokenBridge. We're going to perform a series of steps to:

1. Add the transaction to the batch
2. Estimate the gas required to submit and execute this batch
3. Send the batch to Etherspot to be processed

```javascript
/**
* Step 1: Add the transaction to a clean
* "batch" of transactions.
*
* Note: You can batch many transactions together and
* submit them as one request for a more gas-efficient
* operation. Here, we're just adding 1 transaction to
* this batch.
*/
const daiBatchResponse = await mainnetEtherspotSdk
  .batchExecuteAccountTransaction({
    to: daiContractAddress,
    data: encodedData,
  })
  .catch(console.error);

/**
* Step 2: Estimate the gas required to perform this
* operation. This is useful for presenting to users
* and allowing them to make a final decision.
*/
const daiBatchEstimation = await mainnetEtherspotSdk
  .estimateGatewayBatch()
  .catch(console.error);
  
/**
* Step 3: Next, send this batch to Etherspot for
* processing. We'll manage the transaction, queuing,
* retries and endevour to do whatever it takes to
* get this transaction on the chosen blockchain.
*/
const daiBatchTransaction = await mainnetEtherspotSdk
  .submitGatewayBatch()
  .catch(console.error);
```

### :tada: Finished!


# Native Token Bridge

Cross chain transfer of native tokens between Ropsten and Sokol.

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

In this example, we're going to show you how to transfer native tokens from Ropsten Testnet to Sokol Testnet.

## :octagonal\_sign: Before we continue...

We're going to be using **four** Etherspot SDK instances here:

* A `ropsten` Etherspot SDK for our user wallet
* A `ropsten` Etherspot SDK for the Payment Hub on this network

:arrow\_upper\_right: We will use this instance to send our DAI from and ETH to pay the gas fees.

* A `sokol` Etherspot SDK for our user wallet
* A `sokol` Etherspot SDK for the Payment Hub on this network

:arrow\_lower\_right: We will use this instance to receive our xDai on the xDai chain.

:warning: Make sure you've checked out [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi) before you continue as we also show you the code to instantiate `ropsten` and `sokol` versions of the SDK. **Remember to use the same private key or authentication for both SDK instances to get the same Ethereum address on both Ropsten Testnet and Sokol Testnet.**

## Getting started

We're going to use two of the four instances of the Etherspot SDK as "Payment Hubs".&#x20;

{% hint style="info" %}
Payment Hubs are nothing more than instances of the Etherspot SDK, but exist purely to hold funds for cross-chain transfer.
{% endhint %}

For this guide, we're going to transfer ETH from the `Ropsten` network to the `Sokol` network. To achieve this, we're going to send ETH from our user wallet to the `Ropsten` Payment Hub (which itself is an instance of the Etherspot SDK), and the `Sokol` Payment Hub (which, again, is another instance of the Etherspot SDK) will send the transferred amount back to the user's wallet on the `Sokol` network.

We're going to assume that we're working with the following definitions:

```typescript
/**
* Payment Hubs
* - Network: Ropsten
* - const ropstenEtherspotPaymentHub
*
* - Network: Sokol
* - const sokolEtherspotPaymentHub
*
* User Wallets
* - Network: Ropsten
* - const ropstenEtherspotUser
*
* - Network: Sokol
* - const sokolEtherspotUser
*/
```

## Ensure Payment Hubs are funded

For this process to work, we need to make sure that the Payment Hubs have enough liquidity in them to facilitate the bridge transfer. We're going to be working with the `p2pDepositAddress` from the Payment Hub Etherspot SDKs. We can get this address as follows:

```javascript
const { p2pDepositAddress } = ropstenEtherspotPaymentHub.state;
```

The `p2pDepositAddress` exists purely to provide liquidity for other operations. Your `address` is unaffected.

We now need to add Test ETH from the [Ropsten Faucet](https://faucet.ropsten.be/). Please follow the instructions on the [Ropsten Faucet](https://faucet.ropsten.be/) website to receive Test ETH to the `p2pDepositAddress`.

Once you have received the Test ETH to the `p2pDepositAddress` in the `ropstenEtherspotPaymentHub` instance, we need to perform the same set of operations for the `Sokol` Payment Hub Etherspot SDK.

```javascript
const { p2pDepositAddress } = sokolEtherspotPaymentHub.state;
```

We now need to add Test ETH from the [Sokol Faucet](https://www.poa.network/for-developers/getting-tokens-for-tests/sokol-testnet-faucet). Please follow the instructions on the [Sokol Faucet](https://www.poa.network/for-developers/getting-tokens-for-tests/sokol-testnet-faucet) website to receive Test ETH to the `p2pDepositAddress`.

Once both `p2pDepositAddress` from `Sokol` and `Ropsten` are funded with Test ETH from their respective faucets, we're ready to move on.

## Add liquidity to the Payment Hubs

Now that our Payment Hubs are funded with Test ETH to their respective `p2pDepositAddress`, the next step is to update the Payment Hubs with the amount of liquidity we wish to provide from our respective `p2pDepositAddress`.

```typescript
/**
* We're going to add 1 ETH of liquidity to the
* Ropsten Payment Hub which is taken from the
* p2pDepositAddress.
*/ 
await ropstenHubSdk.updatePaymentHub({
  liquidity: ethers.utils.parseEther(1), // ETH amount
})
.catch(console.error);

/**
* We're going to add 1 ETH of liquidity to the
* Sokol Payment Hub which is taken from the
* p2pDepositAddress.
*/ 
await sokolHubSdk.updatePaymentHub({
  liquidity: ethers.utils.parseEther(1), // ETH amount
})
.catch(console.error);
```

{% hint style="info" %}
Please ensure that the `p2pDepositAddress` has received enough native tokens (in this case, ETH) before adding liquidity using the code above.
{% endhint %}

Once we've completed the liquidity addition operation, we're ready to move on.

## Activate the Payment Hub Bridge

In order to allow transfer from one chain to another, we need to activate the Payment Hub Bridge using the destination Payment Hub SDK instance. Here's how to achieve this:

```javascript
import { NetworkNames } from 'etherspot';

await sokolEtherspotPaymentHub
 .activatePaymentHubBridge({
   acceptedNetworkName: "ropsten" as NetworkNames,
 })
 .catch(console.error);
```

Once the above step is completed, the destination `Sokol` Payment Hub bridged with the `Ropsten` network name and you're ready to move on to the next step.

## Exchanging with the Payment Hubs

From our `Ropsten` user wallet, we first need to transfer the amount of ETH that we want to exchange to ETH on `Sokol` to our `Ropsten` user wallet's `p2pDepositAddress`. We will do this in the normal way that we usually send [Transactions](/use-cases/transactions).

Before we continue, let's clear the `Ropsten` Etherspot SDK Transaction Batch queue. We're keeping the house clean :broom:&#x20;

```javascript
await ropstenEtherspotSdk.clearGatewayBatch();
```

We're going to perform a series of steps to:

1. Add the transaction to the batch
2. Estimate the gas required to perform this transaction
3. Send the batch to Etherspot to be processed

```javascript
/**
* Step 1: Add the transaction (which instructs the DAI
* contract to perform a transfer to the Token Bridge
* contract address) to a clean "batch" of transactions.
*
* Note: You can batch many transactions together and
* submit them as one request for a more gas-efficient
* operation. Here, we're just adding 1 transaction to
* this batch.
*/
const batchResponse = await ropstenEtherspotSdk
  .batchExecuteAccountTransaction({
    to: ropstenEtherspotSdk.state.p2pPaymentDepositAddress,  // your wallet linked p2pDepositAdrress
    ethers.utils.parseEther(value), // value that you wish to transfer.
  })
  .catch(console.error);

/**
* Step 2: Estimate the gas required to perform this
* operation. This is useful for presenting to users
* and allowing them to make a final decision.
*/
const estimateResponse = await ropstenEtherspotSdk
  .estimateGatewayBatch()
  .catch(console.error);

/**
* Step 3: Finally, send this batch to Etherspot for
* processing. We'll manage the transaction, queuing,
* retries and endevour to do whatever it takes to
* get this transaction on the chosen blockchain.
*/
const submissionResponse = await ropstenEtherspotSdk
  .submitGatewayBatch()
  .catch(console.error);
```

{% hint style="info" %}
Make sure to transfer native tokens less than the available liquidity on the Payment Hubs.
{% endhint %}

Once the above batch transaction has been confirmed, we need to perform two steps:

1. Call the `updatePaymentHubDeposit` method on our users `Ropsten` Etherspot SDK with the reference to the `Ropsten` Payment Hub, and the amount we wish to make available from our `p2pDepositAddress` to the `Ropsten` Payment Hub
2. Call the `transferPaymentHubDeposit` method on our users `Ropsten` Etherspot SDK, which will instruct the Payment Hub to move the funds from one Payment Hub to the destination Payment Hub.

```javascript
const exchangeAmount = ethers.utils.parseEther(valueInEth);

await ropstenEtherspotSdk.updatePaymentHubDeposit({
    hub: ropstenEtherspotPaymentHub.state.accountAddress,
    totalAmount: exchangeAmount
}).catch(console.error);

await ropstenEtherspotSdk.transferPaymentHubDeposit({
    hub: ropstenEtherspotPaymentHub.state.accountAddress,
    targetHub: sokolEtherspotPaymentHub.state.accountAddress,
    targetNetworkName: "sokol" as NetworkNames,
    value: exchangeAmount,
}).catch(console.error);
```

Once the above has been completed, the internal ledger operations of the Payment Hub mechanisms will move the available liquidity from the source Payment Hub on Ropsten to the destination Payment Hub on `Sokol`. We're now ready to withdraw the funds on the destination Payment Hub on `Sokol`.

## Withdraw from the destination Payment Hub

To be able to withdraw the above `exchangeAmount` from the destination Sokol Payment Hub, we need to perform a few final steps.&#x20;

{% hint style="info" %}
We're now working primarily with the `Sokol` Payment Hub Etherspot SDK and the `Sokol` User Etherspot SDK.
{% endhint %}

First, we need to instruct the Sokol User Etherspot SDK instance that we are going to make a withdrawal by calling the `updatePaymentHubDeposit` method on the `Sokol` Etherspot User's SDK instance.

```javascript
/**
* Note: Setting `totalAmount` to 0 instructs the
* PaymentHub that we want to make a withdrawal.
*/
await sokolEtherspotUser.updatePaymentHubDeposit({
  hub: ropstenEtherspotPaymentHub.state.accountAddress,
  totalAmount: 0, // See note above.
}).catch(console.error);
```

Internally a new hash has been created, which we will later find and sign to allow the withdrawal to take place. This process allows Etherspot to make the necessary liquidity checks before allowing the withdrawal to take place.

The next step is to find the transaction hash which needs to be signed from the `Sokol` Payment Hub. We'll  first retrieve a list of uncommitted Payment Hub transaction items.

```javascript
const uncommittedPaymentChannels = await sokolEtherspotPaymentHub
  .getP2PPaymentChannels({
    uncommittedOnly: true, // Filter to return uncommitted Payment channels by the receiver
  })
  .catch(console.error);
```

We then need to find the transaction hash to be signed. For the purposes of this guide, we're going to assume that there is just one uncommitted Payment Channel returned from the `getP2PPaymentChannels` method call.

```javascript
const paymentHubChannel = uncommittedPaymentChannels.items[0];
```

Once we have this information, we're going to perform a basic validation check to check two things:

1. That the `paymentHubChannel.state` is `"Opened"`
2. That the `sokolEtherspotUser.state.accountAddress` and the `paymentHubChannel.recipient` are the same

```javascript
let paymentChannelHash = null;

if (
  paymentHubChannel.state == "Opened" &&
  sokolEtherspotUser.state.accountAddress === paymentHubChannel.recipient
) {
  paymentChannelHash = paymentHubChannel.hash;
}
```

Providing that the two above validation points are true, we can sign the Payment Channel hash and commit the Payment Channel.&#x20;

```javascript
await sokolEtherspotPaymentHub
  .signP2PPaymentChannel({
    paymentChannelHash,
  })
  .catch(console.error);
    
// `paymentChannelHash` has now been signed by the Payment Hub
```

Committing the Payment Channel with with the signed hash from the previous code example moves the `exchangeAmount` to the final destination address.

```javascript
/*
* Remember to clear your batch and keep the house clean!
*/
await sokolEtherspotUser.clearGatewayBatch();

/**
* Next, commit the Payment Channel. The 
* batchCommitP2PPaymentChannel takes an object with two
* properties:
* - paymentChannelHash: the previously signed Payment channel hash
* - deposit: 
* - - true: the exchange amount is transferred to the p2pDepositAddress.
* - - false: the exchange amount is transferred to the accountAddress
*/
await sokolEtherspotUser.batchCommitP2PPaymentChannel({
  paymentChannelHash,
  deposit: false, // See notes above
}).catch(console.error);

/**
* Next, we estimate the cost of the transaction...
*/
await sokolEtherspotUser
 .estimateGatewayBatch();

/**
* And finally we submit this to the ETherspot Gateway.
*/
await sokolEtherspotUser
  .submitGatewayBatch();
```

Once you have finished making one or more transactions against the hubs, we are going to commit the Payment Channels that was created by the sender Payment Hub. This is the last step to be completed with the Payment Hub transactions as there could be many transfers between the Etherspot User SDK and the Payment Hub. The next step will total-up the amount transferred so that just a single, minimal gas fee is paid.

To commit the Payment Channel, we need to get the hash generated for the Payment Channel that was previously created. This can be obtained by calling `getP2PPaymentChannels` on the Etherspot SDK.

Firstly, retrieve a list of uncommitted Payment Hub transaction items.

```javascript
/**
* uncommittedOnly: true - Filter to return uncommitted 
* Payment Channels.
*/
const uncommittedPaymentChannels = await ropstenEtherspotPaymentHub
  .getP2PPaymentChannels({
    uncommittedOnly: true, // See note above.
  })
  .catch(console.error);
```

For the purposes of this guide, we're going to assume that there is just one uncommitted Payment Channel returned from the `getP2PPaymentChannels` method call.

```javascript
const paymentHubChannel = uncommittedPaymentChannels.items[0];
```

Once we have this information, we're going to perform a basic validation check to check two things:

1. That the `paymentHubChannel.state` is `"Signed"`
2. That the `ropstenEtherspotUser.state.accountAddress` and the `paymentHubChannel.recipient` are the same

```javascript
let paymentChannelHash = null;

if (
  paymentHubChannel.state == "Signed" &&
  ropstenEtherspotUser.state.accountAddress === paymentHubChannel.recipient
) {
  paymentChannelHash = paymentHubChannel.hash;
}
```

Providing that the two above validation points are true, we can commit the Payment Channel to receive the total amount of funds transferred from your Etherspot SDK `p2pDepositAddress`  to sender's Payment Hub `p2pDepositAddress`.

```javascript
/*
* Remember to clear your batch and keep the house clean!
*/
await ropstenEtherspotUser.clearGatewayBatch();

/**
* Next, commit the Payment Channel. The 
* batchCommitP2PPaymentChannel takes an object with two
* properties:
* - paymentChannelHash: the previously signed Payment channel hash
* - deposit: 
* - - true: the exchange amount is transferred to the p2pDepositAddress.
* - - false: the exchange amount is transferred to the accountAddress
*/
await ropstenEtherspotUser.batchCommitP2PPaymentChannel({
  paymentChannelHash,
  deposit: true, // See notes above
}).catch(console.error);

/**
* Next, we estimate the cost of the transaction...
*/
await ropstenEtherspotUser
 .estimateGatewayBatch();

/**
* And finally we submit this to the ETherspot Gateway.
*/
await ropstenEtherspotUser
  .submitGatewayBatch();
```

## :tada: Finished!


# Custom Contract Interaction

Demonstrate how to execute contract calls using Etherspot SDK

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

In this article, we are going to generically explain how to call a contract method using Etherspot SDK. For better Understanding, we will consider stake method to be called from a staking contract.&#x20;

## Before we continue...

Take the contract address and its abi which is available on the respective chain's block explorer and initialise the sdk on the chain where the contract address was found. For this demostration we will consider Klima DAO as an example which is found in Matic Chain.

```javascript
import {
  Sdk as EtherspotSdk,
  NetworkNames,
  randomPrivateKey,
} from 'etherspot';

// ...

// First, define the contract address and abi
const contractAddress = '0x4D70a031Fc76DA6a9bC0C922101A05FA95c3A227';

// For the sake of example, we are only defining the method we are going to execute
const contractAbi = [
  "function stake(uint256 value)",
]; 

// Next, instantiate our SDK on Matic as the contract address is on the same chain
const etherspotSdk = new EtherspotSdk({
  privateKey: randomPrivateKey(),
}, {
  networkName: NetworkNames.Matic,
});

// Finally, compute the contract account addresses ahead of time
// The responses will return the account details.
const maticAccount = await etherspotSdk.computeContractAccount();
```

## Create Contract Interface using Etherspot SDK

Next, we are going to call registerContract function on the Etherspot SDK to register the contract details and encode the parameters required for the contract method. You can find the required parameters inside the abi on the name of the function.

{% code overflow="wrap" %}

```javascript
const StakingContract = sdk.registerContract<{ encodeStake: (amount: BigNumberish) => TransactionRequest }>('stakingContract', contractAbi, contractAddress); // amount type is defined based on the constract function parameter type
const stakeTransactionRequest = stakingContract.encodeStake(AmountToBeStakedInWei);
```

{% endcode %}

After we get the transaction details (stakeTransactionRequest), the data is passed into Etherspot SDK in order to execute the transaction.

## Adding your transaction to a batch

When using Etherspot to send transactions, we first add the transaction to a "batch". A batch can contain many transactions for a more gas-efficient operation, but in this example - we're just going to add one transaction to the batch. It will behave as if we are just sending a single transaction.

```typescript
await etherspotSdk.batchExecuteAccountTransaction({
  to: stakeTransactionRequest.to,
  data: stakeTransactionRequest.data,
  value: stakeTransactionRequest.value,
}).catch(console.error);
```

To see the full SDK reference for the `batchExecuteAccountTransaction`, click [here](https://sdk.etherspot.dev/classes/executeaccounttransactiondto.html).

## Estimating your batch

At this point, your batch is ready to have the gas cost estimated. This gives you, or your users, the opportunity to see how much this transaction may cost on the chain that you have instantiated the SDK on. You can read more about instantiating the Etherspot SDK on different chains here:[Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi).&#x20;

```typescript
const estimationResponse = await etherspotSdk
  .estimateGatewayBatch()
  .catch(console.error);
  
console.log('Gas estimated at:', estimationResponse);
```

If you're happy with the cost, proceed to the next and final step.

## Submitting your batch

The final step is to submit your batch, containing your one or more transactions, to the Etherspot gateway. The Etherspot gateway will queue and manage your batch, and endeavour to do everything it can to get your transaction onto your chosen blockchain.

```typescript
const submissionResponse = await sdk
  .submitGatewayBatch()
  .catch(console.error);
```

If you had previously set up a notification subscription [here](/use-cases/transactions#optional-setting-up-a-notifications-subscription), then this will fire with different events as your batch is queued, processed and eventually sent to the blockchain.

## :tada: Finished!


# Multi-chain Assets

Using the multi-chain asset data available on Etherspot

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

## Getting started

Before we get started, it's important to know that Etherspot and the Etherspot SDK support the idea of "token lists", where tokens are grouped by a provider for community benefit or purpose. Token lists itself is a Uniswap initiative and can be viewed [here](https://tokenlists.org).&#x20;

Etherspot SDK currently supports the following token lists:

* `CompoundTokens` - [Compound](https://tokenlists.org/token-list?url=https://raw.githubusercontent.com/compound-finance/token-list/master/compound.tokenlist.json)
* `UniswapTokens` - [Uniswap](https://tokenlists.org/token-list?url=https://gateway.ipfs.io/ipns/tokens.uniswap.org)
* `AaveTokens` - [Aave](http://tokenlist.aave.eth.link)

The above two token lists generally represent curated and high quality tokens, and can usually be sufficient for your project needs.

Need something specific with a token list? We can work with you to make a custom token list, or use an existing one from [tokenlists.org](https://tokenlists.org) - get in touch with us (using the links under the "Get In Touch" section in the navigation menu) and we'll be happy to help out.

## Getting the native currencies

The Etherspot SDK provides a utility endpoint for you to read all the native currencies, sometimes also referred to as the "gas token", for each chain.

```typescript
  const nativeCurrencies = await sdk.getNativeCurrencies();

  console.log('Native Currencies:', nativeCurrencies);
```

:zap: [Try this out now on Etherspot Playground](https://try.etherspot.dev/?instance.env=testnets#GetNativeCurrencies)

## Getting a token list

To fetch a token list, simply call the `getTokenListTokens` method on your instantiated Etherspot SDK instance.

{% hint style="info" %}
Fetching a token list will return the default token list available on the chain or network the Etherspot SDK was instantiated with.
{% endhint %}

```typescript
const tokenList = await sdk.getTokenListTokens();

console.log('Token list:', tokenList);
```

## Getting a token list by token list name

Etherspot supports getting a token list by token list name. Simply pass the token list name into the the `name` named object parameter as shown below:

```typescript
const aaveTokenList = await sdk.getTokenListTokens({
  name: 'AaveTokens'
});

console.log('Token list for AaveTokens:', aaveTokenList);
```


# Multi-chain Gas Prices

Find out the current gas prices across multiple chains.

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

## Getting started

Fetching the gas price of a particular chain or network is performed against the Etherspot SDK instance that your application is using, and the chain or network that the instance of the Etherspot SDK was instantiated with.

## Fetching the gas price

To fetch the gas price on a particular chain or network, the following method:`getGatewayGasInfo`, should be called against your Etherspot SDK instance. For example, to fetch the gas price on `mainnet`, the `getGatewayGasInfo` method would need to be called on an Etherspot SDK instance that was instantiated with the `networkName` of `mainnet` as shown below:

```typescript
import { Sdk, NetworkNames, randomPrivateKey } from 'etherspot';

const privateKey = randomPrivateKey();
let etherspotSdkMainnetInstance: Sdk

/**
* If you want to get the gas price of another chain
* or network, simply instantiate the SDK with your
* desired `networkName`.
*/
etherspotSdkMainnetInstance = new Sdk({
  privateKey,
}, {
  networkName: 'mainnet' as NetworkNames,
});

// The following method returns the gas price
etherspotSdkMainnetInstance
  .getGatewayGasInfo();
```


# Peer-to-Peer Payments

Transfer funds from one user to another without Payment Hubs.

{% hint style="success" %}
Before we continue, please ensure that you have had a look at our [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi), followed the steps in [Install Etherspot SDK](/getting-started/install-sdk) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk). We're assuming that you have completed these steps before going forward.
{% endhint %}

In this example, we're going to show you how to transfer the funds using Peer-to-Peer Deposits

## :octagonal\_sign: Before we continue...

We're going to be using **two** Etherspot SDK instances here:

* A `ropsten` Etherspot SDK for our sender user wallet

:arrow\_upper\_right: We will use this instance to send our ETH from.

* A `ropsten` Etherspot SDK for our receiver user wallet

:arrow\_lower\_right: We will use this instance to receive our ETH on ropsten chain and ETH to pay the gas fees.

:warning: Make sure you've checked out [Supported Ethereum Chains](broken://pages/-MeAyzR2e2VKsOneDqAi) before you continue as we also show you the code to instantiate `ropsten` version of the SDK. **Remember to use different private keys or authentication for both SDK instances to get different Ethereum addresses on both Ropsten Testnet.**

## Getting started

For this guide, we're going to transfer ETH from one wallet to another wallet on the `Ropsten` network. To achieve this, we're going to send ETH from our `p2pPaymentDeposit` address linked to the user wallet to the another wallet on the `Ropsten` network.

We're going to assume that we're working with the following definitions:

```typescript
/**
* User Wallets
* - Network: Ropsten
* - const senderEtherspotUser
*
* - Network: Ropsten
* - const receiverEtherspotUser
*/
```

## Ensure Payment Deposit Address is funded

For this process to work, we need to make sure that the Payment Deposit have enough liquidity in them to facilitate the transfer to another wallet. We're going to be working with the `p2pDepositAddress` from our user wallet Etherspot SDKs. We can get this address as follows:

```javascript
const { p2pDepositAddress } = senderEtherspotUser.state;
```

The `p2pDepositAddress` exists purely to provide liquidity for other operations. Your `address` is unaffected.

We now need to add Test ETH from the [Ropsten Faucet](https://faucet.ropsten.be/). Please follow the instructions on the [Ropsten Faucet](https://faucet.ropsten.be/) website to receive Test ETH to the `p2pDepositAddress`.

Once you have received the Test ETH to the `p2pDepositAddress` in the `senderEtherspotUser` instance, we're ready to move on.

## Transfer Funds via Payment Deposit&#x20;

We need to transfer the desired amount of funds from our `p2pDepositAddress` in the `senderEtherspotUser` instance to the `p2pDepositAddress` in the `receiverEtherspotUser` instance

For this, we need to use the Etherspot SDK function `updateP2PPaymentChannel` to transfer from one Etherspot SDK to another with the following code:

```javascript
/**
* We're going to set 1 ETH as amount to be transferred.
*/
const amountToSend = ethers.utils.parseEther('1');

const output = await senderEtherspotUser.updateP2PPaymentChannel({
    recipient: receiverEtherspotUser.state.accountAddress,
    totalAmount: amountToSend, 
}).catch(console.error);

// This is the hash we will use in the next step.
console.log('Hash:', output.hash)
```

## Withdraw Funds from Payment Channel

To be able to withdraw the above `amountToSend` from the receiver Etherspot SDK, we need to perform a few final steps.&#x20;

{% hint style="info" %}
We're now working primarily with the `Ropsten` Receiver Etherspot SDK.
{% endhint %}

From the above `output` we need to get the hash to commit from the receiver SDK. This will allow us to withdraw the amount transferred. This can be done with the following:

```javascript
/*
* Remember to clear your batch and keep the house clean!
*/
await receiverEtherspotUser.clearGatewayBatch();

/**
* Next, commit the Payment Channel. The 
* batchCommitP2PPaymentChannel takes an object with two
* properties:
* - hash: the previously created Payment channel hash
* - deposit: 
* - - true: the exchange amount is transferred to the p2pDepositAddress.
* - - false: the exchange amount is transferred to the accountAddress
*/
await receiverEtherspotUser.batchCommitP2PPaymentChannel({
  hash: output.hash,
  deposit: true, // See notes above
}).catch(console.error);

/**
* Next, we estimate the cost of the transaction...
*/
await receiverEtherspotUser
 .estimateGatewayBatch();

/**
* And finally we submit this to the ETherspot Gateway.
*/
await receiverEtherspotUser
  .submitGatewayBatch();
```

{% hint style="warning" %}
Make sure that the receiver wallet has enough gas fees to pay on your p2pPaymentDepositAddress.
{% endhint %}

## :tada: Finished!


# Etherspot Architecture

<figure><img src="/files/gXeW0otz8yAwu1il0rVQ" alt=""><figcaption></figcaption></figure>


# EIP-1271

An introduction to EIP-1271

### What is EIP-1271?

EIP-1271 is an Ethereum Improvement Proposal that specifies a standard interface for contracts that can verify whether a given message or transaction is valid or not. This interface can be used to implement a kind of signature verification for smart contracts, where the contract can check if a signature is valid before executing a certain action.

To use EIP-1271 with a smart contract, you need to implement the interface defined in the proposal. The interface consists of a single function, called isValidSignature, which takes two arguments:

```solidity
function isValidSignature( bytes32 _messageHash, bytes memory _signature ) 
public view returns (bytes4);
```

The \_messageHash argument is the hash of the message or transaction that you want to verify. The \_signature argument is the signature itself, which is usually a combination of the signer's public key and some cryptographic information. The function returns a four-byte code that indicates whether the signature is valid or not.

The four-byte code is defined as follows:

* 0x00000000 if the signature is invalid.
* 0x20c13b0b if the signature is valid and was produced using the eth\_sign method.
* 0x1626ba7e if the signature is valid and was produced using the personal\_sign method.
* 0x01ffc9a7 if the signature is valid and was produced using the eth\_signTypedData method.

To implement the interface, you need to write a function that takes the \_messageHash and \_signature arguments and returns one of the four-byte codes described above. The function should use cryptographic functions to verify the signature and return the appropriate code.

Once you have implemented the interface, you can use the isValidSignature function in your smart contract to check whether a given signature is valid or not. For example, you could use it to verify that a user has signed a message before allowing them to perform a certain action in your contract.

Overall, EIP-1271 provides a standard way for smart contracts to verify signatures and ensure that only authorized parties can perform certain actions. By implementing the interface, you can add an extra layer of security to your smart contract and prevent unauthorized access or malicious behavior.

### Why is EIP-1271 important for the future of Ethereum?

Smart contracts cannot directly sign messages, so EIP-1271 serves as a guide to implement isValidSignature(hash, signature) on the signing contract that can be called to validate a signature.&#x20;

With the rise of smart contract wallets and DAOs controlled by multi-sigs these parties require the means to use signed messages to demonstrate the right to move assets, vote, or for other purposes. EIP-1271 is, additionally, the foundation for account abstraction which enables the evolution of the Ethereum ecosystem.

### What kind of dApps is EIP-1271 important for?

Any dApp which would like to implement AA features that simplify UX and boost its capabilities should implement EIP-1271.

### How do I implement EIP-1271 on my smart contract?

You can use our npm package that makes it easy for dapps to add support for EIP 1271.&#x20;

`npm install @etherspot/eip1271-verification-util`\
\
You can also take a look at example code [in this repo.](https://github.com/etherspot/eip1271-verification-util/)


# Etherspot/Pillar Audit

{% file src="/files/KgN5Uy2j0vPVT3qsSjl5" %}
This report presents the results of our engagement with Pillar Project to review Pillar accounts, wallets, and payment network. The review was conducted over two weeks, from November 23, 2020 to Dec 4, 2020 by Shayan Eskandari and Sergii Kravchenko.
{% endfile %}


# Etherspot Brand Assets

Etherspot assets for marketing purposes

Zip file containing all files:

{% file src="/files/wgOBGCuAqr4vdgVNNEBY" %}

![](/files/ybDZdsISeCneKs8wIHD1)

## ![](/files/Kej25kRp7Amiolftb0oh)

![](/files/L9njM28HKOKsp978ygHo)

![](/files/2FMLuGcX7kubd4jJc6ug)

![](/files/UZbrDTV8gz1DrecqdP3m)

![](/files/vqy5k5LMa97RNRetvVpE)

![](/files/d671kKwpoEUU8IxZUpaM)

![](/files/wxrX2Arbf7L0aPhzLmkF)

![](/files/w0W1w0sHuB3N80EZHENK)


# Security

At Etherspot we understand the heightened importance of security within web3. We believe in the importance of correctly audited smart contracts and all of our currently used smart contracts in production have gone through an audit with Consensys. This can be read [here](https://consensys.net/diligence/audits/private/j6eeg3t1ipskpf/).

<figure><img src="/files/yumVTdk6f9ayg1hIlbLJ" alt=""><figcaption></figcaption></figure>

The scope of this audit is these contracts shown [here](https://github.com/etherspot/etherspot-contracts/).

We are consistently doing security research internally to ensure we are on top of the current meta.<br>

Another incentive we have is the bug bounties on hackerone for Pillar Project. Pillar is powered by Etherspot APIs so a lot of what is in here is in the same scope.

<figure><img src="/files/YE93p8avr68bjOXmQ6tL" alt=""><figcaption></figcaption></figure>

We also have automation tools in place that constantly monitor for potentially malicious activity on our platform.&#x20;

### Improved security with Smart Contract based wallets:

One example of a common transaction is to approve an ERC20 token using an EOA based wallet. When we approve this, the user must then revoke the approval themselves at a later opportunity, which can potentially be a security risk.&#x20;

With our wallets, only the amount that is needed is approved, and it is automatically revoked in the same trasnaction. This is one of the many examples of improved security using SC based wallets.

### Emergency kit:

To ensure assets can never get locked with any Etherspot contracts, we have emergency methods of retrieving funds for users. Users can call these methods directly via explorers.

### ERC-4337:

\
Moving towards the next stage of account abstraction we plan to continue with our tight security and get all of our new 4337 based smart contracts audited.&#x20;


