Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(evm): Added support for creating cross chain non fungible asset transfer transactions #460

Merged
merged 29 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c222ac9
feat(evm)!: Added support for creating cross chain non fungible asse …
saadahmsiddiqui Aug 15, 2024
69eec79
Added test configuration for nonFungibleTransfer class and fixed buil…
saadahmsiddiqui Aug 15, 2024
be1bcd9
Added more tests for NonFungibleAssetTransfer class
saadahmsiddiqui Aug 15, 2024
0d26bfc
Fix lint errors in `@builwithsygma/utils` package
saadahmsiddiqui Aug 15, 2024
dcd19ad
fix tests
saadahmsiddiqui Aug 15, 2024
aa4f5a4
fix example
saadahmsiddiqui Aug 15, 2024
b5ebe36
fix current example and create non fungible example
saadahmsiddiqui Aug 20, 2024
12fe86d
chore: Added example for EVM ERC721 fungible transfer
saadahmsiddiqui Aug 20, 2024
0162049
Added privateRemarks
saadahmsiddiqui Aug 21, 2024
bd78c24
Merge branch 'main' of github.com:sygmaprotocol/sygma-sdk into feat/n…
saadahmsiddiqui Aug 21, 2024
a9399e7
fix examples
saadahmsiddiqui Aug 21, 2024
6a42550
remove redundant function
saadahmsiddiqui Aug 21, 2024
c4fbbdd
removed unused import
saadahmsiddiqui Aug 21, 2024
f17fbbb
resource setters
saadahmsiddiqui Aug 21, 2024
ce438db
fix build issues
saadahmsiddiqui Aug 21, 2024
5652660
remove source setter
saadahmsiddiqui Aug 21, 2024
055a40a
change example to testnet
saadahmsiddiqui Aug 21, 2024
7ba7421
fix
saadahmsiddiqui Aug 21, 2024
b276212
Merge branch 'main' of github.com:sygmaprotocol/sygma-sdk into feat/n…
saadahmsiddiqui Aug 22, 2024
1c9042f
fixed lint and build issues
saadahmsiddiqui Aug 22, 2024
187c6f9
add deposit data test
saadahmsiddiqui Aug 22, 2024
ceb19c1
eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
saadahmsiddiqui Aug 22, 2024
4955c1e
resolved some of antons comments
saadahmsiddiqui Aug 29, 2024
d0cf116
fix lint issue
saadahmsiddiqui Aug 29, 2024
23b9add
resolved antons comment about tests
saadahmsiddiqui Aug 29, 2024
30fca96
Merge branch 'main' of github.com:sygmaprotocol/sygma-sdk into feat/n…
saadahmsiddiqui Sep 4, 2024
f87e54c
fix lint
saadahmsiddiqui Sep 4, 2024
7245ada
fix test
saadahmsiddiqui Sep 4, 2024
e91c64e
resolved comments
saadahmsiddiqui Sep 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion examples/evm-to-evm-fungible-transfer/.env.sample
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
PRIVATE_KEY=""
CRONOS_RPC_URL="CRONOS_RPC_URL_HERE"
SEPOLIA_RPC_URL="SEPOLIA_RPC_URL_HERE"
SYGMA_ENV="testnet"
13 changes: 8 additions & 5 deletions examples/evm-to-evm-fungible-transfer/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Sygma SDK ERC20 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.
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.

## Prerequisites

Expand All @@ -10,7 +10,7 @@ Before running the script, ensure that you have the following:
- 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
- [Sepolia ETH](https://www.alchemy.com/faucets/ethereum-sepolia) for gas
- An Ethereum [provider](https://www.infura.io/) (in case the hardcoded RPC within the script does not work)

## Getting started
Expand Down Expand Up @@ -63,21 +63,24 @@ To send an ERC20 example transfer run:
yarn run transfer
```

The example will use `ethers` in conjuction with the sygma-sdk to
create a transfer from `Cronos` to `Sepolia` with a test ERC20 token.
The example will use `ethers` in conjuction with the sygma-sdk to
create a transfer from `Sepolia` to `Holesky` with a test ERC20 token.

Replace the placeholder values in the `.env` file with your own Ethereum wallet private key.

**Note**

To replace default rpc Cronos and Sepolia urls use env variables:

- `SEPOLIA_RPC_URL="SEPOLIA_RPC_URL_HERE"`

## Script Functionality

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 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.
Expand Down
9 changes: 9 additions & 0 deletions examples/evm-to-evm-fungible-transfer/src/environment.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Environment } from "@buildwithsygma/core";

declare global {
namespace NodeJS {
interface ProcessEnv {
SYGMA_ENV: Environment;
}
}
}
20 changes: 11 additions & 9 deletions examples/evm-to-evm-fungible-transfer/src/transfer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { Eip1193Provider } from "@buildwithsygma/core";
import { Environment } from "@buildwithsygma/core";
import { createEvmFungibleAssetTransfer } from "@buildwithsygma/evm";
import { Eip1193Provider, getSygmaScanLink } from "@buildwithsygma/core";
import {
createFungibleAssetTransfer,
FungibleTransferParams,
} from "@buildwithsygma/evm";
import dotenv from "dotenv";
import { Wallet, providers } from "ethers";
import Web3HttpProvider from "web3-providers-http";
Expand Down Expand Up @@ -35,18 +37,18 @@ export async function erc20Transfer(): Promise<void> {
const sourceAddress = await wallet.getAddress();
const destinationAddress = await wallet.getAddress();

const params = {
const params: FungibleTransferParams = {
source: SEPOLIA_CHAIN_ID,
destination: AMOY_CHAIN_ID,
sourceNetworkProvider: web3Provider as unknown as Eip1193Provider,
resource: RESOURCE_ID,
amount: BigInt(1) * BigInt(1e18),
destinationAddress: destinationAddress,
environment: (process.env.SYGMA_ENV as Environment) || Environment.TESTNET,
sourceAddress: sourceAddress,
recipientAddress: destinationAddress,
sourceAddress,
};

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

const approvals = await transfer.getApprovalTransactions();
console.log(`Approving Tokens (${approvals.length})...`);
for (const approval of approvals) {
Expand All @@ -61,7 +63,7 @@ export async function erc20Transfer(): Promise<void> {
const response = await wallet.sendTransaction(transferTx);
await response.wait();
console.log(
`Deposited, transaction: ${getTxExplorerUrl({ txHash: response.hash, chainId: SEPOLIA_CHAIN_ID })}`
`Depositted, transaction: ${getSygmaScanLink(response.hash, process.env.SYGMA_ENV)}`
);
}

Expand Down
5 changes: 5 additions & 0 deletions examples/evm-to-evm-non-fungible-transfer/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
PRIVATE_KEY=""
CRONOS_RPC_URL="CRONOS_RPC_URL_HERE"
SEPOLIA_RPC_URL="SEPOLIA_RPC_URL_HERE"
SYGMA_ENV="testnet"
TOKEN_ID=""
88 changes: 88 additions & 0 deletions examples/evm-to-evm-non-fungible-transfer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
## Sygma SDK ERC721 Example

This is an example script that demonstrates the functionality of the SDK using the Sygma ecosystem. The script showcases an ERC721 token transfer between the same account on two different testnets using the Sygma SDK.

## Prerequisites

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

- Node.js
- Yarn (version 3.4.1 or higher)
<!-- - A development wallet funded with `ERC20LRTest` tokens from the [Sygma faucet](https://faucet-ui-stage.buildwithsygma.com/) -->
wainola marked this conversation as resolved.
Show resolved Hide resolved
- 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
- An Ethereum [provider](https://www.infura.io/) (in case the hardcoded RPC within the script does not work)

## Getting started

### 1. Clone the repository

To get started, clone this repository to your local machine with:

```bash
git clone [email protected]:sygmaprotocol/sygma-sdk.git
cd sygma-sdk/
```

### 2. Install dependencies

Install the project dependencies by running:

```bash
yarn install
```

### 3. Build the sdk

To start the example you need to build the sdk first with:

```bash
yarn build:all
```

## 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.

**DO NOT COMMIT PRIVATE KEYS WITH REAL FUNDS TO GITHUB. DOING SO COULD RESULT IN COMPLETE LOSS OF YOUR FUNDS.**

Create a `.env` file in the evm-to-evm example folder:

```bash
cd examples/evm-to-evm-non-fungible-transfer
touch .env
```

Replace between the quotation marks your exported private key:

`PRIVATE_KEY="YOUR_PRIVATE_KEY_HERE"`

To send an ERC20 example transfer run:

```bash
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 ERC721 token. -->

Replace the placeholder values in the `.env` file with your own Ethereum wallet private key.

**Note**

To replace default rpc Cronos and Sepolia urls use env variables:

- `SEPOLIA_RPC_URL="SEPOLIA_RPC_URL_HERE"`

## Script Functionality

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 ERC721 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 ERc721 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 ERc721 tokens.
- Builds the final transfer transaction and sends it using the Ethereum wallet.
37 changes: 37 additions & 0 deletions examples/evm-to-evm-non-fungible-transfer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "@buildwithsygma/evm-to-evm-non-fungible-transfer-example",
"version": "0.1.0",
"type": "module",
"description": "Sygma sdk examples",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/sygmaprotocol/sygma-sdk"
},
"keywords": [
"sygma",
"sygmaprotocol",
"buildwithsygma",
"web3",
"bridge",
"ethereum"
],
"scripts": {
"transfer": "tsx src/transfer.ts"
},
"author": "Sygmaprotocol Product Team",
"license": "LGPL-3.0-or-later",
"devDependencies": {
"dotenv": "^16.3.1",
"eslint": "8",
"ts-node": "10.9.1",
"typescript": "5.0.4"
},
"dependencies": {
"@buildwithsygma/core": "workspace:^",
"@buildwithsygma/evm": "workspace:^",
"ethers": "5.7.2",
"tsx": "^4.15.4",
"web3-providers-http": "1.10.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Environment } from "@buildwithsygma/core";

declare global {
namespace NodeJS {
interface ProcessEnv {
SYGMA_ENV: Environment;
}
}
}
74 changes: 74 additions & 0 deletions examples/evm-to-evm-non-fungible-transfer/src/transfer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {
Eip1193Provider,
Environment,
getSygmaScanLink,
} from "@buildwithsygma/core";
import {
createNonFungibleAssetTransfer,
NonFungibleTransferParams,
} from "@buildwithsygma/evm";
import dotenv from "dotenv";
import { Wallet, providers } from "ethers";
import Web3HttpProvider from "web3-providers-http";

dotenv.config();

const privateKey = process.env.PRIVATE_KEY;

if (!privateKey) {
throw new Error("Missing environment variable: PRIVATE_KEY");
}

const SEPOLIA_CHAIN_ID = 11155111;
const CRONOS_TESTNET_CHAIN_ID = 338;
const RESOURCE_ID =
"0x0000000000000000000000000000000000000000000000000000000000000200";
const SEPOLIA_RPC_URL =
process.env.SEPOLIA_RPC_URL || "https://eth-sepolia-public.unifra.io";

const explorerUrls: Record<number, string> = {
[SEPOLIA_CHAIN_ID]: "https://sepolia.etherscan.io",
};
const getTxExplorerUrl = (params: {
txHash: string;
chainId: number;
}): string => `${explorerUrls[params.chainId]}/tx/${params.txHash}`;

export async function erc721Transfer(): Promise<void> {
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();

const params: NonFungibleTransferParams = {
source: SEPOLIA_CHAIN_ID,
destination: CRONOS_TESTNET_CHAIN_ID,
sourceNetworkProvider: web3Provider as unknown as Eip1193Provider,
resource: RESOURCE_ID,
tokenId: process.env.TOKEN_ID as string,
recipientAddress: destinationAddress,
sourceAddress,
};

const transfer = await createNonFungibleAssetTransfer(params);

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 })}`
);
}

const transferTx = await transfer.getTransferTransaction();
const response = await wallet.sendTransaction(transferTx);
await response.wait();
console.log(
`Depositted, transaction: ${getSygmaScanLink(response.hash, process.env.SYGMA_ENV)}`
);
}

erc721Transfer().finally(() => {});
19 changes: 19 additions & 0 deletions examples/evm-to-evm-non-fungible-transfer/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"composite": true,
"module": "ES2022",
"allowJs": true,
"declaration": true,
"sourceMap": true,
"declarationMap": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
"esModuleInterop": true,
"downlevelIteration": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node"
},
"include": ["src"]
}
16 changes: 9 additions & 7 deletions examples/substrate-to-evm-fungible-transfer/src/transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,17 @@ const substrateTransfer = async (): Promise<void> => {
`Transaction included at blockHash ${status.asInBlock.toString()}`
);
} else if (status.isFinalized) {
const blockNumber = results.blockNumber.toNumber();
const blockNumber = results.blockNumber?.toNumber();
const extrinsicIndex = results.txIndex;

console.log(
`Transaction finalized at blockHash ${status.asFinalized.toString()}`
);
console.log(
`Explorer URL: ${getSygmaExplorerTransferUrl({ blockNumber, extrinsicIndex })}`
);
if (blockNumber && extrinsicIndex) {
console.log(
`Transaction finalized at blockHash ${status.asFinalized.toString()}`
);
console.log(
`Explorer URL: ${getSygmaExplorerTransferUrl({ blockNumber, extrinsicIndex })}`
);
}
unsub();
process.exit(0);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export type ParachainId = number;

export type HexString = `0x${string}`;

export enum RouteType {
GMP = 'gmp',
FUNGIBLE = 'fungible',
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ export function isValidSubstrateAddress(address: string): boolean {
* @returns {boolean}
*/
export function isValidEvmAddress(address: string): boolean {
return !!ethers.utils.isAddress(address);
return ethers.utils.isAddress(address);
}

/**
Expand Down
Loading