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(js): add examples for transfer and withdrawal tx which uses paymaster #14

Merged
merged 2 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 20 additions & 14 deletions js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,26 @@ SDK can be used for development. The examples demonstrate how to:

1. Deposit ETH from Ethereum to zkSync Era.
2. Transfer ETH on zkSync Era.
3. Withdraw ETH from zkSync Era to Ethereum.
4. Deploy a smart contract using create opcode.
5. Deploy a smart contract with constructor using create opcode.
6. Deploy a smart contract with dependency using create opcode.
7. Deploy a smart contract using create2 opcode.
8. Deploy a smart contract with constructor using create2 opcode.
9. Deploy a smart contract with dependency using create2 opcode.
10. Deposit token from Ethereum into zkSync Era.
11. Transfer token on zkSync Era.
12. Withdraw token from zkSync Era to Ethereum.
13. Deploy custom token on zkSync Era.
14. Deploy smart account using create opcode.
15. Deploy smart account using create2 opcode.
16. Use paymaster to pay fee with token.
3. Transfer ETH on zkSync Era using paymaster to pay fee with another token.
4. Withdraw ETH from zkSync Era to Ethereum.
5. Withdraw ETH from zkSync Era to Ethereum using paymaster to pay fee with another token.
6. Finalize withdrawal transaction on Ethereum.
7. Deposit token from Ethereum into zkSync Era.
8. Transfer token on zkSync Era.
9. Transfer token on zkSync Era using paymaster to pay fee with another token.
10. Withdraw token from zkSync Era to Ethereum.
11. Withdraw token from zkSync Era to Ethereum to pay fee with another token.
12. Deploy a smart contract using create method.
13. Deploy a smart contract with constructor using create method.
14. Deploy a smart contract with dependency using create method.
15. Deploy a smart contract using create2 method.
16. Deploy a smart contract with constructor using create2 method.
17. Deploy a smart contract with dependency using create2 method.
18. Deploy custom token on zkSync Era using create method.
19. Deploy custom token on zkSync Era using create2 method.
20. Deploy smart account using create method.
21. Deploy smart account using create2 method.
22. Use paymaster to pay fee with token.

Smart contract deployment use already generated bytecodes and ABIs and go bindings.
There is a [user guide](../solidity/README.md) on how those artifacts
Expand Down
2 changes: 1 addition & 1 deletion js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"prettier": "3.0.3",
"ts-node": "^10.9.1",
"typescript": "^5.1.6",
"zksync-ethers": "6.1.0"
"zksync-ethers": "6.2.0"
},
"peerDependencies": {
"ethers": "^6.7.1"
Expand Down
44 changes: 44 additions & 0 deletions js/src/03_transfer_paymaster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Provider, types, Wallet, utils } from "zksync-ethers";
import { ethers } from "ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const ethProvider = ethers.getDefaultProvider("sepolia");
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider);

const tokenAddress = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free
const paymasterAddress = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token

/*
This example demonstrates how to use a paymaster to facilitate fee payment with an ERC20 token.
The user initiates a transfer transaction that is configured to be paid with an ERC20 token through the paymaster.
During transaction execution, the paymaster receives the ERC20 token from the user and covers the transaction fee using ETH.
*/
async function main() {
const receiver = "0x81E9D85b65E9CC8618D85A1110e4b1DF63fA30d9";

console.log(`Account1 balance before transfer: ${await wallet.getBalance()}`);
console.log(`Account2 balance before transfer: ${await provider.getBalance(receiver)}`);

const tx = await wallet.transfer({
to: receiver,
amount: ethers.parseEther("0.01"),
paymasterParamas: utils.getPaymasterParams(paymasterAddress, {
type: "ApprovalBased",
token: tokenAddress,
minimalAllowance: 1,
innerInput: new Uint8Array(),
}),
});
const receipt = await tx.wait();
console.log(`Tx: ${receipt.hash}`);

console.log(`Account1 balance after transfer: ${await wallet.getBalance()}`);
console.log(`Account2 balance after transfer: ${await provider.getBalance(receiver)}`);
}

main()
.then()
.catch((error) => {
console.log(`Error: ${error}`);
});
File renamed without changes.
45 changes: 45 additions & 0 deletions js/src/05_withdraw_paymaster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Provider, types, utils, Wallet } from "zksync-ethers";
import { ethers } from "ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const ethProvider = ethers.getDefaultProvider("sepolia");
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider);

const tokenAddress = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free
const paymasterAddress = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token

/*
This example demonstrates how to use a paymaster to facilitate fee payment with an ERC20 token.
The user initiates a withdrawal transaction that is configured to be paid with an ERC20 token through the paymaster.
During transaction execution, the paymaster receives the ERC20 token from the user and covers the transaction fee using ETH.
*/
async function main() {
console.log(`L2 balance before withdraw: ${await wallet.getBalance()}`);
console.log(`L1 balance before withdraw: ${await wallet.getBalanceL1()}`);

const tx = await wallet.withdraw({
token: utils.ETH_ADDRESS,
to: await wallet.getAddress(),
amount: ethers.parseEther("0.00020"),
paymasterParamas: utils.getPaymasterParams(paymasterAddress, {
type: "ApprovalBased",
token: tokenAddress,
minimalAllowance: 1,
innerInput: new Uint8Array(),
}),
});
const receipt = await tx.wait();
console.log(`Tx: ${receipt.hash}`);

// The duration for submitting a withdrawal transaction to L1 can last up to 24 hours. For additional information,
// please refer to the documentation: https://era.zksync.io/docs/reference/troubleshooting/withdrawal-delay.html.
// Once the withdrawal transaction is submitted on L1, it needs to be finalized.
// To learn more about how to achieve this, please take a look at the 04_finalize_withdraw.ts script.
}

main()
.then()
.catch((error) => {
console.log(`Error: ${error}`);
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
50 changes: 50 additions & 0 deletions js/src/09_transfer_token_paymaster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Provider, types, Wallet, utils } from "zksync-ethers";
import { ethers } from "ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const ethProvider = ethers.getDefaultProvider("sepolia");
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider);

const tokenAddress = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free
const paymasterAddress = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token

/*
This example demonstrates how to use a paymaster to facilitate fee payment with an ERC20 token.
The user initiates a token transfer transaction that is configured to be paid with an ERC20 token through the paymaster.
During transaction execution, the paymaster receives the ERC20 token from the user and covers the transaction fee using ETH.
*/
async function main() {
const token = "0x6a4Fb925583F7D4dF82de62d98107468aE846FD1";
const receiver = "0x81E9D85b65E9CC8618D85A1110e4b1DF63fA30d9";

console.log(`Account1 balance before transfer: ${await wallet.getBalance(token)}`);
console.log(
`Account2 balance before transfer: ${await provider.getBalance(receiver, "latest", token)}`,
);

const tx = await wallet.transfer({
token: token,
to: receiver,
amount: 5,
paymasterParamas: utils.getPaymasterParams(paymasterAddress, {
type: "ApprovalBased",
token: tokenAddress,
minimalAllowance: 1,
innerInput: new Uint8Array(),
}),
});
const receipt = await tx.wait();
console.log(`Tx: ${receipt.hash}`);

console.log(`Account1 balance after transfer: ${await wallet.getBalance(token)}`);
console.log(
`Account2 balance after transfer: ${await provider.getBalance(receiver, "latest", token)}`,
);
}

main()
.then()
.catch((error) => {
console.log(`Error: ${error}`);
});
File renamed without changes.
47 changes: 47 additions & 0 deletions js/src/11_withdraw_token_paymaster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Provider, types, Wallet, utils } from "zksync-ethers";
import { ethers } from "ethers";

const provider = Provider.getDefaultProvider(types.Network.Sepolia);
const ethProvider = ethers.getDefaultProvider("sepolia");
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider);

const tokenAddress = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free
const paymasterAddress = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token

/*
This example demonstrates how to use a paymaster to facilitate fee payment with an ERC20 token.
The user initiates a token withdrawal transaction that is configured to be paid with an ERC20 token through the paymaster.
During transaction execution, the paymaster receives the ERC20 token from the user and covers the transaction fee using ETH.
*/
async function main() {
const token = "0x6a4Fb925583F7D4dF82de62d98107468aE846FD1";

console.log(`L2 balance before withdrawal: ${await wallet.getBalance()}`);
console.log(`L1 balance before withdrawal: ${await wallet.getBalanceL1()}`);

const tx = await wallet.withdraw({
token: token,
to: await wallet.getAddress(),
amount: 5,
paymasterParamas: utils.getPaymasterParams(paymasterAddress, {
type: "ApprovalBased",
token: tokenAddress,
minimalAllowance: 1,
innerInput: new Uint8Array(),
}),
});
const receipt = await tx.wait();
console.log(`Tx: ${receipt.hash}`);

// The duration for submitting a withdrawal transaction to L1 can last up to 24 hours. For additional information,
// please refer to the documentation: https://era.zksync.io/docs/reference/troubleshooting/withdrawal-delay.html.
// Once the withdrawal transaction is submitted on L1, it needs to be finalized.
// To learn more about how to achieve this, please take a look at the 04_finalize_withdraw.ts script.
}

main()
.then()
.catch((error) => {
console.log(`Error: ${error}`);
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
32 changes: 22 additions & 10 deletions js/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"compilerOptions": {
"module": "CommonJS",
"target": "ES2020",
"moduleResolution": "Node16",

"outDir": "./build",
"esModuleInterop": true,
Expand All @@ -14,14 +13,27 @@
"noImplicitOverride": true
},
"files": [
"./src/01_deposit.ts",
"./src/02_transfer.ts",
"./src/03_withdraw.ts",
"./src/04_finalize_withdraw.ts",
"./src/05_deposit_token.ts",
"./src/06_transfer_token.ts",
"./src/07_withdraw_token.ts",
"./src/08_get_confirmed_tokens.ts",
"./src/09_use_paymaster.ts"
"src/01_deposit.ts",
"src/02_transfer.ts",
"src/03_transfer_paymaster.ts",
"src/04_withdraw.ts",
"src/05_withdraw_paymaster.ts",
"src/06_finalize_withdraw.ts",
"src/07_deposit_token.ts",
"src/08_transfer_token.ts",
"src/09_transfer_token_paymaster.ts",
"src/10_withdraw_token.ts",
"src/11_withdraw_token_paymaster.ts",
"src/12_deploy_create.ts",
"src/13_deploy_create_with_constructor.ts",
"src/14_deploy_create_with_deps.ts",
"src/15_deploy_create2.ts",
"src/16_deploy_create2_with_constructor.ts",
"src/17_deploy_create2_with_deps.ts",
"src/18_deploy_token_create.ts",
"src/19_deploy_token_create2.ts",
"src/20_deploy_create_account.ts",
"src/21_deploy_create2_account.ts",
"src/22_use_paymaster.ts"
]
}
8 changes: 4 additions & 4 deletions js/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==

zksync-ethers@6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-6.1.0.tgz#8fcb973cea39463571839b3c77ec75fe3399d2bf"
integrity sha512-o7pVcPna6yfGljq88mrnoJXALK+nFjZ6rZkuaZ5XahQ26i5dstwgZ7zusuu9neFGXlKqVF6HBirvn+pZ3IKXJA==
zksync-ethers@6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-6.2.0.tgz#4e75292674133a9066dc6622658deea52c3e777b"
integrity sha512-sM65Wo3E4SzyoMPc2gQWv9kVqlaWBfKxBlREk8Ag4gbY10BS9ON1QEosHtcAT542s4NQjypA9qE8QyQ3oKfp3Q==
Loading