From 0f9af9aa06950e0e282f5b6ba9d2b9f43bbae3f2 Mon Sep 17 00:00:00 2001 From: Anton Lykhoyda Date: Tue, 29 Oct 2024 16:30:48 +0100 Subject: [PATCH] chore: Examples doc updates (#555) Co-authored-by: Saad Ahmed Siddiqui --- .nvmrc | 2 +- .../evm-to-evm-fungible-transfer/README.md | 169 ++++++++++++--- .../src/transfer.ts | 9 +- .../.env.sample | 3 +- .../README.md | 200 ++++++++++++++---- .../src/environment.d.ts | 1 + .../src/transfer.ts | 6 +- .../.env.sample | 1 + .../README.md | 65 ++++-- .../src/transfer.ts | 15 +- 10 files changed, 366 insertions(+), 105 deletions(-) diff --git a/.nvmrc b/.nvmrc index 0828ab794..a2ad731bb 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v18 \ No newline at end of file +v18.20.4 \ No newline at end of file diff --git a/examples/evm-to-evm-fungible-transfer/README.md b/examples/evm-to-evm-fungible-transfer/README.md index fb66a013a..83c7d6fee 100644 --- a/examples/evm-to-evm-fungible-transfer/README.md +++ b/examples/evm-to-evm-fungible-transfer/README.md @@ -1,30 +1,36 @@ -## 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: @@ -32,15 +38,15 @@ Install the project dependencies by running: 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. @@ -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 {} +``` -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(() => {}); +``` diff --git a/examples/evm-to-evm-fungible-transfer/src/transfer.ts b/examples/evm-to-evm-fungible-transfer/src/transfer.ts index f34e6cc26..cfa0c2a05 100644 --- a/examples/evm-to-evm-fungible-transfer/src/transfer.ts +++ b/examples/evm-to-evm-fungible-transfer/src/transfer.ts @@ -1,4 +1,8 @@ -import { getSygmaScanLink, type Eip1193Provider } from "@buildwithsygma/core"; +import { + Environment, + getSygmaScanLink, + type Eip1193Provider, +} from "@buildwithsygma/core"; import { createFungibleAssetTransfer, FungibleTransferParams, @@ -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 = { [SEPOLIA_CHAIN_ID]: "https://sepolia.etherscan.io", diff --git a/examples/evm-to-substrate-fungible-transfer/.env.sample b/examples/evm-to-substrate-fungible-transfer/.env.sample index 383a13dc8..ed4e2f715 100644 --- a/examples/evm-to-substrate-fungible-transfer/.env.sample +++ b/examples/evm-to-substrate-fungible-transfer/.env.sample @@ -1,3 +1,4 @@ PRIVATE_KEY="" SOURCE_EVM_RPC_URL="SEPOLIA_RPC_URL_HERE" -SYGMA_ENV="testnet" \ No newline at end of file +SYGMA_ENV="testnet" +RECIPIENT_ADDRESS="" \ No newline at end of file diff --git a/examples/evm-to-substrate-fungible-transfer/README.md b/examples/evm-to-substrate-fungible-transfer/README.md index 5fa1c8388..df090eb9c 100644 --- a/examples/evm-to-substrate-fungible-transfer/README.md +++ b/examples/evm-to-substrate-fungible-transfer/README.md @@ -1,29 +1,35 @@ -## Sygma SDK Substrate Asset Transfer Example +# EVM to Substrate (Sepolia to Tangle) Token Transfer Example -This is an example script that demonstrates the functionality of the SDK using the Sygma ecosystem. The script showcases a EVM Asset transfer between a EVM network and an Substrate network using the Sygma SDK. +The following example demonstrates how to use the Sygma SDK to transfer ERC-20 tokens from an EVM chain (in this case, Sepolia) to a Substrate chain (Tangle) using the SDK’s functionalities and Ethereum’s ethers.js library. -## Prerequisites +In the following example, we will use the `TESTNET` environment to perform a cross-chain ERC-20 transfer with 1 Sepolia `tTNT` token. The transfer will be initiated on the EVM-side via the Sepolia Ethereum testnet and received on the Substrate-side via the Rococo-Phala testnet. + +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/pallets. The complete example can be found in this [repo](https://github.com/sygmaprotocol/sygma-sdk/tree/main/examples/evm-to-substrate-fungible-transfer#sygma-sdk-erc20-example). + +### Prerequisites Before running the script, ensure that you have the following: -- Node.js installed on your machine -- Yarn (version 3.4.1 or higher) -- A EVM development wallet funded with `SepoliaETH` tokens -- The Private key for your EVM development wallet -- An Substrate wallet to receive tokens into (the example presets an existing wallet address already) +- Node.js installed on your machine (v18.20.4) +- Yarn (version 4 or higher) +- 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 +- A Substrate wallet to receive tokens into (the example presets an existing wallet address already) +- [Sepolia ETH](https://sepoliafaucet.com/) 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 `sygUSD` tokens from the [Sygma faucet](https://faucet-ui-stage.buildwithsygma.com/) -## 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: @@ -31,55 +37,171 @@ Install the project dependencies by running: 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 sdk:build +yarn build ``` -## Usage +4. Usage + +:::danger Important Security Notice +This example uses the dotenv module to manage sensitive information like private keys. Never expose your private keys or commit them to public repositories. Doing so could lead to the loss of all your funds. Make sure you handle private keys with care and follow best practices for security. +::: -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. +This script relies on the dotenv module to securely manage your private keys via environment variables. To run the example, you need to configure the environment variables for your test development account’s exported private key. A .env.sample file is provided as a template for you to create and manage these variables. -**DO NOT COMMIT PRIVATE KEYS WITH REAL FUNDS TO GITHUB. DOING SO COULD RESULT IN COMPLETE LOSS OF YOUR FUNDS.** +### Steps to Set Up Environment Variables -Create a `.env` file in the evm-to-evm example folder: +1. Create a `.env` file in the evm-to-substrate-fungible-transfer example folder: ```bash cd examples/evm-to-substrate-fungible-transfer touch .env ``` -Replace between the quotation marks your exported private key: +2. Add your exported private key to the .env file. Replace the placeholder text with your actual private key: + +```dotenv +PRIVATE_KEY="YOUR_PRIVATE_KEY_HERE" +``` -`PRIVATE_KEY="YOUR_PRIVATE_KEY_HERE"` +### Running the Example -To send an ERC20 example transfer run: +To send an ERC-20 token transfer from an EVM chain (Sepolia) to a Substrate chain (Tangle), use the following command: ```bash +cd examples/evm-to-substrate-fungible-transfer yarn run transfer ``` -The example will use `ethers` in conjuction with the sygma-sdk to -create a transfer from `Sepolia` to `Tangle` with a test ERC20 token. +This script uses **ethers.js** in conjunction with the sygma-sdk to handle the cross-chain transfer. The example demonstrates how to transfer `tTNT` tokens from the Sepolia Ethereum testnet to the Tangle Substrate testnet, where it will be received as the same token (`tTNT`). + +### Script functionality + +The script performs the following steps: + +1. Importing Required Packages + +The first step is to import all necessary libraries, including the Sygma SDK, dotenv for managing environment variables, and ethers.js for interacting with the Ethereum blockchain. + +```ts +import type { Eip1193Provider } from "@buildwithsygma/core"; +import { createFungibleAssetTransfer } from "@buildwithsygma/evm"; +import dotenv from "dotenv"; +import { Wallet, providers } from "ethers"; +import Web3HttpProvider from "web3-providers-http"; + +dotenv.config(); +``` + +Here, `dotenv.config()` loads environment variables (such as private keys) from a .env file into process.env. + +2. Loading and Validating the Private Key + +The script fetches the **PRIVATE_KEY** from the .env file. If the private key is not found, an error is thrown to prevent the script from running without the necessary credentials. + +```ts +const privateKey = process.env.PRIVATE_KEY; + +if (!privateKey) { + throw new Error("Missing environment variable: PRIVATE_KEY"); +} +``` + +3. Setting up Constants + Key constants are defined for the Sepolia and Tangle chain IDs, the sygUSD token’s Resource ID, and the Sepolia RPC URL. The script also sets up a function to generate the transaction URL for Etherscan, enabling easy tracking of the transaction. + +```ts +const SEPOLIA_CHAIN_ID = 11155111; +const TANGLE_CHAIN_ID = 3799; +const RESOURCE_ID = + "0x0000000000000000000000000000000000000000000000000000000000002000"; +const SEPOLIA_RPC_URL = + process.env.SOURCE_EVM_RPC_URL ?? + "https://ethereum-sepolia-rpc.publicnode.com"; + +const explorerUrls: Record = { + [SEPOLIA_CHAIN_ID]: "https://sepolia.etherscan.io", +}; +const getTxExplorerUrl = (params: { + txHash: string; + chainId: number; +}): string => `${explorerUrls[params.chainId]}/tx/${params.txHash}`; +``` + +4. Defining the ERC-20 Transfer Function + +The core logic for the token transfer is encapsulated in the erc20Transfer function. This function sets up the provider and wallet using ethers.js, connects to the Sepolia network, and prepares for the cross-chain transfer. +Set up the provider, wallet, and asset transfer objects using the TESTNET environment. + +```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 recipientAddress = process.env.RECIPIENT_ADDRESS; +``` + +5. Constructing the Transfer Object + +The transfer object is created by specifying the source and destination chain IDs, the source and destination addresses, the amount to transfer (1 tTNT token), and the token’s Resource ID. + +```ts +const params = { + source: SEPOLIA_CHAIN_ID, + destination: TANGLE_CHAIN_ID, + sourceNetworkProvider: web3Provider as unknown as Eip1193Provider, + resource: RESOURCE_ID, + amount: BigInt(1) * BigInt(1e18), + recipientAddress: destinationAddress, + sourceAddress: sourceAddress, +}; +const transfer = await createFungibleAssetTransfer(params); +``` -Replace the placeholder values in the `.env` file with your own Ethereum wallet private key. +Here, the transfer object specifies the details of the cross-chain transfer, including the network provider and the token amount. +6. Getting and Sending Approval Transactions -**Note** +Before sending the transfer, the script needs to obtain and send approval transactions to allow the smart contract to move the user’s tokens. This step ensures that the tokens are authorized for transfer. -To replace default Sepolia url use env variables: -- `SOURCE_EVM_RPC_URL="EVM_RPC_URL"` -## Script Functionality +```ts +const approvals = await transfer.getApprovalTransactions(); +console.log(`Approving Tokens (${approvals.length})...`); + +for (const approval of approvals) { + const response = await wallet.sendTransaction(approval); + await response.wait(); + console.log( + `Approved, transaction: ${getTxExplorerUrl({ txHash: response.hash, chainId: SEPOLIA_CHAIN_ID })}` + ); +} +``` -This example script performs the following steps: -- 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 Sepolia and Tangle 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. +This loop iterates through each approval transaction, sending them through the Ethereum network and logging the transaction hash for tracking purposes. + +7. Sending the Transfer Transaction + +After the approvals are complete, the script constructs and sends the actual cross-chain transfer transaction. The transfer is confirmed once the transaction is finalized on the Ethereum side. + +```ts +const transferTx = await transfer.getTransferTransaction(); +const response = await wallet.sendTransaction(transferTx); +await response.wait(); +console.log( + `Deposited, transaction: ${getTxExplorerUrl({ txHash: response.hash, chainId: SEPOLIA_CHAIN_ID })}` +); +``` + +Once the transaction is confirmed, the console logs the deposit confirmation and provides the Etherscan link to track the transaction. + +8. Executing the Transfer Function + +Finally, the erc20Transfer function is executed. The .finally() method ensures that any necessary cleanup is performed once the function has completed. + +```ts +erc20Transfer().finally(() => {}); +``` diff --git a/examples/evm-to-substrate-fungible-transfer/src/environment.d.ts b/examples/evm-to-substrate-fungible-transfer/src/environment.d.ts index 3749b0e87..19c91d8b3 100644 --- a/examples/evm-to-substrate-fungible-transfer/src/environment.d.ts +++ b/examples/evm-to-substrate-fungible-transfer/src/environment.d.ts @@ -6,6 +6,7 @@ declare global { SYGMA_ENV: Environment; PRIVATE_KEY: string; SOURCE_EVM_RPC_URL: string; + RECIPIENT_ADDRESS: string; } } } diff --git a/examples/evm-to-substrate-fungible-transfer/src/transfer.ts b/examples/evm-to-substrate-fungible-transfer/src/transfer.ts index 783dd070e..f84f1c1ba 100644 --- a/examples/evm-to-substrate-fungible-transfer/src/transfer.ts +++ b/examples/evm-to-substrate-fungible-transfer/src/transfer.ts @@ -21,7 +21,7 @@ const RESOURCE_ID = "0x0000000000000000000000000000000000000000000000000000000000002000"; const SEPOLIA_RPC_URL = process.env.SOURCE_EVM_RPC_URL ?? - "https://eth-sepolia.g.alchemy.com/v2/MeCKDrpxLkGOn4LMlBa3cKy1EzzOzwzG"; + "https://ethereum-sepolia-rpc.publicnode.com"; const explorerUrls: Record = { [SEPOLIA_CHAIN_ID]: "https://sepolia.etherscan.io", @@ -36,7 +36,7 @@ export async function erc20Transfer(): Promise { const ethersWeb3Provider = new providers.Web3Provider(web3Provider); const wallet = new Wallet(privateKey ?? "", ethersWeb3Provider); const sourceAddress = await wallet.getAddress(); - const destinationAddress = "5GjowPEaFNnwbrmpPuDmBVdF2e7n3cHwk2LnUwHXsaW5KtEL"; + const recipientAddress = process.env.RECIPIENT_ADDRESS; const params: FungibleTransferParams = { source: SEPOLIA_CHAIN_ID, @@ -44,7 +44,7 @@ export async function erc20Transfer(): Promise { sourceNetworkProvider: web3Provider as unknown as Eip1193Provider, resource: RESOURCE_ID, amount: BigInt(1) * BigInt(1e18), - recipientAddress: destinationAddress, + recipientAddress, sourceAddress: sourceAddress, environment: process.env.SYGMA_ENV, }; diff --git a/examples/substrate-to-evm-fungible-transfer/.env.sample b/examples/substrate-to-evm-fungible-transfer/.env.sample index 6d9d03039..d820a0faa 100644 --- a/examples/substrate-to-evm-fungible-transfer/.env.sample +++ b/examples/substrate-to-evm-fungible-transfer/.env.sample @@ -1,3 +1,4 @@ PRIVATE_MNEMONIC="YOUR TWELVE WORD MNEMONIC HERE WITH SPACES" SOURCE_SUBSTRATE_RPC_URL="TANGLE_RPC_URL_HERE" +RECIPIENT_ADDRESS="RECIPIENT_EVM_ADDRESS" SYGMA_ENV="testnet" \ No newline at end of file diff --git a/examples/substrate-to-evm-fungible-transfer/README.md b/examples/substrate-to-evm-fungible-transfer/README.md index 44c40acbc..1499e3160 100644 --- a/examples/substrate-to-evm-fungible-transfer/README.md +++ b/examples/substrate-to-evm-fungible-transfer/README.md @@ -1,4 +1,4 @@ -## Sygma SDK Substrate Asset Transfer Example +# Sygma SDK Substrate to EVM (Tangle to Sepolia) Asset Transfer Example This is an example script that demonstrates the functionality of the SDK using the Sygma ecosystem. The script showcases a Substrate Asset transfer between a Substrate network and an EVM network using the Sygma SDK. @@ -6,9 +6,9 @@ This is an example script that demonstrates the functionality of the SDK using t Before running the script, ensure that you have the following: -- Node.js installed on your machine +- Node.js installed on your machine (v18.20.4) - Yarn (version 3.4.1 or higher) -- A Substrate development wallet funded with `PHA` tokens; **you may wish** to run the [EVM-to-Substrate example](../evm-to-substrate-fungible-transfer/) first to preload `PHA` tokens into a Substrate wallet +- A Substrate development wallet funded with TANGLE `TNT` tokens; **you may wish** to run the [EVM-to-Substrate example](https://github.com/sygmaprotocol/sygma-sdk/tree/main/examples/evm-to-substrate-fungible-transfer/) first to preload `TNT` tokens into a Substrate wallet - The 12-word mnemonic for your Substrate development wallet - An Ethereum wallet to receive tokens into (the example presets an existing wallet address already) - A Substrate provider (in case the hardcoded WSS within the script does not work) @@ -20,7 +20,7 @@ Before running the script, ensure that you have the following: To get started, clone this repository to your local machine with: ```bash -git clone git@github.com:sygmaprotocol/sygma-sdk.git +git clone https://github.com/sygmaprotocol/sygma-sdk.git cd sygma-sdk/ ``` @@ -37,50 +37,77 @@ yarn install To start the example you need to build the sdk first with: ```bash -yarn sdk:build +yarn build ``` +### Obtaining sygUSD Tokens + +The `RESOURCE_ID` represents the ID for `tTNT` tokens in the Sygma protocol. You will need `tTNT` testnet tokens to complete this transfer. If you are transferring a different asset, you may need to replace this ID with the appropriate resource ID. + +You can obtain testnet `tTNT` tokens for the Tangle testnet by visiting the [Sygma Testnet Faucet](https://docs.buildwithsygma.com/resources/environments/testnet/obtain-testnet-tokens/?ref=blog.buildwithsygma.com). + ## Usage This example uses the `dotenv` module to import the 12-word private mnemonic. To run the example, you will need to configure your environment variable to include your test development account's [12-word seed](https://support.polkadot.network/support/solutions/articles/65000169731-polkadot-extension-how-can-i-view-my-mnemonic-phrase-). A `.env.sample` is provided as a template. -**DO NOT COMMIT YOUR MENOMONIC WITH REAL FUNDS TO GITHUB. DOING SO COULD RESULT IN COMPLETE LOSS OF YOUR FUNDS.** +**DO NOT COMMIT YOUR MNEMONIC WITH REAL FUNDS TO GITHUB. DOING SO COULD RESULT IN COMPLETE LOSS OF YOUR FUNDS.** + +### Environment Variables Create a `.env` file in the substrate-to-evm example folder: ```bash -cd examples/substrate-to-evm-fungible-transfer touch .env ``` +The file should contain the following environment variables: + +- PRIVATE_MNEMONIC: The 12-word mnemonic for your Substrate wallet. +- SOURCE_SUBSTRATE_RPC_URL: The WebSocket URL of the Substrate network (Tangle in this example). +- RECIPIENT_ADDRESS: The destination EVM address that will receive the tokens (Sepolia testnet in this example). +- SYGMA_ENV: The Sygma environment you’re using, e.g., testnet. + +Here’s an example of the .env file: + +```dotenv +PRIVATE_MNEMONIC="YOUR TWELVE WORD MNEMONIC HERE" +SOURCE_SUBSTRATE_RPC_URL="wss://rpc.tangle.tools" +RECIPIENT_ADDRESS="YOUR EVM ADDRESS" +SYGMA_ENV="testnet" +``` + +### Obtaining Your 12-Word Mnemonic + +To create a Substrate wallet and obtain the 12-word mnemonic, follow this [Polkadot wallet guide](https://support.polkadot.network/support/solutions/articles/65000169731-polkadot-extension-how-can-i-view-my-mnemonic-phrase-). + Replace between the quotation marks your 12-word mnemonic: `PRIVATE_MNEMONIC="YOUR TWELVE WORD MNEMONIC HERE WITH SPACES"` +### Run the example + To send a Substrate token to an EVM chain example transfer run: ```bash yarn run transfer ``` -The example will use `@polkadot/keyring` in conjuction with the sygma-sdk to -create a transfer from `Roccoco Phala` to `Sepolia`. +The example will use `@polkadot/keyring` in conjunction with the sygma-sdk to +create a transfer from `Tangle` to `Sepolia`. Replace the placeholder values in the `.env` file with your own Substrate wallet mnemonic, and your own destination EVM address within the script. -**Note** +### Monitoring the Transfer -To replace default rpc Rhala urls use env variables: -- `RHALA_RPC_URL="RHALA_RPC_URL_HERE"` +Once the transaction is finalized, you can view the transaction details in the [Sygma Explorer](https://scan.test.buildwithsygma.com). ## Script Functionality This example script performs the following steps: -- initializes the SDK and establishes a connection to the Substrate node. -- retrieves the list of supported domains and resources from the SDK configuration. -- Searches for the Substrate asset resource with the specified ResourceId -- 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 Substrate asset transfer -- Retrieves the fee required for the transfer from the SDK. -- Builds the final transfer transaction and sends it using the Substrate account. +1. **Initializes the SDK**: It connects to the Substrate node via WebSocket and initializes the SDK. +2. **Retrieves Supported Domains and Resources**: It fetches the list of supported domains (Tangle and Sepolia in this case) and resources like `tTNT`. +3. **Constructs a Transfer Object**: A transfer object is built, specifying the token amount, the source, and destination chains (Tangle and Sepolia). +4. **Fetches Transfer Fees**: The SDK calculates the fees required for the transfer. +5. **Signs and Sends the Transaction**: The transfer transaction is signed with your Substrate account and broadcasted to the network. +6. **Monitors Transaction Status**: The script logs transaction statuses such as `InBlock` and `Finalized`. It provides a link to the [Sygma Explorer](https://scan.test.buildwithsygma.com) where the transaction can be monitored. diff --git a/examples/substrate-to-evm-fungible-transfer/src/transfer.ts b/examples/substrate-to-evm-fungible-transfer/src/transfer.ts index 1d7ef8cfe..ffd6bc916 100644 --- a/examples/substrate-to-evm-fungible-transfer/src/transfer.ts +++ b/examples/substrate-to-evm-fungible-transfer/src/transfer.ts @@ -12,16 +12,17 @@ if (!MNEMONIC) { throw new Error("Missing environment variable: PRIVATE_MNEMONIC"); } -const SEPOLIA_CHAIN_ID = 11155111; const TANGLE_CHAIN_ID = 3799; +const SEPOLIA_CHAIN_ID = 11155111; -const RESOURCE_ID_SYGMA_USD = +const RECIPIENT_ADDRESS = + process.env.RECIPIENT_ADDRESS || "0xE39bb23F17a2cf7C9a8C4918376A32036A8867db"; +const RESOURCE_ID = "0x0000000000000000000000000000000000000000000000000000000000002000"; -const recipient = "0xE39bb23F17a2cf7C9a8C4918376A32036A8867db"; +const SYGMA_EXPLORER_URL = "https://scan.test.buildwithsygma.com"; const TANGLE_RPC_URL = process.env.SOURCE_SUBSTRATE_RPC_URL ?? "wss://rpc.tangle.tools"; -const SYGMA_EXPLORER_URL = "https://scan.test.buildwithsygma.com"; const getSygmaExplorerTransferUrl = (params: { blockNumber: number; extrinsicIndex: number; @@ -41,9 +42,9 @@ const substrateTransfer = async (): Promise => { destination: SEPOLIA_CHAIN_ID, sourceNetworkProvider: api, sourceAddress: account.address, - resource: RESOURCE_ID_SYGMA_USD, + resource: RESOURCE_ID, amount: BigInt(1) * BigInt(1e18), - destinationAddress: recipient, + destinationAddress: RECIPIENT_ADDRESS, environment: process.env.SYGMA_ENV, }; @@ -72,6 +73,8 @@ const substrateTransfer = async (): Promise => { } unsub(); process.exit(0); + } else if (status.isDropped || status.isInvalid || status.isUsurped) { + console.error("Transaction failed. Status:", status.toString()); } }); };