Skip to content

Commit

Permalink
Merge branch 'main' of github.com:sygmaprotocol/sygma-sdk into fix/sa…
Browse files Browse the repository at this point in the history
…me-fungible-interface-substrate-and-evm
  • Loading branch information
saadahmsiddiqui committed Nov 11, 2024
2 parents c57bd12 + 0f9af9a commit dc8a702
Show file tree
Hide file tree
Showing 10 changed files with 366 additions and 105 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18
v18.20.4
169 changes: 136 additions & 33 deletions examples/evm-to-evm-fungible-transfer/README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,52 @@
## Sygma SDK ERC20 Example
# EVM-to-EVM (Sepolia to Base Sepolia) token transfer example

This is an example script that demonstrates the functionality of the SDK using the Sygma ecosystem. The script showcases an ERC20 token transfer between the same account on two different testnets using the Sygma SDK.
In the following example, we will use the `TESTNET` environment to perform a cross-chain ERC-20 transfer with 1 testnet `USDC` tokens. The transfer will be initiated on the EVM-side via the Ethereum Sepolia testnet and received on Base Sepolia testnet.

## Prerequisites
This is an example script that demonstrates the functionality of the Sygma SDK and the wider Sygma ecosystem of relayers and bridge and handler contracts. The complete example can be found in this [repo](https://github.com/sygmaprotocol/sygma-sdk/tree/main/examples/evm-to-evm-fungible-transfer).

### Prerequisites

Before running the script, ensure that you have the following:

- Node.js
- Node.js v18
- Yarn (version 3.4.1 or higher)
- A development wallet funded with `ERC20LRTest` tokens from the [Sygma faucet](https://faucet-ui-stage.buildwithsygma.com/)
- The [exported private key](https://support.metamask.io/hc/en-us/articles/360015289632-How-to-export-an-account-s-private-key) of your development wallet
- [Sepolia ETH](https://www.alchemy.com/faucets/ethereum-sepolia) for gas
- Testnet [ETH](https://cloud.google.com/application/web3/faucet/ethereum/sepolia) for gas
- An Ethereum [provider](https://www.infura.io/) (in case the hardcoded RPC within the script does not work)
- A development wallet funded with `USDC` tokens from the [USDC Faucet](https://faucet.circle.com)

:::danger
We make use of the dotenv module to manage exported private keys with environment variables. Please note that accidentally committing a .env file containing private keys to a wallet with real funds, onto GitHub, could result in the complete loss of your funds. **Never expose your private keys.**
:::

## Getting started
### Getting started

### 1. Clone the repository
1. Clone the repository

To get started, clone this repository to your local machine with:
Clone the sygma-sdk repository into a directory of your choice, and then `cd` into the folder:

```bash
git clone git@github.com:sygmaprotocol/sygma-sdk.git
git clone https://github.com/sygmaprotocol/sygma-sdk.git
cd sygma-sdk/
```

### 2. Install dependencies
2. Install dependencies

Install the project dependencies by running:

```bash
yarn install
```

### 3. Build the sdk
3. Build the SDK

To start the example you need to build the sdk first with:
Build the SDK by running the following command:

```bash
yarn build:all
yarn build
```

## Usage
4. Usage

This example uses the `dotenv` module to manage private keys. To run the example, you will need to configure your environment variable to include your test development account's [exported private key](https://support.metamask.io/hc/en-us/articles/360015289632-How-to-export-an-account-s-private-key). A `.env.sample` is provided as a template.

Expand All @@ -55,34 +61,131 @@ touch .env

Replace between the quotation marks your exported private key:

`PRIVATE_KEY="YOUR_PRIVATE_KEY_HERE"`
```dotenv
PRIVATE_KEY="YOUR_PRIVATE_KEY_HERE"
```

To send an ERC20 example transfer run:
To send an ERC-20 example transfer from EVM to EVM, run:

```bash
cd examples/evm-to-evm-fungible-transfer
yarn run transfer
```

The example will use `ethers` in conjuction with the sygma-sdk to
create a transfer from `Sepolia` to `Holesky` with a test ERC20 token.
The example will use `ethers` in conjunction with the sygma-sdk to create a transfer from Sepolia to Base Sepolia with the `USDC` token. It will be received on Sepolia as the `USDC` token.

## Script functionality

This example script performs a cross-chain ERC-20 token transfer using the Sygma SDK. The transfer starts on one EVM chain (e.g., Sepolia) and is received on another EVM chain (e.g., BASE). Here’s how the script works:

### 1. Imports the Required Packages:

The script first imports all the necessary modules, including those from the Sygma SDK (for asset transfer) and ethers.js (for interacting with Ethereum wallets and providers).

```ts
import { getSygmaScanLink, type Eip1193Provider } from "@buildwithsygma/core";
import {
createFungibleAssetTransfer,
FungibleTransferParams,
} from "@buildwithsygma/evm";
import dotenv from "dotenv";
import { Wallet, providers } from "ethers";
import Web3HttpProvider from "web3-providers-http";
```

Constants like `SEPOLIA_CHAIN_ID`, `RESOURCE_ID`, and `BASE_SEPOLIA_CHAIN_ID` are defined based on the specific environment you are working in.

```ts
const SEPOLIA_CHAIN_ID = 11155111;
const BASE_SEPOLIA_CHAIN_ID = 84532;
const RESOURCE_ID =
"0x0000000000000000000000000000000000000000000000000000000000001200";
const SEPOLIA_RPC_URL =
process.env.SEPOLIA_RPC_URL || "https://ethereum-sepolia-rpc.publicnode.com";
```

### 2. Configures dotenv Module:

The script loads environment variables using the dotenv module. This includes sensitive information like your private key, which should be stored in a .env file for security purposes.

Replace the placeholder values in the `.env` file with your own Ethereum wallet private key.
```ts
import dotenv from "dotenv";

**Note**
dotenv.config();

To replace default rpc Cronos and Sepolia urls use env variables:
const privateKey = process.env.PRIVATE_KEY;

- `SEPOLIA_RPC_URL="SEPOLIA_RPC_URL_HERE"`
if (!privateKey) {
throw new Error("Missing environment variable: PRIVATE_KEY");
}
```

The PRIVATE_KEY environment variable is critical for signing transactions with your Ethereum wallet.

### 3. Defines the Transfer Function:

## Script Functionality
The erc20Transfer function is the main function that handles the token transfer. It initializes the provider and wallet, sets up the asset transfer, and constructs the transfer object.

```ts
export async function erc20Transfer(): Promise<void> {}
```

This example script performs the following steps:
### 4. Sets Up the Provider and Wallet:

- initializes the SDK and establishes a connection to the Ethereum provider.
- retrieves the list of supported domains and resources from the SDK configuration.
- Searches for the ERC20 token resource with the specified symbol
- Searches for the Cronos and Sepolia domains in the list of supported domains based on their chain IDs
- Constructs a transfer object that defines the details of the ERC20 token transfer
- Retrieves the fee required for the transfer from the SDK.
- Builds the necessary approval transactions for the transfer and sends them using the Ethereum wallet. The approval transactions are required to authorize the transfer of ERC20 tokens.
- Builds the final transfer transaction and sends it using the Ethereum wallet.
The script sets up a Web3 provider and creates a wallet using the provided private key. In this case, the script is interacting with the Sepolia network.

```ts
const web3Provider = new Web3HttpProvider(SEPOLIA_RPC_URL);
const ethersWeb3Provider = new providers.Web3Provider(web3Provider);
const wallet = new Wallet(privateKey ?? "", ethersWeb3Provider);
const sourceAddress = await wallet.getAddress();
const destinationAddress = await wallet.getAddress();
```

### 5. Initializes the Asset Transfer Object:

The Sygma SDK’s EVM Asset Transfer object is initialized using the TESTNET environment. This object is used to build and manage the cross-chain ERC-20 transfer. The script constructs a transfer object using the sender’s address, recipient’s address (same in this case but on a different chain), and the amount to be transferred (1 token, represented with 6 decimal places).

```ts
const params: FungibleTransferParams = {
source: SEPOLIA_CHAIN_ID,
destination: BASE_SEPOLIA_CHAIN_ID,
sourceNetworkProvider: web3Provider as unknown as Eip1193Provider,
resource: RESOURCE_ID,
amount: BigInt(1) * BigInt(1e6),
recipientAddress: destinationAddress,
sourceAddress: sourceAddress,
};

const transfer = await createFungibleAssetTransfer(params);
```

### 6. Builds and Sends Approval Transactions:

Before the actual transfer, approval transactions must be sent to authorize the transfer of ERC-20 tokens. The script iterates over the approval transactions, sends them, and logs their transaction hashes.

```ts
const approvals = await transfer.getApprovalTransactions();
for (const approval of approvals) {
const response = await wallet.sendTransaction(approval);
await response.wait();
}
```

### 7. Builds and Sends the Final Transfer Transaction:

After approval, the script builds the transfer transaction and sends it to the Ethereum network. Once the transaction is sent, it logs the transaction hash.

```ts
const transferTx = await transfer.getTransferTransaction();
const response = await wallet.sendTransaction(transferTx);
await response.wait();
```

### 9. Call the method

Call the described method above

```ts
erc20Transfer().finally(() => {});
```
9 changes: 6 additions & 3 deletions examples/evm-to-evm-fungible-transfer/src/transfer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { getSygmaScanLink, type Eip1193Provider } from "@buildwithsygma/core";
import {
Environment,
getSygmaScanLink,
type Eip1193Provider,
} from "@buildwithsygma/core";
import {
createFungibleAssetTransfer,
FungibleTransferParams,
Expand All @@ -20,8 +24,7 @@ const BASE_SEPOLIA_CHAIN_ID = 84532;
const RESOURCE_ID =
"0x0000000000000000000000000000000000000000000000000000000000001200";
const SEPOLIA_RPC_URL =
process.env.SEPOLIA_RPC_URL ||
"https://eth-sepolia.g.alchemy.com/v2/MeCKDrpxLkGOn4LMlBa3cKy1EzzOzwzG";
process.env.SEPOLIA_RPC_URL || "https://ethereum-sepolia-rpc.publicnode.com";

const explorerUrls: Record<number, string> = {
[SEPOLIA_CHAIN_ID]: "https://sepolia.etherscan.io",
Expand Down
3 changes: 2 additions & 1 deletion examples/evm-to-substrate-fungible-transfer/.env.sample
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
PRIVATE_KEY=""
SOURCE_EVM_RPC_URL="SEPOLIA_RPC_URL_HERE"
SYGMA_ENV="testnet"
SYGMA_ENV="testnet"
RECIPIENT_ADDRESS=""
Loading

0 comments on commit dc8a702

Please sign in to comment.