@permissionless-technologies/upp-sdk 0.5.2 → 0.5.4
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.
- package/dist/{chunk-6DCMXFSQ.cjs → chunk-4T5DWZBN.cjs} +217 -4
- package/dist/chunk-4T5DWZBN.cjs.map +1 -0
- package/dist/{chunk-MVSBQMRA.js → chunk-4W7BBQ4H.js} +212 -4
- package/dist/chunk-4W7BBQ4H.js.map +1 -0
- package/dist/chunk-ABVALIIG.js +152 -0
- package/dist/chunk-ABVALIIG.js.map +1 -0
- package/dist/chunk-ARH2SJM3.cjs +155 -0
- package/dist/chunk-ARH2SJM3.cjs.map +1 -0
- package/dist/index.cjs +3 -3
- package/dist/index.js +2 -2
- package/dist/indexer/index.cjs +25 -25
- package/dist/indexer/index.d.cts +6 -0
- package/dist/indexer/index.d.ts +6 -0
- package/dist/indexer/index.js +2 -2
- package/dist/react/index.cjs +3 -3
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +3 -3
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6DCMXFSQ.cjs.map +0 -1
- package/dist/chunk-ERQE57IA.cjs +0 -404
- package/dist/chunk-ERQE57IA.cjs.map +0 -1
- package/dist/chunk-MVSBQMRA.js.map +0 -1
- package/dist/chunk-XV72HNHN.js +0 -399
- package/dist/chunk-XV72HNHN.js.map +0 -1
|
@@ -1,8 +1,216 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkARH2SJM3_cjs = require('./chunk-ARH2SJM3.cjs');
|
|
4
4
|
var viem = require('viem');
|
|
5
5
|
|
|
6
|
+
// src/indexer/storage/localStorage.ts
|
|
7
|
+
var LocalStorageAdapter = class {
|
|
8
|
+
prefix;
|
|
9
|
+
constructor(prefix = "") {
|
|
10
|
+
this.prefix = prefix;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Check if localStorage is available
|
|
14
|
+
*/
|
|
15
|
+
isAvailable() {
|
|
16
|
+
if (typeof window === "undefined") return false;
|
|
17
|
+
try {
|
|
18
|
+
const test = "__storage_test__";
|
|
19
|
+
window.localStorage.setItem(test, test);
|
|
20
|
+
window.localStorage.removeItem(test);
|
|
21
|
+
return true;
|
|
22
|
+
} catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get the full key with prefix
|
|
28
|
+
*/
|
|
29
|
+
getKey(key) {
|
|
30
|
+
return this.prefix ? `upp:${this.prefix}:${key}` : `upp:${key}`;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get a value by key
|
|
34
|
+
*/
|
|
35
|
+
async get(key) {
|
|
36
|
+
if (!this.isAvailable()) {
|
|
37
|
+
throw new Error("localStorage is not available");
|
|
38
|
+
}
|
|
39
|
+
const fullKey = this.getKey(key);
|
|
40
|
+
const value = localStorage.getItem(fullKey);
|
|
41
|
+
if (value === null) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
return JSON.parse(value);
|
|
46
|
+
} catch {
|
|
47
|
+
console.warn(`Failed to parse localStorage value for key "${fullKey}"`);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Set a value
|
|
53
|
+
*/
|
|
54
|
+
async set(key, value) {
|
|
55
|
+
if (!this.isAvailable()) {
|
|
56
|
+
throw new Error("localStorage is not available");
|
|
57
|
+
}
|
|
58
|
+
const fullKey = this.getKey(key);
|
|
59
|
+
try {
|
|
60
|
+
const serialized = JSON.stringify(value);
|
|
61
|
+
localStorage.setItem(fullKey, serialized);
|
|
62
|
+
} catch (e) {
|
|
63
|
+
if (e instanceof Error && e.name === "QuotaExceededError") {
|
|
64
|
+
throw new Error("localStorage quota exceeded. Consider using IndexedDB instead.");
|
|
65
|
+
}
|
|
66
|
+
throw e;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Delete a value
|
|
71
|
+
*/
|
|
72
|
+
async delete(key) {
|
|
73
|
+
if (!this.isAvailable()) {
|
|
74
|
+
throw new Error("localStorage is not available");
|
|
75
|
+
}
|
|
76
|
+
const fullKey = this.getKey(key);
|
|
77
|
+
localStorage.removeItem(fullKey);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Clear all data with this prefix
|
|
81
|
+
*/
|
|
82
|
+
async clear() {
|
|
83
|
+
if (!this.isAvailable()) {
|
|
84
|
+
throw new Error("localStorage is not available");
|
|
85
|
+
}
|
|
86
|
+
const prefix = this.prefix ? `upp:${this.prefix}:` : "upp:";
|
|
87
|
+
const keysToRemove = [];
|
|
88
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
89
|
+
const key = localStorage.key(i);
|
|
90
|
+
if (key && key.startsWith(prefix)) {
|
|
91
|
+
keysToRemove.push(key);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
for (const key of keysToRemove) {
|
|
95
|
+
localStorage.removeItem(key);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
function createLocalStorageAdapter(prefix = "") {
|
|
100
|
+
return new LocalStorageAdapter(prefix);
|
|
101
|
+
}
|
|
102
|
+
var localStorageAdapter = createLocalStorageAdapter();
|
|
103
|
+
|
|
104
|
+
// src/indexer/storage/memory.ts
|
|
105
|
+
var MemoryAdapter = class {
|
|
106
|
+
store;
|
|
107
|
+
prefix;
|
|
108
|
+
constructor(prefix = "") {
|
|
109
|
+
this.store = /* @__PURE__ */ new Map();
|
|
110
|
+
this.prefix = prefix;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Always available
|
|
114
|
+
*/
|
|
115
|
+
isAvailable() {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get the full key with prefix
|
|
120
|
+
*/
|
|
121
|
+
getKey(key) {
|
|
122
|
+
return this.prefix ? `${this.prefix}:${key}` : key;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get a value by key
|
|
126
|
+
*/
|
|
127
|
+
async get(key) {
|
|
128
|
+
const fullKey = this.getKey(key);
|
|
129
|
+
const value = this.store.get(fullKey);
|
|
130
|
+
return value ?? null;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Set a value
|
|
134
|
+
*/
|
|
135
|
+
async set(key, value) {
|
|
136
|
+
const fullKey = this.getKey(key);
|
|
137
|
+
this.store.set(fullKey, structuredClone(value));
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Delete a value
|
|
141
|
+
*/
|
|
142
|
+
async delete(key) {
|
|
143
|
+
const fullKey = this.getKey(key);
|
|
144
|
+
this.store.delete(fullKey);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Clear all data with this prefix
|
|
148
|
+
*/
|
|
149
|
+
async clear() {
|
|
150
|
+
if (!this.prefix) {
|
|
151
|
+
this.store.clear();
|
|
152
|
+
} else {
|
|
153
|
+
const keysToDelete = [];
|
|
154
|
+
for (const key of this.store.keys()) {
|
|
155
|
+
if (key.startsWith(`${this.prefix}:`)) {
|
|
156
|
+
keysToDelete.push(key);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
for (const key of keysToDelete) {
|
|
160
|
+
this.store.delete(key);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get the number of stored items (for testing)
|
|
166
|
+
*/
|
|
167
|
+
size() {
|
|
168
|
+
if (!this.prefix) {
|
|
169
|
+
return this.store.size;
|
|
170
|
+
}
|
|
171
|
+
let count = 0;
|
|
172
|
+
for (const key of this.store.keys()) {
|
|
173
|
+
if (key.startsWith(`${this.prefix}:`)) {
|
|
174
|
+
count++;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return count;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Get all keys (for testing)
|
|
181
|
+
*/
|
|
182
|
+
keys() {
|
|
183
|
+
const result = [];
|
|
184
|
+
const prefixToRemove = this.prefix ? `${this.prefix}:` : "";
|
|
185
|
+
for (const key of this.store.keys()) {
|
|
186
|
+
if (!this.prefix || key.startsWith(prefixToRemove)) {
|
|
187
|
+
result.push(this.prefix ? key.slice(prefixToRemove.length) : key);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
function createMemoryAdapter(prefix = "") {
|
|
194
|
+
return new MemoryAdapter(prefix);
|
|
195
|
+
}
|
|
196
|
+
var memoryAdapter = createMemoryAdapter();
|
|
197
|
+
|
|
198
|
+
// src/indexer/storage/index.ts
|
|
199
|
+
function createAutoAdapter(prefix = "") {
|
|
200
|
+
if (typeof window !== "undefined" && "indexedDB" in window) {
|
|
201
|
+
return chunkARH2SJM3_cjs.createIndexedDBAdapter(prefix);
|
|
202
|
+
}
|
|
203
|
+
if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
|
|
204
|
+
try {
|
|
205
|
+
const test = "__storage_test__";
|
|
206
|
+
localStorage.setItem(test, test);
|
|
207
|
+
localStorage.removeItem(test);
|
|
208
|
+
return createLocalStorageAdapter(prefix);
|
|
209
|
+
} catch {
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return createMemoryAdapter(prefix);
|
|
213
|
+
}
|
|
6
214
|
async function computeSearchTag(sdk, masterViewingSecret, masterViewingPubKey, ephemeralPubkey, debug = false) {
|
|
7
215
|
const dvk = await sdk.deriveDecryptionViewingKey(
|
|
8
216
|
masterViewingSecret,
|
|
@@ -330,7 +538,7 @@ var RpcIndexer = class {
|
|
|
330
538
|
this.batchDelayMs = config.batchDelayMs ?? BATCH_DELAY_MS;
|
|
331
539
|
this.initialFromBlock = config.fromBlock ?? 0;
|
|
332
540
|
const accountPrefix = `${config.chainId}_${config.contractAddress.slice(2, 10)}_${viem.toHex(config.spendingPubkey.x).slice(2, 12)}`;
|
|
333
|
-
this.storage = config.storage ??
|
|
541
|
+
this.storage = config.storage ?? createAutoAdapter(accountPrefix);
|
|
334
542
|
this.rateLimiter = new RateLimiter(DEFAULT_REQUESTS_PER_SECOND, DEFAULT_MAX_CONCURRENT);
|
|
335
543
|
}
|
|
336
544
|
/**
|
|
@@ -990,9 +1198,14 @@ function sleep(ms) {
|
|
|
990
1198
|
}
|
|
991
1199
|
|
|
992
1200
|
exports.computeSearchTag = computeSearchTag;
|
|
1201
|
+
exports.createAutoAdapter = createAutoAdapter;
|
|
1202
|
+
exports.createLocalStorageAdapter = createLocalStorageAdapter;
|
|
1203
|
+
exports.createMemoryAdapter = createMemoryAdapter;
|
|
1204
|
+
exports.localStorageAdapter = localStorageAdapter;
|
|
993
1205
|
exports.makeRpcIndexer = makeRpcIndexer;
|
|
994
1206
|
exports.matchesSearchTag = matchesSearchTag;
|
|
1207
|
+
exports.memoryAdapter = memoryAdapter;
|
|
995
1208
|
exports.tryDecryptNote = tryDecryptNote;
|
|
996
1209
|
exports.unpackNoteData = unpackNoteData;
|
|
997
|
-
//# sourceMappingURL=chunk-
|
|
998
|
-
//# sourceMappingURL=chunk-
|
|
1210
|
+
//# sourceMappingURL=chunk-4T5DWZBN.cjs.map
|
|
1211
|
+
//# sourceMappingURL=chunk-4T5DWZBN.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/indexer/storage/localStorage.ts","../src/indexer/storage/memory.ts","../src/indexer/storage/index.ts","../src/indexer/decryption.ts","../src/indexer/rpc.ts"],"names":["createIndexedDBAdapter","keccak256","toHex","eventsProcessed","eventsSkipped","tryDecryptNote"],"mappings":"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","file":"chunk-4T5DWZBN.cjs","sourcesContent":["/**\n * localStorage Storage Adapter\n *\n * Provides persistent storage using localStorage for browser environments.\n * This is a fallback adapter when IndexedDB is not available or for simpler use cases.\n *\n * Limitations:\n * - 5MB storage limit per origin\n * - Synchronous API (blocks main thread on large operations)\n * - Data must be JSON serializable\n */\n\nimport type { StorageAdapter } from '../types.js'\n\n/**\n * localStorage storage adapter\n */\nclass LocalStorageAdapter implements StorageAdapter {\n private prefix: string\n\n constructor(prefix: string = '') {\n this.prefix = prefix\n }\n\n /**\n * Check if localStorage is available\n */\n isAvailable(): boolean {\n if (typeof window === 'undefined') return false\n try {\n const test = '__storage_test__'\n window.localStorage.setItem(test, test)\n window.localStorage.removeItem(test)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get the full key with prefix\n */\n private getKey(key: string): string {\n return this.prefix ? `upp:${this.prefix}:${key}` : `upp:${key}`\n }\n\n /**\n * Get a value by key\n */\n async get<T>(key: string): Promise<T | null> {\n if (!this.isAvailable()) {\n throw new Error('localStorage is not available')\n }\n\n const fullKey = this.getKey(key)\n const value = localStorage.getItem(fullKey)\n\n if (value === null) {\n return null\n }\n\n try {\n return JSON.parse(value) as T\n } catch {\n // If JSON parse fails, return null\n console.warn(`Failed to parse localStorage value for key \"${fullKey}\"`)\n return null\n }\n }\n\n /**\n * Set a value\n */\n async set<T>(key: string, value: T): Promise<void> {\n if (!this.isAvailable()) {\n throw new Error('localStorage is not available')\n }\n\n const fullKey = this.getKey(key)\n\n try {\n const serialized = JSON.stringify(value)\n localStorage.setItem(fullKey, serialized)\n } catch (e) {\n if (e instanceof Error && e.name === 'QuotaExceededError') {\n throw new Error('localStorage quota exceeded. Consider using IndexedDB instead.')\n }\n throw e\n }\n }\n\n /**\n * Delete a value\n */\n async delete(key: string): Promise<void> {\n if (!this.isAvailable()) {\n throw new Error('localStorage is not available')\n }\n\n const fullKey = this.getKey(key)\n localStorage.removeItem(fullKey)\n }\n\n /**\n * Clear all data with this prefix\n */\n async clear(): Promise<void> {\n if (!this.isAvailable()) {\n throw new Error('localStorage is not available')\n }\n\n const prefix = this.prefix ? `upp:${this.prefix}:` : 'upp:'\n const keysToRemove: string[] = []\n\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key && key.startsWith(prefix)) {\n keysToRemove.push(key)\n }\n }\n\n for (const key of keysToRemove) {\n localStorage.removeItem(key)\n }\n }\n}\n\n/**\n * Create a localStorage storage adapter\n *\n * @param prefix - Optional prefix for keys (useful for multi-account)\n * @returns StorageAdapter instance\n *\n * @example\n * ```ts\n * const storage = createLocalStorageAdapter('account_0x123')\n * await storage.set('notes', myNotes)\n * const notes = await storage.get('notes')\n * ```\n */\nexport function createLocalStorageAdapter(prefix: string = ''): StorageAdapter {\n return new LocalStorageAdapter(prefix)\n}\n\n/**\n * Default localStorage adapter instance (no prefix)\n */\nexport const localStorageAdapter = createLocalStorageAdapter()\n","/**\n * In-Memory Storage Adapter\n *\n * Provides non-persistent storage for testing and development.\n * Data is lost when the process ends or the adapter is cleared.\n *\n * Use cases:\n * - Unit tests\n * - Server-side rendering (where IndexedDB/localStorage aren't available)\n * - Development without persistence\n */\n\nimport type { StorageAdapter } from '../types.js'\n\n/**\n * In-memory storage adapter\n */\nclass MemoryAdapter implements StorageAdapter {\n private store: Map<string, unknown>\n private prefix: string\n\n constructor(prefix: string = '') {\n this.store = new Map()\n this.prefix = prefix\n }\n\n /**\n * Always available\n */\n isAvailable(): boolean {\n return true\n }\n\n /**\n * Get the full key with prefix\n */\n private getKey(key: string): string {\n return this.prefix ? `${this.prefix}:${key}` : key\n }\n\n /**\n * Get a value by key\n */\n async get<T>(key: string): Promise<T | null> {\n const fullKey = this.getKey(key)\n const value = this.store.get(fullKey)\n return (value as T) ?? null\n }\n\n /**\n * Set a value\n */\n async set<T>(key: string, value: T): Promise<void> {\n const fullKey = this.getKey(key)\n // Deep clone to prevent external mutations\n this.store.set(fullKey, structuredClone(value))\n }\n\n /**\n * Delete a value\n */\n async delete(key: string): Promise<void> {\n const fullKey = this.getKey(key)\n this.store.delete(fullKey)\n }\n\n /**\n * Clear all data with this prefix\n */\n async clear(): Promise<void> {\n if (!this.prefix) {\n this.store.clear()\n } else {\n const keysToDelete: string[] = []\n for (const key of this.store.keys()) {\n if (key.startsWith(`${this.prefix}:`)) {\n keysToDelete.push(key)\n }\n }\n for (const key of keysToDelete) {\n this.store.delete(key)\n }\n }\n }\n\n /**\n * Get the number of stored items (for testing)\n */\n size(): number {\n if (!this.prefix) {\n return this.store.size\n }\n let count = 0\n for (const key of this.store.keys()) {\n if (key.startsWith(`${this.prefix}:`)) {\n count++\n }\n }\n return count\n }\n\n /**\n * Get all keys (for testing)\n */\n keys(): string[] {\n const result: string[] = []\n const prefixToRemove = this.prefix ? `${this.prefix}:` : ''\n for (const key of this.store.keys()) {\n if (!this.prefix || key.startsWith(prefixToRemove)) {\n result.push(this.prefix ? key.slice(prefixToRemove.length) : key)\n }\n }\n return result\n }\n}\n\n/**\n * Create an in-memory storage adapter\n *\n * @param prefix - Optional prefix for keys\n * @returns StorageAdapter instance\n *\n * @example\n * ```ts\n * const storage = createMemoryAdapter()\n * await storage.set('notes', myNotes)\n * const notes = await storage.get('notes')\n * ```\n */\nexport function createMemoryAdapter(prefix: string = ''): StorageAdapter & {\n size(): number\n keys(): string[]\n} {\n return new MemoryAdapter(prefix)\n}\n\n/**\n * Default in-memory adapter instance (no prefix)\n */\nexport const memoryAdapter = createMemoryAdapter()\n","/**\n * Storage Adapters\n *\n * Pluggable storage backends for the indexer.\n */\n\n// Types\nexport type { StorageAdapter, IndexerState, SyncState, SerializedNote } from './types.js'\n\n// IndexedDB adapter (default, recommended)\nexport { createIndexedDBAdapter, indexedDBAdapter } from './indexedDB.js'\n\n// localStorage adapter (fallback)\nexport { createLocalStorageAdapter, localStorageAdapter } from './localStorage.js'\n\n// In-memory adapter (testing)\nexport { createMemoryAdapter, memoryAdapter } from './memory.js'\n\n// Static imports for createAutoAdapter (avoid require() which breaks ESM)\nimport { createIndexedDBAdapter } from './indexedDB.js'\nimport { createLocalStorageAdapter } from './localStorage.js'\nimport { createMemoryAdapter } from './memory.js'\nimport type { StorageAdapter } from './types.js'\n\n/**\n * Create the best available storage adapter\n *\n * Tries IndexedDB first, falls back to localStorage, then memory.\n *\n * @param prefix - Optional prefix for keys\n * @returns The best available StorageAdapter\n */\nexport function createAutoAdapter(prefix: string = ''): StorageAdapter {\n if (typeof window !== 'undefined' && 'indexedDB' in window) {\n return createIndexedDBAdapter(prefix)\n }\n\n if (typeof window !== 'undefined' && typeof localStorage !== 'undefined') {\n try {\n const test = '__storage_test__'\n localStorage.setItem(test, test)\n localStorage.removeItem(test)\n return createLocalStorageAdapter(prefix)\n } catch {\n // localStorage not available\n }\n }\n\n return createMemoryAdapter(prefix)\n}\n","/**\n * Decryption utilities for UPP note discovery\n *\n * This module contains the trial decryption logic used by indexers (RPC, Subsquid, etc.)\n * to find notes belonging to a particular account.\n *\n * Key concepts:\n * - Search tag: Lower 64 bits of Poseidon(viewingSharedSecret.x, 0), used to quickly filter events\n * - Dual ECDH: Viewing key for decryption, spending key for commitment verification\n * - UPP note format: amount (32) + blinding (32) + origin (20) + token (20) = 104 bytes\n */\n\nimport { keccak256, toHex, type Hex } from 'viem' // keccak256 still used for AES key derivation\nimport type { Point } from '../utils/babyjubjub.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DecryptedNote {\n amount: bigint\n blinding: bigint\n oneTimeSecret: bigint\n oneTimePubkey: Point\n origin: bigint\n token: bigint\n}\n\nexport interface UnpackedNoteData {\n searchTag: bigint\n ephemeralPubkeyX: bigint\n ephemeralPubkeyY: bigint\n encryptedNote: Hex\n}\n\nexport interface DecryptionKeys {\n spendingSecret: bigint\n spendingPubkey: Point\n masterViewingSecret: bigint\n masterViewingPubKey: Point\n}\n\n// SDK type (loaded dynamically to avoid circular deps)\ntype SDK = typeof import('../index.js')\n\n// ============================================================================\n// Search Tag Filtering\n// ============================================================================\n\n/**\n * Compute the expected search tag for a given ephemeral public key\n *\n * The search tag is computed as: Poseidon(viewingSharedSecret.x, 0) & ((1n << 64n) - 1n)\n * This must match how search tags are computed during note creation in createUPPNote().\n *\n * - DVK is the derived viewing key (derived from master viewing key using R.x as nonce)\n * - R is the ephemeral public key\n * - viewingSharedSecret = DVK * R\n *\n * This allows quick filtering of events before expensive trial decryption.\n */\nexport async function computeSearchTag(\n sdk: SDK,\n masterViewingSecret: bigint,\n masterViewingPubKey: Point,\n ephemeralPubkey: Point,\n debug: boolean = false\n): Promise<bigint> {\n // Derive DVK using R.x as nonce (same as in decryption)\n const dvk = await sdk.deriveDecryptionViewingKey(\n masterViewingSecret,\n masterViewingPubKey,\n ephemeralPubkey.x\n )\n\n // Compute shared secret\n const viewingSharedSecret = await sdk.computeSharedSecret(dvk, ephemeralPubkey)\n\n // Search tag = lower 64 bits of Poseidon(sharedSecret.x, 0)\n // This must match the computation in createUPPNote()\n const searchTagHash = await sdk.poseidon([viewingSharedSecret.x, 0n])\n const searchTag = searchTagHash & ((1n << 64n) - 1n)\n\n if (debug) {\n console.log(`[computeSearchTag] viewingSharedSecret.x: ${viewingSharedSecret.x}`)\n console.log(`[computeSearchTag] searchTagHash: ${searchTagHash}`)\n console.log(`[computeSearchTag] searchTag (lower 64 bits): ${searchTag}`)\n }\n\n return searchTag\n}\n\n/**\n * Check if a search tag from an event matches our viewing key\n *\n * This is a fast check that can filter out 99%+ of events before\n * attempting expensive trial decryption.\n *\n * @param eventSearchTag - The search tag from the event (8 bytes as bigint)\n * @param sdk - The loaded SDK module\n * @param masterViewingSecret - Our master viewing secret\n * @param masterViewingPubKey - Our master viewing public key\n * @param ephemeralPubkey - The ephemeral public key from the event\n * @param debug - Enable debug logging\n * @returns true if the search tag matches (event might be ours)\n */\nexport async function matchesSearchTag(\n eventSearchTag: bigint,\n sdk: SDK,\n masterViewingSecret: bigint,\n masterViewingPubKey: Point,\n ephemeralPubkey: Point,\n debug: boolean = false\n): Promise<boolean> {\n const expectedTag = await computeSearchTag(\n sdk,\n masterViewingSecret,\n masterViewingPubKey,\n ephemeralPubkey,\n debug\n )\n\n if (debug) {\n console.log(`[matchesSearchTag] eventSearchTag: ${eventSearchTag}, expectedTag: ${expectedTag}, match: ${eventSearchTag === expectedTag}`)\n }\n\n return eventSearchTag === expectedTag\n}\n\n// ============================================================================\n// Note Decryption\n// ============================================================================\n\n/**\n * Try to decrypt a note using dual ECDH (UPP format with origin and token)\n *\n * 1. Viewing ECDH: DVK * R → AES decryption key (viewing shared secret)\n * 2. Spending ECDH: spendingSecret * R → one-time key for commitment verification\n *\n * DVK is derived using R.x (ephemeral public key x-coordinate) as the nonce.\n *\n * UPP encrypted payload: amount (32) + blinding (32) + origin (20) + token (20) = 104 bytes\n * UPP commitment: Poseidon(amount, pubkeyX, pubkeyY, blinding, origin, token)\n *\n * @param sdk - The loaded SDK module\n * @param keys - Decryption keys (spending and viewing)\n * @param ephemeralPubkey - The ephemeral public key from the event\n * @param encryptedNote - The encrypted note data\n * @param expectedCommitment - The commitment to verify against\n * @param debug - Enable debug logging\n * @returns Decrypted note data or null if decryption/verification failed\n */\nexport async function tryDecryptNote(\n sdk: SDK,\n keys: DecryptionKeys,\n ephemeralPubkey: Point,\n encryptedNote: Hex,\n expectedCommitment: bigint,\n debug: boolean = false\n): Promise<DecryptedNote | null> {\n try {\n // --- ECDH #2: Viewing key (note decryption) ---\n // Derive DVK using R.x as nonce\n const dvk = await sdk.deriveDecryptionViewingKey(\n keys.masterViewingSecret,\n keys.masterViewingPubKey,\n ephemeralPubkey.x\n )\n const viewingSharedSecret = await sdk.computeSharedSecret(dvk, ephemeralPubkey)\n\n // Derive AES key from viewing shared secret\n const keyMaterial = keccak256(toHex(viewingSharedSecret.x, { size: 32 }))\n const keyBytes = hexToBytes(keyMaterial)\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n keyBytes.buffer.slice(keyBytes.byteOffset, keyBytes.byteOffset + keyBytes.byteLength) as ArrayBuffer,\n { name: 'AES-GCM', length: 256 },\n false,\n ['decrypt']\n )\n\n // Parse encrypted note\n const encryptedBytes = hexToBytes(encryptedNote)\n const nonce = encryptedBytes.slice(0, 12)\n const ciphertext = encryptedBytes.slice(12)\n\n // Decrypt\n const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: nonce }, cryptoKey, ciphertext)\n\n const plaintextBytes = new Uint8Array(plaintext)\n if (debug) {\n console.log(`[tryDecryptNote] Decrypted plaintext length: ${plaintextBytes.length} bytes`)\n }\n\n // UPP payload: amount (32) + blinding (32) + origin (20) + token (20) = 104 bytes\n const amount = bytesToBigint(plaintextBytes.slice(0, 32))\n const blinding = bytesToBigint(plaintextBytes.slice(32, 64))\n const origin = bytesToBigint(plaintextBytes.slice(64, 84))\n const token = bytesToBigint(plaintextBytes.slice(84, 104))\n\n // --- Hash-based ownership verification (BLS12-381) ---\n // ownerHash = Poseidon(spendingSecret)\n // commitment = Poseidon(amount, ownerHash, blinding, origin, token)\n const ownerHash = await sdk.poseidon([keys.spendingSecret])\n const oneTimeSecret = keys.spendingSecret\n\n const computedCommitment = await sdk.poseidon([\n amount,\n ownerHash,\n blinding,\n origin,\n token,\n ])\n\n if (debug) {\n console.log(`[tryDecryptNote] Decrypted values:`)\n console.log(` amount: ${amount}`)\n console.log(` blinding: ${blinding}`)\n console.log(` origin: 0x${origin.toString(16).padStart(40, '0')}`)\n console.log(` token: 0x${token.toString(16).padStart(40, '0')}`)\n console.log(` ownerHash: ${ownerHash}`)\n console.log(` computedCommitment: ${computedCommitment}`)\n console.log(` expectedCommitment: ${expectedCommitment}`)\n console.log(` match: ${computedCommitment === expectedCommitment}`)\n }\n\n if (computedCommitment !== expectedCommitment) {\n if (debug) {\n console.log(`[tryDecryptNote] Commitment mismatch - not our note`)\n }\n return null\n }\n\n return { amount, blinding, oneTimeSecret, oneTimePubkey: { x: ownerHash, y: 0n }, origin, token }\n } catch (e) {\n if (debug) {\n console.log(`[tryDecryptNote] Decryption exception:`, e instanceof Error ? e.message : e)\n console.log(`[tryDecryptNote] encryptedNote hex length: ${encryptedNote.length} chars = ${(encryptedNote.length - 2) / 2} bytes`)\n }\n return null\n }\n}\n\n// ============================================================================\n// Note Unpacking\n// ============================================================================\n\n/**\n * Unpack note data from packed on-chain format\n *\n * Format: searchTag (8 bytes) + ephemeralPubkeyX (32 bytes) + ephemeralPubkeyY (32 bytes) + encryptedNote (variable)\n *\n * @param packed - The packed note data from the event\n * @param debug - Enable debug logging\n * @returns Unpacked note data or null if format is invalid\n */\nexport function unpackNoteData(packed: Hex, debug: boolean = false): UnpackedNoteData | null {\n try {\n const bytes = hexToBytes(packed)\n // Minimum length: 8 + 32 + 32 + 12 (nonce) + 16 (tag) = 100 bytes minimum\n if (bytes.length < 100) {\n if (debug) {\n console.log(`[unpackNoteData] Packed data too short: ${bytes.length} bytes`)\n }\n return null\n }\n\n const searchTag = bytesToBigint(bytes.slice(0, 8))\n const ephemeralPubkeyX = bytesToBigint(bytes.slice(8, 40))\n const ephemeralPubkeyY = bytesToBigint(bytes.slice(40, 72))\n const encryptedNote = ('0x' + Array.from(bytes.slice(72)).map(b => b.toString(16).padStart(2, '0')).join('')) as Hex\n\n if (debug) {\n console.log(`[unpackNoteData] Total packed bytes: ${bytes.length}, header: 72, encryptedNote: ${bytes.length - 72}`)\n console.log(`[unpackNoteData] searchTag=${searchTag}, ephemeralPubkeyX=${ephemeralPubkeyX}`)\n }\n\n return { searchTag, ephemeralPubkeyX, ephemeralPubkeyY, encryptedNote }\n } catch (e) {\n if (debug) {\n console.log(`[unpackNoteData] Failed to unpack:`, e)\n }\n return null\n }\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Convert hex string to bytes\n */\nexport function hexToBytes(hex: string): Uint8Array {\n const h = hex.startsWith('0x') ? hex.slice(2) : hex\n const bytes = new Uint8Array(h.length / 2)\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(h.substr(i * 2, 2), 16)\n }\n return bytes\n}\n\n/**\n * Convert bytes to bigint (big-endian)\n */\nexport function bytesToBigint(bytes: Uint8Array): bigint {\n let result = 0n\n for (let i = 0; i < bytes.length; i++) {\n const byte = bytes[i]\n if (byte !== undefined) {\n result = (result << 8n) | BigInt(byte)\n }\n }\n return result\n}\n","/**\n * RPC Indexer\n *\n * Direct blockchain scanning using RPC getLogs() with adaptive batching.\n * This is the default indexer that works with any RPC provider.\n *\n * Features:\n * - Adaptive batch sizing (shrinks on rate limits, grows on success)\n * - Incremental sync from last processed block\n * - Trial decryption to find notes belonging to the account\n * - Persistent state in pluggable storage\n * - Live sync with configurable interval\n */\n\nimport { keccak256, toHex, type Address, type Hex } from 'viem'\nimport type { Point } from '../utils/babyjubjub.js'\nimport type {\n Indexer,\n IndexedNote,\n RpcIndexerConfig,\n SyncResult,\n NoteFilters,\n LiveSyncConfig,\n IndexerState,\n SyncState,\n SerializedNote,\n SyncConfig,\n} from './types.js'\nimport { createAutoAdapter } from './storage/index.js'\nimport {\n unpackNoteData,\n matchesSearchTag,\n hexToBytes,\n bytesToBigint,\n} from './decryption.js'\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_BATCH_SIZE = 200\nconst MIN_BATCH_SIZE = 50\nconst MAX_BATCH_SIZE = 2000\nconst BATCH_DELAY_MS = 100\nconst DEFAULT_LIVE_SYNC_INTERVAL_MS = 30000\n\n// Rate limiting defaults (tuned for dedicated/high-bandwidth nodes)\nconst DEFAULT_REQUESTS_PER_SECOND = 20 // Higher limit for dedicated nodes\nconst DEFAULT_MAX_CONCURRENT = 10 // Max parallel requests\n\n// Storage keys\nconst STORAGE_KEY_SYNC = 'sync'\nconst STORAGE_KEY_NOTES = 'notes'\nconst STORAGE_KEY_NULLIFIERS = 'nullifiers'\n\n// Event signatures (for getLogs)\nconst COMMITMENT_INSERTED_EVENT = {\n type: 'event' as const,\n name: 'CommitmentInserted',\n inputs: [\n { indexed: true, name: 'commitment', type: 'bytes32' },\n { indexed: false, name: 'leafIndex', type: 'uint256' },\n { indexed: false, name: 'timestamp', type: 'uint256' },\n ],\n}\n\nconst STEALTH_TRANSACT_EVENT = {\n type: 'event' as const,\n name: 'StealthTransact',\n inputs: [\n { indexed: true, name: 'commitment', type: 'bytes32' },\n { indexed: true, name: 'searchTag', type: 'uint64' },\n { indexed: false, name: 'ephemeralPubkeyX', type: 'uint256' },\n { indexed: false, name: 'ephemeralPubkeyY', type: 'uint256' },\n { indexed: false, name: 'encryptedNote', type: 'bytes' },\n ],\n}\n\nconst SHIELDED_EVENT = {\n type: 'event' as const,\n name: 'Shielded',\n inputs: [\n { indexed: true, name: 'token', type: 'address' },\n { indexed: true, name: 'depositor', type: 'address' },\n { indexed: true, name: 'commitment', type: 'bytes32' },\n { indexed: false, name: 'leafIndex', type: 'uint256' },\n { indexed: false, name: 'encryptedNote', type: 'bytes' },\n ],\n}\n\nconst TRANSFERRED_EVENT = {\n type: 'event' as const,\n name: 'Transferred',\n inputs: [\n { indexed: true, name: 'nullifier', type: 'bytes32' },\n { indexed: true, name: 'outputCommitment1', type: 'bytes32' },\n { indexed: true, name: 'outputCommitment2', type: 'bytes32' },\n { indexed: false, name: 'encryptedNote1', type: 'bytes' },\n { indexed: false, name: 'encryptedNote2', type: 'bytes' },\n ],\n}\n\nconst NULLIFIED_EVENT = {\n type: 'event' as const,\n name: 'Nullified',\n inputs: [{ indexed: true, name: 'nullifier', type: 'bytes32' }],\n}\n\nconst WITHDRAWN_EVENT = {\n type: 'event' as const,\n name: 'Withdrawn',\n inputs: [\n { indexed: true, name: 'token', type: 'address' },\n { indexed: true, name: 'recipient', type: 'address' },\n { indexed: true, name: 'nullifier', type: 'bytes32' },\n { indexed: false, name: 'amount', type: 'uint256' },\n { indexed: false, name: 'isRagequit', type: 'bool' },\n ],\n}\n\n// ============================================================================\n// Rate Limiter (Token Bucket)\n// ============================================================================\n\n/**\n * Simple token bucket rate limiter for RPC requests\n *\n * Prevents hitting 429 errors by proactively limiting request rate.\n */\nclass RateLimiter {\n private tokens: number\n private maxTokens: number\n private refillRate: number // tokens per ms\n private lastRefill: number\n private activeRequests: number\n private maxConcurrent: number\n private queue: Array<() => void> = []\n\n constructor(requestsPerSecond: number, maxConcurrent: number) {\n this.maxTokens = requestsPerSecond\n this.tokens = requestsPerSecond\n this.refillRate = requestsPerSecond / 1000 // per ms\n this.lastRefill = Date.now()\n this.activeRequests = 0\n this.maxConcurrent = maxConcurrent\n }\n\n /**\n * Refill tokens based on time elapsed\n */\n private refill(): void {\n const now = Date.now()\n const elapsed = now - this.lastRefill\n this.tokens = Math.min(this.maxTokens, this.tokens + elapsed * this.refillRate)\n this.lastRefill = now\n }\n\n /**\n * Try to process queued requests\n */\n private processQueue(): void {\n while (this.queue.length > 0 && this.activeRequests < this.maxConcurrent) {\n this.refill()\n if (this.tokens >= 1) {\n this.tokens -= 1\n this.activeRequests++\n const resolve = this.queue.shift()\n resolve?.()\n } else {\n break\n }\n }\n }\n\n /**\n * Acquire a token (wait if necessary)\n */\n async acquire(): Promise<void> {\n return new Promise((resolve) => {\n this.refill()\n\n // Can proceed immediately?\n if (this.tokens >= 1 && this.activeRequests < this.maxConcurrent) {\n this.tokens -= 1\n this.activeRequests++\n resolve()\n return\n }\n\n // Queue the request\n this.queue.push(resolve)\n\n // Schedule a check for when tokens should be available\n const waitTime = this.tokens < 1 ? Math.ceil((1 - this.tokens) / this.refillRate) : 10\n setTimeout(() => this.processQueue(), waitTime)\n })\n }\n\n /**\n * Release a token (call after request completes)\n */\n release(): void {\n this.activeRequests = Math.max(0, this.activeRequests - 1)\n this.processQueue()\n }\n\n /**\n * Execute a function with rate limiting\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n await this.acquire()\n try {\n return await fn()\n } finally {\n this.release()\n }\n }\n}\n\n// ============================================================================\n// SDK Loader (lazy load to avoid circular deps)\n// ============================================================================\n\nlet sdkPromise: Promise<typeof import('../index.js')> | null = null\n\nasync function loadSDK() {\n if (!sdkPromise) {\n sdkPromise = import('../index.js')\n }\n return sdkPromise\n}\n\n// ============================================================================\n// RPC Indexer Implementation\n// ============================================================================\n\nclass RpcIndexer implements Indexer {\n private client: RpcIndexerConfig['client']\n private contractAddress: Address\n private chainId: number\n private storage: import('./types.js').StorageAdapter\n private spendingSecret: bigint\n private spendingPubkey: Point\n private masterViewingSecret: bigint\n private masterViewingPubKey: Point\n\n // Adaptive batching state\n private batchSize: number\n private minBatchSize: number\n private batchDelayMs: number\n\n // In-memory cache\n private notes: IndexedNote[] = []\n private nullifiers: Set<string> = new Set()\n private lastBlock: number = 0\n private initialized: boolean = false\n\n // Initial starting block (fallback if no saved state)\n private initialFromBlock: number\n\n // Live sync state\n private liveSyncInterval: ReturnType<typeof setInterval> | null = null\n private liveSyncConfig: LiveSyncConfig | null = null\n\n // Rate limiter for RPC requests\n private rateLimiter: RateLimiter\n\n constructor(config: RpcIndexerConfig) {\n this.client = config.client\n this.contractAddress = config.contractAddress\n this.chainId = config.chainId\n this.spendingSecret = config.spendingSecret\n this.spendingPubkey = config.spendingPubkey\n this.masterViewingSecret = config.masterViewingSecret\n this.masterViewingPubKey = config.masterViewingPubKey\n\n // Batching config\n this.batchSize = config.batchSize ?? DEFAULT_BATCH_SIZE\n this.minBatchSize = config.minBatchSize ?? MIN_BATCH_SIZE\n this.batchDelayMs = config.batchDelayMs ?? BATCH_DELAY_MS\n\n // Initial starting block (0 = scan from beginning)\n this.initialFromBlock = config.fromBlock ?? 0\n\n // Storage (auto-detect if not provided)\n const accountPrefix = `${config.chainId}_${config.contractAddress.slice(2, 10)}_${toHex(config.spendingPubkey.x).slice(2, 12)}`\n this.storage = config.storage ?? createAutoAdapter(accountPrefix)\n\n // Rate limiter for RPC requests (prevents 429 errors)\n this.rateLimiter = new RateLimiter(DEFAULT_REQUESTS_PER_SECOND, DEFAULT_MAX_CONCURRENT)\n }\n\n /**\n * Initialize from storage\n */\n private async init(): Promise<void> {\n if (this.initialized) return\n\n // Load sync state\n const syncState = await this.storage.get<SyncState>(STORAGE_KEY_SYNC)\n if (syncState && syncState.chainId === this.chainId && syncState.contractAddress === this.contractAddress) {\n this.lastBlock = syncState.lastBlock\n } else {\n // No saved state - use initial fromBlock (e.g., account creation block)\n this.lastBlock = this.initialFromBlock\n }\n\n // Load notes\n const serializedNotes = await this.storage.get<SerializedNote[]>(STORAGE_KEY_NOTES)\n if (serializedNotes) {\n this.notes = serializedNotes.map(deserializeNote)\n }\n\n // Load nullifiers\n const nullifiers = await this.storage.get<Hex[]>(STORAGE_KEY_NULLIFIERS)\n if (nullifiers) {\n this.nullifiers = new Set(nullifiers.map((n) => n.toLowerCase()))\n }\n\n this.initialized = true\n\n // Check loaded notes against loaded nullifiers\n // This ensures notes spent in previous sessions are correctly marked\n if (this.notes.length > 0 && this.nullifiers.size > 0) {\n await this.checkNotesAgainstNullifiers()\n }\n }\n\n /**\n * Check all notes against known nullifiers and mark spent ones\n */\n private async checkNotesAgainstNullifiers(): Promise<number> {\n const sdk = await loadSDK()\n let spentCount = 0\n\n console.log(`[Indexer] checkNotesAgainstNullifiers: ${this.notes.length} notes, ${this.nullifiers.size} nullifiers in set`)\n if (this.nullifiers.size > 0) {\n console.log(`[Indexer] Known nullifiers:`)\n for (const n of this.nullifiers) {\n console.log(` ${n}`)\n }\n }\n\n for (const note of this.notes) {\n if (note.status === 'spent') continue\n\n try {\n const nullifier = await sdk.poseidon([\n BigInt(note.oneTimeSecret),\n BigInt(note.leafIndex),\n BigInt(note.commitment),\n ])\n const nullifierHex = toHex(nullifier, { size: 32 }).toLowerCase()\n\n const isSpent = this.nullifiers.has(nullifierHex)\n console.log(`[Indexer] Note ${note.commitment.slice(0, 18)}... leafIndex=${note.leafIndex} → nullifier=${nullifierHex.slice(0, 18)}... → ${isSpent ? 'SPENT' : 'unspent'}`)\n\n if (isSpent) {\n note.status = 'spent'\n spentCount++\n }\n } catch (e) {\n console.error(`[Indexer] Error computing nullifier for note:`, e)\n }\n }\n\n if (spentCount > 0) {\n console.log(`[Indexer] Marked ${spentCount} notes as spent based on nullifiers`)\n await this.persist()\n }\n\n return spentCount\n }\n\n /**\n * Persist current state to storage\n */\n private async persist(): Promise<void> {\n const syncState: SyncState = {\n lastBlock: this.lastBlock,\n chainId: this.chainId,\n contractAddress: this.contractAddress,\n lastSyncTimestamp: Date.now(),\n }\n\n await Promise.all([\n this.storage.set(STORAGE_KEY_SYNC, syncState),\n this.storage.set(STORAGE_KEY_NOTES, this.notes.map(serializeNote)),\n this.storage.set(STORAGE_KEY_NULLIFIERS, Array.from(this.nullifiers) as Hex[]),\n ])\n }\n\n /**\n * Sync notes from blockchain\n *\n * @param config - Optional sync configuration\n */\n async sync(config?: SyncConfig): Promise<SyncResult> {\n const startTime = Date.now()\n await this.init()\n\n const errors: string[] = []\n let newNotesCount = 0\n let spentNotesCount = 0\n const debug = config?.debug ?? false\n // TEMPORARILY DISABLED: Search tag filtering has a bug with transferred notes\n // Set to false to debug - notes from transfers don't match search tags correctly\n const useSearchTagFiltering = config?.useSearchTagFiltering ?? false\n\n try {\n const currentBlock = Number(await this.client.getBlockNumber())\n const fromBlock = this.lastBlock > 0 ? this.lastBlock + 1 : this.initialFromBlock\n\n if (fromBlock > currentBlock) {\n // Already up to date\n return {\n newNotesCount: 0,\n spentNotesCount: 0,\n lastBlock: this.lastBlock,\n durationMs: Date.now() - startTime,\n }\n }\n\n // Report initial progress\n const reportProgress = (currentBlock_: number, eventsProcessed: number, notesFound: number, eventsSkipped: number) => {\n if (config?.onProgress) {\n const totalBlocks = currentBlock - fromBlock + 1\n const processedBlocks = currentBlock_ - fromBlock + 1\n config.onProgress({\n currentBlock: currentBlock_,\n targetBlock: currentBlock,\n eventsProcessed,\n notesFound,\n percent: Math.round((processedBlocks / totalBlocks) * 100),\n eventsSkipped,\n })\n }\n }\n\n // Fetch events in batches\n const commitmentMap = new Map<string, { leafIndex: number; timestamp: number; blockNumber: number }>()\n const stealthEvents: Array<{\n commitment: Hex\n ephemeralPubkeyX: bigint\n ephemeralPubkeyY: bigint\n encryptedNote: Hex\n txHash: Hex\n blockNumber: number\n searchTag?: bigint // For filtering before trial decryption\n }> = []\n const newNullifiers: Hex[] = []\n\n let currentBatchSize = this.batchSize\n let batchStart = fromBlock\n\n while (batchStart <= currentBlock) {\n const batchEnd = Math.min(batchStart + currentBatchSize - 1, currentBlock)\n\n try {\n // Fetch all event types with rate limiting\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const [commitmentLogs, stealthLogs, shieldedLogs, transferredLogs, nullifiedLogs, withdrawnLogs] = await Promise.all([\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: COMMITMENT_INSERTED_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: STEALTH_TRANSACT_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: SHIELDED_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: TRANSFERRED_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: NULLIFIED_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: WITHDRAWN_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n ]) as [any[], any[], any[], any[], any[], any[]]\n\n // Process commitment events\n for (const log of commitmentLogs) {\n const commitment = (log.args as { commitment: Hex }).commitment.toLowerCase()\n commitmentMap.set(commitment, {\n leafIndex: Number((log.args as { leafIndex: number }).leafIndex),\n timestamp: Number((log.args as { timestamp: bigint }).timestamp),\n blockNumber: Number(log.blockNumber),\n })\n }\n\n // Process stealth events\n for (const log of stealthLogs) {\n const args = log.args as {\n commitment: Hex\n searchTag: bigint\n ephemeralPubkeyX: bigint\n ephemeralPubkeyY: bigint\n encryptedNote: Hex\n }\n stealthEvents.push({\n commitment: args.commitment.toLowerCase() as Hex,\n ephemeralPubkeyX: args.ephemeralPubkeyX,\n ephemeralPubkeyY: args.ephemeralPubkeyY,\n encryptedNote: args.encryptedNote,\n txHash: log.transactionHash,\n blockNumber: Number(log.blockNumber),\n searchTag: args.searchTag,\n })\n }\n\n // Process shielded events (packed note format)\n for (const log of shieldedLogs) {\n const args = log.args as {\n commitment: Hex\n leafIndex: bigint\n encryptedNote: Hex\n }\n // Unpack note data: searchTag (8) + ephemeralPubkeyX (32) + ephemeralPubkeyY (32) + encryptedNote\n const unpacked = unpackNoteData(args.encryptedNote)\n if (unpacked) {\n stealthEvents.push({\n commitment: args.commitment.toLowerCase() as Hex,\n ephemeralPubkeyX: unpacked.ephemeralPubkeyX,\n ephemeralPubkeyY: unpacked.ephemeralPubkeyY,\n encryptedNote: unpacked.encryptedNote,\n txHash: log.transactionHash,\n blockNumber: Number(log.blockNumber),\n searchTag: unpacked.searchTag,\n })\n // Also track in commitmentMap\n commitmentMap.set(args.commitment.toLowerCase(), {\n leafIndex: Number(args.leafIndex),\n timestamp: Math.floor(Date.now() / 1000),\n blockNumber: Number(log.blockNumber),\n })\n }\n }\n\n // Process transferred events (2 packed notes)\n for (const log of transferredLogs) {\n const args = log.args as {\n outputCommitment1: Hex\n outputCommitment2: Hex\n encryptedNote1: Hex\n encryptedNote2: Hex\n }\n // Process first output\n const unpacked1 = unpackNoteData(args.encryptedNote1)\n if (unpacked1) {\n stealthEvents.push({\n commitment: args.outputCommitment1.toLowerCase() as Hex,\n ephemeralPubkeyX: unpacked1.ephemeralPubkeyX,\n ephemeralPubkeyY: unpacked1.ephemeralPubkeyY,\n encryptedNote: unpacked1.encryptedNote,\n txHash: log.transactionHash,\n blockNumber: Number(log.blockNumber),\n searchTag: unpacked1.searchTag,\n })\n }\n // Process second output (change note)\n const unpacked2 = unpackNoteData(args.encryptedNote2)\n if (unpacked2) {\n stealthEvents.push({\n commitment: args.outputCommitment2.toLowerCase() as Hex,\n ephemeralPubkeyX: unpacked2.ephemeralPubkeyX,\n ephemeralPubkeyY: unpacked2.ephemeralPubkeyY,\n encryptedNote: unpacked2.encryptedNote,\n txHash: log.transactionHash,\n blockNumber: Number(log.blockNumber),\n searchTag: unpacked2.searchTag,\n })\n }\n }\n\n // Process nullifier events (explicit Nullified events)\n for (const log of nullifiedLogs) {\n const nullifier = (log.args as { nullifier: Hex }).nullifier.toLowerCase() as Hex\n newNullifiers.push(nullifier)\n }\n\n // Also extract nullifiers from Transferred events (the input that was spent)\n for (const log of transferredLogs) {\n const args = log.args as { nullifier: Hex }\n if (args.nullifier) {\n newNullifiers.push(args.nullifier.toLowerCase() as Hex)\n }\n }\n\n // Extract nullifiers from Withdrawn events (notes spent via withdrawal)\n if (withdrawnLogs.length > 0) {\n console.log(`[Indexer] Found ${withdrawnLogs.length} Withdrawn events in batch`)\n }\n for (const log of withdrawnLogs) {\n const args = log.args as { nullifier: Hex }\n if (args.nullifier) {\n const nullifierLower = args.nullifier.toLowerCase() as Hex\n console.log(`[Indexer] Withdrawn event nullifier: ${nullifierLower}`)\n newNullifiers.push(nullifierLower)\n }\n }\n\n // Success - try to increase batch size\n if (currentBatchSize < MAX_BATCH_SIZE) {\n currentBatchSize = Math.min(currentBatchSize * 2, MAX_BATCH_SIZE)\n }\n\n // Report progress after each batch\n reportProgress(batchEnd, stealthEvents.length, 0, 0)\n\n batchStart = batchEnd + 1\n\n // Small delay between batches to avoid overwhelming RPC\n if (batchStart <= currentBlock) {\n await sleep(this.batchDelayMs)\n }\n } catch (e) {\n // Check if rate limit error\n if (isRateLimitError(e)) {\n // Shrink batch size\n currentBatchSize = Math.max(Math.floor(currentBatchSize / 2), this.minBatchSize)\n errors.push(`Rate limited at block ${batchStart}, reducing batch size to ${currentBatchSize}`)\n await sleep(1000) // Wait a second before retrying\n continue // Retry same batch with smaller size\n }\n throw e\n }\n }\n\n // Update adaptive batch size for next sync\n this.batchSize = currentBatchSize\n\n // Process nullifiers - add to set\n console.log(`[Indexer] Processing ${newNullifiers.length} new nullifiers`)\n for (const nullifier of newNullifiers) {\n if (!this.nullifiers.has(nullifier.toLowerCase())) {\n this.nullifiers.add(nullifier.toLowerCase())\n }\n }\n console.log(`[Indexer] Total nullifiers in set: ${this.nullifiers.size}`)\n\n // NOTE: checkNotesAgainstNullifiers is called AFTER trial decryption\n // so that newly discovered notes can also be checked against nullifiers\n\n // Trial decryption for stealth events\n const sdk = await loadSDK()\n const existingCommitmentsMap = new Map(this.notes.map((n) => [n.commitment.toLowerCase(), n]))\n\n // Always log sync summary (useful for debugging)\n console.log(`[Indexer] Sync: blocks ${fromBlock} to ${currentBlock} (${currentBlock - fromBlock + 1} blocks)`)\n console.log(`[Indexer] Found: ${stealthEvents.length} stealth events, ${commitmentMap.size} commitment events`)\n console.log(`[Indexer] Search tag filtering: ${useSearchTagFiltering ? 'ENABLED' : 'DISABLED'}`)\n\n if (debug) {\n console.log(`[Indexer] Existing notes in memory: ${this.notes.length}`)\n console.log(`[Indexer] masterViewingPubKey: x=${this.masterViewingPubKey.x}, y=${this.masterViewingPubKey.y}`)\n }\n\n // Search tag filtering: skip events that don't match our viewing key\n let eventsSkipped = 0\n let eventsProcessed = 0\n\n for (const event of stealthEvents) {\n const commitmentLower = event.commitment.toLowerCase()\n const existingNote = existingCommitmentsMap.get(commitmentLower)\n\n // If we already have this note as confirmed, skip it\n if (existingNote && existingNote.status === 'confirmed') {\n continue\n }\n\n // If we have a pending note with this commitment, update it to confirmed\n if (existingNote && existingNote.status === 'pending') {\n const info = commitmentMap.get(commitmentLower)\n existingNote.status = 'confirmed'\n existingNote.leafIndex = info?.leafIndex ?? existingNote.leafIndex\n existingNote.blockNumber = info?.blockNumber ?? event.blockNumber\n existingNote.timestamp = info?.timestamp ?? existingNote.timestamp\n newNotesCount++ // Count as \"new\" since it's newly confirmed\n continue\n }\n\n // Search tag filtering: check if this event might be ours before expensive decryption\n if (useSearchTagFiltering && event.searchTag !== undefined) {\n const ephemeralPubkey = { x: event.ephemeralPubkeyX, y: event.ephemeralPubkeyY }\n\n // Log first few events for debugging (limit to avoid spam)\n const shouldLogDetails = debug && eventsSkipped + eventsProcessed < 3\n if (shouldLogDetails) {\n console.log(`[Indexer] Checking event searchTag=${event.searchTag}`)\n console.log(`[Indexer] ephemeralPubkey: x=${ephemeralPubkey.x}, y=${ephemeralPubkey.y}`)\n }\n\n const matches = await matchesSearchTag(\n event.searchTag,\n sdk,\n this.masterViewingSecret,\n this.masterViewingPubKey,\n ephemeralPubkey,\n shouldLogDetails // Pass debug flag\n )\n if (!matches) {\n eventsSkipped++\n continue // Not our note, skip expensive trial decryption\n }\n if (debug) {\n console.log(`[Indexer] ✓ Search tag MATCHED for commitment ${event.commitment.slice(0, 18)}...`)\n }\n }\n\n eventsProcessed++\n try {\n if (debug) {\n console.log(`[Indexer] Trying to decrypt event commitment: ${event.commitment}`)\n console.log(`[Indexer] Encrypted note length: ${(event.encryptedNote.length - 2) / 2} bytes`)\n }\n\n const decrypted = await tryDecryptNote(\n sdk,\n this.spendingSecret,\n this.spendingPubkey,\n this.masterViewingSecret,\n this.masterViewingPubKey,\n { x: event.ephemeralPubkeyX, y: event.ephemeralPubkeyY },\n event.encryptedNote,\n BigInt(event.commitment)\n )\n\n if (decrypted) {\n if (debug) {\n console.log(`[Indexer] ✓ Decryption SUCCESS for commitment ${event.commitment.slice(0, 18)}...`)\n console.log(`[Indexer] Amount: ${decrypted.amount}, Origin: 0x${decrypted.origin.toString(16)}, Token: 0x${decrypted.token.toString(16)}`)\n }\n const info = commitmentMap.get(event.commitment.toLowerCase())\n const note: IndexedNote = {\n amount: decrypted.amount,\n blinding: decrypted.blinding,\n commitment: event.commitment.toLowerCase() as Hex,\n oneTimeSecret: toHex(decrypted.oneTimeSecret, { size: 32 }),\n oneTimePubkeyX: toHex(decrypted.oneTimePubkey.x, { size: 32 }),\n oneTimePubkeyY: toHex(decrypted.oneTimePubkey.y, { size: 32 }),\n leafIndex: info?.leafIndex ?? 0,\n txHash: event.txHash,\n status: 'confirmed',\n blockNumber: info?.blockNumber ?? event.blockNumber,\n timestamp: info?.timestamp ?? Math.floor(Date.now() / 1000),\n origin: ('0x' + decrypted.origin.toString(16).padStart(40, '0')) as Address,\n token: ('0x' + decrypted.token.toString(16).padStart(40, '0')) as Address,\n ephemeralX: toHex(event.ephemeralPubkeyX, { size: 32 }),\n ephemeralY: toHex(event.ephemeralPubkeyY, { size: 32 }),\n }\n\n this.notes.push(note)\n existingCommitmentsMap.set(note.commitment.toLowerCase(), note)\n newNotesCount++\n }\n } catch (decryptErr) {\n // Decryption failed - not our note, continue\n if (debug) {\n console.log(`[Indexer] ✗ Decryption FAILED for commitment ${event.commitment.slice(0, 18)}...`, decryptErr)\n }\n }\n }\n\n // Always log search tag filtering stats (useful for debugging)\n if (stealthEvents.length > 0) {\n console.log(`[Indexer] Result: ${eventsSkipped} skipped by search tag, ${eventsProcessed} processed, ${newNotesCount} notes found`)\n }\n\n // Report final progress\n reportProgress(currentBlock, eventsProcessed, newNotesCount, eventsSkipped)\n\n // Mark notes as spent by computing their nullifiers and checking against on-chain nullifiers\n // This MUST happen AFTER trial decryption so newly discovered notes are checked too\n spentNotesCount = await this.checkNotesAgainstNullifiers()\n\n this.lastBlock = currentBlock\n await this.persist()\n\n // Notify live sync callbacks\n if (newNotesCount > 0 && this.liveSyncConfig?.onNewNotes) {\n const newNotes = this.notes.slice(-newNotesCount)\n this.liveSyncConfig.onNewNotes(newNotes)\n }\n\n return {\n newNotesCount,\n spentNotesCount,\n lastBlock: this.lastBlock,\n durationMs: Date.now() - startTime,\n errors: errors.length > 0 ? errors : undefined,\n }\n } catch (e) {\n const error = e instanceof Error ? e : new Error(String(e))\n if (this.liveSyncConfig?.onError) {\n this.liveSyncConfig.onError(error)\n }\n throw error\n }\n }\n\n /**\n * Get total balance of unspent notes\n */\n getBalance(token?: Address): bigint {\n const unspent = this.getUnspentNotes()\n const filtered = token ? unspent.filter((n) => n.token === token) : unspent\n return filtered.reduce((sum, n) => sum + n.amount, 0n)\n }\n\n /**\n * Get all notes matching filters\n */\n getNotes(filters?: NoteFilters): IndexedNote[] {\n let result = [...this.notes]\n\n if (filters?.status) {\n const statuses = Array.isArray(filters.status) ? filters.status : [filters.status]\n result = result.filter((n) => statuses.includes(n.status))\n }\n\n if (filters?.token) {\n result = result.filter((n) => n.token === filters.token)\n }\n\n if (filters?.minAmount !== undefined) {\n result = result.filter((n) => n.amount >= filters.minAmount!)\n }\n\n if (filters?.maxAmount !== undefined) {\n result = result.filter((n) => n.amount <= filters.maxAmount!)\n }\n\n return result\n }\n\n /**\n * Get unspent notes\n */\n getUnspentNotes(): IndexedNote[] {\n return this.notes.filter((n) => n.status !== 'spent')\n }\n\n /**\n * Get the last synced block number\n */\n getLastBlock(): number {\n return this.lastBlock\n }\n\n /**\n * Mark a note as spent\n */\n markSpent(commitment: Hex): void {\n const note = this.notes.find((n) => n.commitment.toLowerCase() === commitment.toLowerCase())\n if (note) {\n note.status = 'spent'\n // Persist async (don't block)\n this.persist().catch(console.error)\n }\n }\n\n /**\n * Add a note directly\n */\n addNote(note: IndexedNote): void {\n // Check for duplicate\n if (this.notes.some((n) => n.commitment.toLowerCase() === note.commitment.toLowerCase())) {\n return\n }\n this.notes.push(note)\n // Persist async (don't block)\n this.persist().catch(console.error)\n }\n\n /**\n * Start live sync\n */\n startLiveSync(config?: LiveSyncConfig): void {\n if (this.liveSyncInterval) {\n this.stopLiveSync()\n }\n\n this.liveSyncConfig = config ?? {}\n const intervalMs = config?.intervalMs ?? DEFAULT_LIVE_SYNC_INTERVAL_MS\n\n this.liveSyncInterval = setInterval(() => {\n this.sync().catch((e) => {\n if (config?.onError) {\n config.onError(e instanceof Error ? e : new Error(String(e)))\n }\n })\n }, intervalMs)\n\n // Also sync immediately\n this.sync().catch((e) => {\n if (config?.onError) {\n config.onError(e instanceof Error ? e : new Error(String(e)))\n }\n })\n }\n\n /**\n * Stop live sync\n */\n stopLiveSync(): void {\n if (this.liveSyncInterval) {\n clearInterval(this.liveSyncInterval)\n this.liveSyncInterval = null\n }\n this.liveSyncConfig = null\n }\n\n /**\n * Check if live sync is running\n */\n isLiveSyncing(): boolean {\n return this.liveSyncInterval !== null\n }\n\n /**\n * Clear all indexed data\n */\n async clear(): Promise<void> {\n this.notes = []\n this.nullifiers.clear()\n this.lastBlock = 0\n await this.storage.clear()\n }\n\n /**\n * Export current state\n */\n async exportState(): Promise<IndexerState> {\n await this.init()\n return {\n sync: {\n lastBlock: this.lastBlock,\n chainId: this.chainId,\n contractAddress: this.contractAddress,\n lastSyncTimestamp: Date.now(),\n },\n notes: this.notes.map(serializeNote),\n nullifiers: Array.from(this.nullifiers) as Hex[],\n }\n }\n\n /**\n * Import state\n */\n async importState(state: IndexerState): Promise<void> {\n // Validate chain/contract match\n if (state.sync.chainId !== this.chainId || state.sync.contractAddress !== this.contractAddress) {\n throw new Error('State does not match indexer configuration')\n }\n\n this.lastBlock = state.sync.lastBlock\n this.notes = state.notes.map(deserializeNote)\n this.nullifiers = new Set(state.nullifiers.map((n) => n.toLowerCase()))\n this.initialized = true\n\n await this.persist()\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create an RPC indexer\n *\n * @param config - Indexer configuration\n * @returns Indexer instance\n *\n * @example\n * ```ts\n * import { makeRpcIndexer } from '@upp/sdk/indexer'\n * import { createPublicClient, http } from 'viem'\n *\n * const client = createPublicClient({ transport: http() })\n *\n * const indexer = makeRpcIndexer({\n * client,\n * contractAddress: '0x...',\n * chainId: 1,\n * spendingSecret: mySpendingSecret,\n * spendingPubkey: mySpendingPubkey,\n * })\n *\n * // Initial sync\n * const result = await indexer.sync()\n * console.log(`Found ${result.newNotesCount} new notes`)\n *\n * // Get balance\n * const balance = indexer.getBalance()\n *\n * // Start live sync\n * indexer.startLiveSync({\n * intervalMs: 30000,\n * onNewNotes: (notes) => console.log('New notes:', notes),\n * })\n * ```\n */\nexport function makeRpcIndexer(config: RpcIndexerConfig): Indexer {\n return new RpcIndexer(config)\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Try to decrypt a note using dual ECDH (UPP format with origin and token)\n *\n * 1. Viewing ECDH: DVK * R → AES decryption key (viewing shared secret)\n * 2. Spending ECDH: spendingSecret * R → one-time key for commitment verification\n *\n * DVK is derived using R.x (ephemeral public key x-coordinate) as the nonce.\n *\n * UPP encrypted payload: amount (32) + blinding (32) + origin (20) + token (20) = 104 bytes\n * UPP commitment: Poseidon(amount, pubkeyX, pubkeyY, blinding, origin, token)\n */\nasync function tryDecryptNote(\n sdk: typeof import('../index.js'),\n spendingSecret: bigint,\n _spendingPubkey: Point,\n _masterViewingSecret: bigint,\n _masterViewingPubKey: Point,\n _ephemeralPubkey: Point,\n encryptedNote: Hex,\n expectedCommitment: bigint\n): Promise<{\n amount: bigint\n blinding: bigint\n oneTimeSecret: bigint\n oneTimePubkey: Point\n origin: bigint\n token: bigint\n} | null> {\n try {\n // --- Viewing key decryption (hash-based, BLS12-381) ---\n // For self-shielded notes, the AES key is derived from the viewing secret directly.\n // For stealth notes (future), ECDH will be re-implemented with a non-BabyJubJub curve.\n const dvk = await sdk.deriveDecryptionViewingKey(_masterViewingSecret, _masterViewingPubKey, _ephemeralPubkey.x)\n const viewingSharedSecret = await sdk.computeSharedSecret(dvk, _ephemeralPubkey)\n\n // Derive AES key from viewing shared secret\n const keyMaterial = keccak256(toHex(viewingSharedSecret.x, { size: 32 }))\n const keyBytes = hexToBytes(keyMaterial)\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n keyBytes.buffer.slice(keyBytes.byteOffset, keyBytes.byteOffset + keyBytes.byteLength) as ArrayBuffer,\n { name: 'AES-GCM', length: 256 },\n false,\n ['decrypt']\n )\n\n // Parse encrypted note\n const encryptedBytes = hexToBytes(encryptedNote)\n const nonce = encryptedBytes.slice(0, 12)\n const ciphertext = encryptedBytes.slice(12)\n\n // Decrypt\n const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: nonce }, cryptoKey, ciphertext)\n\n const plaintextBytes = new Uint8Array(plaintext)\n console.log(`[tryDecryptNote] Decrypted plaintext length: ${plaintextBytes.length} bytes`)\n\n // UPP payload: amount (32) + blinding (32) + origin (20) + token (20) = 104 bytes\n const amount = bytesToBigint(plaintextBytes.slice(0, 32))\n const blinding = bytesToBigint(plaintextBytes.slice(32, 64))\n const origin = bytesToBigint(plaintextBytes.slice(64, 84))\n const token = bytesToBigint(plaintextBytes.slice(84, 104))\n\n // --- Hash-based ownership verification (BLS12-381) ---\n const ownerHash = await sdk.poseidon([spendingSecret])\n const oneTimeSecret = spendingSecret\n const oneTimePubkey = { x: ownerHash, y: 0n }\n\n // Verify UPP commitment (5 elements: amount, ownerHash, blinding, origin, token)\n const computedCommitment = await sdk.poseidon([\n amount,\n ownerHash,\n blinding,\n origin,\n token,\n ])\n\n console.log(`[tryDecryptNote] Decrypted values:`)\n console.log(` amount: ${amount}`)\n console.log(` blinding: ${blinding}`)\n console.log(` origin: 0x${origin.toString(16).padStart(40, '0')}`)\n console.log(` token: 0x${token.toString(16).padStart(40, '0')}`)\n console.log(` oneTimePubkey.x: ${oneTimePubkey.x}`)\n console.log(` oneTimePubkey.y: ${oneTimePubkey.y}`)\n console.log(` computedCommitment: ${computedCommitment}`)\n console.log(` expectedCommitment: ${expectedCommitment}`)\n console.log(` match: ${computedCommitment === expectedCommitment}`)\n\n if (computedCommitment !== expectedCommitment) {\n console.log(`[tryDecryptNote] Commitment mismatch - not our note`)\n return null\n }\n\n return { amount, blinding, oneTimeSecret, oneTimePubkey, origin, token }\n } catch (e) {\n console.log(`[tryDecryptNote] Decryption exception:`, e instanceof Error ? e.message : e)\n console.log(`[tryDecryptNote] encryptedNote hex length: ${encryptedNote.length} chars = ${(encryptedNote.length - 2) / 2} bytes`)\n return null\n }\n}\n\n/**\n * Serialize a note for storage\n */\nfunction serializeNote(note: IndexedNote): SerializedNote {\n return {\n amount: note.amount.toString(),\n blinding: note.blinding.toString(),\n commitment: note.commitment,\n oneTimeSecret: note.oneTimeSecret,\n oneTimePubkeyX: note.oneTimePubkeyX,\n oneTimePubkeyY: note.oneTimePubkeyY,\n leafIndex: note.leafIndex,\n txHash: note.txHash,\n status: note.status,\n blockNumber: note.blockNumber,\n timestamp: note.timestamp,\n origin: note.origin,\n token: note.token,\n ephemeralX: note.ephemeralX,\n ephemeralY: note.ephemeralY,\n }\n}\n\n/**\n * Deserialize a note from storage\n */\nfunction deserializeNote(note: SerializedNote): IndexedNote {\n return {\n amount: BigInt(note.amount),\n blinding: BigInt(note.blinding),\n commitment: note.commitment as Hex,\n oneTimeSecret: note.oneTimeSecret as Hex,\n oneTimePubkeyX: note.oneTimePubkeyX as Hex,\n oneTimePubkeyY: note.oneTimePubkeyY as Hex,\n leafIndex: note.leafIndex,\n txHash: note.txHash as Hex | undefined,\n status: note.status,\n blockNumber: note.blockNumber,\n timestamp: note.timestamp,\n origin: note.origin as Address | undefined,\n token: note.token as Address | undefined,\n ephemeralX: note.ephemeralX as Hex | undefined,\n ephemeralY: note.ephemeralY as Hex | undefined,\n }\n}\n\n/**\n * Check if an error is a rate limit error\n */\nfunction isRateLimitError(e: unknown): boolean {\n if (e instanceof Error) {\n const message = e.message.toLowerCase()\n return (\n message.includes('rate limit') ||\n message.includes('too many requests') ||\n message.includes('429') ||\n message.includes('exceeded')\n )\n }\n return false\n}\n\n/**\n * Sleep for a given number of milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n// hexToBytes, bytesToBigint, unpackNoteData are now imported from ./decryption.js\n"]}
|