From 48ef1cf525eef15d0c80357f73c91d83d5558db4 Mon Sep 17 00:00:00 2001 From: Danijel Radakovic <129277218+danijelTxFusion@users.noreply.github.com> Date: Fri, 9 Feb 2024 11:07:14 +0100 Subject: [PATCH] feat(js-sdk): add documentation `Provider.getProof` (#903) --- docs/build/sdks/js/accounts.md | 199 +++++++++++++---- docs/build/sdks/js/providers.md | 202 ++++++++++++++---- docs/build/sdks/js/types.md | 11 + docs/build/sdks/js/zksync-ethers/accounts.md | 198 +++++++++++++---- .../sdks/js/zksync-ethers/getting-started.md | 8 +- docs/build/sdks/js/zksync-ethers/providers.md | 202 ++++++++++++++---- docs/build/sdks/js/zksync-ethers/types.md | 11 + 7 files changed, 660 insertions(+), 171 deletions(-) diff --git a/docs/build/sdks/js/accounts.md b/docs/build/sdks/js/accounts.md index bcd3c340c4..9dd8ab4782 100644 --- a/docs/build/sdks/js/accounts.md +++ b/docs/build/sdks/js/accounts.md @@ -593,15 +593,16 @@ For convenience, the `Wallet` class has `transfer` method, which can transfer `E #### Inputs -| Parameter | Type | Description | -| ------------ | ---------------------- | ----------------------------------------------------------------------------------------------------- | -| `tx.to` | `Address` | The address of the recipient. | -| `tx.amount` | `BigNumberish` | The amount of the token to transfer (optional). | -| `tx.token?` | `Address` | The address of the token. `ETH` by default (optional). | -| `overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------------------ | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `transaction.to` | `Address` | The address of the recipient. | +| `transaction.amount` | `BigNumberish` | The amount of the token to transfer (optional). | +| `transaction.token?` | `Address` | The address of the token. `ETH` by default (optional). | +| `transaction.paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `transaction.overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | ```ts -async transfer(tx: { +async transfer(transaction: { to: Address; amount: BigNumberish; token?: Address; @@ -609,23 +610,53 @@ async transfer(tx: { }): Promise ``` -#### Example +#### Examples + +Transfer ETH. ```ts import { Wallet, Provider, utils } from "zksync-ethers"; -import { ethers } from "ethers"; const PRIVATE_KEY = ""; const provider = Provider.getDefaultProvider(types.Network.Sepolia); -const ethProvider = ethers.getDefaultProvider("sepolia"); -const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); +const wallet = new Wallet(PRIVATE_KEY, provider); const recipient = Wallet.createRandom(); const transferHandle = await wallet.transfer({ to: recipient.address, - amount: ethers.utils.parseEther("0.01"), + amount: ethers.parseEther("0.01"), +}); + +const tx = await transferHandle.wait(); + +console.log(`The sum of ${tx.value} ETH was transferred to ${tx.to}`); +``` + +Transfer ETH using paymaster to facilitate fee payment with an ERC20 token. + +```ts +import { Wallet, Provider, utils } from "zksync-ethers"; + +const PRIVATE_KEY = ""; +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); +const wallet = new Wallet(PRIVATE_KEY, provider); + +const recipient = Wallet.createRandom(); + +const transferHandle = await wallet.transfer({ + to: recipient.address, + amount: ethers.parseEther("0.01"), + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), }); const tx = await transferHandle.wait(); @@ -1009,13 +1040,14 @@ L1 network. #### Inputs -| Parameter | Type | Description | -| ---------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------- | -| `transaction.token` | `Address` | The address of the token. `ETH` by default. | -| `transaction.amount` | `BigNumberish` | The amount of the token to withdraw. | -| `transaction.to?` | `Address` | The address of the recipient on L1 (optional). | -| `transaction.bridgeAddress?` | `Address` | The address of the bridge contract to be used (optional). | -| `overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------------------ | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `transaction.token` | `Address` | The address of the token. `ETH` by default. | +| `transaction.amount` | `BigNumberish` | The amount of the token to withdraw. | +| `transaction.to?` | `Address` | The address of the recipient on L1 (optional). | +| `transaction.bridgeAddress?` | `Address` | The address of the bridge contract to be used (optional). | +| `transaction.paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `transaction.overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | ```ts async withdraw(transaction: { @@ -1023,26 +1055,52 @@ async withdraw(transaction: { amount: BigNumberish; to?: Address; bridgeAddress?: Address; + paymasterParams?: PaymasterParams; overrides?: ethers.CallOverrides; }): Promise ``` -#### Example +#### Examples + +Withdraw ETH. ```ts import { Wallet, Provider, utils } from "zksync-ethers"; -import { ethers } from "ethers"; const PRIVATE_KEY = ""; const provider = Provider.getDefaultProvider(types.Network.Sepolia); -const ethProvider = ethers.getDefaultProvider("sepolia"); -const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); +const wallet = new Wallet(PRIVATE_KEY, provider); const tokenL2 = "0x6a4Fb925583F7D4dF82de62d98107468aE846FD1"; const tokenWithdrawHandle = await wallet.withdraw({ token: tokenL2, - amount: "10000000", + amount: 10_000_000, +}); +``` + +Withdraw ETH using paymaster to facilitate fee payment with an ERC20 token. + +```ts +import { Wallet, Provider, utils } from "zksync-ethers"; + +const PRIVATE_KEY = ""; +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); +const wallet = new Wallet(PRIVATE_KEY, provider); + +const tokenL2 = "0x6a4Fb925583F7D4dF82de62d98107468aE846FD1"; +const tokenWithdrawHandle = await wallet.withdraw({ + token: tokenL2, + amount: 10_000_000, + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), }); ``` @@ -1534,27 +1592,30 @@ But for convenience, the `Wallet` class has `transfer` method, which can transfe #### Inputs -| Parameter | Type | Description | -| ------------ | ---------------------- | ----------------------------------------------------------------------------------------------------- | -| `tx.to` | `Address` | The address of the recipient. | -| `tx.amount` | `BigNumberish` | The amount of the token to transfer. | -| `token?` | `Address` | The address of the token. `ETH` by default. | -| `overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------------------ | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `transaction.to` | `Address` | The address of the recipient. | +| `transaction.amount` | `BigNumberish` | The amount of the token to transfer. | +| `transaction.token?` | `Address` | The address of the token. `ETH` by default. | +| `transaction.paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `transaction.overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | ```ts -async transfer(tx: { +async transfer(transaction: { to: Address; amount: BigNumberish; token?: Address; + paymasterParams?: PaymasterParams; overrides?: ethers.CallOverrides; }): Promise ``` -#### Example +#### Examples + +Transfer ETH. ```ts import { Wallet, Web3Provider } from "zksync-ethers"; -import { ethers } from "ethers"; const provider = new Web3Provider(window.ethereum); const signer = provider.getSigner(); @@ -1567,6 +1628,31 @@ const transferHandle = signer.transfer({ }); ``` +Transfer ETH using paymaster to facilitate fee payment with an ERC20 token. + +```ts +import { Wallet, Web3Provider } from "zksync-ethers"; + +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + +const provider = new Web3Provider(window.ethereum); +const signer = provider.getSigner(); + +const recipient = Wallet.createRandom(); + +const transferHandle = signer.transfer({ + to: recipient.address, + amount: ethers.utils.parseEther("0.01"), + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), +}); +``` + ### `withdraw` Initiates the withdrawal process which withdraws ETH or any ERC20 token from the associated account on L2 network to the target account on @@ -1574,13 +1660,14 @@ L1 network. #### Inputs -| Parameter | Type | Description | -| ---------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------- | -| `transaction.token` | `Address` | The address of the token. `ETH` by default. | -| `transaction.amount` | `BigNumberish` | The amount of the token to withdraw. | -| `transaction.to?` | `Address` | The address of the recipient on L1 (optional). | -| `transaction.bridgeAddress?` | `Address` | The address of the bridge contract to be used (optional). | -| `overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------------------ | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `transaction.token` | `Address` | The address of the token. `ETH` by default. | +| `transaction.amount` | `BigNumberish` | The amount of the token to withdraw. | +| `transaction.to?` | `Address` | The address of the recipient on L1 (optional). | +| `transaction.bridgeAddress?` | `Address` | The address of the bridge contract to be used (optional). | +| `transaction.paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `transaction.overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | ```ts async withdraw(transaction: { @@ -1588,15 +1675,17 @@ async withdraw(transaction: { amount: BigNumberish; to?: Address; bridgeAddress?: Address; + paymasterParams?: PaymasterParams; overrides?: ethers.CallOverrides; }): Promise ``` -#### Example +#### Examples + +Withdraw ETH. ```ts import { Web3Provider } from "zksync-ethers"; -import { ethers } from "ethers"; const provider = new Web3Provider(window.ethereum); const signer = provider.getSigner(); @@ -1604,7 +1693,31 @@ const signer = provider.getSigner(); const tokenL2 = "0x6a4Fb925583F7D4dF82de62d98107468aE846FD1"; const tokenWithdrawHandle = await signer.withdraw({ token: tokenL2, - amount: "10000000", + amount: 10_000_000, +}); +``` + +Withdraw ETH using paymaster to facilitate fee payment with an ERC20 token. + +```ts +import { Web3Provider } from "zksync-ethers"; + +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + +const provider = new Web3Provider(window.ethereum); +const signer = provider.getSigner(); + +const tokenL2 = "0x6a4Fb925583F7D4dF82de62d98107468aE846FD1"; +const tokenWithdrawHandle = await signer.withdraw({ + token: tokenL2, + amount: 10_000_000, + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), }); ``` diff --git a/docs/build/sdks/js/providers.md b/docs/build/sdks/js/providers.md index 734c72777e..5573d4f107 100644 --- a/docs/build/sdks/js/providers.md +++ b/docs/build/sdks/js/providers.md @@ -97,7 +97,7 @@ async estimateGas(transaction: utils.Deferrable): Promise ``` @@ -199,7 +201,7 @@ async estimateGasTransfer(transaction: { #### Example ```ts -import { Provider, types } from "zksync-ethers"; +import { Provider, types, utils } from "zksync-ethers"; const provider = Provider.getDefaultProvider(types.Network.Sepolia); const gasTransfer = await provider.estimateGasTransfer({ @@ -220,14 +222,15 @@ withdrawal transaction and sends it to the [`estimateGas`](#estimategas) method. #### Inputs -| Parameter | Type | Description | -| ---------------- | ---------------------- | ----------------------------------------------------------------------------------------------------- | -| `token` | `Address` | Token address. | -| `amount` | `BigNumberish` | Amount of token. | -| `from?` | `Address` | From address (optional). | -| `to?` | `Address` | To address (optional). | -| `bridgeAddress?` | `Address` | Bridge address (optional). | -| `overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------ | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `token` | `Address` | Token address. | +| `amount` | `BigNumberish` | Amount of token. | +| `from?` | `Address` | From address (optional). | +| `to?` | `Address` | To address (optional). | +| `bridgeAddress?` | `Address` | Bridge address (optional). | +| `paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | ```ts async estimateGasWithdraw(transaction: { @@ -236,6 +239,7 @@ async estimateGasWithdraw(transaction: { from?: Address; to?: Address; bridgeAddress?: Address; + paymasterParams ?: PaymasterParams; overrides?: ethers.CallOverrides; }): Promise ``` @@ -243,7 +247,7 @@ async estimateGasWithdraw(transaction: { #### Example ```ts -import { Provider, types } from "zksync-ethers"; +import { Provider, types, utils } from "zksync-ethers"; const provider = Provider.getDefaultProvider(types.Network.Sepolia); const gasWithdraw = await provider.estimateGasWithdraw({ @@ -252,6 +256,7 @@ const gasWithdraw = await provider.estimateGasWithdraw({ to: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", }); +console.log(`Gas for withdrawal tx: ${gasWithdraw}`); ``` ### `estimateL1ToL2Execute` @@ -518,7 +523,7 @@ async getFilterChanges(idx: BigNumber): Promise> #### Example ```ts -import { Provider, types } from "zksync-ethers"; +import { Provider, types, utils } from "zksync-ethers"; const provider = Provider.getDefaultProvider(types.Network.Sepolia); const filter = await provider.newFilter({ @@ -773,6 +778,55 @@ if (l1TxResponse) { } ``` +### `getProof` + +Returns Merkle [`proofs`](./types.md#storageproof) for one or more storage values at the specified account along with a Merkle proof of their authenticity. + +Calls the [`zks_getProof`](../../api.md#zks-getproof) JSON-RPC method. + +#### Inputs + +| Parameter | Type | Description | +| --------------- | ---------- | ----------------------------------------------------------------------------------------------- | +| `address` | `Address` | The account to fetch storage values and proofs for. | +| `keys` | `string[]` | Vector of storage keys in the account. | +| `l1BatchNumber` | `number` | Number of the L1 batch specifying the point in time at which the requested values are returned. | + +```ts +async getProof(address: Address, keys: string[], l1BatchNumber: number): Promise +``` + +#### Example + +Helper function: [toJSON](#tojson). + +```ts +import { Provider, types, utils } from "zksync-ethers"; + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); +const address = "0x082b1BB53fE43810f646dDd71AA2AB201b4C6b04"; + +// Fetching the storage proof for rawNonces storage slot in NonceHolder system contract. +// mapping(uint256 => uint256) internal rawNonces; + +// Ensure the address is a 256-bit number by padding it +// because rawNonces slot uses uint256 for mapping addresses and their nonces. +const addressPadded = ethers.utils.hexZeroPad(wallet.address, 32); + +// Convert the slot number to a hex string and pad it to 32 bytes. +const slotPadded = ethers.utils.hexZeroPad(ethers.utils.hexlify(0), 32); + +// Concatenate the padded address and slot number. +const concatenated = addressPadded + slotPadded.slice(2); // slice to remove '0x' from the slotPadded + +// Hash the concatenated string using Keccak-256. +const storageKey = ethers.utils.keccak256(concatenated); + +const l1BatchNumber = await provider.getL1BatchNumber(); +const storageProof = await provider.getProof(utils.NONCE_HOLDER_ADDRESS, [storageKey], l1BatchNumber); +console.log(`Storage proof: ${toJSON(storageProof)}`); +``` + ### `getRawBlockTransactions` Returns data of transactions in a block. @@ -937,13 +991,14 @@ Returns the populated transfer transaction. #### Inputs -| Parameter | Type | Description | -| ------------ | ---------------------- | ----------------------------------------------------------------------------------------------------- | -| `token` | `Address` | Token address. | -| `amount` | `BigNumberish` | Amount of token. | -| `from?` | `Address` | From address (optional). | -| `to?` | `Address` | To address (optional). | -| `overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------ | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `token` | `Address` | Token address. | +| `amount` | `BigNumberish` | Amount of token. | +| `from?` | `Address` | From address (optional). | +| `to?` | `Address` | To address (optional). | +| `paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | ```ts async getTransferTx(transaction: { @@ -951,20 +1006,51 @@ async getTransferTx(transaction: { amount: BigNumberish; from ? : Address; token ? : Address; + paymasterParams?: PaymasterParams; overrides?: ethers.CallOverrides; }): Promise ``` -#### Example +#### Examples + +Retrieve populated ETH transfer transaction. ```ts +import { Provider, types, utils } from "zksync-ethers"; + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); + const tx = await provider.getTransferTx({ token: utils.ETH_ADDRESS, amount: 7_000_000_000, to: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618", from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", }); -console.log(`Gas for transfer tx: ${tx}`); +console.log(`Transfer tx: ${tx}`); +``` + +Retrieve populated ETH transfer transaction using paymaster to facilitate fee payment with an ERC20 token. + +```ts +import { Provider, types, utils } from "zksync-ethers"; + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + +const tx = await provider.getTransferTx({ + token: utils.ETH_ADDRESS, + amount: 7_000_000_000, + to: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618", + from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), +}); +console.log(`Transfer tx: ${tx}`); ``` ### `getWithdrawTx` @@ -973,14 +1059,15 @@ Returns the populated withdrawal transaction. #### Inputs -| Parameter | Type | Description | -| ---------------- | ---------------------- | ----------------------------------------------------------------------------------------------------- | -| `token` | `Address` | Token address. | -| `amount` | `BigNumberish` | Amount of token. | -| `from?` | `Address` | From address (optional). | -| `to?` | `Address` | To address (optional). | -| `bridgeAddress?` | `Address` | Bridge address (optional). | -| `overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------ | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `token` | `Address` | Token address. | +| `amount` | `BigNumberish` | Amount of token. | +| `from?` | `Address` | From address (optional). | +| `to?` | `Address` | To address (optional). | +| `bridgeAddress?` | `Address` | Bridge address (optional). | +| `paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `overrides?` | `ethers.CallOverrides` | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | ```ts async getWithdrawTx(transaction: { @@ -989,20 +1076,51 @@ async getWithdrawTx(transaction: { from ? : Address; to ? : Address; bridgeAddress ? : Address; + paymasterParams?: PaymasterParams; overrides?: ethers.CallOverrides; }): Promise ``` -#### Example +#### Examples + +Retrieve populated ETH withdrawal transactions. ```ts +import { Provider, types, utils } from "zksync-ethers"; + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); + +const tx = await provider.getWithdrawTx({ + token: utils.ETH_ADDRESS, + amount: 7_000_000_000, + to: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", +}); +console.log(`Withdrawal tx: ${tx}`); +``` + +Retrieve populated ETH withdrawal transaction using paymaster to facilitate fee payment with an ERC20 token. + +```ts +import { Provider, types, utils } from "zksync-ethers"; + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + const tx = await provider.getWithdrawTx({ token: utils.ETH_ADDRESS, amount: 7_000_000_000, to: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), }); -console.log(`Gas for withdrawal tx: ${tx}`); +console.log(`Withdrawal tx: ${tx}`); ``` ### `l1ChainId` @@ -1159,7 +1277,7 @@ async sendTransaction(transaction: string | Promise): Promise ``` -#### Example +#### Examples + +Transfer ETH. ```ts import { Wallet, Provider, utils } from "zksync-ethers"; -import { ethers } from "ethers"; const PRIVATE_KEY = ""; const provider = Provider.getDefaultProvider(types.Network.Sepolia); -const ethProvider = ethers.getDefaultProvider("sepolia"); -const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); +const wallet = new Wallet(PRIVATE_KEY, provider); const recipient = Wallet.createRandom(); @@ -632,6 +634,36 @@ const tx = await transferHandle.wait(); console.log(`The sum of ${tx.value} ETH was transferred to ${tx.to}`); ``` +Transfer ETH using paymaster to facilitate fee payment with an ERC20 token. + +```ts +import { Wallet, Provider, utils } from "zksync-ethers"; + +const PRIVATE_KEY = ""; +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); +const wallet = new Wallet(PRIVATE_KEY, provider); + +const recipient = Wallet.createRandom(); + +const transferHandle = await wallet.transfer({ + to: recipient.address, + amount: ethers.parseEther("0.01"), + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), +}); + +const tx = await transferHandle.wait(); + +console.log(`The sum of ${tx.value} ETH was transferred to ${tx.to}`); +``` + ### `getAllowanceL1` Returns the amount of approved tokens for a specific L1 bridge. @@ -1008,13 +1040,14 @@ L1 network. #### Inputs -| Parameter | Type | Description | -| ---------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | -| `transaction.token` | `Address` | The address of the token. `ETH` by default. | -| `transaction.amount` | `BigNumberish` | The amount of the token to withdraw. | -| `transaction.to?` | `Address` | The address of the recipient on L1 (optional). | -| `transaction.bridgeAddress?` | `Address` | The address of the bridge contract to be used (optional). | -| `transaction.overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------------------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | +| `transaction.token` | `Address` | The address of the token. `ETH` by default. | +| `transaction.amount` | `BigNumberish` | The amount of the token to withdraw. | +| `transaction.to?` | `Address` | The address of the recipient on L1 (optional). | +| `transaction.bridgeAddress?` | `Address` | The address of the bridge contract to be used (optional). | +| `transaction.paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `transaction.overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | ```ts async withdraw(transaction: { @@ -1022,26 +1055,52 @@ async withdraw(transaction: { amount: BigNumberish; to?: Address; bridgeAddress?: Address; + paymasterParams?: PaymasterParams; overrides?: ethers.Overrides; }): Promise ``` -#### Example +#### Examples + +Withdraw ETH. ```ts import { Wallet, Provider, utils } from "zksync-ethers"; -import { ethers } from "ethers"; const PRIVATE_KEY = ""; const provider = Provider.getDefaultProvider(types.Network.Sepolia); -const ethProvider = ethers.getDefaultProvider("sepolia"); -const wallet = new Wallet(PRIVATE_KEY, provider, ethProvider); +const wallet = new Wallet(PRIVATE_KEY, provider); const tokenL2 = "0x6a4Fb925583F7D4dF82de62d98107468aE846FD1"; const tokenWithdrawHandle = await wallet.withdraw({ token: tokenL2, - amount: "10000000", + amount: 10_000_000, +}); +``` + +Withdraw ETH using paymaster to facilitate fee payment with an ERC20 token. + +```ts +import { Wallet, Provider, utils } from "zksync-ethers"; + +const PRIVATE_KEY = ""; +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); +const wallet = new Wallet(PRIVATE_KEY, provider); + +const tokenL2 = "0x6a4Fb925583F7D4dF82de62d98107468aE846FD1"; +const tokenWithdrawHandle = await wallet.withdraw({ + token: tokenL2, + amount: 10_000_000, + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), }); ``` @@ -1534,28 +1593,52 @@ But for convenience, the `Wallet` class has `transfer` method, which can transfe #### Inputs -| Parameter | Type | Description | -| ------------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | -| `tx.to` | `Address` | The address of the recipient. | -| `tx.amount` | `BigNumberish` | The amount of the token to transfer. | -| `token?` | `Address` | The address of the token. `ETH` by default. | -| `overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------------------ | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | +| `transaction.to` | `Address` | The address of the recipient. | +| `transaction.amount` | `BigNumberish` | The amount of the token to transfer. | +| `transaction.token?` | `Address` | The address of the token. `ETH` by default. | +| `transaction.paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `transaction.overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`,
`gasPrice`, `value`, etc (optional). | ```ts -async transfer(tx: { +async transfer(transaction: { to: Address; amount: BigNumberish; token ? : Address; + paymasterParams?: PaymasterParams; overrides ? : ethers.Overrides; }): Promise ``` -#### Example +#### Examples + +Transfer ETH. + +```ts +import { BrowserProvider } from "zksync-ethers"; +import { ethers } from "ethers"; + +const provider = new BrowserProvider(window.ethereum); +const signer = provider.getSigner(); + +const recipient = Wallet.createRandom(); + +const transferHandle = signer.transfer({ + to: recipient.address, + amount: ethers.parseEther("0.01"), +}); +``` + +Transfer ETH using paymaster to facilitate fee payment with an ERC20 token. ```ts import { BrowserProvider } from "zksync-ethers"; import { ethers } from "ethers"; +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + const provider = new BrowserProvider(window.ethereum); const signer = provider.getSigner(); @@ -1564,6 +1647,12 @@ const recipient = Wallet.createRandom(); const transferHandle = signer.transfer({ to: recipient.address, amount: ethers.parseEther("0.01"), + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), }); ``` @@ -1574,13 +1663,14 @@ L1 network. #### Inputs -| Parameter | Type | Description | -| ---------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | -| `transaction.token` | `Address` | The address of the token. `ETH` by default. | -| `transaction.amount` | `BigNumberish` | The amount of the token to withdraw. | -| `transaction.to?` | `Address` | The address of the recipient on L1 (optional). | -| `transaction.bridgeAddress?` | `Address` | The address of the bridge contract to be used (optional). | -| `overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------------------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | +| `transaction.token` | `Address` | The address of the token. `ETH` by default. | +| `transaction.amount` | `BigNumberish` | The amount of the token to withdraw. | +| `transaction.to?` | `Address` | The address of the recipient on L1 (optional). | +| `transaction.bridgeAddress?` | `Address` | The address of the bridge contract to be used (optional). | +| `transaction.paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | ```ts async withdraw(transaction: { @@ -1588,11 +1678,14 @@ async withdraw(transaction: { amount: BigNumberish; to?: Address; bridgeAddress?: Address; + paymasterParams?: PaymasterParams; overrides?: ethers.Overrides; }): Promise ``` -#### Example +#### Examples + +Withdraw ETH. ```ts import { BrowserProvider } from "zksync-ethers"; @@ -1604,7 +1697,32 @@ const signer = provider.getSigner(); const tokenL2 = "0x6a4Fb925583F7D4dF82de62d98107468aE846FD1"; const tokenWithdrawHandle = await signer.withdraw({ token: tokenL2, - amount: "10000000", + amount: 10_000_000, +}); +``` + +Withdraw ETH using paymaster to facilitate fee payment with an ERC20 token. + +```ts +import { BrowserProvider } from "zksync-ethers"; +import { ethers } from "ethers"; + +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + +const provider = new BrowserProvider(window.ethereum); +const signer = provider.getSigner(); + +const tokenL2 = "0x6a4Fb925583F7D4dF82de62d98107468aE846FD1"; +const tokenWithdrawHandle = await signer.withdraw({ + token: tokenL2, + amount: 10_000_000, + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), }); ``` diff --git a/docs/build/sdks/js/zksync-ethers/getting-started.md b/docs/build/sdks/js/zksync-ethers/getting-started.md index 180a959fc9..a78a16f5c4 100644 --- a/docs/build/sdks/js/zksync-ethers/getting-started.md +++ b/docs/build/sdks/js/zksync-ethers/getting-started.md @@ -86,8 +86,8 @@ Also, the following examples demonstrate how to: 1. [Deposit ETH and tokens from Ethereum into zkSync Era](https://github.com/zksync-sdk/zksync2-examples/blob/main/js/src/01_deposit.ts) 2. [Transfer ETH and tokens on zkSync Era](https://github.com/zksync-sdk/zksync2-examples/blob/main/js/src/02_transfer.ts) -3. [Withdraw ETH and tokens from zkSync Era to Ethereum](https://github.com/zksync-sdk/zksync2-examples/blob/main/js/src/03_withdraw.ts) -4. [Use paymaster to pay fee with token](https://github.com/zksync-sdk/zksync2-examples/blob/main/js/src/19_use_paymaster.ts) +3. [Withdraw ETH and tokens from zkSync Era to Ethereum](https://github.com/zksync-sdk/zksync2-examples/blob/main/js/src/04_withdraw.ts) +4. [Use paymaster to pay fee with token](https://github.com/zksync-sdk/zksync2-examples/blob/main/js/src/22_use_paymaster.ts) -Full code for all examples is available [here](https://github.com/zksync-sdk/zksync2-examples/tree/main/js/src). Examples are configured to -interact with `zkSync Era` and `Sepolia` test networks. +Full code for all examples is available [here](https://github.com/zksync-sdk/zksync2-examples/tree/main/js/src). +Examples are configured to interact with `zkSync Era` and `Sepolia` test networks. diff --git a/docs/build/sdks/js/zksync-ethers/providers.md b/docs/build/sdks/js/zksync-ethers/providers.md index dbeeb04770..06f8173e50 100644 --- a/docs/build/sdks/js/zksync-ethers/providers.md +++ b/docs/build/sdks/js/zksync-ethers/providers.md @@ -132,7 +132,7 @@ async estimateGas(_tx: TransactionRequest): Promise #### Example ```ts -import { Provider, types } from "zksync-ethers"; +import { Provider, types, utils } from "zksync-ethers"; const provider = Provider.getDefaultProvider(types.Network.Sepolia); const gasTokenApprove = await provider.estimateGas({ @@ -144,10 +144,10 @@ console.log(`Gas for token approval tx: ${gasTokenApprove}`); ``` ```ts -import { Provider, types } from "zksync-ethers"; +import { Provider, types, utils } from "zksync-ethers"; -const ADDRESS = "
"; -const RECEIVER = ""; +const ADDRESS = "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049"; +const RECEIVER = "0xa61464658AfeAf65CccaaFD3a512b69A83B77618"; const provider = Provider.getDefaultProvider(types.Network.Sepolia); const tokenAddress = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free const paymasterAddress = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token @@ -212,13 +212,14 @@ Calls internal method [`getTransferTx`](#gettransfertx) to get the transfer tran #### Inputs -| Parameter | Type | Description | -| ------------ | ------------------------------------------------------------------------ | ----------------------------------- | -| `token` | `Address` | Token address. | -| `amount` | `BigNumberish` | Amount of token. | -| `from?` | `Address` | From address (optional). | -| `to?` | `Address` | To address (optional). | -| `overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Ethers overrides object (optional). | +| Parameter | Type | Description | +| ------------------ | ------------------------------------------------------------------------ | ----------------------------------- | +| `token` | `Address` | Token address. | +| `amount` | `BigNumberish` | Amount of token. | +| `from?` | `Address` | From address (optional). | +| `to?` | `Address` | To address (optional). | +| `paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Ethers overrides object (optional). | ```ts async estimateGasTransfer(transaction: { @@ -226,6 +227,7 @@ async estimateGasTransfer(transaction: { amount: BigNumberish; from ? : Address; token ? : Address; + paymasterParams ?: PaymasterParams; overrides ? : ethers.Overrides; }): Promise ``` @@ -233,7 +235,7 @@ async estimateGasTransfer(transaction: { #### Example ```ts -import { Provider, types } from "zksync-ethers"; +import { Provider, types, utils } from "zksync-ethers"; const provider = Provider.getDefaultProvider(types.Network.Sepolia); const gasTransfer = await provider.estimateGasTransfer({ @@ -254,14 +256,15 @@ withdrawal transaction and sends it to the [`estimateGas`](#estimategas) method. #### Inputs -| Parameter | Type | Description | -| ---------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- | -| `token` | `Address` | Token address. | -| `amount` | `BigNumberish` | Amount of token. | -| `from?` | `Address` | From address (optional). | -| `to?` | `Address` | To address (optional). | -| `bridgeAddress?` | `Address` | Bridge address (optional). | -| `overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). . | +| Parameter | Type | Description | +| ------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- | +| `token` | `Address` | Token address. | +| `amount` | `BigNumberish` | Amount of token. | +| `from?` | `Address` | From address (optional). | +| `to?` | `Address` | To address (optional). | +| `bridgeAddress?` | `Address` | Bridge address (optional). | +| `paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). . | ```ts async estimateGasWithdraw(transaction: { @@ -270,6 +273,7 @@ async estimateGasWithdraw(transaction: { from ? : Address; to ? : Address; bridgeAddress ? : Address; + paymasterParams ?: PaymasterParams; overrides ? : ethers.Overrides; }): Promise ``` @@ -277,7 +281,7 @@ async estimateGasWithdraw(transaction: { #### Example ```ts -import { Provider, types } from "zksync-ethers"; +import { Provider, types, utils } from "zksync-ethers"; const provider = Provider.getDefaultProvider(types.Network.Sepolia); const gasWithdraw = await provider.estimateGasWithdraw({ @@ -286,6 +290,7 @@ const gasWithdraw = await provider.estimateGasWithdraw({ to: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", }); +console.log(`Gas for withdrawal tx: ${gasWithdraw}`); ``` ### `estimateL1ToL2Execute` @@ -559,7 +564,7 @@ async getFilterChanges(idx: bigint): Promise> #### Example ```ts -import { Provider, types } from "zksync-ethers"; +import { Provider, types, utils } from "zksync-ethers"; const provider = Provider.getDefaultProvider(types.Network.Sepolia); const filter = await provider.newFilter({ @@ -741,7 +746,7 @@ async getLogs(filter: Filter | FilterByBlockHash): Promise Helper function: [toJSON](#tojson). ```ts -import { Provider, types } from "zksync-ethers"; +import { Provider, types, utils } from "zksync-ethers"; const provider = Provider.getDefaultProvider(types.Network.Sepolia); console.log(`Logs: ${toJSON(await provider.getLogs({ fromBlock: 0, toBlock: 5, address: utils.L2_ETH_TOKEN_ADDRESS }))}`); @@ -798,6 +803,55 @@ if (l1TxResponse) { } ``` +### `getProof` + +Returns Merkle [`proofs`](./types.md#storageproof) for one or more storage values at the specified account along with a Merkle proof of their authenticity. + +Calls the [`zks_getProof`](../../../api.md#zks-getproof) JSON-RPC method. + +#### Inputs + +| Parameter | Type | Description | +| --------------- | ---------- | ----------------------------------------------------------------------------------------------- | +| `address` | `Address` | The account to fetch storage values and proofs for. | +| `keys` | `string[]` | Vector of storage keys in the account. | +| `l1BatchNumber` | `number` | Number of the L1 batch specifying the point in time at which the requested values are returned. | + +```ts +async getProof(address: Address, keys: string[], l1BatchNumber: number): Promise +``` + +#### Example + +Helper function: [toJSON](#tojson). + +```ts +import { Provider, types, utils } from "zksync-ethers"; + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); +const address = "0x082b1BB53fE43810f646dDd71AA2AB201b4C6b04"; + +// Fetching the storage proof for rawNonces storage slot in NonceHolder system contract. +// mapping(uint256 => uint256) internal rawNonces; + +// Ensure the address is a 256-bit number by padding it +// because rawNonces slot uses uint256 for mapping addresses and their nonces. +const addressPadded = ethers.zeroPadValue(address, 32); + +// Convert the slot number to a hex string and pad it to 32 bytes. +const slotPadded = ethers.zeroPadValue(ethers.toBeHex(0), 32); + +// Concatenate the padded address and slot number. +const concatenated = addressPadded + slotPadded.slice(2); // slice to remove '0x' from the slotPadded + +// Hash the concatenated string using Keccak-256. +const storageKey = ethers.keccak256(concatenated); + +const l1BatchNumber = await provider.getL1BatchNumber(); +const storageProof = await provider.getProof(utils.NONCE_HOLDER_ADDRESS, [storageKey], l1BatchNumber); +console.log(`Storage proof: ${toJSON(storageProof)}`); +``` + ### `getRawBlockTransactions` Returns data of transactions in a block. @@ -962,13 +1016,14 @@ Returns the populated transfer transaction. #### Inputs -| Parameter | Type | Description | -| ------------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | -| `token` | `Address` | Token address. | -| `amount` | `BigNumberish` | Amount of token. | -| `from?` | `Address` | From address (optional). | -| `to?` | `Address` | To address (optional). | -| `overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | +| `token` | `Address` | Token address. | +| `amount` | `BigNumberish` | Amount of token. | +| `from?` | `Address` | From address (optional). | +| `to?` | `Address` | To address (optional). | +| `paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | ```ts async getTransferTx(transaction: { @@ -976,20 +1031,51 @@ async getTransferTx(transaction: { amount: BigNumberish; from ? : Address; token ? : Address; + paymasterParams?: PaymasterParams; overrides ? : ethers.Overrides; }): Promise ``` -#### Example +#### Examples + +Retrieve populated ETH transfer transaction. + +```ts +import { Provider, types, utils } from "zksync-ethers"; + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); + +const tx = await provider.getTransferTx({ + token: utils.ETH_ADDRESS, + amount: 7_000_000_000, + to: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618", + from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", +}); +console.log(`Transfer tx: ${tx}`); +``` + +Retrieve populated ETH transfer transaction using paymaster to facilitate fee payment with an ERC20 token. ```ts +import { Provider, types, utils } from "zksync-ethers"; + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + const tx = await provider.getTransferTx({ token: utils.ETH_ADDRESS, amount: 7_000_000_000, to: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618", from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), }); -console.log(`Gas for transfer tx: ${tx}`); +console.log(`Transfer tx: ${tx}`); ``` ### `getWithdrawTx` @@ -998,14 +1084,15 @@ Returns the populated withdrawal transaction. #### Inputs -| Parameter | Type | Description | -| ---------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | -| `token` | `Address` | Token address. | -| `amount` | `BigNumberish` | Amount of token. | -| `from?` | `Address` | From address (optional). | -| `to?` | `Address` | To address (optional). | -| `bridgeAddress?` | `Address` | Bridge address (optional). | -| `overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | +| Parameter | Type | Description | +| ------------------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | +| `token` | `Address` | Token address. | +| `amount` | `BigNumberish` | Amount of token. | +| `from?` | `Address` | From address (optional). | +| `to?` | `Address` | To address (optional). | +| `bridgeAddress?` | `Address` | Bridge address (optional). | +| `paymasterParams?` | [`PaymasterParams`](./types.md#paymasterparams) | Paymaster parameters (optional). | +| `overrides?` | [`ethers.Overrides`](https://docs.ethers.org/v6/api/contract/#Overrides) | Transaction's overrides which may be used to pass l2 `gasLimit`, `gasPrice`, `value`, etc (optional). | ```ts async getWithdrawTx(transaction: { @@ -1014,20 +1101,51 @@ async getWithdrawTx(transaction: { from ? : Address; to ? : Address; bridgeAddress ? : Address; + paymasterParams?: PaymasterParams; overrides ? : ethers.Overrides; }): Promise ``` -#### Example +#### Examples + +Retrieve populated ETH withdrawal transactions. ```ts +import { Provider, types, utils } from "zksync-ethers"; + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); + +const tx = await provider.getWithdrawTx({ + token: utils.ETH_ADDRESS, + amount: 7_000_000_000, + to: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", +}); +console.log(`Withdrawal tx: ${tx}`); +``` + +Retrieve populated ETH withdrawal transaction using paymaster to facilitate fee payment with an ERC20 token. + +```ts +import { Provider, types, utils } from "zksync-ethers"; + +const provider = Provider.getDefaultProvider(types.Network.Sepolia); +const token = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +const paymaster = "0x13D0D8550769f59aa241a41897D4859c87f7Dd46"; // Paymaster for Crown token + const tx = await provider.getWithdrawTx({ token: utils.ETH_ADDRESS, amount: 7_000_000_000, to: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + paymasterParams: utils.getPaymasterParams(paymaster, { + type: "ApprovalBased", + token: token, + minimalAllowance: 1, + innerInput: new Uint8Array(), + }), }); -console.log(`Gas for withdrawal tx: ${tx}`); +console.log(`Withdrawal tx: ${tx}`); ``` ### `l1ChainId` diff --git a/docs/build/sdks/js/zksync-ethers/types.md b/docs/build/sdks/js/zksync-ethers/types.md index 0ba1768b0e..ea1364e164 100644 --- a/docs/build/sdks/js/zksync-ethers/types.md +++ b/docs/build/sdks/js/zksync-ethers/types.md @@ -266,6 +266,17 @@ Interface representation of raw block with transactions 0x-prefixed, hex-encoded, ECDSA signature as string. +## `StorageProof` + +Interace representation of Merkle proofs for storage values. + +- `address`: `string`; +- `storageProof` (Array): + - `key`: `string`; + - `value`: `string`; + - `index`: `number`; + - `proof`: `string[]`; + ## `Token` Interface representation of token containing various fields.