In this guide, we will go through the process of creating a script in Typescript for making cross-chain swaps with Stargate. Also, we will cover the LazyerZero protocol that is used under the hood of Stargate, how to interact with smart contracts, and passing CLI arguments. Our final goal is to make a cross-chain swap from Fantom to Polygon through Stargate by calling the script.
So, let’s dive in!
About Stargate and LayerZero
Stargate is an organization powered by the community, that is working towards building the initial fully composable native asset bridge, as well as the initial dApp constructed on LayerZero. The primary objective of Stargate is to enable the transfer of cross-chain liquidity as a seamless process that requires a single transaction. As stated in their whitepaper, current cross-chain bridge solutions mint you their own wrapped version of an asset on the destination chain, not the native asset itself.
Stargate on the other hand is providing liquidity pools on different chains so you receive the native token on the destination chain, not some wrapped version. Hence, you won’t be in a situation when there is not enough liquidity on DEX to unwrap your token and don’t have to pay fees for unwrap as well.
Actually, Stargate is the first dApp built on LayerZero. LayerZero is an omnichain interoperability protocol that provides easy cross-chain messaging. This messaging mechanism is used for cross-chain swaps on Stargate.
Setting up Project
Dependencies
- dontenv - for environmental variables handling
- ethers - for interaction with smart contracts
- minimist - This tiny tool will make it easier for us to handle CLI arguments, so we could set e.g. fromNetwork, toNetwork, token and amount straight from terminal when running a script.
- typechain - generating types for smart contracts
- ts-node - run Typescript
Env Variables
We will just store private key and slippage here.
Slippage is set to 5, that means 0.5% actually. It is used for calculating minAmountOut for swap.
DON'T FORGET to set private key before running script
ABIs
ABI (Application Binary Interface) - is an interface of smart contract that includes data about contract's events, functions etc. It allows us to interact with the smart contract. We'd need Router ABI and a basic ERC20 so we could send any token available through Stargate with our script!
Here are the links to the Router’s official smart contract and to the Gist with ERC20 ABI, so you can grab ABIs from here:
- StargateRouter - https://etherscan.io/address/0x8731d54E9D02c286767d56ac03e8037C07e01e98#code
- ERC20 - https://gist.github.com/nfedosenko/ed8f2f4c229fd24422e35a8c6b6c8815
Coding script
Generate types
Create providers.ts
utility
Here we will define utility functions for initializing providers for different blockchains, store router addresses and any arbitrary data needed. I’ve put data in such kind of mappings for easy fetching needed data related to blockchain. It would be useful in the main script
All of the addresses could be found here: https://stargateprotocol.gitbook.io/stargate/developers/contract-addresses/mainnet
Create tokens.ts
utility
This utility will store data about tokens(address, decimals) on different blockchains so we could use it for swaps. Currently, it only has USDC but can be extended easily. We have to remember that Stargate supports specific list of tokens and paths available for cross chain swaps. Full list of paths could be found here.
Main script
Here is our final cross chain swap script!
-
Firstly, we initialize
dotenv
so we would use environmental variables. -
Then we parse CLI arguments passed with the script: we would be able to specify
fromNetwork
,toNetwork
,token
,amount
.We calculate
amountOutMin
based on the slippage percentage specified in.env
. -
Next step is initializing providers for different chains and fetch fee data for source chain so we can set
gasPrice
correctly. -
Checking if wallet has enough balance and allowance for the Router contract. Script will throw error if it’s not enough balance and will approve needed amount if allowance is lower than needed.
-
Now we are going to quote LayerZero fee data. We need to pass it when calling a cross chain swap.
-
Finally, we are calling
swap
on the router contract, passing chainId, liquidity poolIds on each chain respectively -
Wait for confirmation and write URL to the transaction on the source chain to the terminal
Testing
Here are the logs from my terminal after running the script, works like a charm! It took about 5 mins for money to come from Fantom to Polygon.
Also, you can see that I'm passing fromNetwork, toNetwork, token and amount as CLI args
Conclusion
All in all, we've set up a perfect infrastructure for running cross-chain swaps in Typescript with a brand new blockchain technology stack!
In the next guide, I’m going to improve the script to store info about possible cross-chain paths and run swaps consequently from chain to chain.