From bb4cd571bce5e868469295080d028a993a8f8514 Mon Sep 17 00:00:00 2001 From: Ngozi-Txfusion Date: Tue, 2 Jul 2024 20:44:44 +0100 Subject: [PATCH] chore: minor changes --- .../10.v5/00.providers/02.web3provider.md | 715 +++++++++++++++--- .../05.api/10.v5/01.accounts/03.l1signer.md | 2 +- .../20.v6/00.providers/02.browser-provider.md | 635 +++++++++++++++- .../05.api/20.v6/01.accounts/03.l1signer.md | 2 +- 4 files changed, 1224 insertions(+), 130 deletions(-) diff --git a/content/sdk/10.js/00.ethers/05.api/10.v5/00.providers/02.web3provider.md b/content/sdk/10.js/00.ethers/05.api/10.v5/00.providers/02.web3provider.md index 65bbe243..fc01df5c 100644 --- a/content/sdk/10.js/00.ethers/05.api/10.v5/00.providers/02.web3provider.md +++ b/content/sdk/10.js/00.ethers/05.api/10.v5/00.providers/02.web3provider.md @@ -4,30 +4,53 @@ description: Web3Provider objects for integrating with ZKsync. tags: ["zksync", "web3", "providers", "integration"] --- -The `Web3Provider` class inherits from `JsonRpcProvider`. It facilitates the transition from web3.js based applications -to `ethers.js` by wrapping an existing Web3-compatible provider -(such as [`Web3HttpProvider`](https://github.com/ethereum/web3.js/tree/1.x/packages/web3-providers-http), [`Web3IpcProvider`](https://github.com/ethereum/web3.js/tree/1.x/packages/web3-providers-ipc), -or [`Web3WsProvider`](https://github.com/ethereum/web3.js/tree/1.x/packages/web3-providers-ws)) and exposing it as an -ethers.js `Provider`. It can also wrap a standard [EIP-1193 provider](https://eips.ethereum.org/EIPS/eip-1193). +The `Web3Provider` is an extension of the `Provider` class specifically designed for use in browser environments and +integration with browser wallets (e.g., MetaMask, WalletConnect). It supports RPC endpoints within the `zks` namespace. -### Purpose +## `Constructor` -- **Integration:** Ease the transition from web3.js to ethers.js. -- **Compatibility:** Supports wrapping EIP-1193 providers and Web3-compatible providers. +```typescript +constructor(provider: ExternalProvider, network?: ethers.providers.Networkish) +``` -### Constructor +- **provider**: The provider injected from the browser. For instance, MetaMask is `window.ethereum`. +- **network**: Optional. The network name, chain ID, or object with network details. -Creates a new `Web3Provider`, which wraps an EIP-1193 Provider or Web3-compatible Provider. +#### Example ```typescript -new ethers.providers.Web3Provider(externalProvider: ExternalProvider | JsonRpcFetchFunc, network?: ethers.providers.Networkish) +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); ``` -#### Inputs -| Parameter | Type | Description | -| ---------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -| `externalProvider` | `ExternalProvider \| JsonRpcFetchFunc` | An EIP-1193 Provider or Web3Provider-compatible provider (e.g., `window.ethereum`). | -| `network?` | `Networkish` | The description of the network. | +## Methods + +### `getTransactionReceipt` + +```typescript +override async getTransactionReceipt(txHash: string): Promise +``` + +Returns the transaction receipt for the specified `txHash`, if mined. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +const TX_HASH = ""; +console.log(`Transaction receipt: ${utils.toJSON(await provider.getTransactionReceipt(TX_HASH))}`); +``` + +### `getTransaction` + +```typescript +override async getTransaction(txHash: string): Promise +``` + +Returns the transaction for the specified `txHash`. #### Example @@ -35,130 +58,638 @@ new ethers.providers.Web3Provider(externalProvider: ExternalProvider | JsonRpcFe import { Web3Provider } from "zksync-ethers"; const provider = new Web3Provider(window.ethereum); +const TX_HASH = ""; +const tx = await provider.getTransaction(TX_HASH); + +// Wait until the transaction is processed by the server. +await tx.wait(); +// Wait until the transaction is finalized. +await tx.waitFinalize(); +``` + +### `getBlock` + +```typescript +override async getBlock(blockHashOrBlockTag: BlockTag | string | Promise): Promise +``` + +Returns the block for the specified `blockHashOrBlockTag`. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Block: ${utils.toJSON(await provider.getBlock("latest", true))}`); +``` + +### `getBlockWithTransactions` + +```typescript +override async getBlockWithTransactions(blockHashOrBlockTag: BlockTag | string | Promise): Promise +``` + +Returns the block for the specified `blockHashOrBlockTag`, including all transactions. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Block: ${utils.toJSON(await provider.getBlockWithTransactions("latest", true))}`); +``` + +### `getLogs` + +```typescript +override async getLogs(filter: EventFilter | Promise = {}): Promise> ``` -### Properties +Returns the list of logs that match the specified `filter`. -#### provider -Returns the `ExternalProvider` used to create this instance. +#### Example ```typescript -web3Provider.provider: ExternalProvider +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Logs: ${utils.toJSON(await provider.getLogs({ fromBlock: 0, toBlock: 5, address: utils.L2_ETH_TOKEN_ADDRESS }))}`); ``` -### Methods +### `getBalance` -#### send -Sends a JSON-RPC request to the network. +```typescript +override async getBalance(address: Address, blockTag?: BlockTag, tokenAddress?: Address): Promise +``` + +Returns the account balance for the specified `address`, `blockTag`, and `tokenAddress`. -##### Inputs -| Parameter | Type | Description | -| --------- | ------------ | ---------------------------------- | -| `method` | `string` | Request method name. | -| `params?` | `Array` | Parameters of any type. | +#### Example ```typescript -async send(method: string, params?: Array): Promise +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +const account = "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049"; +const tokenAddress = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +console.log(`ETH balance: ${await provider.getBalance(account)}`); +console.log(`Token balance: ${await provider.getBalance(account, "latest", tokenAddress)}`); ``` -##### Example +### `l2TokenAddress` + +```typescript +override async l2TokenAddress(token: Address): Promise +``` + +Returns the L2 token address equivalent for a L1 token address. + +#### Example ```typescript import { Web3Provider } from "zksync-ethers"; const provider = new Web3Provider(window.ethereum); -const transaction = { - from: "", - to: "", - value: ethers.utils.parseEther("0.01"), -}; -const result = await provider.send("eth_sendTransaction", [transaction]); -console.log(result); +console.log(`L2 token address: ${await provider.l2TokenAddress("0x5C221E77624690fff6dd741493D735a17716c26B")}`); ``` -### ExternalProvider Signatures +### `l1TokenAddress` -#### externalProvider.request -This follows the EIP-1193 API signature. +```typescript +override async l1TokenAddress(token: Address): Promise +``` + +Returns the L1 token address equivalent for a L2 token address. + +#### Example ```typescript -externalProvider.request(request: { method: string, params?: Array }): Promise +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`L1 token address: ${await provider.l1TokenAddress("0x3e7676937A7E96CFB7616f255b9AD9FF47363D4b")}`); +``` + +### `getProtocolVersion` + +```typescript +override async getProtocolVersion(id?: number): Promise ``` -#### externalProvider.sendAsync -This follows the Web3.js Provider Signature. +Returns the protocol version. + +#### Example ```typescript -externalProvider.sendAsync(request: { method: string, params?: Array }, callback: (error: any, result: any) => void): void +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Protocol version: ${await provider.getProtocolVersion()}`); ``` -#### externalProvider.send -Identical to `sendAsync`. Historically used synchronous web requests, but this method is deprecated. +### `estimateGasL1` ```typescript -externalProvider.send(request: { method: string, params?: Array }, callback: (error: any, result: any) => void): void +override async estimateGasL1(transaction: TransactionRequest): Promise ``` -### Implementation +Estimates the amount of gas required to submit a transaction from L1 to L2. -The `Web3Provider` constructor initializes the provider by determining the appropriate JSON-RPC fetch function based -on the type of `ExternalProvider` passed. It supports `request`, `sendAsync`, and `send` methods to handle various -provider signatures. +#### Example ```typescript -export class Web3Provider extends JsonRpcProvider { - readonly provider: ExternalProvider; - readonly jsonRpcFetchFunc: JsonRpcFetchFunc; +import { Web3Provider } from "zksync-ethers"; - constructor(provider: ExternalProvider | JsonRpcFetchFunc, network?: Networkish) { - if (provider == null) { - logger.throwArgumentError("missing provider", "provider", provider); - } +const provider = new Web3Provider(window.ethereum); +const gasL1 = await provider.estimateGasL1({ + from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + to: await provider.getMainContractAddress(), + value: 7_000_000_000, + customData: { + gasPerPubdata: 800, + }, +}); +console.log(`L1 gas: ${gasL1}`); +``` - let path: string = null; - let jsonRpcFetchFunc: JsonRpcFetchFunc = null; - let subprovider: ExternalProvider = null; +### `estimateFee` - if (typeof(provider) === "function") { - path = "unknown:"; - jsonRpcFetchFunc = provider; - } else { - path = provider.host || provider.path || ""; - if (!path && provider.isMetaMask) { - path = "metamask"; - } +```typescript +override async estimateFee(transaction: TransactionRequest): Promise +``` - subprovider = provider; +Returns an estimated fee for the requested transaction. - if (provider.request) { - if (path === "") { path = "eip-1193:"; } - jsonRpcFetchFunc = buildEip1193Fetcher(provider); - } else if (provider.sendAsync) { - jsonRpcFetchFunc = buildWeb3LegacyFetcher(provider, provider.sendAsync.bind(provider)); - } else if (provider.send) { - jsonRpcFetchFunc = buildWeb3LegacyFetcher(provider, provider.send.bind(provider)); - } else { - logger.throwArgumentError("unsupported provider", "provider", provider); - } +#### Example - if (!path) { path = "unknown:"; } - } +```typescript +import { Web3Provider, utils } from "zksync-ethers"; - super(path, network); +const provider = new Web3Provider(window.ethereum); +const fee = await provider.estimateFee({ + from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + to: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618", + value: BigNumber.from(7_000_000_000).toHexString(), +}); +console.log(`Fee: ${utils.toJSON(fee)}`); +``` - defineReadOnly(this, "jsonRpcFetchFunc", jsonRpcFetchFunc); - defineReadOnly(this, "provider", subprovider); - } +### `getFeeParams` - send(method: string, params: Array): Promise { - return this.jsonRpcFetchFunc(method, params); - } -} +```typescript +override async getFeeParams(): Promise +``` + +Returns the current fee parameters. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +const feeParams = await provider.getFeeParams(); +console.log(`Fee: ${utils.toJSON(feeParams)}`); +``` + +### `getGasPrice` + +```typescript +override async getGasPrice(): Promise +``` + +Returns an estimate of the gas price to use in a transaction. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Gas price: ${await provider.getGasPrice()}`); +``` + +### `getLogProof` + +```typescript +override async getLogProof(txHash: BytesLike, index?: number): Promise +``` + +Returns the proof for a transaction's L2 to L1 log sent via the `L1Messenger` system contract. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +// Any L2 -> L1 transaction can be used. +// In this case, withdrawal transaction is used. +const tx = "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e"; +console.log(`Log ${utils.toJSON(await provider.getLogProof(tx, 0))}`); +``` + +### `getL1BatchBlockRange` + +```typescript +override async getL1BatchBlockRange(l1BatchNumber: number): Promise<[number, number] | null> +``` + +Returns the range of blocks contained within a batch given by batch number. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +const l1BatchNumber = await provider.getL1BatchNumber(); +console.log(`L1 batch block range: ${utils.toJSON(await provider.getL1BatchBlockRange(l1BatchNumber))}`); +``` + +### `getBridgehubContractAddress` + +```typescript +override async getBridgehubContractAddress(): Promise
+``` + +Returns the Bridgehub smart contract address. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Bridgehub: ${await provider.getBridgehubContractAddress() + +}`); +``` + +### `getBaseTokenContractAddress` + +```typescript +override async getBaseTokenContractAddress(): Promise
+``` + +Returns the L1 base token address. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Base token: ${await provider.getBaseTokenContractAddress()}`); +``` + +### `isEthBasedChain` + +```typescript +override async isEthBasedChain(): Promise +``` + +Returns whether the chain is ETH-based. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Is ETH based chain: ${await provider.isEthBasedChain()}`); +``` + +### `isBaseToken` + +```typescript +override async isBaseToken(token: Address): Promise +``` + +Returns whether the `token` is the base token. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Is base token: ${await provider.isBaseToken("0x5C221E77624690fff6dd741493D735a17716c26B")}`); +``` + +### `getMainContractAddress` + +```typescript +override async getMainContractAddress(): Promise
+``` + +Returns the main ZKsync Era smart contract address. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Main contract: ${await provider.getMainContractAddress()}`); +``` + +### `getTestnetPaymasterAddress` + +```typescript +override async getTestnetPaymasterAddress(): Promise
+``` + +Returns the testnet paymaster address, if available. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Testnet paymaster: ${await provider.getTestnetPaymasterAddress()}`); +``` + +### `getDefaultBridgeAddresses` + +```typescript +override async getDefaultBridgeAddresses(): Promise<{ erc20L1: string; erc20L2: string; wethL1: string; wethL2: string; sharedL1: string; sharedL2: string; }> +``` + +Returns the addresses of the default ZKsync Era bridge contracts on both L1 and L2. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Bridge addresses: ${await provider.getDefaultBridgeAddresses()}`); +``` + +### `getAllAccountBalances` + +```typescript +override async getAllAccountBalances(address: Address): Promise +``` + +Returns all balances for confirmed tokens given by an account address. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +const balances = await provider.getAllAccountBalances("0x36615Cf349d7F6344891B1e7CA7C72883F5dc049"); +console.log(`All balances: ${utils.toJSON(balances)}`); +``` + +### `getConfirmedTokens` + +```typescript +override async getConfirmedTokens(start?: number, limit?: number): Promise +``` + +Returns confirmed tokens. Confirmed token is any token bridged to ZKsync Era via the official bridge. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +const tokens = await provider.getConfirmedTokens(); +console.log(`Confirmed tokens: ${utils.toJSON(tokens)}`); +``` + +### `l1ChainId` + +```typescript +override async l1ChainId(): Promise +``` + +Returns the L1 chain ID. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +const l1ChainId = await provider.l1ChainId(); +console.log(`All balances: ${l1ChainId}`); +``` + +### `getL1BatchNumber` + +```typescript +override async getL1BatchNumber(): Promise +``` + +Returns the latest L1 batch number. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`L1 batch number: ${await provider.getL1BatchNumber()}`); +``` + +### `getL1BatchDetails` + +```typescript +override async getL1BatchDetails(number: number): Promise +``` + +Returns data pertaining to a given batch. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +const l1BatchNumber = await provider.getL1BatchNumber(); +console.log(`L1 batch details: ${utils.toJSON(await provider.getL1BatchDetails(l1BatchNumber))}`); +``` + +### `getBlockDetails` + +```typescript +override async getBlockDetails(number: number): Promise +``` + +Returns additional ZKsync-specific information about the L2 block. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Block details: ${utils.toJSON(await provider.getBlockDetails(90_000))}`); +``` + +### `getTransactionDetails` + +```typescript +override async getTransactionDetails(txHash: BytesLike): Promise +``` + +Returns data from a specific transaction given by the transaction hash. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +const TX_HASH = ""; +console.log(`Transaction details: ${utils.toJSON(await provider.getTransactionDetails(TX_HASH))}`); +``` + +### `getBytecodeByHash` + +```typescript +override async getBytecodeByHash(bytecodeHash: BytesLike): Promise +``` + +Returns bytecode of a contract given by its hash. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +// Bytecode hash can be computed by following these steps: +// const testnetPaymasterBytecode = await provider.getCode(await provider.getTestnetPaymasterAddress()); +// const testnetPaymasterBytecodeHash = ethers.utils.hexlify(utils.hashBytecode(testnetPaymasterBytecode)); + +const testnetPaymasterBytecodeHash = "0x010000f16d2b10ddeb1c32f2c9d222eb1aea0f638ec94a81d4e916c627720e30"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Bytecode: ${await provider.getBytecodeByHash(testnetPaymasterBytecodeHash)}`); +``` + +### `getRawBlockTransactions` + +```typescript +override async getRawBlockTransactions(number: number): Promise +``` + +Returns data of transactions in a block. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +console.log(`Raw block transactions: ${utils.toJSON(await provider.getRawBlockTransactions(90_000))}`); +``` + +### `getProof` + +```typescript +override async getProof(address: Address, keys: string[], l1BatchNumber: number): Promise +``` + +Returns Merkle proofs for one or more storage values at the specified account along with a Merkle proof of their authenticity. + +#### Example + +```typescript +import { Web3Provider, utils } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +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(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: ${utils.toJSON(storageProof)}`); +``` + +### `sendRawTransactionWithDetailedOutput` + +```typescript +override async sendRawTransactionWithDetailedOutput(signedTx: string): Promise +``` + +Executes a transaction and returns its hash, storage logs, and events that would have been generated if the +transaction had already been included in the block. + +#### Example + +```typescript +import { Web3Provider, Wallet, Provider, utils, types } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +const signer = Signer.from( + await provider.getSigner(), + Number((await provider.getNetwork()).chainId), + Provider.getDefaultProvider(types.Network.Sepolia) +); + +const txWithOutputs = await provider.send + +RawTransactionWithDetailedOutput( + await signer.signTransaction({ + to: "0x0330808583C22F812DD9B647Ed9F0411f44A1e6f", + value: 7_000_000_000, + customData: { + gasPerPubdata: 800, + }, + }) +); +console.log(`Transaction: ${utils.toJSON(txWithOutputs)}`); +``` + +## `getSigner` + +```typescript +getSigner(addressOrIndex?: string | number): JsonRpcSigner +``` + +Returns a `JsonRpcSigner` instance for the specified `addressOrIndex`. This is used to sign transactions and messages +using the connected wallet. + +#### Example + +```typescript +import { Web3Provider } from "zksync-ethers"; + +const provider = new Web3Provider(window.ethereum); +const signer = provider.getSigner(); +const message = "Hello, ZKsync!"; +const signature = await signer.signMessage(message); +console.log(`Signature: ${signature}`); ``` -### Appendix +## Appendix -#### toJSON +### toJSON ```ts function toJSON(object: any): string { diff --git a/content/sdk/10.js/00.ethers/05.api/10.v5/01.accounts/03.l1signer.md b/content/sdk/10.js/00.ethers/05.api/10.v5/01.accounts/03.l1signer.md index 3407e31d..ce9cc61b 100644 --- a/content/sdk/10.js/00.ethers/05.api/10.v5/01.accounts/03.l1signer.md +++ b/content/sdk/10.js/00.ethers/05.api/10.v5/01.accounts/03.l1signer.md @@ -74,7 +74,7 @@ async getL1BridgeContracts(): Promise<{ }> ``` -### Example +#### Example ```ts import { Provider, L1Signer, types } from "zksync-ethers"; diff --git a/content/sdk/10.js/00.ethers/05.api/20.v6/00.providers/02.browser-provider.md b/content/sdk/10.js/00.ethers/05.api/20.v6/00.providers/02.browser-provider.md index 4349cd0a..6a4a7415 100644 --- a/content/sdk/10.js/00.ethers/05.api/20.v6/00.providers/02.browser-provider.md +++ b/content/sdk/10.js/00.ethers/05.api/20.v6/00.providers/02.browser-provider.md @@ -5,8 +5,8 @@ tags: ["zksync", "browser", "providers", "integration"] --- The [`BrowserProvider`](https://docs.ethers.org/v6/api/providers/#BrowserProvider) class is designed for integrating -ZKsync with Web3 browser wallets such as Metamask and -WalletConnect. It provides an easy way to interact with ZKsync Era using standard browser wallets. +ZKsync with Web3 browser wallets such as Metamask and WalletConnect. It provides an easy way to interact with ZKsync +Era using standard browser wallets. ## Usage @@ -15,91 +15,654 @@ WalletConnect. It provides an easy way to interact with ZKsync Era using standar A `BrowserProvider` wraps an injected provider adhering to the EIP-1193 standard. This class extends the functionality of the `Provider` class to support browser-based Ethereum providers. -### What it is meant for +### `constructor` -- Integrating ZKsync with browser wallets. -- Providing compatibility with Metamask, WalletConnect, and other popular browser wallets. -- Enabling gas estimation, transaction signing, and sending RPC requests via a browser wallet. +Returns a provider object by extending the constructor of the `Provider` class and accepting an `Eip1193Provider` +instead of a node URL. -## Creating instances +#### Inputs -To create an instance of `BrowserProvider`: +| Parameter | Type | Description | +| ---------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- | +| `ethereum` | [`Eip1193Provider`](https://docs.ethers.org/v6/api/providers/#Eip1193Provider) | The `Eip1193Provider` class instance. For instance, Metamask is `window.ethereum`. | +| `network?` | [`Networkish`](https://docs.ethers.org/v6/api/providers/#Networkish) | Network name. | + +```ts +constructor(ethereum: Eip1193Provider, network?: Networkish) +``` + +#### Example ```ts import { BrowserProvider } from "zksync-ethers"; -const provider = new BrowserProvider(window.ethereum, network); +const provider = new BrowserProvider(window.ethereum); +``` + +## Method + +The `BrowserProvider` includes all methods from the `Provider` class with similar parameters. Below are the methods +and their examples. + +### `getTransactionReceipt` + +Returns the transaction receipt for the given transaction hash. + +```ts +async getTransactionReceipt(txHash: string): Promise ``` -### Constructor +#### Example ```ts -constructor(ethereum: Eip1193Provider, network?: Networkish, options?: BrowserProviderOptions) +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +const TX_HASH = ""; +console.log(`Transaction receipt: ${utils.toJSON(await provider.getTransactionReceipt(TX_HASH))}`); ``` -- `ethereum`: An instance of `Eip1193Provider` (e.g., `window.ethereum` for Metamask). -- `network`: (Optional) Network name or configuration. +### `getTransaction` -## Methods +Returns the transaction for the given transaction hash. -### `_send` +```ts +async getTransaction(txHash: string): Promise +``` -Sends JSON-RPC payload(s) to the provider. +#### Example ```ts -browserProvider._send(payload: JsonRpcPayload | Array): Promise> +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); + +const TX_HASH = ""; +const tx = await provider.getTransaction(TX_HASH); + +// Wait until the transaction is processed by the server. +await tx.wait(); +// Wait until the transaction is finalized. +await tx.waitFinalize(); ``` -### `getRpcError` +### `getBlock` -Retrieves a formatted RPC error. +Returns the block for the given block hash or block tag. ```ts -browserProvider.getRpcError(payload: JsonRpcPayload, error: JsonRpcError): Error +async getBlock(blockHashOrBlockTag: BlockTag, includeTxs?: boolean): Promise ``` -### `getSigner` +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Block: ${utils.toJSON(await provider.getBlock("latest", true))}`); +``` + +### `getLogs` + +Returns the logs that match the given filter. + +```ts +async getLogs(filter: Filter | FilterByBlockHash): Promise +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Logs: ${utils.toJSON(await provider.getLogs({ fromBlock: 0, toBlock: 5, address: utils.L2_ETH_TOKEN_ADDRESS }))}`); +``` + +### `getBalance` + +Returns the account balance for the specified account address, block tag, and token address. + +```ts +async getBalance(address: Address, blockTag?: BlockTag, tokenAddress?: Address): Promise +``` + +#### Example -Gets a signer instance for a given address. +```ts +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +const account = "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049"; +const tokenAddress = "0x927488F48ffbc32112F1fF721759649A89721F8F"; // Crown token which can be minted for free +console.log(`ETH balance: ${await provider.getBalance(account)}`); +console.log(`Token balance: ${await provider.getBalance(account, "latest", tokenAddress)}`); +``` + +### `l2TokenAddress` + +Returns the L2 token address equivalent for a given L1 token address. + +```ts +async l2TokenAddress(token: Address): Promise +``` + +#### Example ```ts -browserProvider.getSigner(address?: number | string): Promise +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`L2 token address: ${await provider.l2TokenAddress("0x5C221E77624690fff6dd741493D735a17716c26B")}`); ``` -### `hasSigner` +### `l1TokenAddress` -Checks if the provider manages the given address. +Returns the L1 token address equivalent for a given L2 token address. ```ts -browserProvider.hasSigner(address: number | string): Promise +async l1TokenAddress(token: Address): Promise ``` -### `send` +#### Example + +```ts +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`L1 token address: ${await provider.l1TokenAddress("0x3e7676937A7E96CFB7616f255b9AD9FF47363D4b")}`); +``` + +### `getProtocolVersion` + +Returns the protocol version. -Sends an RPC request. +```ts +async getProtocolVersion(id?: number): Promise +``` + +#### Example ```ts -browserProvider.send(method: string, params: Array | Record): Promise +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Protocol version: ${await provider.getProtocolVersion()}`); ``` -## Example usage +### `estimateGasL1` -### Estimating gas +Returns an estimate of the amount of gas required to submit a transaction from L1 to L2. ```ts +async estimateGasL1(transaction: TransactionRequest): Promise +``` + +#### Example + +```ts +import { BrowserProvider } from "zksync-ethers"; + const provider = new BrowserProvider(window.ethereum); -const gas = await provider.estimateGas({ - to: "", - amount: ethers.parseEther("0.01"), +const gasL1 = await provider.estimateGasL1({ + from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + to: await provider.getMainContractAddress(), + value: 7_000_000_000, + customData: { + gasPerPubdata: 800, + }, }); -console.log(`Gas: ${gas}`); +console.log(`L1 gas: ${BigInt(gasL1)}`); +``` + +### `estimateFee` + +Returns an estimated fee for a requested transaction. + +```ts +async estimateFee(transaction: TransactionRequest): Promise +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +const fee = await provider.estimateFee({ + from: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049", + to: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618", + value: `0x${BigInt(7_000_000_000).toString(16)}`, +}); +console.log(`Fee: ${utils.toJSON(fee)}`); +``` + +### `getFeeParams` + +Returns the current fee parameters. + +```ts +async getFeeParams(): Promise +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +const feeParams = await provider.getFeeParams(); +console.log(`Fee: ${utils.toJSON(feeParams)}`); +``` + +### `getGasPrice` + +Returns an estimate of the gas price to use in a transaction. + +```ts +async getGasPrice(): Promise +``` + +#### Example + +```ts +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Gas price: ${await provider.getGasPrice()}`); +``` + +### `getLogProof` + +Returns the proof for a transaction's L2 to L1 log. + +```ts +async getLogProof(txHash: BytesLike, index?: number): Promise +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +const tx = "0x2a1c6c74b184965c0cb015aae9ea134fd96215d2e4f4979cfec12563295f610e"; +console.log(`Log ${utils.toJSON(await provider.getLogProof(tx, 0))}`); +``` + +### `getL1BatchBlockRange` + +Returns the range of blocks contained within a batch given by batch number. + +```ts +async getL1BatchBlockRange(l1BatchNumber: number): Promise<[number, number] | null> +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = + + new BrowserProvider(window.ethereum); +const l1BatchNumber = await provider.getL1BatchNumber(); +console.log(`L1 batch block range: ${utils.toJSON(await provider.getL1BatchBlockRange(l1BatchNumber))}`); +``` + +### `getMainContractAddress` + +Returns the main ZKsync Era smart contract address. + +```ts +async getMainContractAddress(): Promise
+``` + +#### Example + +```ts +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Main contract: ${await provider.getMainContractAddress()}`); +``` + +### `getBridgehubContractAddress` + +Returns the Bridgehub smart contract address. + +```ts +async getBridgehubContractAddress(): Promise
+``` + +#### Example + +```ts +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Bridgehub: ${await provider.getBridgehubContractAddress()}`); +``` + +### `getBaseTokenContractAddress` + +Returns the L1 base token address. + +```ts +async getBaseTokenContractAddress(): Promise
+``` + +#### Example + +```ts +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Base token: ${await provider.getBaseTokenContractAddress()}`); +``` + +### `isEthBasedChain` + +Returns whether the chain is ETH-based. + +```ts +async isEthBasedChain(): Promise +``` + +#### Example + +```ts +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Is ETH based chain: ${await provider.isEthBasedChain()}`); +``` + +### `isBaseToken` + +Returns whether the `token` is the base token. + +```ts +async isBaseToken(token: Address): Promise +``` + +#### Example + +```ts +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Is base token: ${await provider.isBaseToken("0x5C221E77624690fff6dd741493D735a17716c26B")}`); +``` + +### `getTestnetPaymasterAddress` + +Returns the testnet paymaster address if available, or `null`. + +```ts +async getTestnetPaymasterAddress(): Promise
+``` + +#### Example + +```ts +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Testnet paymaster: ${await provider.getTestnetPaymasterAddress()}`); +``` + +### `getDefaultBridgeAddresses` + +Returns the addresses of the default ZKsync Era bridge contracts on both L1 and L2. + +```ts +async getDefaultBridgeAddresses(): Promise<{ + erc20L1: string; + erc20L2: string; + wethL1: string; + wethL2: string; + sharedL1: string; + sharedL2: string; +}> +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +const bridgeAddresses = await provider.getDefaultBridgeAddresses(); +console.log(`Default bridges: ${utils.toJSON(bridgeAddresses)}`); +``` + +### `getAllAccountBalances` + +Returns all balances for confirmed tokens given by an account address. + +```ts +async getAllAccountBalances(address: Address): Promise +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +const balances = await provider.getAllAccountBalances("0x36615Cf349d7F6344891B1e7CA7C72883F5dc049"); +console.log(`All balances: ${utils.toJSON(balances)}`); +``` + +### `getConfirmedTokens` + +Returns confirmed tokens bridged to ZKsync Era via the official bridge. + +```ts +async getConfirmedTokens(start = 0, limit = 255): Promise +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +const tokens = await provider.getConfirmedTokens(); +console.log(`Confirmed tokens: ${utils.toJSON(tokens)}`); +``` + +### `l1ChainId` + +Returns the L1 chain ID. + +```ts +async l1ChainId(): Promise +``` + +#### Example + +```ts +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +const l1ChainId = await provider.l1ChainId(); +console.log(`All balances: ${l1ChainId}`); ``` -### Getting a signer +### `getL1BatchNumber` + +Returns the latest L1 batch number. + +```ts +async getL1BatchNumber(): Promise +``` + +#### Example ```ts +import { BrowserProvider } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`L1 batch number: ${await provider.getL1BatchNumber()}`); +``` + +### `getL1BatchDetails` + +Returns data pertaining to a given batch. + +```ts +async getL1BatchDetails(number: number): Promise +``` + +#### Example + +#### `getL1BatchDetails` + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +const l1BatchNumber = await provider.getL1BatchNumber(); +console.log(`L1 batch details: ${utils.toJSON(await provider.getL1BatchDetails(l1BatchNumber))}`); +``` + +### `getBlockDetails` + +Returns additional ZKsync-specific information about the L2 block. + +```ts +async getBlockDetails(number: number): Promise +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Block details: ${utils.toJSON(await provider.getBlockDetails(90_000))}`); +``` + +### `getTransactionDetails` + +Returns data from a specific transaction given by the transaction hash. + +```ts +async getTransactionDetails(txHash: BytesLike): Promise +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); + +const TX_HASH = ""; +console.log(`Transaction details: ${utils.toJSON(await provider.getTransactionDetails(TX_HASH))}`); +``` + +### `getBytecodeByHash` + +Returns bytecode of a contract given by its hash. + +```ts +async getBytecodeByHash(bytecodeHash: BytesLike): Promise +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +// Bytecode hash can be computed by following these steps: +// const testnetPaymasterBytecode = await provider.getCode(await provider.getTestnetPaymasterAddress()); +// const testnetPaymasterBytecodeHash = ethers.hexlify(utils.hashBytecode(testnetPaymasterBytecode)); + +const testnetPaymasterBytecodeHash = "0x010000f16d2b10ddeb1c32f2c9d222eb1aea0f638ec94a81d4e916c627720e30"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Bytecode: ${await provider.getBytecodeByHash(testnetPaymasterBytecodeHash)}`); +``` + +### `getRawBlockTransactions` + +Returns data of transactions in a block. + +```ts +async getRawBlockTransactions(number: number): Promise +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; + +const provider = new BrowserProvider(window.ethereum); +console.log(`Raw block transactions: ${utils.toJSON(await provider.getRawBlockTransactions(90_000))}`); +``` + +### `getProof` + +Returns Merkle proofs for one or more storage values at the specified account. + +```ts +async getProof(address: Address, keys: string[], l1BatchNumber: number): Promise +``` + +#### Example + +```ts +import { BrowserProvider, utils } from "zksync-ethers"; +import { ethers } from "ethers"; + +const provider = new BrowserProvider(window.ethereum); +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 to get the storage key. +const storageKey = ethers.keccak256(concatenated); + +const l1BatchNumber = await provider.getL1BatchNumber(); +const proof = await provider.getProof(address, [storageKey], l1BatchNumber); +console.log(`Proof: ${utils.toJSON(proof)}`); +``` + +### `getSigner` + +Returns a signer object for the provider. + +```ts +async getSigner(address?: Address): Promise +``` + +#### Example + +```ts +import { BrowserProvider, Wallet } from "zksync-ethers"; + const provider = new BrowserProvider(window.ethereum); const signer = await provider.getSigner(); + +// Verify that signer matches the expected wallet address. +console.log(`Signer address: ${await signer.getAddress()}`); ``` ### Appendix diff --git a/content/sdk/10.js/00.ethers/05.api/20.v6/01.accounts/03.l1signer.md b/content/sdk/10.js/00.ethers/05.api/20.v6/01.accounts/03.l1signer.md index 309214d5..28352263 100644 --- a/content/sdk/10.js/00.ethers/05.api/20.v6/01.accounts/03.l1signer.md +++ b/content/sdk/10.js/00.ethers/05.api/20.v6/01.accounts/03.l1signer.md @@ -74,7 +74,7 @@ async getL1BridgeContracts(): Promise<{ }> ``` -### Example +#### Example ```ts import { Provider, L1Signer, types } from "zksync-ethers";