Skip to content

Commit

Permalink
feat(provider): add getProof method for fetching storage proofs
Browse files Browse the repository at this point in the history
  • Loading branch information
danijelTxFusion committed Feb 6, 2024
1 parent 7bc5887 commit d364000
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
RawBlockTransaction,
PaymasterParams,
TransactionLike,
StorageProof,
} from "./types";
import {
isETH,
Expand Down Expand Up @@ -269,6 +270,10 @@ export function JsonRpcApiProvider<TBase extends Constructor<ethers.JsonRpcApiPr
return await this.send("zks_getRawBlockTransactions", [number]);
}

async getProof(address: Address, keys: string[], l1BatchNumber: number): Promise<StorageProof> {
return await this.send("zks_getProof", [address, keys, l1BatchNumber]);
}

async getWithdrawTx(transaction: {
token: Address;
amount: BigNumberish;
Expand Down
10 changes: 10 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,3 +533,13 @@ export interface FinalizeWithdrawalParams {
sender: string;
proof: string[];
}

export interface StorageProof {
address: string;
storageProof: {
key: string;
value: string;
index: number;
proof: string[];
}[];
}
29 changes: 28 additions & 1 deletion tests/integration/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,40 @@ describe("Provider", () => {
});

describe("#getRawBlockTransactions()", () => {
it("should return the raw transactions", async () => {
it("should return a raw transactions", async () => {
const blockNumber = await provider.getBlockNumber();
const result = await provider.getRawBlockTransactions(blockNumber);
expect(result).not.to.be.null;
});
});

describe("#getProof()", () => {
it("should return a storage proof", async () => {
// fetchin the storage proof for rawHonce storage slot in NonceHolder system contract
// mapping(uint256 => uint256) internal rawNonces;

// Ensure the address is a 256-bit number by padding it
// because rawNonces uses uint256 for mapping addresses and their nonces
const addressPadded = ethers.zeroPadValue(wallet.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();
try {
const result = await provider.getProof(utils.NONCE_HOLDER_ADDRESS, [storageKey], l1BatchNumber);
expect(result).not.to.be.null;
} catch (error) {}
});
});


describe("#getTransactionStatus()", () => {
it("should return the `Committed` status for a mined transaction", async () => {
const result = await provider.getTransactionStatus(tx.hash);
Expand Down

0 comments on commit d364000

Please sign in to comment.