prividium 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { createClient, publicActions } from 'viem';
2
- import { selectiveDisclosureActions } from './selective-disclosure/actions';
2
+ import { selectiveDisclosureActions } from './selective-disclosure/actions.js';
3
3
  function prividiumActions(client) {
4
4
  return {
5
5
  call: (args) => {
@@ -1,5 +1,5 @@
1
1
  import { type Address, type Hex, type PublicClient } from 'viem';
2
- import type { AccountDataDisclosureResult, AccountProperties } from './disclosure-result';
2
+ import type { AccountDataDisclosureResult, AccountProperties } from './disclosure-result.js';
3
3
  export declare function encodeAccountProperties(params: AccountProperties): Hex;
4
4
  /**
5
5
  * Compute the internal bytecode hash: blake2s(code || padding || artifacts)
@@ -1,9 +1,9 @@
1
1
  import { bytesToHex, hexToBigInt, hexToBytes, keccak256, pad } from 'viem';
2
- import { encodeBatchInfo } from './batch-info';
3
- import { computeStateCommitment } from './state-commitment';
4
- import { blake2s256 } from './utils';
5
- import { calculateStateMerkleRoot } from './verifiy-proofs';
6
- import { DIAMOND_ABI } from './verify-disclosure';
2
+ import { encodeBatchInfo } from './batch-info.js';
3
+ import { computeStateCommitment } from './state-commitment.js';
4
+ import { blake2s256 } from './utils.js';
5
+ import { calculateStateMerkleRoot } from './verifiy-proofs.js';
6
+ import { DIAMOND_ABI } from './verify-disclosure.js';
7
7
  const PUSH1 = 0x60;
8
8
  const PUSH32 = 0x7f;
9
9
  const JUMPDEST = 0x5b;
@@ -1,5 +1,5 @@
1
1
  import { type Account, type Address, type BlockTag, type Chain, type Client, type Hex, type RpcSchema, type Transport } from 'viem';
2
- import type { AccountDataDisclosureResult, EthCallDisclosureResult } from './disclosure-result';
2
+ import type { AccountDataDisclosureResult, EthCallDisclosureResult } from './disclosure-result.js';
3
3
  export type DisclosureBlockNumber = number | bigint | Hex | BlockTag;
4
4
  export type SelectiveDisclosureActions = {
5
5
  tokenSupplyDisclosure: (tokenAddress: Address, blockNumber: DisclosureBlockNumber) => Promise<EthCallDisclosureResult>;
@@ -1,5 +1,5 @@
1
1
  import type { Address, Hex } from 'viem';
2
- import type { StorageSlotProof } from './verifiy-proofs';
2
+ import type { StorageSlotProof } from './verifiy-proofs.js';
3
3
  export type StateCommitmentPreimage = {
4
4
  nextFreeSlot: Hex;
5
5
  blockNumber: Hex;
@@ -28,6 +28,8 @@ export type AccountStorageProofs = {
28
28
  */
29
29
  export type EthCallDisclosureResult = {
30
30
  result: Hex;
31
+ from: Address;
32
+ to: Address;
31
33
  callData: Hex;
32
34
  batchNumber: number;
33
35
  stateCommitmentPreimage: StateCommitmentPreimage;
@@ -1,7 +1,7 @@
1
- export * from './account-properties';
2
- export * from './actions';
3
- export * from './batch-info';
4
- export * from './disclosure-result';
5
- export * from './state-commitment';
6
- export * from './verifiy-proofs';
7
- export * from './verify-disclosure';
1
+ export * from './account-properties.js';
2
+ export * from './actions.js';
3
+ export * from './batch-info.js';
4
+ export * from './disclosure-result.js';
5
+ export * from './state-commitment.js';
6
+ export * from './verifiy-proofs.js';
7
+ export * from './verify-disclosure.js';
@@ -1,7 +1,7 @@
1
- export * from './account-properties';
2
- export * from './actions';
3
- export * from './batch-info';
4
- export * from './disclosure-result';
5
- export * from './state-commitment';
6
- export * from './verifiy-proofs';
7
- export * from './verify-disclosure';
1
+ export * from './account-properties.js';
2
+ export * from './actions.js';
3
+ export * from './batch-info.js';
4
+ export * from './disclosure-result.js';
5
+ export * from './state-commitment.js';
6
+ export * from './verifiy-proofs.js';
7
+ export * from './verify-disclosure.js';
@@ -1,5 +1,5 @@
1
1
  import { bytesToHex, hexToBytes } from 'viem';
2
- import { blake2s256, concatBytes } from './utils';
2
+ import { blake2s256, concatBytes } from './utils.js';
3
3
  export function computeStateCommitment(treeRoot, nextFreeSlot, blockNumber, last256BlockHashesBlake, lastBlockTimestamp) {
4
4
  const nextFreeSlotBytes = new Uint8Array(8);
5
5
  new DataView(nextFreeSlotBytes.buffer).setBigUint64(0, nextFreeSlot, false); // big-endian
@@ -1,5 +1,5 @@
1
1
  import { bytesToHex, hexToBytes, pad } from 'viem';
2
- import { blake2s256, concatBytes } from './utils';
2
+ import { blake2s256, concatBytes } from './utils.js';
3
3
  function deriveFlatKey(address, storageKey) {
4
4
  // blake2s(pad32(address) || storageKey)
5
5
  const addressBytes = hexToBytes(pad(address));
@@ -1,5 +1,5 @@
1
1
  import { type Address, type Hex, type PublicClient } from 'viem';
2
- import type { EthCallDisclosureResult } from './disclosure-result';
2
+ import type { EthCallDisclosureResult } from './disclosure-result.js';
3
3
  export declare const DIAMOND_ABI: {
4
4
  readonly name: "storedBatchHash";
5
5
  readonly type: "function";
@@ -1,10 +1,36 @@
1
1
  import { keccak256, pad, parseAbiItem } from 'viem';
2
- import { encodeBatchInfo } from './batch-info';
3
- import { computeStateCommitment } from './state-commitment';
4
- import { calculateStateMerkleRoot } from './verifiy-proofs';
2
+ import { encodeBatchInfo } from './batch-info.js';
3
+ import { computeStateCommitment } from './state-commitment.js';
4
+ import { calculateStateMerkleRoot } from './verifiy-proofs.js';
5
5
  export const DIAMOND_ABI = [
6
6
  parseAbiItem('function storedBatchHash(uint256 _batchNumber) external view returns (bytes32)')
7
7
  ];
8
+ const tracerStr = `{
9
+ prevTop: null,
10
+ state: {
11
+ reads: {},success: null, value: null
12
+ },
13
+ step: function (log, _db) {
14
+ if (log.op.toString() === 'SLOAD') {
15
+ const addr = log.contract.getAddress();
16
+ const slot = this.prevTop;
17
+ if (!this.state.reads[addr]) this.state.reads[addr] = [];
18
+ if (this.state.reads[addr].indexOf(slot) === -1) this.state.reads[addr].push(slot);
19
+ }
20
+
21
+ if (log.stack.length() > 0) {
22
+ this.prevTop = log.stack.peek(0).toString(16);
23
+ } else {
24
+ this.prevTop = null;
25
+ }
26
+ },
27
+ fault: (_log, _db) => {},
28
+ result: function (ctx, _db) {
29
+ this.state.success = ctx.error === null;
30
+ this.state.value = ctx.output.toString('hex');
31
+ return this.state;
32
+ }
33
+ }`;
8
34
  /**
9
35
  * Verifies an ethCall disclosure response end-to-end.
10
36
  *
@@ -60,31 +86,51 @@ export async function verifyEthCallDisclosure(disclosure, l1Client, l2Client, di
60
86
  if (batchInfoHash !== storedBatchHash) {
61
87
  return false;
62
88
  }
63
- // Step 5: Replay the call on L2 with state overrides to verify the proven
64
- // storage values produce the expected result.
65
- const contractAddress = disclosure.proofs[0].address;
66
- const stateOverride = disclosure.proofs.map((proof) => {
89
+ const contractAddress = disclosure.to;
90
+ const stateOverride = {};
91
+ for (const proof of disclosure.proofs) {
67
92
  const address = proof.address.toLowerCase();
68
93
  const code = contractBytecodes[address];
69
94
  if (!code) {
70
95
  throw new Error(`Missing bytecode for contract ${address}`);
71
96
  }
72
- return {
73
- address,
97
+ const state = {};
98
+ for (const sp of proof.storageProofs) {
99
+ state[sp.key] = sp.proof.type === 'existing' ? sp.proof.value : pad('0x0');
100
+ }
101
+ stateOverride[address] = {
74
102
  code,
75
- state: proof.storageProofs.map((sp) => ({
76
- slot: sp.key,
77
- value: sp.proof.type === 'existing' ? sp.proof.value : pad('0x0')
78
- }))
103
+ state: state
79
104
  };
105
+ }
106
+ const debugResult = await l2Client.request({
107
+ method: 'debug_traceCall',
108
+ params: [
109
+ {
110
+ from: disclosure.from,
111
+ to: contractAddress,
112
+ data: disclosure.callData
113
+ },
114
+ 'latest',
115
+ {
116
+ tracer: tracerStr,
117
+ stateOverrides: stateOverride
118
+ }
119
+ ]
80
120
  });
81
- const callResult = await l2Client.call({
82
- to: contractAddress,
83
- data: disclosure.callData,
84
- stateOverride
85
- });
86
- if (!callResult.data) {
121
+ if (!debugResult.success) {
87
122
  return false;
88
123
  }
89
- return BigInt(callResult.data) === BigInt(disclosure.result);
124
+ for (const address in debugResult.reads) {
125
+ for (const slot of debugResult.reads[address]) {
126
+ const realSlot = `0x${slot}`;
127
+ const exists = disclosure.proofs.find((p) => p.address.toLowerCase() === address.toLowerCase() &&
128
+ p.storageProofs.some((sp) => BigInt(sp.key) === BigInt(realSlot)));
129
+ if (!exists) {
130
+ return false;
131
+ }
132
+ }
133
+ }
134
+ const callResult = debugResult.value;
135
+ return BigInt(callResult) === BigInt(disclosure.result);
90
136
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prividium",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "prividium": "bin/cli.js"