@fatsolutions/privacy-pools-core-starknet-sdk 0.0.42 → 0.0.43

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.
@@ -8,7 +8,7 @@ import { ETH_ADDRESS } from "../constants.js";
8
8
  import { SNContractError, SNPoolError, StarknetSDKError } from "../errors/index.js";
9
9
  import { AssetConfig, Withdrawal } from "../types/entrypoint.js";
10
10
  import { StarknetAddress } from "../types/starknet.js";
11
- import { castBigInt, toAddress, toCairoOption } from "../utils.js";
11
+ import { castBigInt, toAddress } from "../utils.js";
12
12
  import { executeIntent, simulateIntent } from "./transactionHandler.js";
13
13
 
14
14
  /**
@@ -251,9 +251,8 @@ export class SNContractInteractionsService {
251
251
  */
252
252
  withdraw(withdrawal: Withdrawal, withdrawalProofGaraga: bigint[], scope: Hash, options: OptionModeExecute): Promise<InvokeFunctionResponse>;
253
253
  async withdraw(withdrawal: Withdrawal, withdrawalProofGaraga: bigint[], scope: Hash, options?: OptionModes): Promise<CallResult> {
254
- const _withdrawal = { ...withdrawal, auditorData: toCairoOption(withdrawal.auditorData) };
255
254
  const { poolAddress } = await this.getScopeData(scope);
256
- const call = this.pool(poolAddress).populate("withdraw", [_withdrawal, { fullProof: withdrawalProofGaraga }]);
255
+ const call = this.pool(poolAddress).populate("withdraw", [withdrawal, { fullProof: withdrawalProofGaraga }]);
257
256
  return _intentOptionWrapper(call, options && { ...options, account: this.providerOrAccount });
258
257
  }
259
258
 
@@ -287,8 +286,7 @@ export class SNContractInteractionsService {
287
286
  */
288
287
  relay(withdrawal: Withdrawal, withdrawalProofGaraga: bigint[], scope: Hash, options: OptionModeExecute): Promise<InvokeFunctionResponse>;
289
288
  relay(withdrawal: Withdrawal, withdrawalProofGaraga: bigint[], scope: Hash, options?: OptionModes): Promise<CallResult> {
290
- const _withdrawal = { ...withdrawal, auditorData: toCairoOption(withdrawal.auditorData) };
291
- const call = this.entrypoint.populate("relay", [_withdrawal, scope, { fullProof: withdrawalProofGaraga }]);
289
+ const call = this.entrypoint.populate("relay", [withdrawal, scope, { fullProof: withdrawalProofGaraga }]);
292
290
  return _intentOptionWrapper(call, options && { ...options, account: this.providerOrAccount });
293
291
  }
294
292
 
@@ -5,7 +5,6 @@ import {
5
5
  RagequitEvent,
6
6
  WithdrawalEvent,
7
7
  } from "@0xbow/privacy-pools-core-sdk";
8
- import { AuditEvent } from "./auditor.js"
9
8
  import {
10
9
  AbiParser2,
11
10
  EmittedEvent,
@@ -22,7 +21,6 @@ import {
22
21
  StarknetSDKError,
23
22
  } from "./errors/index.js";
24
23
 
25
-
26
24
  // Calculate event selectors using Starknet keccak
27
25
  export const DEPOSIT_EVENT_SELECTOR = num.toHex(
28
26
  hash.starknetKeccak("Deposited")
@@ -34,21 +32,15 @@ export const RAGEQUIT_EVENT_SELECTOR = num.toHex(
34
32
  hash.starknetKeccak("RageQuit")
35
33
  ); // 0x2a2469e4569da9d3c3df9bc1a2ddece1e640a89b8ecd537da96f064d64c8183
36
34
 
37
- export const AUDIT_EVENT_SELECTOR = num.toHex(
38
- hash.starknetKeccak("AuditEvent")
39
- );
40
-
41
35
  // ABI event names for direct selection
42
36
  export const DEPOSIT_EVENT_ABI_NAME = "privacy_pools::interfaces::IPool::Deposited";
43
37
  export const WITHDRAWAL_EVENT_ABI_NAME = "privacy_pools::interfaces::IPool::Withdrawn";
44
38
  export const RAGEQUIT_EVENT_ABI_NAME = "privacy_pools::interfaces::IPool::RageQuit";
45
- export const AUDIT_EVENT_ABI_NAME = "privacy_pools::interfaces::IPool::AuditEvent";
46
39
 
47
40
  export const AbiEventName = {
48
41
  Deposit: DEPOSIT_EVENT_ABI_NAME,
49
42
  Withdraw: WITHDRAWAL_EVENT_ABI_NAME,
50
43
  Ragequit: RAGEQUIT_EVENT_ABI_NAME,
51
- Audit: AUDIT_EVENT_ABI_NAME,
52
44
  } as const;
53
45
 
54
46
  type AbiEventName = (typeof AbiEventName)[keyof typeof AbiEventName];
@@ -67,7 +59,6 @@ export interface StarknetWithdrawnEventData {
67
59
  newCommitmentHash: bigint;
68
60
  withdrawnValue: bigint;
69
61
  existingNullifierHash: bigint;
70
- auditorData: string;
71
62
  }
72
63
 
73
64
  export interface StarknetRageQuitEventData {
@@ -77,24 +68,15 @@ export interface StarknetRageQuitEventData {
77
68
  value: bigint;
78
69
  }
79
70
 
80
- export interface StarknetAuditEventData {
81
- tag: bigint;
82
- ciphertext:string;
83
- prevNullifierHash: bigint,
84
- newCommitment: bigint,
85
- }
86
-
87
71
  type AbiToEvent = {
88
72
  [AbiEventName.Deposit]: StarknetDepositedEventData;
89
73
  [AbiEventName.Withdraw]: StarknetWithdrawnEventData;
90
74
  [AbiEventName.Ragequit]: StarknetRageQuitEventData;
91
- [AbiEventName.Audit]: StarknetAuditEventData;
92
75
  };
93
76
 
94
77
  export type StarknetEvent =
95
78
  | StarknetDepositedEventData
96
79
  | StarknetWithdrawnEventData
97
- | StarknetAuditEventData
98
80
  | StarknetRageQuitEventData;
99
81
 
100
82
  /**
@@ -141,17 +123,15 @@ export class StarknetDataService {
141
123
  */
142
124
  async getDeposits(
143
125
  pool: PoolInfo,
144
- fromBlock: bigint = pool.deploymentBlock,
145
- label?: bigint,
126
+ fromBlock: bigint = pool.deploymentBlock
146
127
  ): Promise<DepositEvent[]> {
147
128
  try {
148
- const keys = label? [[DEPOSIT_EVENT_SELECTOR],[],[String(label)]] : [[DEPOSIT_EVENT_SELECTOR]];
149
129
  // Fetch events using Starknet provider
150
130
  const eventsResult = await this.getEvents({
151
131
  from_block: { block_number: Number(fromBlock) },
152
132
  to_block: "latest",
153
133
  address: pool.address,
154
- keys, // Filter by deposit event selector
134
+ keys: [[DEPOSIT_EVENT_SELECTOR]], // Filter by deposit event selector
155
135
  chunk_size: 1000, // Starknet pagination
156
136
  });
157
137
 
@@ -313,63 +293,6 @@ export class StarknetDataService {
313
293
  transactionHash: transactionHash || "0x0",
314
294
  } as RagequitEvent)
315
295
  );
316
- // PARSEAR
317
- } catch (error) {
318
- if (error instanceof StarknetSDKError) throw error;
319
- throw new StarknetSDKError(
320
- `Failed to fetch ragequits: ${error instanceof Error ? error.message : "Unknown error"
321
- }`,
322
- SNBaseErrorCode.UNKNOWN
323
- );
324
- }
325
- }
326
-
327
- async getAuditEventForTag(
328
- tag: bigint,
329
- pool: PoolInfo,
330
- fromBlock: bigint = pool.deploymentBlock
331
- ) {
332
- try {
333
- const eventsResult = await this.getEvents({
334
- from_block: { block_number: Number(fromBlock) },
335
- to_block: "latest",
336
- address: pool.address,
337
- keys: [[AUDIT_EVENT_SELECTOR], [String(tag)]],
338
- chunk_size: 1000,
339
- });
340
-
341
- // Parse all events at once using starknet.js event parser
342
- const abiEvents = events.getAbiEvents(PrivacyPoolABI);
343
- const parsedEvents = events.parseEvents(
344
- eventsResult,
345
- abiEvents,
346
- {},
347
- {},
348
- this.abiParser
349
- );
350
-
351
- return parsedEvents
352
- .filter(
353
- (parsedEvent) => parsedEvent[AUDIT_EVENT_ABI_NAME] !== undefined
354
- )
355
- .map((parsedEvent) => ({
356
- eventData: parsedEvent[
357
- AUDIT_EVENT_ABI_NAME
358
- ] as unknown as StarknetAuditEventData,
359
- blockNumber: parsedEvent.block_number,
360
- transactionHash: parsedEvent.transaction_hash,
361
- }))
362
- .map(
363
- ({ eventData, blockNumber, transactionHash }) =>
364
- ({
365
- tag: eventData.tag as Hash,
366
- ciphertext: eventData.ciphertext,
367
- prevNullifierHash: eventData.prevNullifierHash as Hash,
368
- newCommitment: eventData.newCommitment as Hash,
369
- blockNumber: BigInt(blockNumber || 0),
370
- transactionHash: transactionHash || "0x0",
371
- } as AuditEvent)
372
- );
373
296
  } catch (error) {
374
297
  if (error instanceof StarknetSDKError) throw error;
375
298
  throw new StarknetSDKError(
package/src/index.ts CHANGED
@@ -85,8 +85,3 @@ export {
85
85
  } from "./data.service.js";
86
86
 
87
87
  export { type StarknetAddress } from "./types/starknet.js";
88
-
89
- // Auditor
90
- export * from "./auditor.js";
91
-
92
- export * from './account.service.js';
@@ -1,9 +1,8 @@
1
- import { BigNumberish, cairo, CallData, num, CairoOption, byteArray } from "starknet";
1
+ import { BigNumberish, cairo, CallData, num } from "starknet";
2
2
 
3
3
  import { EntryPointABI } from "../abis/index.js";
4
4
  import { SNFormatError } from "../errors/index.js";
5
5
  import { StarknetAddress } from "./starknet.js";
6
- import { AuditorData } from "../auditor.js";
7
6
 
8
7
  const RelayDataAbi = [
9
8
  {
@@ -47,7 +46,6 @@ const entrypointCd = new CallData(EntryPointABI);
47
46
  export interface Withdrawal {
48
47
  /** The address of the processor handling this withdrawal */
49
48
  processor: BigNumberish,
50
- auditorData?: AuditorData;
51
49
  /** Additional data required for processing the withdrawal */
52
50
  data: BigNumberish[];
53
51
  }
@@ -115,48 +113,18 @@ export function parseRelayData(rawData: string[]): RelayData {
115
113
  * @returns Array of string representations of the withdrawal fields
116
114
  */
117
115
  export function serializeWithdrawal(withdrawal: Withdrawal): `0x${string}`[] {
118
- let result: `0x${string}`[] = [];
119
- const { processor, auditorData, data } = withdrawal;
120
-
121
- result.push(num.toHex64(processor) as `0x${string}`);
122
-
123
- if (auditorData === undefined) {
124
- result.push(num.toHex64(1) as `0x${string}`);
125
- } else {
126
- result.push(num.toHex64(0) as `0x${string}`);
127
- const { tag, ciphertext } = auditorData;
128
- const { low, high } = cairo.uint256(tag);
129
- result.push(num.toHex64(low) as `0x${string}`);
130
- result.push(num.toHex64(high) as `0x${string}`);
131
-
132
- const array = CallData.compile([byteArray.byteArrayFromString(ciphertext)]);
133
- array.forEach((x) => result.push(num.toHex64(x) as `0x${string}`));
134
- }
135
-
136
- result.push(num.toHex64(data.length) as `0x${string}`);
137
- data.forEach((x) => result.push(num.toHex64(x) as `0x${string}`));
138
- return result;
116
+ const { processor, data } = withdrawal;
117
+ return [
118
+ num.toHex64(processor) as `0x${string}`,
119
+ num.toHex64(data.length) as `0x${string}`,
120
+ ...data.map(x => num.toHex64(x) as `0x${string}`)
121
+ ];
139
122
  }
140
123
 
141
- type CairoWithdrawal = {
142
- processor: BigNumberish;
143
- data: BigNumberish[];
144
- auditorData: CairoOption<AuditorData>;
145
- };
146
- function isWithdrawal(data: unknown): data is CairoWithdrawal {
147
- const _data = data as CairoWithdrawal;
148
- return (
149
- _data.processor !== undefined &&
150
- num.isBigNumberish(_data.processor)
151
- ) && (
152
- _data.data !== undefined &&
153
- _data.data.every(num.isBigNumberish)
154
- ) && (
155
- (
156
- _data.auditorData.Some?.ciphertext !== undefined &&
157
- _data.auditorData.Some?.tag !== undefined
158
- ) || _data.auditorData.None !== undefined
159
- );
124
+ function isWithdrawal(data: unknown): data is Withdrawal {
125
+ const _data = data as Withdrawal;
126
+ return (_data.processor !== undefined && num.isBigNumberish(_data.processor))
127
+ && (_data.data !== undefined && _data.data.every(num.isBigNumberish));
160
128
  }
161
129
 
162
130
  /**
@@ -172,8 +140,7 @@ export function parseWithdrawal(rawData: string[]): Withdrawal {
172
140
  }
173
141
  const structName = "privacy_pools::interfaces::Structs::Withdrawal";
174
142
  const result = entrypointCd.decodeParameters(structName, rawData);
175
- if (isWithdrawal(result)) {
176
- return { ...result, auditorData: result.auditorData.unwrap() };
177
- }
143
+ if (isWithdrawal(result))
144
+ return result;
178
145
  throw SNFormatError.parse(`Can't parse Withdrawal from ${rawData}`);
179
146
  }
package/src/utils.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { WithdrawalProof } from "@0xbow/privacy-pools-core-sdk";
2
2
  import { poseidonHashMany } from "@scure/starknet";
3
- import { BigNumberish, cairo, CairoOption, CairoOptionVariant, num, uint256, Uint256, validateAndParseAddress, validateChecksumAddress } from "starknet";
3
+ import { BigNumberish, cairo, num, uint256, Uint256, validateAndParseAddress, validateChecksumAddress } from "starknet";
4
4
 
5
5
  import { getGroth16CallData } from "./garaga.js";
6
6
  import { snarkJsKeyIntoGaraga, snarkJsProofIntoGaraga } from "./types/conversions.js";
@@ -94,15 +94,3 @@ export function castBigInt(x: number | bigint | Uint256) {
94
94
  export function toAddress(x: BigNumberish): StarknetAddress {
95
95
  return validateAndParseAddress(x) as StarknetAddress;
96
96
  }
97
-
98
- export const Some = <T>(t: T): CairoOption<T> => {
99
- return new CairoOption<T>(CairoOptionVariant.Some, t);
100
- };
101
-
102
- export const None = <T>(): CairoOption<T> => {
103
- return new CairoOption<T>(CairoOptionVariant.None);
104
- };
105
-
106
- export const toCairoOption = <T>(t?: T): CairoOption<T> => {
107
- return t === undefined ? None() : Some(t);
108
- };
@@ -1,15 +0,0 @@
1
- import { AccountService, PoolAccount } from "@0xbow/privacy-pools-core-sdk";
2
- import { StarknetDataService } from "./data.service.js";
3
- import { AuditorData } from "./auditor.js";
4
- type AccountServiceConfig = Exclude<ConstructorParameters<typeof AccountService>[1], {
5
- account: any;
6
- }>;
7
- export declare class StarknetAccountService extends AccountService {
8
- private mnemonic;
9
- constructor(dataService: StarknetDataService, config: AccountServiceConfig);
10
- createAuditorData({ label, deposit, children }: PoolAccount, withdrawalValue?: bigint): {
11
- auditorData: AuditorData;
12
- withdrawalSecrets: ReturnType<StarknetAccountService['createWithdrawalSecrets']>;
13
- };
14
- }
15
- export {};
@@ -1,27 +0,0 @@
1
- import { AccountService } from "@0xbow/privacy-pools-core-sdk";
2
- import { deriveKeyFromMnemonic, packAuditorData, computeTag, encrypt } from "./auditor.js";
3
- import { base64 } from "@scure/base";
4
- export class StarknetAccountService extends AccountService {
5
- mnemonic;
6
- constructor(dataService, config) {
7
- super(dataService, config);
8
- this.mnemonic = config.mnemonic;
9
- }
10
- createAuditorData({ label, deposit, children }, withdrawalValue) {
11
- const viewKey = deriveKeyFromMnemonic(this.mnemonic, label);
12
- const accountCommitment = children.at(-1) || deposit;
13
- const withdrawalIndex = children.length;
14
- const withdrawalSecrets = this.createWithdrawalSecrets(accountCommitment);
15
- const packedData = packAuditorData({
16
- value: withdrawalValue || accountCommitment.value,
17
- label,
18
- ...withdrawalSecrets,
19
- });
20
- const cipherArray = encrypt(packedData, viewKey);
21
- const ciphertext = base64.encode(cipherArray);
22
- const tag = computeTag(viewKey, withdrawalIndex);
23
- const auditorData = { tag, ciphertext };
24
- return { auditorData, withdrawalSecrets };
25
- }
26
- }
27
- //# sourceMappingURL=account.service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"account.service.js","sourceRoot":"","sources":["../src/account.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAe,MAAM,+BAA+B,CAAC;AAE5E,OAAO,EAAe,qBAAqB,EAAC,eAAe,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAIpC,MAAM,OAAO,sBAAuB,SAAQ,cAAc;IAC9C,QAAQ,CAAS;IACzB,YAAY,WAAgC,EAAE,MAA4B;QACtE,KAAK,CAAC,WAAoB,EAAE,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACpC,CAAC;IAED,iBAAiB,CACb,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAe,EACzC,eAAwB;QAKxB,MAAM,OAAO,GAAG,qBAAqB,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC5D,MAAM,iBAAiB,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;QACrD,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC;QAExC,MAAM,iBAAiB,GAAG,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;QAE1E,MAAM,UAAU,GAAG,eAAe,CAAC;YAC/B,KAAK,EAAE,eAAe,IAAI,iBAAiB,CAAC,KAAK;YACjD,KAAK;YACL,GAAG,iBAAiB;SACvB,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAE9C,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QACjD,MAAM,WAAW,GAAgB,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;QACrD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;IAC9C,CAAC;CACJ"}
package/dist/auditor.d.ts DELETED
@@ -1,31 +0,0 @@
1
- import { AccountCommitment, Hash, PoolInfo } from "@0xbow/privacy-pools-core-sdk";
2
- import { StarknetDataService } from "./data.service.js";
3
- export interface AuditEvent {
4
- tag: Hash;
5
- ciphertext: string;
6
- prevNullifierHash: Hash;
7
- newCommitment: Hash;
8
- blockNumber: bigint;
9
- transactionHash: string;
10
- }
11
- export declare function deriveKey(secret: Uint8Array, label: bigint): Uint8Array;
12
- export declare function deriveKeyFromMnemonic(mnemonic: string, label: bigint): Uint8Array;
13
- export declare function encrypt(plaintext: Uint8Array, viewKey: Uint8Array): Uint8Array<ArrayBuffer>;
14
- export declare function decrypt(input: Uint8Array, viewKey: Uint8Array): Uint8Array;
15
- export declare function packAuditorData({ label: declaredLabel, value: declaredValue, nullifier: declaredNullifier, secret: declaredSecret }: Pick<AccountCommitment, 'label' | 'value' | 'nullifier' | 'secret'>): Uint8Array;
16
- export declare function unpackAuditorData(packedData: Uint8Array): {
17
- declaredLabel: bigint;
18
- declaredValue: bigint;
19
- declaredNullifier: bigint;
20
- declaredSecret: bigint;
21
- };
22
- export declare function reconstructAccountCommitment(event: AuditEvent, viewKey: Uint8Array): AccountCommitment;
23
- export declare function computeTag(viewKey: Uint8Array, withdraw_number: number): bigint;
24
- export declare function constructSequence(viewKey: Uint8Array, serviceData: StarknetDataService, pool: PoolInfo): Promise<AccountCommitment[]>;
25
- /**
26
- * Represents a AuditEvent event from a privacy pool
27
- */
28
- export interface AuditorData {
29
- tag: bigint;
30
- ciphertext: string;
31
- }
package/dist/auditor.js DELETED
@@ -1,148 +0,0 @@
1
- import { xchacha20poly1305 } from "@noble/ciphers/chacha.js";
2
- import { hkdf } from "@noble/hashes/hkdf.js";
3
- import { sha3_256 as sha256 } from "@noble/hashes/sha3.js";
4
- import { bytesToNumberBE, numberToBytesBE } from "@noble/ciphers/utils.js";
5
- import { getCommitment } from "@0xbow/privacy-pools-core-sdk";
6
- import { poseidonHashMany } from "@scure/starknet";
7
- import { base64 } from "@scure/base";
8
- import { mnemonicToEntropy } from "@scure/bip39";
9
- import { wordlist } from '@scure/bip39/wordlists/english';
10
- //TODO: The first time you will need to generate a viewing key is in the first withdraw
11
- // of a deposited note. At that point you allready have a label. I suggest for the viewKey to be derivable
12
- // from the account secret + deposit label. There is no need to store another secret for each deposit.
13
- // viewKey =~ Hash(AccountSecret, Label);
14
- export function deriveKey(secret, label) {
15
- const info = new TextEncoder().encode("xchacha-key");
16
- const salt = new TextEncoder().encode(String(label));
17
- const viewKey = hkdf(sha256, secret, salt, info, 32);
18
- return viewKey;
19
- }
20
- export function deriveKeyFromMnemonic(mnemonic, label) {
21
- const secret = mnemonicToEntropy(mnemonic, wordlist);
22
- return deriveKey(secret, label);
23
- }
24
- export function encrypt(plaintext, viewKey) {
25
- const nonce = crypto.getRandomValues(new Uint8Array(24));
26
- const chacha = xchacha20poly1305(viewKey, nonce);
27
- const ciphertext = chacha.encrypt(plaintext);
28
- // Prepend the nonce
29
- const output = new Uint8Array(24 + ciphertext.length);
30
- output.set(nonce, 0);
31
- output.set(ciphertext, 24);
32
- return output;
33
- }
34
- export function decrypt(input, viewKey) {
35
- const nonce = input.slice(0, 24);
36
- const chacha = xchacha20poly1305(viewKey, nonce);
37
- const ciphertext = input.slice(24);
38
- //TODO: What happens if AE fails?
39
- const decrypted = chacha.decrypt(ciphertext);
40
- return decrypted;
41
- }
42
- export function packAuditorData({ label: declaredLabel, value: declaredValue, nullifier: declaredNullifier, secret: declaredSecret }) {
43
- //TODO: Add assertions about lenght of bigint
44
- const output = new Uint8Array(128);
45
- output.set(numberToBytesBE(declaredLabel, 32), 0);
46
- output.set(numberToBytesBE(declaredValue, 32), 32);
47
- output.set(numberToBytesBE(declaredNullifier, 32), 64);
48
- output.set(numberToBytesBE(declaredSecret, 32), 96);
49
- return output;
50
- }
51
- export function unpackAuditorData(packedData) {
52
- const declaredLabel = bytesToNumberBE(packedData.slice(0, 32));
53
- const declaredValue = bytesToNumberBE(packedData.slice(32, 64));
54
- const declaredNullifier = bytesToNumberBE(packedData.slice(64, 96));
55
- const declaredSecret = bytesToNumberBE(packedData.slice(96, 128));
56
- return { declaredLabel, declaredValue, declaredNullifier, declaredSecret };
57
- }
58
- export function reconstructAccountCommitment(event, viewKey) {
59
- const { ciphertext, blockNumber, transactionHash, prevNullifierHash } = event;
60
- const auditorData = decrypt(base64.decode(ciphertext), viewKey);
61
- const { declaredLabel, declaredValue, declaredNullifier, declaredSecret } = unpackAuditorData(auditorData);
62
- const { hash, nullifierHash, preimage: { value: _value, label, precommitment: _precommitment } } = getCommitment(declaredValue, declaredLabel, declaredNullifier, declaredSecret);
63
- if (nullifierHash != prevNullifierHash) {
64
- throw new Error("Inconsistency in emitted nullifier hash");
65
- }
66
- return {
67
- hash,
68
- value: declaredValue,
69
- label: label,
70
- nullifier: declaredNullifier,
71
- secret: declaredSecret,
72
- blockNumber,
73
- txHash: transactionHash,
74
- };
75
- }
76
- export function computeTag(viewKey, withdraw_number) {
77
- const viewKeyBigInt = bytesToNumberBE(viewKey);
78
- const tag = poseidonHashMany([viewKeyBigInt, BigInt(withdraw_number)]);
79
- return tag;
80
- }
81
- ;
82
- async function fetchAuditEventsForViewKey(viewKey, serviceData, pool) {
83
- let out = [];
84
- let withdraw_number = 0;
85
- while (true) {
86
- let tag = computeTag(viewKey, withdraw_number);
87
- let events = await serviceData.getAuditEventForTag(tag, pool);
88
- if (!events) {
89
- break;
90
- }
91
- ;
92
- //It should be only ONE event with this tag. But it is not eforced. A troll could make a withdraw with
93
- //the tag of a previous withraw from another label.
94
- events.forEach(event => out.push([event, withdraw_number]));
95
- withdraw_number++;
96
- }
97
- return out;
98
- }
99
- export async function constructSequence(viewKey, serviceData, pool) {
100
- const commitments = [];
101
- const events = await fetchAuditEventsForViewKey(viewKey, serviceData, pool);
102
- const events_for_index = events.filter(([_, b]) => b === 0);
103
- if (events_for_index.length === 0) {
104
- throw new Error("No withdraws for this key");
105
- }
106
- let declaredCommitment;
107
- for (const [event, _withdraw_number] of events_for_index) {
108
- try {
109
- declaredCommitment = reconstructAccountCommitment(event, viewKey);
110
- }
111
- catch {
112
- //What should we do here?
113
- }
114
- }
115
- if (!declaredCommitment) {
116
- throw new Error("No event could be decrypted");
117
- }
118
- let initialLabel = declaredCommitment.label;
119
- let deposit = await serviceData.getDeposits(pool, pool.deploymentBlock, initialLabel);
120
- if (deposit.length != 1) {
121
- throw new Error("No deposit found for this label");
122
- }
123
- let initialCommitment = deposit[0].commitment;
124
- if (initialCommitment != declaredCommitment.hash) {
125
- throw new Error("mismatch");
126
- }
127
- commitments.push(declaredCommitment);
128
- for (let i = 1; i < events.length; i++) {
129
- let events_for_index = events.filter(([_, b]) => b === i);
130
- for (const [event, _withdraw_number] of events_for_index) {
131
- try {
132
- declaredCommitment = reconstructAccountCommitment(event, viewKey);
133
- }
134
- catch {
135
- //What should we do here?
136
- }
137
- }
138
- if (initialLabel != declaredCommitment.label) {
139
- throw new Error("mismatch");
140
- }
141
- if (commitments[i - 1].hash != declaredCommitment.hash) {
142
- throw new Error("mismatch");
143
- }
144
- commitments.push(declaredCommitment);
145
- }
146
- return commitments;
147
- }
148
- //# sourceMappingURL=auditor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auditor.js","sourceRoot":"","sources":["../src/auditor.ts"],"names":[],"mappings":"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"}
@@ -1,42 +0,0 @@
1
- import { AccountService, PoolAccount } from "@0xbow/privacy-pools-core-sdk";
2
- import { StarknetDataService } from "./data.service.js";
3
- import { AuditorData, deriveKeyFromMnemonic,packAuditorData, computeTag, encrypt } from "./auditor.js";
4
- import { base64 } from "@scure/base"
5
-
6
- type AccountServiceConfig = Exclude<ConstructorParameters<typeof AccountService>[1], {account:any}>
7
-
8
- export class StarknetAccountService extends AccountService {
9
- private mnemonic: string;
10
- constructor(dataService: StarknetDataService, config: AccountServiceConfig){
11
- super(dataService as never, config);
12
- this.mnemonic = config.mnemonic;
13
- }
14
-
15
- createAuditorData(
16
- { label, deposit, children }: PoolAccount,
17
- withdrawalValue?: bigint
18
- ): {
19
- auditorData: AuditorData;
20
- withdrawalSecrets: ReturnType<StarknetAccountService['createWithdrawalSecrets']>;
21
- } {
22
- const viewKey = deriveKeyFromMnemonic(this.mnemonic, label);
23
- const accountCommitment = children.at(-1) || deposit;
24
- const withdrawalIndex = children.length;
25
-
26
- const withdrawalSecrets = this.createWithdrawalSecrets(accountCommitment);
27
-
28
- const packedData = packAuditorData({
29
- value: withdrawalValue || accountCommitment.value,
30
- label,
31
- ...withdrawalSecrets,
32
- });
33
-
34
- const cipherArray = encrypt(packedData, viewKey);
35
- const ciphertext = base64.encode(cipherArray);
36
-
37
- const tag = computeTag(viewKey, withdrawalIndex);
38
- const auditorData: AuditorData = { tag, ciphertext };
39
- return { auditorData, withdrawalSecrets };
40
- }
41
- }
42
-