# Crosschain Streaming

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.md) and how to [Bootstrap Etherspot SDK](/getting-started/bootstrap-etherspot-sdk.md). 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);
```


---

# Agent Instructions: Querying This Documentation

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

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

```
GET https://v1.etherspot.io/use-cases/crosschain-streaming.md?ask=<question>
```

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

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