@permissionless-technologies/upp-sdk 0.5.5 → 0.5.7
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-Q6BLTPWV.js → chunk-2NKFTLPD.js} +3 -3
- package/dist/{chunk-Q6BLTPWV.js.map → chunk-2NKFTLPD.js.map} +1 -1
- package/dist/{chunk-EHGH6TAW.js → chunk-37RFFZU2.js} +3 -3
- package/dist/{chunk-EHGH6TAW.js.map → chunk-37RFFZU2.js.map} +1 -1
- package/dist/{chunk-UQIM2KT3.js → chunk-4E23V3AT.js} +29 -4
- package/dist/chunk-4E23V3AT.js.map +1 -0
- package/dist/{chunk-53JACDGZ.js → chunk-A6IYQ7UF.js} +3 -3
- package/dist/chunk-A6IYQ7UF.js.map +1 -0
- package/dist/{chunk-7T4CUE6E.js → chunk-AVSR443A.js} +3 -3
- package/dist/{chunk-7T4CUE6E.js.map → chunk-AVSR443A.js.map} +1 -1
- package/dist/{chunk-UFEDJJSH.cjs → chunk-BCSMUH4L.cjs} +30 -3
- package/dist/chunk-BCSMUH4L.cjs.map +1 -0
- package/dist/{chunk-IYRCJAME.cjs → chunk-C3HXJ5A6.cjs} +9 -9
- package/dist/{chunk-IYRCJAME.cjs.map → chunk-C3HXJ5A6.cjs.map} +1 -1
- package/dist/{chunk-DTEAFJG7.js → chunk-FTEXUSHR.js} +4 -4
- package/dist/{chunk-DTEAFJG7.js.map → chunk-FTEXUSHR.js.map} +1 -1
- package/dist/chunk-FW2U6TKQ.js +498 -0
- package/dist/chunk-FW2U6TKQ.js.map +1 -0
- package/dist/{chunk-6TFDBBAQ.js → chunk-H4NDMIPF.js} +3 -3
- package/dist/{chunk-6TFDBBAQ.js.map → chunk-H4NDMIPF.js.map} +1 -1
- package/dist/{chunk-7BNJV2ZS.cjs → chunk-LKXC3OQT.cjs} +14 -14
- package/dist/{chunk-7BNJV2ZS.cjs.map → chunk-LKXC3OQT.cjs.map} +1 -1
- package/dist/{chunk-MEFCUBQC.js → chunk-N2VHE47N.js} +73 -7
- package/dist/chunk-N2VHE47N.js.map +1 -0
- package/dist/{chunk-HB43C26P.cjs → chunk-NGXEIUQ6.cjs} +4 -4
- package/dist/chunk-NGXEIUQ6.cjs.map +1 -0
- package/dist/{chunk-M6O7HMN7.js → chunk-OG6TNEAT.js} +6 -20
- package/dist/chunk-OG6TNEAT.js.map +1 -0
- package/dist/chunk-PGIV2GDM.cjs +511 -0
- package/dist/chunk-PGIV2GDM.cjs.map +1 -0
- package/dist/{chunk-DD2RTRPE.cjs → chunk-TKUOY2PQ.cjs} +22 -36
- package/dist/chunk-TKUOY2PQ.cjs.map +1 -0
- package/dist/{chunk-I5EKGD4P.cjs → chunk-XNSMPNY6.cjs} +4 -4
- package/dist/{chunk-I5EKGD4P.cjs.map → chunk-XNSMPNY6.cjs.map} +1 -1
- package/dist/{chunk-U3YFYMWF.cjs → chunk-XSJ5VVH4.cjs} +5 -5
- package/dist/{chunk-U3YFYMWF.cjs.map → chunk-XSJ5VVH4.cjs.map} +1 -1
- package/dist/{chunk-KV2QFPSJ.cjs → chunk-Y3VL3LOE.cjs} +73 -4
- package/dist/chunk-Y3VL3LOE.cjs.map +1 -0
- package/dist/{chunk-SWTNJPK5.cjs → chunk-Y6WCXYOC.cjs} +11 -11
- package/dist/{chunk-SWTNJPK5.cjs.map → chunk-Y6WCXYOC.cjs.map} +1 -1
- package/dist/core/index.cjs +117 -121
- package/dist/core/index.d.cts +2 -5
- package/dist/core/index.d.ts +2 -5
- package/dist/core/index.js +7 -7
- package/dist/crypto-FWREDAVI.js +8 -0
- package/dist/crypto-FWREDAVI.js.map +1 -0
- package/dist/crypto-IZKHHFDU.cjs +42 -0
- package/dist/crypto-IZKHHFDU.cjs.map +1 -0
- package/dist/{index-BRgBwiBM.d.ts → index-2eL8ZLD0.d.ts} +11 -23
- package/dist/{index-DHW5lKcd.d.ts → index-B31tBTbC.d.ts} +3 -4
- package/dist/{index-D6YhhbRP.d.cts → index-CzmvOht6.d.cts} +3 -4
- package/dist/{index-brLSTa0y.d.cts → index-a_f935pS.d.cts} +11 -23
- package/dist/index.cjs +285 -285
- package/dist/index.d.cts +4 -7
- package/dist/index.d.ts +4 -7
- package/dist/index.js +10 -10
- package/dist/indexer/index.cjs +62 -11
- package/dist/indexer/index.d.cts +196 -12
- package/dist/indexer/index.d.ts +196 -12
- package/dist/indexer/index.js +4 -1
- package/dist/keys/index.cjs +17 -17
- package/dist/keys/index.js +3 -3
- package/dist/react/index.cjs +237 -754
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +142 -6
- package/dist/react/index.d.ts +142 -6
- package/dist/react/index.js +215 -732
- package/dist/react/index.js.map +1 -1
- package/dist/transfer-27GZNGCI.js +9 -0
- package/dist/{transfer-BVZAMEJH.js.map → transfer-27GZNGCI.js.map} +1 -1
- package/dist/{transfer-ZD76R7XF.cjs → transfer-TJNDCZF2.cjs} +14 -10
- package/dist/{transfer-ZD76R7XF.cjs.map → transfer-TJNDCZF2.cjs.map} +1 -1
- package/dist/{transfer-p-NXHdGY.d.cts → transfer-_qaZXsv7.d.cts} +47 -156
- package/dist/{transfer-BxiDgCvx.d.ts → transfer-x7UChjh7.d.ts} +47 -156
- package/dist/utils/index.cjs +63 -63
- package/dist/utils/index.d.cts +186 -5
- package/dist/utils/index.d.ts +186 -5
- package/dist/utils/index.js +4 -4
- package/package.json +1 -1
- package/src/deployments/31337.json +2 -1
- package/dist/chunk-53JACDGZ.js.map +0 -1
- package/dist/chunk-DD2RTRPE.cjs.map +0 -1
- package/dist/chunk-HB43C26P.cjs.map +0 -1
- package/dist/chunk-KV2QFPSJ.cjs.map +0 -1
- package/dist/chunk-M6O7HMN7.js.map +0 -1
- package/dist/chunk-MEFCUBQC.js.map +0 -1
- package/dist/chunk-UFEDJJSH.cjs.map +0 -1
- package/dist/chunk-UQIM2KT3.js.map +0 -1
- package/dist/stark-BcTD1OaJ.d.cts +0 -185
- package/dist/stark-BcTD1OaJ.d.ts +0 -185
- package/dist/transfer-BVZAMEJH.js +0 -9
package/dist/react/index.cjs
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkC3HXJ5A6_cjs = require('../chunk-C3HXJ5A6.cjs');
|
|
4
|
+
var chunkY3VL3LOE_cjs = require('../chunk-Y3VL3LOE.cjs');
|
|
5
|
+
require('../chunk-IX7HV5TE.cjs');
|
|
4
6
|
var chunkXVIICZKW_cjs = require('../chunk-XVIICZKW.cjs');
|
|
5
7
|
var chunkVVW5VVY3_cjs = require('../chunk-VVW5VVY3.cjs');
|
|
8
|
+
require('../chunk-IIUKM5VE.cjs');
|
|
9
|
+
var chunkPGIV2GDM_cjs = require('../chunk-PGIV2GDM.cjs');
|
|
6
10
|
var chunkARH2SJM3_cjs = require('../chunk-ARH2SJM3.cjs');
|
|
7
|
-
require('../chunk-
|
|
11
|
+
var chunkBCSMUH4L_cjs = require('../chunk-BCSMUH4L.cjs');
|
|
8
12
|
var chunkHEHXSV47_cjs = require('../chunk-HEHXSV47.cjs');
|
|
9
13
|
var chunkG7VZBCD6_cjs = require('../chunk-G7VZBCD6.cjs');
|
|
10
14
|
var react = require('react');
|
|
@@ -13,6 +17,7 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
13
17
|
var reactDom = require('react-dom');
|
|
14
18
|
var upcSdk = require('@permissionless-technologies/upc-sdk');
|
|
15
19
|
|
|
20
|
+
// src/core/eip712.ts
|
|
16
21
|
var UPP_EIP712_DOMAIN = {
|
|
17
22
|
name: "UPP Stealth Account",
|
|
18
23
|
version: "2"
|
|
@@ -24,14 +29,8 @@ var UPP_EIP712_TYPES = {
|
|
|
24
29
|
{ name: "passwordHash", type: "bytes32" }
|
|
25
30
|
]
|
|
26
31
|
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
async function loadSDK() {
|
|
30
|
-
if (!sdkPromise) {
|
|
31
|
-
sdkPromise = import('../index.cjs');
|
|
32
|
-
}
|
|
33
|
-
return sdkPromise;
|
|
34
|
-
}
|
|
32
|
+
|
|
33
|
+
// src/core/storage-keys.ts
|
|
35
34
|
function getStorageKey(ethAddress) {
|
|
36
35
|
return `upp_pq_account_${ethAddress.toLowerCase()}`;
|
|
37
36
|
}
|
|
@@ -41,6 +40,8 @@ function getNotesStorageKey(chainId, ownerHashPrefix) {
|
|
|
41
40
|
function getChainFingerprintKey(chainId) {
|
|
42
41
|
return `upp_chain_fp_${chainId}`;
|
|
43
42
|
}
|
|
43
|
+
|
|
44
|
+
// src/core/chain-fingerprint.ts
|
|
44
45
|
async function checkChainFingerprint(chainId, publicClient) {
|
|
45
46
|
if (typeof window === "undefined" || !publicClient) return true;
|
|
46
47
|
const fpKey = getChainFingerprintKey(chainId);
|
|
@@ -70,6 +71,99 @@ async function checkChainFingerprint(chainId, publicClient) {
|
|
|
70
71
|
return true;
|
|
71
72
|
}
|
|
72
73
|
}
|
|
74
|
+
|
|
75
|
+
// src/core/circuit-selector.ts
|
|
76
|
+
function selectOptimalCircuit(unspentNotes, requiredAmount, tokenAddress) {
|
|
77
|
+
let candidates = unspentNotes;
|
|
78
|
+
if (tokenAddress) {
|
|
79
|
+
candidates = candidates.filter(
|
|
80
|
+
(n) => n.token?.toLowerCase() === tokenAddress.toLowerCase()
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
const sortedNotes = [...candidates].sort((a, b) => a.amount > b.amount ? 1 : -1);
|
|
84
|
+
const singleNote = sortedNotes.find((n) => n.amount >= requiredAmount);
|
|
85
|
+
if (singleNote) {
|
|
86
|
+
return { circuit: "1x2", selectedNotes: [singleNote] };
|
|
87
|
+
}
|
|
88
|
+
for (let i = 0; i < sortedNotes.length; i++) {
|
|
89
|
+
for (let j = i + 1; j < sortedNotes.length; j++) {
|
|
90
|
+
const combined = sortedNotes[i].amount + sortedNotes[j].amount;
|
|
91
|
+
if (combined >= requiredAmount) {
|
|
92
|
+
return { circuit: "2x2", selectedNotes: [sortedNotes[i], sortedNotes[j]] };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const candidateBalance = candidates.reduce((acc, n) => acc + n.amount, 0n);
|
|
97
|
+
if (candidateBalance >= requiredAmount) {
|
|
98
|
+
return {
|
|
99
|
+
circuit: null,
|
|
100
|
+
selectedNotes: [],
|
|
101
|
+
error: "Requires more than 2 notes. Please consolidate first."
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return { circuit: null, selectedNotes: [], error: "Insufficient balance" };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/core/note-crypto.ts
|
|
108
|
+
chunkBCSMUH4L_cjs.init_crypto();
|
|
109
|
+
async function createHashBasedNote(sdk, amount, spendingSecret, ownerHash, viewingSecret, origin, token) {
|
|
110
|
+
const blinding = await Promise.resolve(sdk.randomFieldElement());
|
|
111
|
+
const commitment = await sdk.poseidon([
|
|
112
|
+
amount,
|
|
113
|
+
ownerHash,
|
|
114
|
+
blinding,
|
|
115
|
+
origin,
|
|
116
|
+
token
|
|
117
|
+
]);
|
|
118
|
+
const searchTagHash = await sdk.poseidon([viewingSecret, commitment]);
|
|
119
|
+
const searchTag = searchTagHash & (1n << 64n) - 1n;
|
|
120
|
+
const encryptedNote = await encryptNoteData(amount, blinding, origin, token, viewingSecret);
|
|
121
|
+
return {
|
|
122
|
+
commitment,
|
|
123
|
+
ownerSecret: spendingSecret,
|
|
124
|
+
ownerHash,
|
|
125
|
+
blinding,
|
|
126
|
+
encryptedNote,
|
|
127
|
+
searchTag,
|
|
128
|
+
amount,
|
|
129
|
+
origin,
|
|
130
|
+
token
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
async function encryptNoteData(amount, blinding, origin, token, viewingSecret) {
|
|
134
|
+
const keyMaterial = viem.keccak256(viem.toHex(viewingSecret, { size: 32 }));
|
|
135
|
+
const keyBytes = chunkBCSMUH4L_cjs.hexToBytes(keyMaterial);
|
|
136
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
137
|
+
"raw",
|
|
138
|
+
keyBytes.buffer.slice(keyBytes.byteOffset, keyBytes.byteOffset + keyBytes.byteLength),
|
|
139
|
+
{ name: "AES-GCM", length: 256 },
|
|
140
|
+
false,
|
|
141
|
+
["encrypt"]
|
|
142
|
+
);
|
|
143
|
+
const plaintext = new Uint8Array(104);
|
|
144
|
+
plaintext.set(chunkBCSMUH4L_cjs.bigintToBytes(amount, 32), 0);
|
|
145
|
+
plaintext.set(chunkBCSMUH4L_cjs.bigintToBytes(blinding, 32), 32);
|
|
146
|
+
plaintext.set(chunkBCSMUH4L_cjs.bigintToBytes(origin, 20), 64);
|
|
147
|
+
plaintext.set(chunkBCSMUH4L_cjs.bigintToBytes(token, 20), 84);
|
|
148
|
+
const nonce = crypto.getRandomValues(new Uint8Array(12));
|
|
149
|
+
const ciphertext = await crypto.subtle.encrypt(
|
|
150
|
+
{ name: "AES-GCM", iv: nonce },
|
|
151
|
+
cryptoKey,
|
|
152
|
+
plaintext
|
|
153
|
+
);
|
|
154
|
+
const result = new Uint8Array(12 + ciphertext.byteLength);
|
|
155
|
+
result.set(nonce, 0);
|
|
156
|
+
result.set(new Uint8Array(ciphertext), 12);
|
|
157
|
+
return viem.toHex(result);
|
|
158
|
+
}
|
|
159
|
+
var UPPAccountContext = react.createContext(null);
|
|
160
|
+
var sdkPromise = null;
|
|
161
|
+
async function loadSDK() {
|
|
162
|
+
if (!sdkPromise) {
|
|
163
|
+
sdkPromise = import('../index.cjs');
|
|
164
|
+
}
|
|
165
|
+
return sdkPromise;
|
|
166
|
+
}
|
|
73
167
|
function UPPAccountProvider({
|
|
74
168
|
children,
|
|
75
169
|
ethAddress,
|
|
@@ -88,10 +182,10 @@ function UPPAccountProvider({
|
|
|
88
182
|
const [isSyncing, setIsSyncing] = react.useState(false);
|
|
89
183
|
const [lastSyncedBlock, _setLastSyncedBlock] = react.useState(0);
|
|
90
184
|
const [liveSyncInterval, setLiveSyncInterval] = react.useState(null);
|
|
91
|
-
const unwatchRef = react.useRef(null);
|
|
92
|
-
const syncPromiseRef = react.useRef(null);
|
|
93
185
|
const noteStoreRef = react.useRef(null);
|
|
186
|
+
const [noteStoreReady, setNoteStoreReady] = react.useState(false);
|
|
94
187
|
const accountAdapterRef = react.useRef(null);
|
|
188
|
+
const [initNonce, setInitNonce] = react.useState(0);
|
|
95
189
|
react.useEffect(() => {
|
|
96
190
|
loadSDK().then(() => setCryptoReady(true));
|
|
97
191
|
}, []);
|
|
@@ -104,11 +198,12 @@ function UPPAccountProvider({
|
|
|
104
198
|
setStarkMasterKeys(null);
|
|
105
199
|
setNotes([]);
|
|
106
200
|
noteStoreRef.current = null;
|
|
201
|
+
setNoteStoreReady(false);
|
|
107
202
|
accountAdapterRef.current = null;
|
|
108
203
|
return;
|
|
109
204
|
}
|
|
110
205
|
const accountStorage = chunkARH2SJM3_cjs.createIndexedDBAdapter(`upp_account`);
|
|
111
|
-
const adapter = new
|
|
206
|
+
const adapter = new chunkC3HXJ5A6_cjs.StorableAccountAdapter(accountStorage, ethAddress);
|
|
112
207
|
accountAdapterRef.current = adapter;
|
|
113
208
|
const legacyKey = getStorageKey(ethAddress);
|
|
114
209
|
const legacySaved = typeof window !== "undefined" ? localStorage.getItem(legacyKey) : null;
|
|
@@ -149,8 +244,9 @@ function UPPAccountProvider({
|
|
|
149
244
|
const ownerHashHex2 = viem.toHex(account.keys.ownerHash, { size: 32 });
|
|
150
245
|
const storagePrefix = `upp_${chainId}_${ownerHashHex2.slice(0, 12)}`;
|
|
151
246
|
const noteStorage = chunkARH2SJM3_cjs.createIndexedDBAdapter(storagePrefix);
|
|
152
|
-
const store = new
|
|
247
|
+
const store = new chunkC3HXJ5A6_cjs.NoteStore(noteStorage, "notes");
|
|
153
248
|
noteStoreRef.current = store;
|
|
249
|
+
setNoteStoreReady(true);
|
|
154
250
|
noteStoreUnsub = store.onChange(() => {
|
|
155
251
|
if (!cancelled) setNotes([...store.getNotes()]);
|
|
156
252
|
});
|
|
@@ -189,15 +285,8 @@ function UPPAccountProvider({
|
|
|
189
285
|
return () => {
|
|
190
286
|
cancelled = true;
|
|
191
287
|
if (noteStoreUnsub) noteStoreUnsub();
|
|
192
|
-
syncPromiseRef.current = null;
|
|
193
288
|
};
|
|
194
|
-
}, [ethAddress, cryptoReady, chainId, publicClientProp]);
|
|
195
|
-
const persistNotes = react.useCallback(
|
|
196
|
-
(_notesToSave) => {
|
|
197
|
-
noteStoreRef.current?.persist().catch(console.error);
|
|
198
|
-
},
|
|
199
|
-
[]
|
|
200
|
-
);
|
|
289
|
+
}, [ethAddress, cryptoReady, chainId, publicClientProp, initNonce]);
|
|
201
290
|
const setupAccount = react.useCallback(
|
|
202
291
|
async (signature) => {
|
|
203
292
|
if (!ethAddress || !cryptoReady) {
|
|
@@ -215,6 +304,7 @@ function UPPAccountProvider({
|
|
|
215
304
|
if (adapter) {
|
|
216
305
|
await adapter.save(keys, starkKeys);
|
|
217
306
|
}
|
|
307
|
+
setInitNonce((n) => n + 1);
|
|
218
308
|
} finally {
|
|
219
309
|
setIsLoading(false);
|
|
220
310
|
}
|
|
@@ -252,8 +342,8 @@ function UPPAccountProvider({
|
|
|
252
342
|
const logout = react.useCallback(() => {
|
|
253
343
|
noteStoreRef.current?.clear().catch(console.error);
|
|
254
344
|
noteStoreRef.current = null;
|
|
345
|
+
setNoteStoreReady(false);
|
|
255
346
|
accountAdapterRef.current?.clear().catch(console.error);
|
|
256
|
-
accountAdapterRef.current = null;
|
|
257
347
|
if (masterKeys) {
|
|
258
348
|
const ownerHashHex2 = viem.toHex(masterKeys.ownerHash, { size: 32 });
|
|
259
349
|
const notesKey = getNotesStorageKey(chainId, ownerHashHex2.slice(0, 12));
|
|
@@ -320,546 +410,87 @@ function UPPAccountProvider({
|
|
|
320
410
|
() => unspentNotes.reduce((acc, n) => acc + n.amount, 0n),
|
|
321
411
|
[unspentNotes]
|
|
322
412
|
);
|
|
323
|
-
const
|
|
324
|
-
(requiredAmount, tokenAddress) =>
|
|
325
|
-
|
|
326
|
-
if (tokenAddress) {
|
|
327
|
-
candidates = candidates.filter(
|
|
328
|
-
(n) => n.token?.toLowerCase() === tokenAddress.toLowerCase()
|
|
329
|
-
);
|
|
330
|
-
}
|
|
331
|
-
const sortedNotes = [...candidates].sort((a, b) => a.amount > b.amount ? 1 : -1);
|
|
332
|
-
const singleNote = sortedNotes.find((n) => n.amount >= requiredAmount);
|
|
333
|
-
if (singleNote) {
|
|
334
|
-
return { circuit: "1x2", selectedNotes: [singleNote] };
|
|
335
|
-
}
|
|
336
|
-
for (let i = 0; i < sortedNotes.length; i++) {
|
|
337
|
-
for (let j = i + 1; j < sortedNotes.length; j++) {
|
|
338
|
-
const combined = sortedNotes[i].amount + sortedNotes[j].amount;
|
|
339
|
-
if (combined >= requiredAmount) {
|
|
340
|
-
return { circuit: "2x2", selectedNotes: [sortedNotes[i], sortedNotes[j]] };
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
const candidateBalance = candidates.reduce((acc, n) => acc + n.amount, 0n);
|
|
345
|
-
if (candidateBalance >= requiredAmount) {
|
|
346
|
-
return {
|
|
347
|
-
circuit: null,
|
|
348
|
-
selectedNotes: [],
|
|
349
|
-
error: "Requires more than 2 notes. Please consolidate first."
|
|
350
|
-
};
|
|
351
|
-
}
|
|
352
|
-
return { circuit: null, selectedNotes: [], error: "Insufficient balance" };
|
|
353
|
-
},
|
|
354
|
-
[unspentNotes, balance]
|
|
413
|
+
const selectOptimalCircuitCb = react.useCallback(
|
|
414
|
+
(requiredAmount, tokenAddress) => selectOptimalCircuit(unspentNotes, requiredAmount, tokenAddress),
|
|
415
|
+
[unspentNotes]
|
|
355
416
|
);
|
|
417
|
+
const syncEngineRef = react.useRef(null);
|
|
418
|
+
react.useEffect(() => {
|
|
419
|
+
if (!masterKeys || !cryptoReady || !publicClientProp || !indexerConfig?.contractAddress || !noteStoreReady) {
|
|
420
|
+
syncEngineRef.current = null;
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
let cancelled = false;
|
|
424
|
+
loadSDK().then((sdk) => {
|
|
425
|
+
if (cancelled) return;
|
|
426
|
+
const store = noteStoreRef.current;
|
|
427
|
+
if (!store) return;
|
|
428
|
+
syncEngineRef.current = chunkPGIV2GDM_cjs.createSyncEngine({
|
|
429
|
+
client: publicClientProp,
|
|
430
|
+
contractAddress: indexerConfig.contractAddress,
|
|
431
|
+
swapModuleAddress: indexerConfig.swapModuleAddress,
|
|
432
|
+
ownerHash: masterKeys.ownerHash,
|
|
433
|
+
spendingSecret: masterKeys.spendingSecret,
|
|
434
|
+
viewingSecret: masterKeys.viewingSecret,
|
|
435
|
+
noteStore: store,
|
|
436
|
+
fromBlock: indexerConfig.fromBlock,
|
|
437
|
+
poseidonFn: (inputs) => sdk.poseidon(inputs)
|
|
438
|
+
});
|
|
439
|
+
});
|
|
440
|
+
return () => {
|
|
441
|
+
cancelled = true;
|
|
442
|
+
};
|
|
443
|
+
}, [masterKeys, cryptoReady, publicClientProp, noteStoreReady, indexerConfig?.contractAddress, indexerConfig?.swapModuleAddress, indexerConfig?.fromBlock]);
|
|
356
444
|
const syncNotes = react.useCallback(
|
|
357
|
-
async (
|
|
358
|
-
|
|
359
|
-
if (
|
|
360
|
-
|
|
445
|
+
async (_contractAddress, _client) => {
|
|
446
|
+
const engine = syncEngineRef.current;
|
|
447
|
+
if (!engine) return 0;
|
|
448
|
+
setIsSyncing(true);
|
|
449
|
+
try {
|
|
450
|
+
const result = await engine.sync();
|
|
451
|
+
return result.discovered + result.repaired;
|
|
452
|
+
} finally {
|
|
453
|
+
setIsSyncing(false);
|
|
361
454
|
}
|
|
362
|
-
const syncPromise = (async () => {
|
|
363
|
-
setIsSyncing(true);
|
|
364
|
-
try {
|
|
365
|
-
const sdk = await loadSDK();
|
|
366
|
-
const viewingSecret = masterKeys.viewingSecret;
|
|
367
|
-
const spendingSecret = masterKeys.spendingSecret;
|
|
368
|
-
const scanFromBlock = BigInt(indexerConfig?.fromBlock ?? 0);
|
|
369
|
-
const swapModuleAddr = indexerConfig?.swapModuleAddress;
|
|
370
|
-
const aesKeyHex = viem.keccak256(viem.toHex(viewingSecret, { size: 32 }));
|
|
371
|
-
const aesKeyBytes = hexToBytes(aesKeyHex);
|
|
372
|
-
const cryptoKey = await crypto.subtle.importKey(
|
|
373
|
-
"raw",
|
|
374
|
-
aesKeyBytes.buffer.slice(aesKeyBytes.byteOffset, aesKeyBytes.byteOffset + aesKeyBytes.byteLength),
|
|
375
|
-
{ name: "AES-GCM", length: 256 },
|
|
376
|
-
false,
|
|
377
|
-
["decrypt"]
|
|
378
|
-
);
|
|
379
|
-
const currentStore = noteStoreRef.current;
|
|
380
|
-
const existingCommitments = new Set(
|
|
381
|
-
(currentStore ? currentStore.getNotes() : notes).map((n) => n.commitment.toLowerCase())
|
|
382
|
-
);
|
|
383
|
-
const candidates = [];
|
|
384
|
-
console.log("[syncNotes] Scanning contract:", contractAddress, "\u2014 existing:", existingCommitments.size, "notes", "\u2014 store:", currentStore ? "ready" : "NULL");
|
|
385
|
-
try {
|
|
386
|
-
const shieldedLogs = await client.getLogs({
|
|
387
|
-
address: contractAddress,
|
|
388
|
-
event: {
|
|
389
|
-
type: "event",
|
|
390
|
-
name: "Shielded",
|
|
391
|
-
inputs: [
|
|
392
|
-
{ name: "token", type: "address", indexed: true },
|
|
393
|
-
{ name: "depositor", type: "address", indexed: true },
|
|
394
|
-
{ name: "commitment", type: "bytes32", indexed: true },
|
|
395
|
-
{ name: "leafIndex", type: "uint256", indexed: false },
|
|
396
|
-
{ name: "encryptedNote", type: "bytes", indexed: false }
|
|
397
|
-
]
|
|
398
|
-
},
|
|
399
|
-
fromBlock: scanFromBlock,
|
|
400
|
-
toBlock: "latest"
|
|
401
|
-
});
|
|
402
|
-
for (const log of shieldedLogs) {
|
|
403
|
-
const commitment = log.args.commitment;
|
|
404
|
-
if (existingCommitments.has(commitment.toLowerCase())) continue;
|
|
405
|
-
candidates.push({
|
|
406
|
-
commitment,
|
|
407
|
-
leafIndex: Number(log.args.leafIndex),
|
|
408
|
-
packedData: log.args.encryptedNote,
|
|
409
|
-
txHash: log.transactionHash
|
|
410
|
-
});
|
|
411
|
-
}
|
|
412
|
-
} catch (e) {
|
|
413
|
-
console.warn("[syncNotes] Failed to scan Shielded events:", e?.message ?? e);
|
|
414
|
-
}
|
|
415
|
-
const commitmentLeafMap = /* @__PURE__ */ new Map();
|
|
416
|
-
try {
|
|
417
|
-
const transferredLogs = await client.getLogs({
|
|
418
|
-
address: contractAddress,
|
|
419
|
-
event: {
|
|
420
|
-
type: "event",
|
|
421
|
-
name: "Transferred",
|
|
422
|
-
inputs: [
|
|
423
|
-
{ name: "nullifier", type: "bytes32", indexed: true },
|
|
424
|
-
{ name: "outputCommitment1", type: "bytes32", indexed: true },
|
|
425
|
-
{ name: "outputCommitment2", type: "bytes32", indexed: true },
|
|
426
|
-
{ name: "encryptedNote1", type: "bytes", indexed: false },
|
|
427
|
-
{ name: "encryptedNote2", type: "bytes", indexed: false }
|
|
428
|
-
]
|
|
429
|
-
},
|
|
430
|
-
fromBlock: scanFromBlock,
|
|
431
|
-
toBlock: "latest"
|
|
432
|
-
});
|
|
433
|
-
try {
|
|
434
|
-
const ciLogs = await client.getLogs({
|
|
435
|
-
address: contractAddress,
|
|
436
|
-
event: {
|
|
437
|
-
type: "event",
|
|
438
|
-
name: "CommitmentInserted",
|
|
439
|
-
inputs: [
|
|
440
|
-
{ name: "commitment", type: "bytes32", indexed: true },
|
|
441
|
-
{ name: "leafIndex", type: "uint256", indexed: false },
|
|
442
|
-
{ name: "timestamp", type: "uint256", indexed: false }
|
|
443
|
-
]
|
|
444
|
-
},
|
|
445
|
-
fromBlock: scanFromBlock,
|
|
446
|
-
toBlock: "latest"
|
|
447
|
-
});
|
|
448
|
-
for (const log of ciLogs) {
|
|
449
|
-
commitmentLeafMap.set(
|
|
450
|
-
log.args.commitment.toLowerCase(),
|
|
451
|
-
Number(log.args.leafIndex)
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
} catch (e) {
|
|
455
|
-
console.warn("[syncNotes] Failed to scan CommitmentInserted events:", e);
|
|
456
|
-
}
|
|
457
|
-
for (const log of transferredLogs) {
|
|
458
|
-
const c1 = log.args.outputCommitment1;
|
|
459
|
-
const c2 = log.args.outputCommitment2;
|
|
460
|
-
const txHash = log.transactionHash;
|
|
461
|
-
if (!existingCommitments.has(c1.toLowerCase())) {
|
|
462
|
-
candidates.push({
|
|
463
|
-
commitment: c1,
|
|
464
|
-
leafIndex: commitmentLeafMap.get(c1.toLowerCase()) ?? -1,
|
|
465
|
-
packedData: log.args.encryptedNote1,
|
|
466
|
-
txHash
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
if (!existingCommitments.has(c2.toLowerCase())) {
|
|
470
|
-
candidates.push({
|
|
471
|
-
commitment: c2,
|
|
472
|
-
leafIndex: commitmentLeafMap.get(c2.toLowerCase()) ?? -1,
|
|
473
|
-
packedData: log.args.encryptedNote2,
|
|
474
|
-
txHash
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
} catch (e) {
|
|
479
|
-
console.warn("[syncNotes] Failed to scan Transferred events:", e);
|
|
480
|
-
}
|
|
481
|
-
if (swapModuleAddr) try {
|
|
482
|
-
const filledLogs = await client.getLogs({
|
|
483
|
-
address: swapModuleAddr,
|
|
484
|
-
event: {
|
|
485
|
-
type: "event",
|
|
486
|
-
name: "SwapOrderFilled",
|
|
487
|
-
inputs: [
|
|
488
|
-
{ name: "orderId", type: "bytes32", indexed: true },
|
|
489
|
-
{ name: "fillerNullifier", type: "bytes32", indexed: true },
|
|
490
|
-
{ name: "fillerOutputCommitment", type: "bytes32", indexed: true },
|
|
491
|
-
{ name: "takeAmount", type: "uint256", indexed: false },
|
|
492
|
-
{ name: "giveAmount", type: "uint256", indexed: false },
|
|
493
|
-
{ name: "fillerAspId", type: "uint256", indexed: false },
|
|
494
|
-
{ name: "remainingSellAmount", type: "uint256", indexed: false },
|
|
495
|
-
{ name: "encryptedFillerNote", type: "bytes", indexed: false }
|
|
496
|
-
]
|
|
497
|
-
},
|
|
498
|
-
fromBlock: scanFromBlock,
|
|
499
|
-
toBlock: "latest"
|
|
500
|
-
});
|
|
501
|
-
for (const log of filledLogs) {
|
|
502
|
-
const c = log.args.fillerOutputCommitment;
|
|
503
|
-
if (!existingCommitments.has(c.toLowerCase())) {
|
|
504
|
-
candidates.push({
|
|
505
|
-
commitment: c,
|
|
506
|
-
leafIndex: commitmentLeafMap.get(c.toLowerCase()) ?? -1,
|
|
507
|
-
packedData: log.args.encryptedFillerNote,
|
|
508
|
-
txHash: log.transactionHash
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
} catch (e) {
|
|
513
|
-
console.warn("[syncNotes] Failed to scan SwapOrderFilled events:", e);
|
|
514
|
-
}
|
|
515
|
-
if (swapModuleAddr) try {
|
|
516
|
-
const claimedLogs = await client.getLogs({
|
|
517
|
-
address: swapModuleAddr,
|
|
518
|
-
event: {
|
|
519
|
-
type: "event",
|
|
520
|
-
name: "SwapOrderClaimed",
|
|
521
|
-
inputs: [
|
|
522
|
-
{ name: "orderId", type: "bytes32", indexed: true },
|
|
523
|
-
{ name: "accumulatedBuyAmount", type: "uint256", indexed: false },
|
|
524
|
-
{ name: "refundedSellAmount", type: "uint256", indexed: false },
|
|
525
|
-
{ name: "buyOutputCommitment", type: "bytes32", indexed: false },
|
|
526
|
-
{ name: "encryptedBuyNote", type: "bytes", indexed: false },
|
|
527
|
-
{ name: "refundCommitment", type: "bytes32", indexed: false },
|
|
528
|
-
{ name: "encryptedRefundNote", type: "bytes", indexed: false }
|
|
529
|
-
]
|
|
530
|
-
},
|
|
531
|
-
fromBlock: scanFromBlock,
|
|
532
|
-
toBlock: "latest"
|
|
533
|
-
});
|
|
534
|
-
for (const log of claimedLogs) {
|
|
535
|
-
const buyC = log.args.buyOutputCommitment;
|
|
536
|
-
const refundC = log.args.refundCommitment;
|
|
537
|
-
const txHash = log.transactionHash;
|
|
538
|
-
if (buyC && !existingCommitments.has(buyC.toLowerCase())) {
|
|
539
|
-
candidates.push({
|
|
540
|
-
commitment: buyC,
|
|
541
|
-
leafIndex: commitmentLeafMap.get(buyC.toLowerCase()) ?? -1,
|
|
542
|
-
packedData: log.args.encryptedBuyNote,
|
|
543
|
-
txHash
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
if (refundC && !existingCommitments.has(refundC.toLowerCase())) {
|
|
547
|
-
candidates.push({
|
|
548
|
-
commitment: refundC,
|
|
549
|
-
leafIndex: commitmentLeafMap.get(refundC.toLowerCase()) ?? -1,
|
|
550
|
-
packedData: log.args.encryptedRefundNote,
|
|
551
|
-
txHash
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
} catch (e) {
|
|
556
|
-
console.warn("[syncNotes] Failed to scan SwapOrderClaimed events:", e);
|
|
557
|
-
}
|
|
558
|
-
if (swapModuleAddr) try {
|
|
559
|
-
const cancelledLogs = await client.getLogs({
|
|
560
|
-
address: swapModuleAddr,
|
|
561
|
-
event: {
|
|
562
|
-
type: "event",
|
|
563
|
-
name: "SwapOrderCancelled",
|
|
564
|
-
inputs: [
|
|
565
|
-
{ name: "orderId", type: "bytes32", indexed: true },
|
|
566
|
-
{ name: "refundedSellAmount", type: "uint256", indexed: false },
|
|
567
|
-
{ name: "refundCommitment", type: "bytes32", indexed: false },
|
|
568
|
-
{ name: "encryptedRefundNote", type: "bytes", indexed: false }
|
|
569
|
-
]
|
|
570
|
-
},
|
|
571
|
-
fromBlock: scanFromBlock,
|
|
572
|
-
toBlock: "latest"
|
|
573
|
-
});
|
|
574
|
-
for (const log of cancelledLogs) {
|
|
575
|
-
const c = log.args.refundCommitment;
|
|
576
|
-
if (c && !existingCommitments.has(c.toLowerCase())) {
|
|
577
|
-
candidates.push({
|
|
578
|
-
commitment: c,
|
|
579
|
-
leafIndex: commitmentLeafMap.get(c.toLowerCase()) ?? -1,
|
|
580
|
-
packedData: log.args.encryptedRefundNote,
|
|
581
|
-
txHash: log.transactionHash
|
|
582
|
-
});
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
} catch (e) {
|
|
586
|
-
console.warn("[syncNotes] Failed to scan SwapOrderCancelled events:", e);
|
|
587
|
-
}
|
|
588
|
-
let discovered = 0;
|
|
589
|
-
let skippedEmpty = 0, skippedOwner = 0;
|
|
590
|
-
for (const candidate of candidates) {
|
|
591
|
-
try {
|
|
592
|
-
const packed = candidate.packedData;
|
|
593
|
-
if (!packed || packed === "0x" || packed.length < 82) {
|
|
594
|
-
skippedEmpty++;
|
|
595
|
-
continue;
|
|
596
|
-
}
|
|
597
|
-
const raw = packed.startsWith("0x") ? packed.slice(2) : packed;
|
|
598
|
-
const noteOwnerHash = BigInt("0x" + raw.slice(16, 80));
|
|
599
|
-
const encryptedPayload = raw.slice(80);
|
|
600
|
-
if (noteOwnerHash !== masterKeys.ownerHash) {
|
|
601
|
-
console.log(`[syncNotes] ownerHash mismatch: note=${noteOwnerHash.toString(16).slice(0, 16)}\u2026 ours=${masterKeys.ownerHash.toString(16).slice(0, 16)}\u2026`);
|
|
602
|
-
skippedOwner++;
|
|
603
|
-
continue;
|
|
604
|
-
}
|
|
605
|
-
const encBytes = hexToBytes("0x" + encryptedPayload);
|
|
606
|
-
if (encBytes.length < 12) continue;
|
|
607
|
-
const nonce = encBytes.slice(0, 12);
|
|
608
|
-
const ciphertext = encBytes.slice(12);
|
|
609
|
-
let plaintext;
|
|
610
|
-
try {
|
|
611
|
-
plaintext = await crypto.subtle.decrypt(
|
|
612
|
-
{ name: "AES-GCM", iv: nonce },
|
|
613
|
-
cryptoKey,
|
|
614
|
-
ciphertext
|
|
615
|
-
);
|
|
616
|
-
} catch {
|
|
617
|
-
continue;
|
|
618
|
-
}
|
|
619
|
-
const ptBytes = new Uint8Array(plaintext);
|
|
620
|
-
if (ptBytes.length !== 104) continue;
|
|
621
|
-
const amount = bytesToBigint(ptBytes.slice(0, 32));
|
|
622
|
-
const blinding = bytesToBigint(ptBytes.slice(32, 64));
|
|
623
|
-
const originRaw = "0x" + Array.from(ptBytes.slice(64, 84)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
624
|
-
const tokenRaw = "0x" + Array.from(ptBytes.slice(84, 104)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
625
|
-
const origin = viem.getAddress(originRaw);
|
|
626
|
-
const token = viem.getAddress(tokenRaw);
|
|
627
|
-
const ownerHash = await sdk.poseidon([spendingSecret]);
|
|
628
|
-
const expectedCommitment = await sdk.poseidon([
|
|
629
|
-
amount,
|
|
630
|
-
ownerHash,
|
|
631
|
-
blinding,
|
|
632
|
-
BigInt(origin),
|
|
633
|
-
BigInt(token)
|
|
634
|
-
]);
|
|
635
|
-
const expectedHex = viem.toHex(expectedCommitment, { size: 32 });
|
|
636
|
-
if (expectedHex.toLowerCase() !== candidate.commitment.toLowerCase()) {
|
|
637
|
-
console.warn(`[syncNotes] Commitment mismatch: expected=${expectedHex.slice(0, 16)}\u2026 got=${candidate.commitment.slice(0, 16)}\u2026`);
|
|
638
|
-
continue;
|
|
639
|
-
}
|
|
640
|
-
const newNote = {
|
|
641
|
-
commitment: candidate.commitment,
|
|
642
|
-
amount,
|
|
643
|
-
blinding,
|
|
644
|
-
ownerSecret: viem.toHex(spendingSecret, { size: 32 }),
|
|
645
|
-
ownerHash: viem.toHex(masterKeys.ownerHash, { size: 32 }),
|
|
646
|
-
origin,
|
|
647
|
-
token,
|
|
648
|
-
leafIndex: candidate.leafIndex,
|
|
649
|
-
status: "confirmed",
|
|
650
|
-
timestamp: Math.floor(Date.now() / 1e3),
|
|
651
|
-
txHash: candidate.txHash,
|
|
652
|
-
proofSystem: "snark"
|
|
653
|
-
};
|
|
654
|
-
const store2 = noteStoreRef.current;
|
|
655
|
-
if (store2) {
|
|
656
|
-
if (store2.addNote(newNote)) discovered++;
|
|
657
|
-
} else {
|
|
658
|
-
setNotes((prev) => {
|
|
659
|
-
if (prev.some((n) => n.commitment.toLowerCase() === newNote.commitment.toLowerCase())) return prev;
|
|
660
|
-
return [...prev, newNote];
|
|
661
|
-
});
|
|
662
|
-
discovered++;
|
|
663
|
-
}
|
|
664
|
-
} catch (e) {
|
|
665
|
-
console.warn("[syncNotes] Failed to process candidate:", e);
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
if (discovered > 0 || candidates.length > 0) {
|
|
669
|
-
console.log(`[syncNotes] Discovered ${discovered} new notes from ${candidates.length} candidates`);
|
|
670
|
-
}
|
|
671
|
-
if (commitmentLeafMap.size === 0) {
|
|
672
|
-
try {
|
|
673
|
-
const ciLogs = await client.getLogs({
|
|
674
|
-
address: contractAddress,
|
|
675
|
-
event: {
|
|
676
|
-
type: "event",
|
|
677
|
-
name: "CommitmentInserted",
|
|
678
|
-
inputs: [
|
|
679
|
-
{ name: "commitment", type: "bytes32", indexed: true },
|
|
680
|
-
{ name: "leafIndex", type: "uint256", indexed: false },
|
|
681
|
-
{ name: "timestamp", type: "uint256", indexed: false }
|
|
682
|
-
]
|
|
683
|
-
},
|
|
684
|
-
fromBlock: scanFromBlock,
|
|
685
|
-
toBlock: "latest"
|
|
686
|
-
});
|
|
687
|
-
for (const log of ciLogs) {
|
|
688
|
-
commitmentLeafMap.set(
|
|
689
|
-
log.args.commitment.toLowerCase(),
|
|
690
|
-
Number(log.args.leafIndex)
|
|
691
|
-
);
|
|
692
|
-
}
|
|
693
|
-
} catch {
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
let repaired = 0;
|
|
697
|
-
const store = noteStoreRef.current;
|
|
698
|
-
if (store) {
|
|
699
|
-
for (const note of store.getNotes()) {
|
|
700
|
-
const correctLeafIndex = commitmentLeafMap.get(note.commitment.toLowerCase());
|
|
701
|
-
if (correctLeafIndex !== void 0 && note.leafIndex !== correctLeafIndex) {
|
|
702
|
-
store.updateLeafIndex(note.commitment, correctLeafIndex);
|
|
703
|
-
repaired++;
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
try {
|
|
708
|
-
const currentNotes = store ? store.getNotes() : notes;
|
|
709
|
-
const snarkNotes = currentNotes.filter((n) => n.proofSystem !== "stark");
|
|
710
|
-
const unspentSnarkNotes = snarkNotes.filter((n) => n.status !== "spent");
|
|
711
|
-
if (unspentSnarkNotes.length > 0) {
|
|
712
|
-
const sdk2 = await loadSDK();
|
|
713
|
-
for (const note of unspentSnarkNotes) {
|
|
714
|
-
const correctLeaf = commitmentLeafMap.get(note.commitment.toLowerCase());
|
|
715
|
-
if (correctLeaf === void 0) continue;
|
|
716
|
-
const ownerSecret = BigInt(note.ownerSecret);
|
|
717
|
-
const commitment = BigInt(note.commitment);
|
|
718
|
-
const nullifier = await sdk2.poseidon([
|
|
719
|
-
ownerSecret,
|
|
720
|
-
BigInt(correctLeaf),
|
|
721
|
-
commitment
|
|
722
|
-
]);
|
|
723
|
-
const nullifierHex = viem.toHex(nullifier, { size: 32 });
|
|
724
|
-
const isUsed = await client.readContract({
|
|
725
|
-
address: contractAddress,
|
|
726
|
-
abi: [{
|
|
727
|
-
type: "function",
|
|
728
|
-
name: "nullifierUsed",
|
|
729
|
-
inputs: [{ name: "", type: "bytes32" }],
|
|
730
|
-
outputs: [{ name: "", type: "bool" }],
|
|
731
|
-
stateMutability: "view"
|
|
732
|
-
}],
|
|
733
|
-
functionName: "nullifierUsed",
|
|
734
|
-
args: [nullifierHex]
|
|
735
|
-
});
|
|
736
|
-
if (isUsed) {
|
|
737
|
-
console.log(`[syncNotes] Marking note ${note.commitment.slice(0, 12)} as spent \u2014 nullifier found on-chain`);
|
|
738
|
-
if (store) store.markSpent(note.commitment);
|
|
739
|
-
repaired++;
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
const spentSnarkNotes = snarkNotes.filter((n) => n.status === "spent");
|
|
744
|
-
if (spentSnarkNotes.length > 0) {
|
|
745
|
-
const sdk2 = await loadSDK();
|
|
746
|
-
for (const note of spentSnarkNotes) {
|
|
747
|
-
const correctLeaf = commitmentLeafMap.get(note.commitment.toLowerCase());
|
|
748
|
-
if (correctLeaf === void 0) continue;
|
|
749
|
-
const ownerSecret = BigInt(note.ownerSecret);
|
|
750
|
-
const commitment = BigInt(note.commitment);
|
|
751
|
-
const nullifier = await sdk2.poseidon([
|
|
752
|
-
ownerSecret,
|
|
753
|
-
BigInt(correctLeaf),
|
|
754
|
-
commitment
|
|
755
|
-
]);
|
|
756
|
-
const nullifierHex = viem.toHex(nullifier, { size: 32 });
|
|
757
|
-
const isUsed = await client.readContract({
|
|
758
|
-
address: contractAddress,
|
|
759
|
-
abi: [{
|
|
760
|
-
type: "function",
|
|
761
|
-
name: "nullifierUsed",
|
|
762
|
-
inputs: [{ name: "", type: "bytes32" }],
|
|
763
|
-
outputs: [{ name: "", type: "bool" }],
|
|
764
|
-
stateMutability: "view"
|
|
765
|
-
}],
|
|
766
|
-
functionName: "nullifierUsed",
|
|
767
|
-
args: [nullifierHex]
|
|
768
|
-
});
|
|
769
|
-
if (!isUsed) {
|
|
770
|
-
console.log(`[syncNotes] Un-spending note ${note.commitment.slice(0, 12)} \u2014 nullifier not used on-chain`);
|
|
771
|
-
if (store) {
|
|
772
|
-
store.unmarkSpent(note.commitment);
|
|
773
|
-
store.updateLeafIndex(note.commitment, correctLeaf);
|
|
774
|
-
}
|
|
775
|
-
repaired++;
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
} catch (e) {
|
|
780
|
-
console.warn("[syncNotes] Nullifier verification failed:", e);
|
|
781
|
-
}
|
|
782
|
-
if (repaired > 0) {
|
|
783
|
-
console.log(`[syncNotes] Repaired ${repaired} existing notes`);
|
|
784
|
-
}
|
|
785
|
-
if (store && (discovered > 0 || repaired > 0)) {
|
|
786
|
-
await store.persist();
|
|
787
|
-
console.log(`[syncNotes] Persisted ${store.getNotes().length} notes to IndexedDB`);
|
|
788
|
-
} else if (!store) {
|
|
789
|
-
console.warn("[syncNotes] No NoteStore \u2014 notes NOT persisted");
|
|
790
|
-
}
|
|
791
|
-
return discovered + repaired;
|
|
792
|
-
} finally {
|
|
793
|
-
setIsSyncing(false);
|
|
794
|
-
syncPromiseRef.current = null;
|
|
795
|
-
}
|
|
796
|
-
})();
|
|
797
|
-
syncPromiseRef.current = syncPromise;
|
|
798
|
-
return syncPromise;
|
|
799
455
|
},
|
|
800
|
-
|
|
801
|
-
// sync loops. The callback reads notes from noteStoreRef.current directly.
|
|
802
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
803
|
-
[masterKeys, cryptoReady, persistNotes, indexerConfig?.fromBlock]
|
|
456
|
+
[]
|
|
804
457
|
);
|
|
805
458
|
const startLiveSync = react.useCallback(
|
|
806
|
-
(
|
|
807
|
-
|
|
808
|
-
if (
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
try {
|
|
814
|
-
const unwatch = client.watchContractEvent({
|
|
815
|
-
address: contractAddress,
|
|
816
|
-
eventName: "CommitmentInserted",
|
|
817
|
-
onLogs: () => {
|
|
818
|
-
syncNotes(contractAddress, client).catch(console.error);
|
|
819
|
-
}
|
|
820
|
-
});
|
|
821
|
-
unwatchRef.current = unwatch;
|
|
822
|
-
} catch (e) {
|
|
823
|
-
console.warn("[liveSync] watchContractEvent not available, using polling only:", e);
|
|
824
|
-
}
|
|
825
|
-
const fallbackMs = indexerConfig?.liveSyncIntervalMs ?? 6e4;
|
|
826
|
-
const interval = setInterval(() => {
|
|
827
|
-
syncNotes(contractAddress, client).catch(console.error);
|
|
828
|
-
}, fallbackMs);
|
|
829
|
-
setLiveSyncInterval(interval);
|
|
459
|
+
(_contractAddress, _client) => {
|
|
460
|
+
const engine = syncEngineRef.current;
|
|
461
|
+
if (!engine) return;
|
|
462
|
+
engine.startLiveSync({
|
|
463
|
+
intervalMs: indexerConfig?.liveSyncIntervalMs ?? 6e4
|
|
464
|
+
});
|
|
465
|
+
setLiveSyncInterval(true);
|
|
830
466
|
},
|
|
831
|
-
[
|
|
467
|
+
[indexerConfig?.liveSyncIntervalMs]
|
|
832
468
|
);
|
|
833
469
|
const stopLiveSync = react.useCallback(() => {
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
}
|
|
838
|
-
if (unwatchRef.current) {
|
|
839
|
-
unwatchRef.current();
|
|
840
|
-
unwatchRef.current = null;
|
|
841
|
-
}
|
|
842
|
-
}, [liveSyncInterval]);
|
|
470
|
+
syncEngineRef.current?.stopLiveSync();
|
|
471
|
+
setLiveSyncInterval(null);
|
|
472
|
+
}, []);
|
|
843
473
|
react.useEffect(() => {
|
|
844
474
|
return () => {
|
|
845
|
-
|
|
846
|
-
if (unwatchRef.current) {
|
|
847
|
-
unwatchRef.current();
|
|
848
|
-
unwatchRef.current = null;
|
|
849
|
-
}
|
|
475
|
+
syncEngineRef.current?.stopLiveSync();
|
|
850
476
|
};
|
|
851
|
-
}, [
|
|
477
|
+
}, []);
|
|
852
478
|
react.useEffect(() => {
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
479
|
+
if (!syncEngineRef.current) return;
|
|
480
|
+
syncEngineRef.current.startLiveSync({
|
|
481
|
+
intervalMs: indexerConfig?.liveSyncIntervalMs ?? 6e4
|
|
482
|
+
});
|
|
483
|
+
setLiveSyncInterval(true);
|
|
484
|
+
return () => {
|
|
485
|
+
syncEngineRef.current?.stopLiveSync();
|
|
486
|
+
setLiveSyncInterval(null);
|
|
487
|
+
};
|
|
857
488
|
}, [masterKeys, publicClientProp, indexerConfig?.contractAddress]);
|
|
858
489
|
const ownerHashHex = masterKeys ? viem.toHex(masterKeys.ownerHash, { size: 32 }) : null;
|
|
859
490
|
const stealthAddress = react.useMemo(() => {
|
|
860
491
|
if (!masterKeys) return null;
|
|
861
492
|
try {
|
|
862
|
-
const { encodeStealthAddress } = (
|
|
493
|
+
const { encodeStealthAddress } = (chunkC3HXJ5A6_cjs.init_stealth(), chunkG7VZBCD6_cjs.__toCommonJS(chunkC3HXJ5A6_cjs.stealth_exports));
|
|
863
494
|
return encodeStealthAddress(masterKeys.ownerHash, masterKeys.viewingHash);
|
|
864
495
|
} catch {
|
|
865
496
|
return null;
|
|
@@ -868,7 +499,7 @@ function UPPAccountProvider({
|
|
|
868
499
|
const starkStealthAddress = react.useMemo(() => {
|
|
869
500
|
if (!starkMasterKeys) return null;
|
|
870
501
|
try {
|
|
871
|
-
const { encodeStarkStealthAddress } = (
|
|
502
|
+
const { encodeStarkStealthAddress } = (chunkC3HXJ5A6_cjs.init_stealth(), chunkG7VZBCD6_cjs.__toCommonJS(chunkC3HXJ5A6_cjs.stealth_exports));
|
|
872
503
|
return encodeStarkStealthAddress(starkMasterKeys.starkOwnerHash, starkMasterKeys.starkViewingHash);
|
|
873
504
|
} catch {
|
|
874
505
|
return null;
|
|
@@ -901,7 +532,7 @@ function UPPAccountProvider({
|
|
|
901
532
|
markNoteSpent,
|
|
902
533
|
createNoteForSelf,
|
|
903
534
|
getOwnerHash,
|
|
904
|
-
selectOptimalCircuit,
|
|
535
|
+
selectOptimalCircuit: selectOptimalCircuitCb,
|
|
905
536
|
syncNotes,
|
|
906
537
|
startLiveSync,
|
|
907
538
|
stopLiveSync,
|
|
@@ -918,80 +549,6 @@ function useUPPAccount() {
|
|
|
918
549
|
}
|
|
919
550
|
return context;
|
|
920
551
|
}
|
|
921
|
-
async function createHashBasedNote(sdk, amount, spendingSecret, ownerHash, viewingSecret, origin, token) {
|
|
922
|
-
const blinding = await sdk.randomFieldElement();
|
|
923
|
-
const commitment = await sdk.poseidon([
|
|
924
|
-
amount,
|
|
925
|
-
ownerHash,
|
|
926
|
-
blinding,
|
|
927
|
-
origin,
|
|
928
|
-
token
|
|
929
|
-
]);
|
|
930
|
-
const searchTagHash = await sdk.poseidon([viewingSecret, commitment]);
|
|
931
|
-
const searchTag = searchTagHash & (1n << 64n) - 1n;
|
|
932
|
-
const encryptedNote = await encryptNoteData(amount, blinding, origin, token, viewingSecret);
|
|
933
|
-
return {
|
|
934
|
-
commitment,
|
|
935
|
-
ownerSecret: spendingSecret,
|
|
936
|
-
ownerHash,
|
|
937
|
-
blinding,
|
|
938
|
-
encryptedNote,
|
|
939
|
-
searchTag,
|
|
940
|
-
amount,
|
|
941
|
-
origin,
|
|
942
|
-
token
|
|
943
|
-
};
|
|
944
|
-
}
|
|
945
|
-
async function encryptNoteData(amount, blinding, origin, token, viewingSecret) {
|
|
946
|
-
const keyMaterial = viem.keccak256(viem.toHex(viewingSecret, { size: 32 }));
|
|
947
|
-
const keyBytes = hexToBytes(keyMaterial);
|
|
948
|
-
const cryptoKey = await crypto.subtle.importKey(
|
|
949
|
-
"raw",
|
|
950
|
-
keyBytes.buffer.slice(keyBytes.byteOffset, keyBytes.byteOffset + keyBytes.byteLength),
|
|
951
|
-
{ name: "AES-GCM", length: 256 },
|
|
952
|
-
false,
|
|
953
|
-
["encrypt"]
|
|
954
|
-
);
|
|
955
|
-
const plaintext = new Uint8Array(104);
|
|
956
|
-
plaintext.set(bigintToBytes(amount, 32), 0);
|
|
957
|
-
plaintext.set(bigintToBytes(blinding, 32), 32);
|
|
958
|
-
plaintext.set(bigintToBytes(origin, 20), 64);
|
|
959
|
-
plaintext.set(bigintToBytes(token, 20), 84);
|
|
960
|
-
const nonce = crypto.getRandomValues(new Uint8Array(12));
|
|
961
|
-
const ciphertext = await crypto.subtle.encrypt(
|
|
962
|
-
{ name: "AES-GCM", iv: nonce },
|
|
963
|
-
cryptoKey,
|
|
964
|
-
plaintext
|
|
965
|
-
);
|
|
966
|
-
const result = new Uint8Array(12 + ciphertext.byteLength);
|
|
967
|
-
result.set(nonce, 0);
|
|
968
|
-
result.set(new Uint8Array(ciphertext), 12);
|
|
969
|
-
return viem.toHex(result);
|
|
970
|
-
}
|
|
971
|
-
function hexToBytes(hex) {
|
|
972
|
-
const h = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
973
|
-
const bytes = new Uint8Array(h.length / 2);
|
|
974
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
975
|
-
bytes[i] = parseInt(h.substr(i * 2, 2), 16);
|
|
976
|
-
}
|
|
977
|
-
return bytes;
|
|
978
|
-
}
|
|
979
|
-
function bigintToBytes(n, length) {
|
|
980
|
-
const bytes = new Uint8Array(length);
|
|
981
|
-
let temp = n;
|
|
982
|
-
for (let i = length - 1; i >= 0; i--) {
|
|
983
|
-
bytes[i] = Number(temp & 0xffn);
|
|
984
|
-
temp >>= 8n;
|
|
985
|
-
}
|
|
986
|
-
return bytes;
|
|
987
|
-
}
|
|
988
|
-
function bytesToBigint(bytes) {
|
|
989
|
-
let result = 0n;
|
|
990
|
-
for (const b of bytes) {
|
|
991
|
-
result = result << 8n | BigInt(b);
|
|
992
|
-
}
|
|
993
|
-
return result;
|
|
994
|
-
}
|
|
995
552
|
|
|
996
553
|
// src/react/utils/avatar.ts
|
|
997
554
|
function hashBytes(input) {
|
|
@@ -1596,12 +1153,6 @@ function useUPPCrypto() {
|
|
|
1596
1153
|
getSubOrder
|
|
1597
1154
|
};
|
|
1598
1155
|
}
|
|
1599
|
-
function packNoteData(note) {
|
|
1600
|
-
return viem.encodePacked(
|
|
1601
|
-
["uint64", "uint256", "bytes"],
|
|
1602
|
-
[note.searchTag, note.ownerHash, note.encryptedNote]
|
|
1603
|
-
);
|
|
1604
|
-
}
|
|
1605
1156
|
function useShield(config) {
|
|
1606
1157
|
const { createNoteForSelf, isSetup, masterKeys } = useUPPAccount();
|
|
1607
1158
|
const [isPending, setIsPending] = react.useState(false);
|
|
@@ -1631,7 +1182,7 @@ function useShield(config) {
|
|
|
1631
1182
|
setStage("creating_note");
|
|
1632
1183
|
const noteData = await createNoteForSelf(amount, origin, token);
|
|
1633
1184
|
const commitment = viem.toHex(noteData.commitment, { size: 32 });
|
|
1634
|
-
const encryptedNote = packNoteData(noteData);
|
|
1185
|
+
const encryptedNote = chunkY3VL3LOE_cjs.packNoteData(noteData);
|
|
1635
1186
|
return {
|
|
1636
1187
|
amount,
|
|
1637
1188
|
token: cfg.tokenAddress,
|
|
@@ -1658,12 +1209,6 @@ function useShield(config) {
|
|
|
1658
1209
|
reset
|
|
1659
1210
|
};
|
|
1660
1211
|
}
|
|
1661
|
-
function packNoteData2(note) {
|
|
1662
|
-
return viem.encodePacked(
|
|
1663
|
-
["uint64", "uint256", "bytes"],
|
|
1664
|
-
[note.searchTag, note.ownerHash, note.encryptedNote]
|
|
1665
|
-
);
|
|
1666
|
-
}
|
|
1667
1212
|
function usePoolTransfer(config) {
|
|
1668
1213
|
const {
|
|
1669
1214
|
unspentNotes,
|
|
@@ -1716,7 +1261,7 @@ function usePoolTransfer(config) {
|
|
|
1716
1261
|
const recipientNote = await createNoteForSelf(amount, origin, token);
|
|
1717
1262
|
const changeNote = await createNoteForSelf(changeAmount, origin, token);
|
|
1718
1263
|
const [transferModule, proofModule, aspModule] = await Promise.all([
|
|
1719
|
-
import('../transfer-
|
|
1264
|
+
import('../transfer-TJNDCZF2.cjs'),
|
|
1720
1265
|
import('../proof-X3MVQFFZ.cjs'),
|
|
1721
1266
|
import('../asp-CUE3NMBN.cjs')
|
|
1722
1267
|
]);
|
|
@@ -1755,7 +1300,7 @@ function usePoolTransfer(config) {
|
|
|
1755
1300
|
changeNoteWithAmount
|
|
1756
1301
|
);
|
|
1757
1302
|
setProvingProgress(null);
|
|
1758
|
-
const { proof } = await
|
|
1303
|
+
const { proof } = await chunkC3HXJ5A6_cjs.generateUPPProofAsync(
|
|
1759
1304
|
"transfer",
|
|
1760
1305
|
circuitInputs,
|
|
1761
1306
|
cfg.circuitBaseUrl,
|
|
@@ -1775,8 +1320,8 @@ function usePoolTransfer(config) {
|
|
|
1775
1320
|
token: cfg.tokenAddress,
|
|
1776
1321
|
outputCommitment1: viem.toHex(recipientNote.commitment, { size: 32 }),
|
|
1777
1322
|
outputCommitment2: viem.toHex(changeNote.commitment, { size: 32 }),
|
|
1778
|
-
encryptedNote1:
|
|
1779
|
-
encryptedNote2:
|
|
1323
|
+
encryptedNote1: chunkY3VL3LOE_cjs.packNoteData(recipientNote),
|
|
1324
|
+
encryptedNote2: chunkY3VL3LOE_cjs.packNoteData(changeNote),
|
|
1780
1325
|
spentNote: selectedNote,
|
|
1781
1326
|
recipientNoteData: recipientNote,
|
|
1782
1327
|
changeNoteData: changeNote
|
|
@@ -1802,15 +1347,6 @@ function usePoolTransfer(config) {
|
|
|
1802
1347
|
reset
|
|
1803
1348
|
};
|
|
1804
1349
|
}
|
|
1805
|
-
chunkHEHXSV47_cjs.init_poseidon();
|
|
1806
|
-
var STATE_TREE_DEPTH = 32;
|
|
1807
|
-
var ASP_TREE_DEPTH2 = 20;
|
|
1808
|
-
function padToDepth(arr, padValue, depth) {
|
|
1809
|
-
if (arr.length >= depth) {
|
|
1810
|
-
return arr.slice(0, depth);
|
|
1811
|
-
}
|
|
1812
|
-
return [...arr, ...Array(depth - arr.length).fill(padValue)];
|
|
1813
|
-
}
|
|
1814
1350
|
function useWithdraw(config) {
|
|
1815
1351
|
const {
|
|
1816
1352
|
isSetup,
|
|
@@ -1840,6 +1376,8 @@ function useWithdraw(config) {
|
|
|
1840
1376
|
recipient,
|
|
1841
1377
|
aspId = 0n,
|
|
1842
1378
|
aspRoot = 0n,
|
|
1379
|
+
aspPathElements,
|
|
1380
|
+
aspPathIndices,
|
|
1843
1381
|
isRagequit = false
|
|
1844
1382
|
} = params;
|
|
1845
1383
|
const cfg = configRef.current;
|
|
@@ -1873,10 +1411,9 @@ function useWithdraw(config) {
|
|
|
1873
1411
|
const origin = BigInt(selectedNote.origin);
|
|
1874
1412
|
const token = BigInt(selectedNote.token);
|
|
1875
1413
|
setStage("creating_outputs");
|
|
1876
|
-
const [transferModule, proofModule
|
|
1877
|
-
import('../transfer-
|
|
1878
|
-
import('../proof-X3MVQFFZ.cjs')
|
|
1879
|
-
import('../index.cjs')
|
|
1414
|
+
const [transferModule, proofModule] = await Promise.all([
|
|
1415
|
+
import('../transfer-TJNDCZF2.cjs'),
|
|
1416
|
+
import('../proof-X3MVQFFZ.cjs')
|
|
1880
1417
|
]);
|
|
1881
1418
|
const { syncMerkleTree, getMerkleProofsForNotes } = transferModule;
|
|
1882
1419
|
const { formatPlonkProofForContract } = proofModule;
|
|
@@ -1894,52 +1431,20 @@ function useWithdraw(config) {
|
|
|
1894
1431
|
};
|
|
1895
1432
|
const [noteProof] = await getMerkleProofsForNotes([spendableNote], leaves, tree);
|
|
1896
1433
|
setStage("generating_proof");
|
|
1897
|
-
const
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
const
|
|
1909
|
-
if (localCommitment !== storedCommitment) {
|
|
1910
|
-
throw new Error(
|
|
1911
|
-
`Note commitment mismatch \u2014 this note was created with an outdated commitment formula. Clear your shielded account (localStorage) and re-shield tokens.`
|
|
1912
|
-
);
|
|
1913
|
-
}
|
|
1914
|
-
const nullifier = await sdk.poseidon([
|
|
1915
|
-
BigInt(selectedNote.ownerSecret),
|
|
1916
|
-
BigInt(actualLeafIndex),
|
|
1917
|
-
storedCommitment
|
|
1918
|
-
]);
|
|
1919
|
-
const circuitInputs = {
|
|
1920
|
-
// Public inputs
|
|
1921
|
-
stateRoot: stateRootBI.toString(),
|
|
1922
|
-
aspRoot: aspRoot.toString(),
|
|
1923
|
-
nullifier: nullifier.toString(),
|
|
1924
|
-
amount: selectedNote.amount.toString(),
|
|
1925
|
-
recipient: BigInt(recipient).toString(),
|
|
1926
|
-
token: BigInt(cfg.tokenAddress).toString(),
|
|
1927
|
-
isRagequit: isRagequit ? "1" : "0",
|
|
1928
|
-
// Private inputs - Input Note
|
|
1929
|
-
// IMPORTANT: Use actualLeafIndex from Merkle proof, not stored leafIndex
|
|
1930
|
-
inputAmount: selectedNote.amount.toString(),
|
|
1931
|
-
inputOneTimeSecret: BigInt(selectedNote.ownerSecret).toString(),
|
|
1932
|
-
inputBlinding: selectedNote.blinding.toString(),
|
|
1933
|
-
inputOrigin: origin.toString(),
|
|
1934
|
-
inputLeafIndex: actualLeafIndex.toString(),
|
|
1935
|
-
inputPathElements: padToDepth(merkleProof.pathElements.map(String), "0", STATE_TREE_DEPTH),
|
|
1936
|
-
inputPathIndices: padToDepth(merkleProof.pathIndices.map(String), "0", STATE_TREE_DEPTH),
|
|
1937
|
-
// ASP membership proof (zeros for ragequit)
|
|
1938
|
-
aspPathElements: Array(ASP_TREE_DEPTH2).fill("0"),
|
|
1939
|
-
aspPathIndices: Array(ASP_TREE_DEPTH2).fill("0")
|
|
1940
|
-
};
|
|
1434
|
+
const circuitInputs = await chunkY3VL3LOE_cjs.buildWithdrawCircuitInputs({
|
|
1435
|
+
selectedNote: spendableNote,
|
|
1436
|
+
merkleProof: noteProof.proof,
|
|
1437
|
+
recipient: BigInt(recipient),
|
|
1438
|
+
tokenAddress: BigInt(cfg.tokenAddress),
|
|
1439
|
+
aspRoot,
|
|
1440
|
+
aspPathElements,
|
|
1441
|
+
aspPathIndices,
|
|
1442
|
+
isRagequit
|
|
1443
|
+
});
|
|
1444
|
+
const stateRootBI = noteProof.proof.root;
|
|
1445
|
+
const nullifier = BigInt(circuitInputs.nullifier);
|
|
1941
1446
|
setProvingProgress(null);
|
|
1942
|
-
const { proof } = await
|
|
1447
|
+
const { proof } = await chunkC3HXJ5A6_cjs.generateUPPProofAsync(
|
|
1943
1448
|
"withdraw",
|
|
1944
1449
|
circuitInputs,
|
|
1945
1450
|
cfg.circuitBaseUrl,
|
|
@@ -2098,12 +1603,8 @@ function storePersonalASPId(chainId, address, aspId) {
|
|
|
2098
1603
|
storeASPId(chainId, address, aspId);
|
|
2099
1604
|
}
|
|
2100
1605
|
chunkHEHXSV47_cjs.init_poseidon();
|
|
2101
|
-
var
|
|
2102
|
-
var
|
|
2103
|
-
function padToDepth2(arr, padValue, depth) {
|
|
2104
|
-
if (arr.length >= depth) return arr.slice(0, depth);
|
|
2105
|
-
return [...arr, ...Array(depth - arr.length).fill(padValue)];
|
|
2106
|
-
}
|
|
1606
|
+
var STATE_TREE_DEPTH = 32;
|
|
1607
|
+
var ASP_TREE_DEPTH2 = 20;
|
|
2107
1608
|
var SWAP_ORDERS_ABI = [{
|
|
2108
1609
|
type: "function",
|
|
2109
1610
|
name: "swapOrders",
|
|
@@ -2135,7 +1636,7 @@ function useSwapOrderBook(config) {
|
|
|
2135
1636
|
try {
|
|
2136
1637
|
const logs = await config.publicClient.getLogs({
|
|
2137
1638
|
address: config.swapModuleAddress,
|
|
2138
|
-
event:
|
|
1639
|
+
event: chunkC3HXJ5A6_cjs.SWAP_ORDER_PLACED_EVENT,
|
|
2139
1640
|
fromBlock: config.fromBlock ?? 0n,
|
|
2140
1641
|
toBlock: "latest"
|
|
2141
1642
|
});
|
|
@@ -2151,10 +1652,10 @@ function useSwapOrderBook(config) {
|
|
|
2151
1652
|
blockNumber: log.blockNumber ?? 0n
|
|
2152
1653
|
}));
|
|
2153
1654
|
if (config.sellToken && config.buyToken) {
|
|
2154
|
-
parsedOrders =
|
|
1655
|
+
parsedOrders = chunkC3HXJ5A6_cjs.filterOrdersByTokenPair(parsedOrders, config.sellToken, config.buyToken);
|
|
2155
1656
|
}
|
|
2156
1657
|
if (config.acceptableAspIds && config.acceptableAspIds.length > 0) {
|
|
2157
|
-
parsedOrders =
|
|
1658
|
+
parsedOrders = chunkC3HXJ5A6_cjs.filterOrdersByASP(parsedOrders, config.acceptableAspIds);
|
|
2158
1659
|
}
|
|
2159
1660
|
const enriched = [];
|
|
2160
1661
|
for (const order of parsedOrders) {
|
|
@@ -2252,7 +1753,7 @@ function useSwap(config) {
|
|
|
2252
1753
|
}
|
|
2253
1754
|
setStage("creating_outputs");
|
|
2254
1755
|
const [transferModule, proofModule, sdk, aspModule] = await Promise.all([
|
|
2255
|
-
import('../transfer-
|
|
1756
|
+
import('../transfer-TJNDCZF2.cjs'),
|
|
2256
1757
|
import('../proof-X3MVQFFZ.cjs'),
|
|
2257
1758
|
import('../index.cjs'),
|
|
2258
1759
|
import('../asp-CUE3NMBN.cjs')
|
|
@@ -2312,13 +1813,13 @@ function useSwap(config) {
|
|
|
2312
1813
|
inputBlinding: selectedNote.blinding.toString(),
|
|
2313
1814
|
inputOrigin: origin.toString(),
|
|
2314
1815
|
inputLeafIndex: actualLeafIndex.toString(),
|
|
2315
|
-
inputPathElements:
|
|
2316
|
-
inputPathIndices:
|
|
2317
|
-
aspPathElements:
|
|
2318
|
-
aspPathIndices:
|
|
1816
|
+
inputPathElements: chunkY3VL3LOE_cjs.padToDepth(merkleProof.pathElements.map(String), "0", STATE_TREE_DEPTH),
|
|
1817
|
+
inputPathIndices: chunkY3VL3LOE_cjs.padToDepth(merkleProof.pathIndices.map(String), "0", STATE_TREE_DEPTH),
|
|
1818
|
+
aspPathElements: chunkY3VL3LOE_cjs.padToDepth(aspProofData.aspPathElements.map(String), "0", ASP_TREE_DEPTH2),
|
|
1819
|
+
aspPathIndices: chunkY3VL3LOE_cjs.padToDepth(aspProofData.aspPathIndices.map(String), "0", ASP_TREE_DEPTH2)
|
|
2319
1820
|
};
|
|
2320
1821
|
setProvingProgress(null);
|
|
2321
|
-
const { proof } = await
|
|
1822
|
+
const { proof } = await chunkC3HXJ5A6_cjs.generateUPPProofAsync(
|
|
2322
1823
|
"withdraw",
|
|
2323
1824
|
circuitInputs,
|
|
2324
1825
|
cfg.circuitBaseUrl,
|
|
@@ -2329,8 +1830,8 @@ function useSwap(config) {
|
|
|
2329
1830
|
}
|
|
2330
1831
|
);
|
|
2331
1832
|
const formattedProof = await formatPlonkProofForContract(proof);
|
|
2332
|
-
const cancelSecret =
|
|
2333
|
-
const cancelKeyHash =
|
|
1833
|
+
const cancelSecret = chunkC3HXJ5A6_cjs.generateCancelSecret();
|
|
1834
|
+
const cancelKeyHash = chunkC3HXJ5A6_cjs.computeCancelKeyHash(cancelSecret);
|
|
2334
1835
|
const currentBlock = await cfg.publicClient.getBlockNumber();
|
|
2335
1836
|
const expiry = currentBlock + expiryBlocks;
|
|
2336
1837
|
return {
|
|
@@ -2379,7 +1880,7 @@ function useSwap(config) {
|
|
|
2379
1880
|
noteOverride
|
|
2380
1881
|
} = params;
|
|
2381
1882
|
const cfg = configRef.current;
|
|
2382
|
-
const giveAmount =
|
|
1883
|
+
const giveAmount = chunkC3HXJ5A6_cjs.computeGiveAmount(takeAmount, rate);
|
|
2383
1884
|
setStage("selecting_notes");
|
|
2384
1885
|
let selectedNote;
|
|
2385
1886
|
if (noteOverride) {
|
|
@@ -2400,7 +1901,7 @@ function useSwap(config) {
|
|
|
2400
1901
|
}
|
|
2401
1902
|
setStage("creating_outputs");
|
|
2402
1903
|
const [transferModule, proofModule, sdk, aspModule] = await Promise.all([
|
|
2403
|
-
import('../transfer-
|
|
1904
|
+
import('../transfer-TJNDCZF2.cjs'),
|
|
2404
1905
|
import('../proof-X3MVQFFZ.cjs'),
|
|
2405
1906
|
import('../index.cjs'),
|
|
2406
1907
|
import('../asp-CUE3NMBN.cjs')
|
|
@@ -2466,13 +1967,13 @@ function useSwap(config) {
|
|
|
2466
1967
|
inputBlinding: selectedNote.blinding.toString(),
|
|
2467
1968
|
inputOrigin: origin.toString(),
|
|
2468
1969
|
inputLeafIndex: actualLeafIndex.toString(),
|
|
2469
|
-
inputPathElements:
|
|
2470
|
-
inputPathIndices:
|
|
2471
|
-
aspPathElements:
|
|
2472
|
-
aspPathIndices:
|
|
1970
|
+
inputPathElements: chunkY3VL3LOE_cjs.padToDepth(merkleProof.pathElements.map(String), "0", STATE_TREE_DEPTH),
|
|
1971
|
+
inputPathIndices: chunkY3VL3LOE_cjs.padToDepth(merkleProof.pathIndices.map(String), "0", STATE_TREE_DEPTH),
|
|
1972
|
+
aspPathElements: chunkY3VL3LOE_cjs.padToDepth(aspProofData.aspPathElements.map(String), "0", ASP_TREE_DEPTH2),
|
|
1973
|
+
aspPathIndices: chunkY3VL3LOE_cjs.padToDepth(aspProofData.aspPathIndices.map(String), "0", ASP_TREE_DEPTH2)
|
|
2473
1974
|
};
|
|
2474
1975
|
setProvingProgress(null);
|
|
2475
|
-
const { proof } = await
|
|
1976
|
+
const { proof } = await chunkC3HXJ5A6_cjs.generateUPPProofAsync(
|
|
2476
1977
|
"withdraw",
|
|
2477
1978
|
circuitInputs,
|
|
2478
1979
|
cfg.circuitBaseUrl,
|
|
@@ -2483,11 +1984,7 @@ function useSwap(config) {
|
|
|
2483
1984
|
}
|
|
2484
1985
|
);
|
|
2485
1986
|
const formattedProof = await formatPlonkProofForContract(proof);
|
|
2486
|
-
const
|
|
2487
|
-
const packedFillerNote = encodePacked3(
|
|
2488
|
-
["uint64", "uint256", "bytes"],
|
|
2489
|
-
[fillerNoteData.searchTag, fillerNoteData.ownerHash, fillerNoteData.encryptedNote]
|
|
2490
|
-
);
|
|
1987
|
+
const packedFillerNote = chunkY3VL3LOE_cjs.packNoteData(fillerNoteData);
|
|
2491
1988
|
return {
|
|
2492
1989
|
proof: formattedProof,
|
|
2493
1990
|
nullifier: viem.toHex(nullifier, { size: 32 }),
|
|
@@ -2547,18 +2044,13 @@ function useSwap(config) {
|
|
|
2547
2044
|
);
|
|
2548
2045
|
}
|
|
2549
2046
|
const zeroHex = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
2550
|
-
const { encodePacked: encodePacked3 } = await import('viem');
|
|
2551
|
-
const packNote = (note) => encodePacked3(
|
|
2552
|
-
["uint64", "uint256", "bytes"],
|
|
2553
|
-
[note.searchTag, note.ownerHash, note.encryptedNote]
|
|
2554
|
-
);
|
|
2555
2047
|
return {
|
|
2556
2048
|
orderId,
|
|
2557
2049
|
cancelSecret,
|
|
2558
2050
|
buyOutputCommitment: buyNoteData ? viem.toHex(buyNoteData.commitment, { size: 32 }) : zeroHex,
|
|
2559
2051
|
refundCommitment: refundNoteData ? viem.toHex(refundNoteData.commitment, { size: 32 }) : zeroHex,
|
|
2560
|
-
buyEncryptedNote: buyNoteData ?
|
|
2561
|
-
refundEncryptedNote: refundNoteData ?
|
|
2052
|
+
buyEncryptedNote: buyNoteData ? chunkY3VL3LOE_cjs.packNoteData(buyNoteData) : "0x",
|
|
2053
|
+
refundEncryptedNote: refundNoteData ? chunkY3VL3LOE_cjs.packNoteData(refundNoteData) : "0x",
|
|
2562
2054
|
buyNoteData,
|
|
2563
2055
|
refundNoteData
|
|
2564
2056
|
};
|
|
@@ -2589,11 +2081,7 @@ function useSwap(config) {
|
|
|
2589
2081
|
cancelOrigin,
|
|
2590
2082
|
BigInt(sellToken)
|
|
2591
2083
|
);
|
|
2592
|
-
const
|
|
2593
|
-
const packedRefund = encodePacked3(
|
|
2594
|
-
["uint64", "uint256", "bytes"],
|
|
2595
|
-
[refundNoteData.searchTag, refundNoteData.ownerHash, refundNoteData.encryptedNote]
|
|
2596
|
-
);
|
|
2084
|
+
const packedRefund = chunkY3VL3LOE_cjs.packNoteData(refundNoteData);
|
|
2597
2085
|
return {
|
|
2598
2086
|
orderId,
|
|
2599
2087
|
cancelSecret,
|
|
@@ -2638,7 +2126,7 @@ function useSwap(config) {
|
|
|
2638
2126
|
createNoteForSelf(changeAmount, origin, token)
|
|
2639
2127
|
]);
|
|
2640
2128
|
const [transferModule, proofModule, aspModule] = await Promise.all([
|
|
2641
|
-
import('../transfer-
|
|
2129
|
+
import('../transfer-TJNDCZF2.cjs'),
|
|
2642
2130
|
import('../proof-X3MVQFFZ.cjs'),
|
|
2643
2131
|
import('../asp-CUE3NMBN.cjs')
|
|
2644
2132
|
]);
|
|
@@ -2669,7 +2157,7 @@ function useSwap(config) {
|
|
|
2669
2157
|
changeNoteWithAmount
|
|
2670
2158
|
);
|
|
2671
2159
|
setProvingProgress(null);
|
|
2672
|
-
const { proof } = await
|
|
2160
|
+
const { proof } = await chunkC3HXJ5A6_cjs.generateUPPProofAsync(
|
|
2673
2161
|
"transfer",
|
|
2674
2162
|
circuitInputs,
|
|
2675
2163
|
cfg.circuitBaseUrl,
|
|
@@ -2680,11 +2168,6 @@ function useSwap(config) {
|
|
|
2680
2168
|
}
|
|
2681
2169
|
);
|
|
2682
2170
|
const formattedProof = await formatPlonkProofForContract(proof);
|
|
2683
|
-
const { encodePacked: encodePacked3 } = await import('viem');
|
|
2684
|
-
const packNote = (n) => encodePacked3(
|
|
2685
|
-
["uint64", "uint256", "bytes"],
|
|
2686
|
-
[n.searchTag, n.ownerHash, n.encryptedNote]
|
|
2687
|
-
);
|
|
2688
2171
|
const proofSystem = note.proofSystem ?? "snark";
|
|
2689
2172
|
const exactShieldedNote = {
|
|
2690
2173
|
amount: targetAmount,
|
|
@@ -2720,8 +2203,8 @@ function useSwap(config) {
|
|
|
2720
2203
|
token: note.token,
|
|
2721
2204
|
outputCommitment1: viem.toHex(exactNoteData.commitment, { size: 32 }),
|
|
2722
2205
|
outputCommitment2: viem.toHex(changeNoteData.commitment, { size: 32 }),
|
|
2723
|
-
encryptedNote1:
|
|
2724
|
-
encryptedNote2:
|
|
2206
|
+
encryptedNote1: chunkY3VL3LOE_cjs.packNoteData(exactNoteData),
|
|
2207
|
+
encryptedNote2: chunkY3VL3LOE_cjs.packNoteData(changeNoteData),
|
|
2725
2208
|
exactNote: exactShieldedNote,
|
|
2726
2209
|
changeNote: changeShieldedNote,
|
|
2727
2210
|
spentNote: note,
|
|
@@ -2760,7 +2243,7 @@ function useProofWorker(worker) {
|
|
|
2760
2243
|
setManager(null);
|
|
2761
2244
|
return;
|
|
2762
2245
|
}
|
|
2763
|
-
const m = new
|
|
2246
|
+
const m = new chunkC3HXJ5A6_cjs.ProofWorkerManager(worker);
|
|
2764
2247
|
setManager(m);
|
|
2765
2248
|
return () => {
|
|
2766
2249
|
m.terminate();
|
|
@@ -2848,7 +2331,7 @@ function usePrivateBalance(config) {
|
|
|
2848
2331
|
try {
|
|
2849
2332
|
const placedLogs = await publicClient.getLogs({
|
|
2850
2333
|
address: swapModuleAddress,
|
|
2851
|
-
event:
|
|
2334
|
+
event: chunkC3HXJ5A6_cjs.SWAP_ORDER_PLACED_EVENT,
|
|
2852
2335
|
fromBlock,
|
|
2853
2336
|
toBlock: "latest"
|
|
2854
2337
|
});
|
|
@@ -2856,7 +2339,7 @@ function usePrivateBalance(config) {
|
|
|
2856
2339
|
for (const log of placedLogs) {
|
|
2857
2340
|
const args = log.args;
|
|
2858
2341
|
const orderId = args.orderId;
|
|
2859
|
-
if (walletAddress && !
|
|
2342
|
+
if (walletAddress && !chunkC3HXJ5A6_cjs.getCancelSecret(orderId, walletAddress)) continue;
|
|
2860
2343
|
orders.set(orderId.toLowerCase(), {
|
|
2861
2344
|
sellToken: args.sellToken,
|
|
2862
2345
|
sellAmount: BigInt(args.sellAmount),
|
|
@@ -2865,7 +2348,7 @@ function usePrivateBalance(config) {
|
|
|
2865
2348
|
}
|
|
2866
2349
|
const filledLogs = await publicClient.getLogs({
|
|
2867
2350
|
address: swapModuleAddress,
|
|
2868
|
-
event:
|
|
2351
|
+
event: chunkC3HXJ5A6_cjs.SWAP_ORDER_FILLED_EVENT,
|
|
2869
2352
|
fromBlock,
|
|
2870
2353
|
toBlock: "latest"
|
|
2871
2354
|
});
|
|
@@ -2884,7 +2367,7 @@ function usePrivateBalance(config) {
|
|
|
2884
2367
|
}
|
|
2885
2368
|
const claimedLogs = await publicClient.getLogs({
|
|
2886
2369
|
address: swapModuleAddress,
|
|
2887
|
-
event:
|
|
2370
|
+
event: chunkC3HXJ5A6_cjs.SWAP_ORDER_CLAIMED_EVENT,
|
|
2888
2371
|
fromBlock,
|
|
2889
2372
|
toBlock: "latest"
|
|
2890
2373
|
});
|
|
@@ -2893,7 +2376,7 @@ function usePrivateBalance(config) {
|
|
|
2893
2376
|
}
|
|
2894
2377
|
const cancelledLogs = await publicClient.getLogs({
|
|
2895
2378
|
address: swapModuleAddress,
|
|
2896
|
-
event:
|
|
2379
|
+
event: chunkC3HXJ5A6_cjs.SWAP_ORDER_CANCELLED_EVENT,
|
|
2897
2380
|
fromBlock,
|
|
2898
2381
|
toBlock: "latest"
|
|
2899
2382
|
});
|
|
@@ -2985,11 +2468,11 @@ function usePrivateBalance(config) {
|
|
|
2985
2468
|
|
|
2986
2469
|
Object.defineProperty(exports, "ProofWorkerManager", {
|
|
2987
2470
|
enumerable: true,
|
|
2988
|
-
get: function () { return
|
|
2471
|
+
get: function () { return chunkC3HXJ5A6_cjs.ProofWorkerManager; }
|
|
2989
2472
|
});
|
|
2990
2473
|
Object.defineProperty(exports, "generateUPPProofAsync", {
|
|
2991
2474
|
enumerable: true,
|
|
2992
|
-
get: function () { return
|
|
2475
|
+
get: function () { return chunkC3HXJ5A6_cjs.generateUPPProofAsync; }
|
|
2993
2476
|
});
|
|
2994
2477
|
Object.defineProperty(exports, "ASP_TREE_DEPTH", {
|
|
2995
2478
|
enumerable: true,
|