Skip to content

Commit

Permalink
Implement new rpc methods (#64)
Browse files Browse the repository at this point in the history
* add methods, schemas and types

* rpc

* add tests

* add msg proof test

* fix tests
  • Loading branch information
avkos authored Sep 17, 2024
1 parent 9b4df27 commit 3b85b4b
Show file tree
Hide file tree
Showing 6 changed files with 376 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ jobs:
- run: yarn build
- run: export PRIVATE_KEY=${{secrets.PRIVATE_KEY}}
- run: yarn test:unit
- run: yarn test test/integration/rpc test/integration/mainnet test/integration/zksync test/integration/utils
- run: yarn test test/integration/rpc.test test/integration/mainnet test/integration/zksync test/integration/utils
123 changes: 122 additions & 1 deletion src/rpc.methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as web3Utils from 'web3-utils';
import type * as web3Types from 'web3-types';
import { DEFAULT_RETURN_FORMAT } from 'web3';
import type { DataFormat } from 'web3-types/src/data_format_types';
import type {
import {
BatchDetails,
BlockDetails,
BridgeAddresses,
Expand All @@ -15,6 +15,11 @@ import type {
WalletBalances,
TransactionRequest,
Address,
ProtocolVersion,
FeeParams,
Token,
RawTransactionWithDetailedOutput,
MessageProof,
} from './types';
import {
AddressSchema,
Expand All @@ -23,11 +28,15 @@ import {
BridgeAddressesSchema,
BytesArraySchema,
BytesSchema,
ConfirmedTokensSchema,
EstimateFeeSchema,
FeeParamsSchema,
IntSchema,
L2ToL1ProofSchema,
ProofSchema,
ProtocolVersionSchema,
RawBlockTransactionSchema,
RawTransactionWithDetailedOutputSchema,
TransactionDetailsSchema,
UintSchema,
} from './schemas';
Expand Down Expand Up @@ -392,4 +401,116 @@ export class RpcMethods {
returnFormat,
) as Address;
}

/**
* Lists confirmed tokens. Confirmed in the method name means any token bridged to ZKsync Era via the official bridge.
* The tokens are returned in alphabetical order by their symbol. This means the token id is its position in an alphabetically sorted array of tokens.
*
* @param fromTokenId - The token id to start from.
* @param limit - The number of tokens to return.
* @param returnFormat - The format of the return value.
*/
public async getConfirmedTokens(
fromTokenId: number,
limit: number,
returnFormat: DataFormat = DEFAULT_RETURN_FORMAT,
): Promise<Token[]> {
return web3Utils.format(
ConfirmedTokensSchema,
await this._send('zks_getConfirmedTokens', [fromTokenId, limit]),
returnFormat,
) as Token[];
}

/**
* Retrieves the proof for an L2 to L1 message.
*
* @param l2BlockNumber - The L2 block number.
* @param senderAddress - The sender address.
* @param messageHash - The message hash.
* @param l2LogPosition - The log position in L2.
* @param returnFormat - The format of the return value.
*/
public async getL2ToL1MsgProof(
l2BlockNumber: number,
senderAddress: web3Types.Address,
messageHash: web3Types.Bytes,
l2LogPosition?: number,
returnFormat: DataFormat = DEFAULT_RETURN_FORMAT,
): Promise<MessageProof> {
return web3Utils.format(
L2ToL1ProofSchema,
await this._send('zks_getL2ToL1MsgProof', [
l2BlockNumber,
senderAddress,
messageHash,
l2LogPosition || 0,
]),
returnFormat,
) as MessageProof;
}

/**
* Retrieves the current L1 gas price.
*
* @param returnFormat - The format of the return value.
*/
public async getL1GasPrice(returnFormat: DataFormat = DEFAULT_RETURN_FORMAT): Promise<BigInt> {
return web3Utils.format(
{ format: 'uint' },
await this._send('zks_getL1GasPrice', []),
returnFormat,
) as BigInt;
}

/**
* Retrieves the current fee parameters.
*
* @param returnFormat - The format of the return value.
*/
public async getFeeParams(
returnFormat: DataFormat = DEFAULT_RETURN_FORMAT,
): Promise<FeeParams> {
return web3Utils.format(
FeeParamsSchema,
await this._send('zks_getFeeParams', []),
returnFormat,
) as FeeParams;
}

/**
* Gets the protocol version.
*
* @param versionId - The version ID.
* @param returnFormat - The format of the return value.
*/
public async getProtocolVersion(
versionId?: number,
returnFormat: DataFormat = DEFAULT_RETURN_FORMAT,
): Promise<ProtocolVersion> {
return web3Utils.format(
ProtocolVersionSchema,
await this._send('zks_getProtocolVersion', [versionId]),
returnFormat,
) as ProtocolVersion;
}

/**
* 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. The API has a similar behaviour to eth_sendRawTransaction but with some extra data returned from it.
* With this API Consumer apps can apply "optimistic" events in their applications instantly without having to wait for ZKsync block confirmation time.
* It’s expected that the optimistic logs of two uncommitted transactions that modify the same state will not have causal relationships between each other.
*
* @param data - The transaction data.
* @param returnFormat - The format of the return value.
*/
public async sendRawTransactionWithDetailedOutput(
data: web3Types.Bytes,
returnFormat: DataFormat = DEFAULT_RETURN_FORMAT,
): Promise<RawTransactionWithDetailedOutput> {
return web3Utils.format(
RawTransactionWithDetailedOutputSchema,
await this._send('zks_sendRawTransactionWithDetailedOutput', [data]),
returnFormat,
) as RawTransactionWithDetailedOutput;
}
}
114 changes: 114 additions & 0 deletions src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,117 @@ export const ZKTransactionReceiptSchema = {
},
},
};

export const RawTransactionWithDetailedOutputSchema = {
type: 'object',
properties: {
transactionHash: { format: 'bytes32' },
storageLogs: {
type: 'array',
items: {
type: 'object',
properties: {
address: { format: 'address' },
key: { format: 'bytes32' },
writtenValue: { format: 'bytes32' },
},
},
},
events: {
type: 'array',
items: {
type: 'object',
properties: {
address: { format: 'address' },
topics: {
type: 'array',
items: {
type: 'object',
properties: {
topic: { format: 'bytes32' },
},
},
},
data: { format: 'bytes' },
blockHash: { format: 'bytes32' },
blockNumber: { format: 'uint' },
l1BatchNumber: { format: 'uint' },
transactionHash: { format: 'bytes32' },
transactionIndex: { format: 'uint' },
logIndex: { format: 'uint' },
transactionLogIndex: { format: 'uint' },
logType: { format: 'string' },
removed: { format: 'bool' },
},
},
},
},
};

export const ProtocolVersionSchema = {
type: 'object',
properties: {
version_id: { format: 'uint' },
timestamp: { format: 'uint' },
verification_keys_hashes: {
type: 'object',
properties: {
params: {
type: 'object',
properties: {
recursion_node_level_vk_hash: { format: 'bytes32' },
recursion_leaf_level_vk_hash: { format: 'bytes32' },
recursion_circuits_set_vks_hash: { format: 'bytes32' },
},
},
recursion_scheduler_level_vk_hash: { format: 'bytes32' },
},
},
base_system_contracts: {
type: 'object',
properties: {
bootloader: { format: 'bytes32' },
default_aa: { format: 'bytes32' },
},
},
l2_system_upgrade_tx_hash: { format: 'bytes32' },
},
};

export const FeeParamsSchema = {
type: 'object',
properties: {
V2: {
type: 'object',
properties: {
config: {
type: 'object',
properties: {
minimal_l2_gas_price: { format: 'uint' },
compute_overhead_part: { format: 'uint' },
pubdata_overhead_part: { format: 'uint' },
batch_overhead_l1_gas: { format: 'uint' },
max_gas_per_batch: { format: 'uint' },
max_pubdata_per_batch: { format: 'uint' },
},
},
l1_gas_price: { format: 'uint' },
l1_pubdata_price: { format: 'uint' },
},
},
},
};

export const ConfirmedTokensSchema = {
type: 'array',
items: {
type: 'object',
properties: {
l1Address: { format: 'address' },
l2Address: { format: 'address' },
name: { format: 'string' },
symbol: { format: 'string' },
decimals: { format: 'uint' },
},
},
};
55 changes: 55 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,61 @@ export type ZKSyncContractsCollection = {
};
};

export type RawTransactionWithDetailedOutput = {
transactionHash: string;
storageLogs: {
address: string;
key: string;
writtenValue: string;
}[];
events: {
address: string;
topics: string[];
data: string;
blockHash: string;
blockNumber: Numbers;
l1BatchNumber: Numbers;
transactionHash: string;
transactionIndex: Numbers;
logIndex: Numbers;
transactionLogIndex: Numbers;
logType: string;
removed: boolean;
}[];
};

export type ProtocolVersion = {
version_id: number;
timestamp: number;
verification_keys_hashes: {
params: {
recursion_node_level_vk_hash: string;
recursion_leaf_level_vk_hash: string;
recursion_circuits_set_vks_hash: string;
};
recursion_scheduler_level_vk_hash: string;
};
base_system_contracts: {
bootloader: string;
default_aa: string;
};
l2_system_upgrade_tx_hash: string;
};

export type FeeParams = {
V2: {
config: {
minimal_l2_gas_price: Numbers;
compute_overhead_part: Numbers;
pubdata_overhead_part: Numbers;
batch_overhead_l1_gas: Numbers;
max_gas_per_batch: Numbers;
max_pubdata_per_batch: Numbers;
};
l1_gas_price: Numbers;
l1_pubdata_price: Numbers;
};
};
export type DepositTransactionDetails = {
/**
* The address of the token to deposit.
Expand Down
32 changes: 32 additions & 0 deletions test/integration/rpc.paid.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Web3 } from 'web3';
import { ZKsyncPlugin } from '../../src';
import { PRIVATE_KEY1 } from '../utils';
import { privateKeyToAccount } from 'web3-eth-accounts';
const PRIVATE_KEY = (process.env.PRIVATE_KEY as string) || PRIVATE_KEY1;
const mainAccount = privateKeyToAccount(PRIVATE_KEY);
describe('ZkSyncPlugin rpc paid tests', () => {
let web3: Web3;

beforeAll(() => {
web3 = new Web3();
web3.registerPlugin(new ZKsyncPlugin('https://sepolia.era.zksync.dev'));
web3.ZKsync.L2.eth.accounts.wallet.add(mainAccount);
});

it('sendRawTransactionWithDetailedOutput', async () => {
const populated = await web3.ZKsync.L2.populateTransaction({
from: mainAccount.address,
to: '0x9a6de0f62aa270a8bcb1e2610078650d539b1ef9',
value: 1n,
});
const signed = await web3.ZKsync.L2.signTransaction(populated);
const res = await web3.ZKsync.rpc.sendRawTransactionWithDetailedOutput(signed);
expect(res.transactionHash).toBeDefined();
expect(res.storageLogs).toBeDefined();
expect(Array.isArray(res.storageLogs)).toBeTruthy();
expect(res.storageLogs.length).toBeGreaterThan(0);
expect(res.events).toBeDefined();
expect(Array.isArray(res.events)).toBeTruthy();
expect(res.events.length).toBeGreaterThan(0);
});
});
Loading

0 comments on commit 3b85b4b

Please sign in to comment.