diff --git a/.changeset/empty-poems-grin.md b/.changeset/empty-poems-grin.md new file mode 100644 index 0000000000..f8310b8fac --- /dev/null +++ b/.changeset/empty-poems-grin.md @@ -0,0 +1,5 @@ +--- +"viem": patch +--- + +**ZKsync**: Added `getGasPerPubdata` Action. diff --git a/src/zksync/actions/getGasPerPubdata.test.ts b/src/zksync/actions/getGasPerPubdata.test.ts new file mode 100644 index 0000000000..76cfc9cb4e --- /dev/null +++ b/src/zksync/actions/getGasPerPubdata.test.ts @@ -0,0 +1,17 @@ +import { expect, test } from 'vitest' +import { + mockClientPublicActionsL2, + zksyncClientLocalNode, +} from '../../../test/src/zksync.js' +import { gasPerPubdataDefault } from '../constants/number.js' +import { getGasPerPubdata } from './getGasPerPubdata.js' + +const client = { ...zksyncClientLocalNode } + +mockClientPublicActionsL2(client) + +test('default', async () => { + const fee = await getGasPerPubdata(client) + + expect(fee).toEqual(gasPerPubdataDefault) +}) diff --git a/src/zksync/actions/getGasPerPubdata.ts b/src/zksync/actions/getGasPerPubdata.ts new file mode 100644 index 0000000000..9cff893157 --- /dev/null +++ b/src/zksync/actions/getGasPerPubdata.ts @@ -0,0 +1,26 @@ +import type { Client } from '../../clients/createClient.js' +import type { Transport } from '../../clients/transports/createTransport.js' +import type { Account } from '../../types/account.js' +import { hexToBigInt } from '../../utils/encoding/fromHex.js' +import type { ChainEIP712 } from '../types/chain.js' +import type { PublicZksyncRpcSchema } from '../types/eip1193.js' + +export type GetGasPerPubdataReturnType = bigint + +export async function getGasPerPubdata< + chain extends ChainEIP712 | undefined, + account extends Account | undefined, +>( + client: Client, +): Promise { + const result = await client.request( + { + method: 'zks_gasPerPubdata', + }, + { + dedupe: true, + }, + ) + + return hexToBigInt(result) +} diff --git a/src/zksync/decorators/publicL2.test.ts b/src/zksync/decorators/publicL2.test.ts index 869d9ede60..9a6558ea97 100644 --- a/src/zksync/decorators/publicL2.test.ts +++ b/src/zksync/decorators/publicL2.test.ts @@ -27,6 +27,7 @@ import type { GetAllBalancesReturnType } from '../actions/getAllBalances.js' import { getLogProof } from '../actions/getLogProof.js' import { getTransactionDetails } from '../actions/getTransactionDetails.js' import { zksyncLocalNode } from '../chains.js' +import { gasPerPubdataDefault } from '../constants/number.js' import { publicActionsL2 } from './publicL2.js' const mockedZksyncClient = createPublicClient({ @@ -257,3 +258,8 @@ test.skip('getL1TokenAddress', async () => { }), ).toBeDefined() }) + +test('getGasPerPubdata', async () => { + const gasPerPubdata = await mockedZksyncClient.getGasPerPubdata() + expect(gasPerPubdata).to.equal(gasPerPubdataDefault) +}) diff --git a/src/zksync/decorators/publicL2.ts b/src/zksync/decorators/publicL2.ts index 65807bd0c2..33331db59c 100644 --- a/src/zksync/decorators/publicL2.ts +++ b/src/zksync/decorators/publicL2.ts @@ -34,6 +34,10 @@ import { type GetDefaultBridgeAddressesReturnType, getDefaultBridgeAddresses, } from '../actions/getDefaultBridgeAddresses.js' +import { + type GetGasPerPubdataReturnType, + getGasPerPubdata, +} from '../actions/getGasPerPubdata.js' import { type GetL1BatchBlockRangeParameters, type GetL1BatchBlockRangeReturnParameters, @@ -471,6 +475,25 @@ export type PublicActionsL2< getL1TokenAddress: ( args: GetL1TokenAddressParameters, ) => Promise + + /** + * Returns the scaled gas per pubdata limit for the currently open batch. Available since node version 28.7.0. + * + * @returns the scaled gas per pubdata limit for the currently open batch + * + * @example + * import { createPublicClient, http } from 'viem' + * import { zksyncLocalNode } from 'viem/chains' + * import { publicActionsL2 } from 'viem/zksync' + * + * const client = createPublicClient({ + * chain: zksyncLocalNode, + * transport: http(), + * }).extend(publicActionsL2()) + * + * const gasPerPubdata = await client.getGasPerPubdata(); + */ + getGasPerPubdata: () => Promise } export function publicActionsL2() { @@ -500,6 +523,7 @@ export function publicActionsL2() { getBaseTokenL1Address: () => getBaseTokenL1Address(client), getL2TokenAddress: (args) => getL2TokenAddress(client, args), getL1TokenAddress: (args) => getL1TokenAddress(client, args), + getGasPerPubdata: () => getGasPerPubdata(client), } } } diff --git a/src/zksync/index.ts b/src/zksync/index.ts index 6b58c19f10..a3d276e038 100644 --- a/src/zksync/index.ts +++ b/src/zksync/index.ts @@ -60,6 +60,10 @@ export { getDefaultBridgeAddresses, } from './actions/getDefaultBridgeAddresses.js' export { getBridgehubContractAddress } from './actions/getBridgehubContractAddress.js' +export { + type GetGasPerPubdataReturnType, + getGasPerPubdata, +} from './actions/getGasPerPubdata.js' export { type GetL1AllowanceErrorType, type GetL1AllowanceParameters, diff --git a/src/zksync/types/eip1193.ts b/src/zksync/types/eip1193.ts index 9e452c2abd..d012ac8497 100644 --- a/src/zksync/types/eip1193.ts +++ b/src/zksync/types/eip1193.ts @@ -160,4 +160,9 @@ export type PublicZksyncRpcSchema = [ Parameters: undefined ReturnType: Address }, + { + Method: 'zks_gasPerPubdata' + Parameters?: undefined + ReturnType: Hex + }, ] diff --git a/test/src/zksync.ts b/test/src/zksync.ts index bfaf1408db..ae42f9c082 100644 --- a/test/src/zksync.ts +++ b/test/src/zksync.ts @@ -37,6 +37,8 @@ export const mockFeeValues = { max_priority_fee_per_gas: '0x0', } +export const mockGasPerPubdata = '0x42' + export const mockAccountBalances = { '0x0000000000000000000000000000000000000000': '1000000000000000000', '0x0000000000000000000000000000000000000001': '2000000000000000000', @@ -497,6 +499,7 @@ export const mockLogProof = { export const mockRequestReturnData = async (method: string) => { if (method === 'zks_L1ChainId') return mockChainId if (method === 'zks_estimateFee') return mockFeeValues + if (method === 'zks_gasPerPubdata') return mockGasPerPubdata if (method === 'zks_getAllAccountBalances') return mockAccountBalances if (method === 'zks_getBaseTokenL1Address') return mockBaseTokenL1Address if (method === 'zks_getBlockDetails') return mockBlockDetails