@auditable/privacy-pool-zk-sdk 0.0.2-rc.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,75 +1,432 @@
1
1
  import * as snarkjs from 'snarkjs';
2
2
 
3
- let wasm;
4
-
5
- const heap = new Array(128).fill(undefined);
6
-
7
- heap.push(undefined, null, true, false);
3
+ /* @ts-self-types="./client_sdk_wasm.d.ts" */
8
4
 
9
- function getObject(idx) { return heap[idx]; }
5
+ /**
6
+ * Merkle root, path, and coin field strings for the first withdraw leg (JSON → JSON).
7
+ * @param {string} coin_json
8
+ * @param {string} state_json
9
+ * @returns {string}
10
+ */
11
+ function buildWithdrawMerkleWitness(coin_json, state_json) {
12
+ let deferred4_0;
13
+ let deferred4_1;
14
+ try {
15
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
16
+ const ptr0 = passStringToWasm0(coin_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
17
+ const len0 = WASM_VECTOR_LEN;
18
+ const ptr1 = passStringToWasm0(state_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
19
+ const len1 = WASM_VECTOR_LEN;
20
+ wasm.buildWithdrawMerkleWitness(retptr, ptr0, len0, ptr1, len1);
21
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
22
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
23
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
24
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
25
+ var ptr3 = r0;
26
+ var len3 = r1;
27
+ if (r3) {
28
+ ptr3 = 0; len3 = 0;
29
+ throw takeObject(r2);
30
+ }
31
+ deferred4_0 = ptr3;
32
+ deferred4_1 = len3;
33
+ return getStringFromWasm0(ptr3, len3);
34
+ } finally {
35
+ wasm.__wbindgen_add_to_stack_pointer(16);
36
+ wasm.__wbindgen_export4(deferred4_0, deferred4_1, 1);
37
+ }
38
+ }
10
39
 
11
- let heap_next = heap.length;
40
+ /**
41
+ * Calculate nullifier hash from nullifier decimal string.
42
+ * Returns hex string (0x...)
43
+ * @param {string} nullifier_decimal
44
+ * @returns {string}
45
+ */
46
+ function calculateNullifierHash(nullifier_decimal) {
47
+ let deferred3_0;
48
+ let deferred3_1;
49
+ try {
50
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
51
+ const ptr0 = passStringToWasm0(nullifier_decimal, wasm.__wbindgen_export, wasm.__wbindgen_export2);
52
+ const len0 = WASM_VECTOR_LEN;
53
+ wasm.calculateNullifierHash(retptr, ptr0, len0);
54
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
55
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
56
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
57
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
58
+ var ptr2 = r0;
59
+ var len2 = r1;
60
+ if (r3) {
61
+ ptr2 = 0; len2 = 0;
62
+ throw takeObject(r2);
63
+ }
64
+ deferred3_0 = ptr2;
65
+ deferred3_1 = len2;
66
+ return getStringFromWasm0(ptr2, len2);
67
+ } finally {
68
+ wasm.__wbindgen_add_to_stack_pointer(16);
69
+ wasm.__wbindgen_export4(deferred3_0, deferred3_1, 1);
70
+ }
71
+ }
12
72
 
13
- function addHeapObject(obj) {
14
- if (heap_next === heap.length) heap.push(heap.length + 1);
15
- const idx = heap_next;
16
- heap_next = heap[idx];
73
+ /**
74
+ * UTF-8 seed → `SHA256` → scalar → BabyJubJub `BASE8 * r` (circom `ECDHEphemeralKey`).
75
+ * `x` and `y` are lowercase hex (no `0x`). Bech32 / stealth string: TypeScript `encodeStealthAddress`.
76
+ * @param {string} seed
77
+ * @returns {any}
78
+ */
79
+ function ecdhEphemeralPublicKey(seed) {
80
+ try {
81
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
82
+ const ptr0 = passStringToWasm0(seed, wasm.__wbindgen_export, wasm.__wbindgen_export2);
83
+ const len0 = WASM_VECTOR_LEN;
84
+ wasm.ecdhEphemeralPublicKey(retptr, ptr0, len0);
85
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
86
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
87
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
88
+ if (r2) {
89
+ throw takeObject(r1);
90
+ }
91
+ return takeObject(r0);
92
+ } finally {
93
+ wasm.__wbindgen_add_to_stack_pointer(16);
94
+ }
95
+ }
17
96
 
18
- heap[idx] = obj;
19
- return idx;
97
+ /**
98
+ * 32-byte scalar as 64 hex chars (optional `0x`) → `ecdh_ephemeral_public_key` (no UTF-8 seed hash).
99
+ * @param {string} scalar_hex
100
+ * @returns {any}
101
+ */
102
+ function ecdhEphemeralPublicKeyFromScalarHex(scalar_hex) {
103
+ try {
104
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
105
+ const ptr0 = passStringToWasm0(scalar_hex, wasm.__wbindgen_export, wasm.__wbindgen_export2);
106
+ const len0 = WASM_VECTOR_LEN;
107
+ wasm.ecdhEphemeralPublicKeyFromScalarHex(retptr, ptr0, len0);
108
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
109
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
110
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
111
+ if (r2) {
112
+ throw takeObject(r1);
113
+ }
114
+ return takeObject(r0);
115
+ } finally {
116
+ wasm.__wbindgen_add_to_stack_pointer(16);
117
+ }
20
118
  }
21
119
 
22
- function handleError(f, args) {
120
+ /**
121
+ * Circuit `ECDH`: `priv * (pub_x, pub_y)` → shared key (`key[0], key[1]` hex).
122
+ * @param {string} priv_hex
123
+ * @param {string} pub_x_hex
124
+ * @param {string} pub_y_hex
125
+ * @returns {any}
126
+ */
127
+ function ecdhSharedKey(priv_hex, pub_x_hex, pub_y_hex) {
23
128
  try {
24
- return f.apply(this, args);
25
- } catch (e) {
26
- wasm.__wbindgen_export_0(addHeapObject(e));
129
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
130
+ const ptr0 = passStringToWasm0(priv_hex, wasm.__wbindgen_export, wasm.__wbindgen_export2);
131
+ const len0 = WASM_VECTOR_LEN;
132
+ const ptr1 = passStringToWasm0(pub_x_hex, wasm.__wbindgen_export, wasm.__wbindgen_export2);
133
+ const len1 = WASM_VECTOR_LEN;
134
+ const ptr2 = passStringToWasm0(pub_y_hex, wasm.__wbindgen_export, wasm.__wbindgen_export2);
135
+ const len2 = WASM_VECTOR_LEN;
136
+ wasm.ecdhSharedKey(retptr, ptr0, len0, ptr1, len1, ptr2, len2);
137
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
138
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
139
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
140
+ if (r2) {
141
+ throw takeObject(r1);
142
+ }
143
+ return takeObject(r0);
144
+ } finally {
145
+ wasm.__wbindgen_add_to_stack_pointer(16);
27
146
  }
28
147
  }
29
148
 
30
- let cachedUint8ArrayMemory0 = null;
149
+ /**
150
+ * Generate a new coin with random nullifier, secret, and shared-secret field elements.
151
+ * `amount` is stroops (u64); JS passes `bigint`.
152
+ * Returns JSON: { coin: { value, nullifier, secret, commitment }, commitment_hex }
153
+ * @param {bigint} amount
154
+ * @returns {any}
155
+ */
156
+ function generateCoin(amount) {
157
+ const ret = wasm.generateCoin(amount);
158
+ return takeObject(ret);
159
+ }
31
160
 
32
- function getUint8ArrayMemory0() {
33
- if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
34
- cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
161
+ /**
162
+ * `Poseidon₁(scalar)` secret + fixed ECDH shared coords (hex), matching an aligned deposit witness.
163
+ * @param {string} scalar_hex
164
+ * @param {string} shared_x_hex
165
+ * @param {string} shared_y_hex
166
+ * @param {bigint} amount
167
+ * @returns {any}
168
+ */
169
+ function generateCoinForDepositWithSharedHex(scalar_hex, shared_x_hex, shared_y_hex, amount) {
170
+ try {
171
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
172
+ const ptr0 = passStringToWasm0(scalar_hex, wasm.__wbindgen_export, wasm.__wbindgen_export2);
173
+ const len0 = WASM_VECTOR_LEN;
174
+ const ptr1 = passStringToWasm0(shared_x_hex, wasm.__wbindgen_export, wasm.__wbindgen_export2);
175
+ const len1 = WASM_VECTOR_LEN;
176
+ const ptr2 = passStringToWasm0(shared_y_hex, wasm.__wbindgen_export, wasm.__wbindgen_export2);
177
+ const len2 = WASM_VECTOR_LEN;
178
+ wasm.generateCoinForDepositWithSharedHex(retptr, ptr0, len0, ptr1, len1, ptr2, len2, amount);
179
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
180
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
181
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
182
+ if (r2) {
183
+ throw takeObject(r1);
184
+ }
185
+ return takeObject(r0);
186
+ } finally {
187
+ wasm.__wbindgen_add_to_stack_pointer(16);
35
188
  }
36
- return cachedUint8ArrayMemory0;
37
189
  }
38
190
 
39
- let cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
191
+ /**
192
+ * `secret` in coin = `Poseidon255(1)(scalar)` per `deposit.circom`; scalar is 32-byte hex (64 chars, optional `0x`).
193
+ * @param {string} scalar_hex
194
+ * @param {bigint} amount
195
+ * @returns {any}
196
+ */
197
+ function generateCoinFromDepositEphemeralScalarHex(scalar_hex, amount) {
198
+ try {
199
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
200
+ const ptr0 = passStringToWasm0(scalar_hex, wasm.__wbindgen_export, wasm.__wbindgen_export2);
201
+ const len0 = WASM_VECTOR_LEN;
202
+ wasm.generateCoinFromDepositEphemeralScalarHex(retptr, ptr0, len0, amount);
203
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
204
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
205
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
206
+ if (r2) {
207
+ throw takeObject(r1);
208
+ }
209
+ return takeObject(r0);
210
+ } finally {
211
+ wasm.__wbindgen_add_to_stack_pointer(16);
212
+ }
213
+ }
40
214
 
41
- if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }
42
- const MAX_SAFARI_DECODE_BYTES = 2146435072;
43
- let numBytesDecoded = 0;
44
- function decodeText(ptr, len) {
45
- numBytesDecoded += len;
46
- if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
47
- cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
48
- cachedTextDecoder.decode();
49
- numBytesDecoded = len;
215
+ /**
216
+ * Same as `generateCoin`, but commitment uses the given ECDH shared key (64-char hex coords from `ecdhSharedKey`); shared coords are not stored in `coin` JSON.
217
+ * @param {string} shared_x_hex
218
+ * @param {string} shared_y_hex
219
+ * @param {bigint} amount
220
+ * @returns {any}
221
+ */
222
+ function generateCoinWithSharedSecretHex(shared_x_hex, shared_y_hex, amount) {
223
+ try {
224
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
225
+ const ptr0 = passStringToWasm0(shared_x_hex, wasm.__wbindgen_export, wasm.__wbindgen_export2);
226
+ const len0 = WASM_VECTOR_LEN;
227
+ const ptr1 = passStringToWasm0(shared_y_hex, wasm.__wbindgen_export, wasm.__wbindgen_export2);
228
+ const len1 = WASM_VECTOR_LEN;
229
+ wasm.generateCoinWithSharedSecretHex(retptr, ptr0, len0, ptr1, len1, amount);
230
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
231
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
232
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
233
+ if (r2) {
234
+ throw takeObject(r1);
235
+ }
236
+ return takeObject(r0);
237
+ } finally {
238
+ wasm.__wbindgen_add_to_stack_pointer(16);
50
239
  }
51
- return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
52
240
  }
53
241
 
54
- function getStringFromWasm0(ptr, len) {
55
- ptr = ptr >>> 0;
56
- return decodeText(ptr, len);
242
+ /**
243
+ * Convert snarkjs proof JSON to hex bytes for Soroban contract.
244
+ * @param {string} proof_json
245
+ * @returns {string}
246
+ */
247
+ function proofToHex(proof_json) {
248
+ let deferred2_0;
249
+ let deferred2_1;
250
+ try {
251
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
252
+ const ptr0 = passStringToWasm0(proof_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
253
+ const len0 = WASM_VECTOR_LEN;
254
+ wasm.proofToHex(retptr, ptr0, len0);
255
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
256
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
257
+ deferred2_0 = r0;
258
+ deferred2_1 = r1;
259
+ return getStringFromWasm0(r0, r1);
260
+ } finally {
261
+ wasm.__wbindgen_add_to_stack_pointer(16);
262
+ wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
263
+ }
57
264
  }
58
265
 
59
- function dropObject(idx) {
60
- if (idx < 132) return;
61
- heap[idx] = heap_next;
62
- heap_next = idx;
266
+ /**
267
+ * Convert snarkjs public signals JSON to hex bytes for Soroban contract.
268
+ * @param {string} public_json
269
+ * @returns {string}
270
+ */
271
+ function publicToHex(public_json) {
272
+ let deferred2_0;
273
+ let deferred2_1;
274
+ try {
275
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
276
+ const ptr0 = passStringToWasm0(public_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
277
+ const len0 = WASM_VECTOR_LEN;
278
+ wasm.publicToHex(retptr, ptr0, len0);
279
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
280
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
281
+ deferred2_0 = r0;
282
+ deferred2_1 = r1;
283
+ return getStringFromWasm0(r0, r1);
284
+ } finally {
285
+ wasm.__wbindgen_add_to_stack_pointer(16);
286
+ wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
287
+ }
63
288
  }
64
289
 
65
- function takeObject(idx) {
66
- const ret = getObject(idx);
67
- dropObject(idx);
68
- return ret;
290
+ function __wbg_get_imports() {
291
+ const import0 = {
292
+ __proto__: null,
293
+ __wbg_String_8564e559799eccda: function(arg0, arg1) {
294
+ const ret = String(getObject(arg1));
295
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);
296
+ const len1 = WASM_VECTOR_LEN;
297
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
298
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
299
+ },
300
+ __wbg___wbindgen_debug_string_5398f5bb970e0daa: function(arg0, arg1) {
301
+ const ret = debugString(getObject(arg1));
302
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);
303
+ const len1 = WASM_VECTOR_LEN;
304
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
305
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
306
+ },
307
+ __wbg___wbindgen_is_function_3c846841762788c1: function(arg0) {
308
+ const ret = typeof(getObject(arg0)) === 'function';
309
+ return ret;
310
+ },
311
+ __wbg___wbindgen_is_object_781bc9f159099513: function(arg0) {
312
+ const val = getObject(arg0);
313
+ const ret = typeof(val) === 'object' && val !== null;
314
+ return ret;
315
+ },
316
+ __wbg___wbindgen_is_string_7ef6b97b02428fae: function(arg0) {
317
+ const ret = typeof(getObject(arg0)) === 'string';
318
+ return ret;
319
+ },
320
+ __wbg___wbindgen_is_undefined_52709e72fb9f179c: function(arg0) {
321
+ const ret = getObject(arg0) === undefined;
322
+ return ret;
323
+ },
324
+ __wbg___wbindgen_throw_6ddd609b62940d55: function(arg0, arg1) {
325
+ throw new Error(getStringFromWasm0(arg0, arg1));
326
+ },
327
+ __wbg_call_2d781c1f4d5c0ef8: function() { return handleError(function (arg0, arg1, arg2) {
328
+ const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
329
+ return addHeapObject(ret);
330
+ }, arguments); },
331
+ __wbg_crypto_38df2bab126b63dc: function(arg0) {
332
+ const ret = getObject(arg0).crypto;
333
+ return addHeapObject(ret);
334
+ },
335
+ __wbg_getRandomValues_c44a50d8cfdaebeb: function() { return handleError(function (arg0, arg1) {
336
+ getObject(arg0).getRandomValues(getObject(arg1));
337
+ }, arguments); },
338
+ __wbg_length_ea16607d7b61445b: function(arg0) {
339
+ const ret = getObject(arg0).length;
340
+ return ret;
341
+ },
342
+ __wbg_msCrypto_bd5a034af96bcba6: function(arg0) {
343
+ const ret = getObject(arg0).msCrypto;
344
+ return addHeapObject(ret);
345
+ },
346
+ __wbg_new_ab79df5bd7c26067: function() {
347
+ const ret = new Object();
348
+ return addHeapObject(ret);
349
+ },
350
+ __wbg_new_with_length_825018a1616e9e55: function(arg0) {
351
+ const ret = new Uint8Array(arg0 >>> 0);
352
+ return addHeapObject(ret);
353
+ },
354
+ __wbg_node_84ea875411254db1: function(arg0) {
355
+ const ret = getObject(arg0).node;
356
+ return addHeapObject(ret);
357
+ },
358
+ __wbg_process_44c7a14e11e9f69e: function(arg0) {
359
+ const ret = getObject(arg0).process;
360
+ return addHeapObject(ret);
361
+ },
362
+ __wbg_prototypesetcall_d62e5099504357e6: function(arg0, arg1, arg2) {
363
+ Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), getObject(arg2));
364
+ },
365
+ __wbg_randomFillSync_6c25eac9869eb53c: function() { return handleError(function (arg0, arg1) {
366
+ getObject(arg0).randomFillSync(takeObject(arg1));
367
+ }, arguments); },
368
+ __wbg_require_b4edbdcf3e2a1ef0: function() { return handleError(function () {
369
+ const ret = module.require;
370
+ return addHeapObject(ret);
371
+ }, arguments); },
372
+ __wbg_set_6be42768c690e380: function(arg0, arg1, arg2) {
373
+ getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
374
+ },
375
+ __wbg_static_accessor_GLOBAL_8adb955bd33fac2f: function() {
376
+ const ret = typeof global === 'undefined' ? null : global;
377
+ return isLikeNone(ret) ? 0 : addHeapObject(ret);
378
+ },
379
+ __wbg_static_accessor_GLOBAL_THIS_ad356e0db91c7913: function() {
380
+ const ret = typeof globalThis === 'undefined' ? null : globalThis;
381
+ return isLikeNone(ret) ? 0 : addHeapObject(ret);
382
+ },
383
+ __wbg_static_accessor_SELF_f207c857566db248: function() {
384
+ const ret = typeof self === 'undefined' ? null : self;
385
+ return isLikeNone(ret) ? 0 : addHeapObject(ret);
386
+ },
387
+ __wbg_static_accessor_WINDOW_bb9f1ba69d61b386: function() {
388
+ const ret = typeof window === 'undefined' ? null : window;
389
+ return isLikeNone(ret) ? 0 : addHeapObject(ret);
390
+ },
391
+ __wbg_subarray_a068d24e39478a8a: function(arg0, arg1, arg2) {
392
+ const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0);
393
+ return addHeapObject(ret);
394
+ },
395
+ __wbg_versions_276b2795b1c6a219: function(arg0) {
396
+ const ret = getObject(arg0).versions;
397
+ return addHeapObject(ret);
398
+ },
399
+ __wbindgen_cast_0000000000000001: function(arg0, arg1) {
400
+ // Cast intrinsic for `Ref(Slice(U8)) -> NamedExternref("Uint8Array")`.
401
+ const ret = getArrayU8FromWasm0(arg0, arg1);
402
+ return addHeapObject(ret);
403
+ },
404
+ __wbindgen_cast_0000000000000002: function(arg0, arg1) {
405
+ // Cast intrinsic for `Ref(String) -> Externref`.
406
+ const ret = getStringFromWasm0(arg0, arg1);
407
+ return addHeapObject(ret);
408
+ },
409
+ __wbindgen_object_clone_ref: function(arg0) {
410
+ const ret = getObject(arg0);
411
+ return addHeapObject(ret);
412
+ },
413
+ __wbindgen_object_drop_ref: function(arg0) {
414
+ takeObject(arg0);
415
+ },
416
+ };
417
+ return {
418
+ __proto__: null,
419
+ "./client_sdk_wasm_bg.js": import0,
420
+ };
69
421
  }
70
422
 
71
- function isLikeNone(x) {
72
- return x === undefined || x === null;
423
+ function addHeapObject(obj) {
424
+ if (heap_next === heap.length) heap.push(heap.length + 1);
425
+ const idx = heap_next;
426
+ heap_next = heap[idx];
427
+
428
+ heap[idx] = obj;
429
+ return idx;
73
430
  }
74
431
 
75
432
  function debugString(val) {
@@ -137,25 +494,58 @@ function debugString(val) {
137
494
  return className;
138
495
  }
139
496
 
140
- let WASM_VECTOR_LEN = 0;
497
+ function dropObject(idx) {
498
+ if (idx < 1028) return;
499
+ heap[idx] = heap_next;
500
+ heap_next = idx;
501
+ }
141
502
 
142
- const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
503
+ function getArrayU8FromWasm0(ptr, len) {
504
+ ptr = ptr >>> 0;
505
+ return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
506
+ }
143
507
 
144
- const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
145
- ? function (arg, view) {
146
- return cachedTextEncoder.encodeInto(arg, view);
508
+ let cachedDataViewMemory0 = null;
509
+ function getDataViewMemory0() {
510
+ if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
511
+ cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
512
+ }
513
+ return cachedDataViewMemory0;
147
514
  }
148
- : function (arg, view) {
149
- const buf = cachedTextEncoder.encode(arg);
150
- view.set(buf);
151
- return {
152
- read: arg.length,
153
- written: buf.length
154
- };
155
- });
156
515
 
157
- function passStringToWasm0(arg, malloc, realloc) {
516
+ function getStringFromWasm0(ptr, len) {
517
+ ptr = ptr >>> 0;
518
+ return decodeText(ptr, len);
519
+ }
520
+
521
+ let cachedUint8ArrayMemory0 = null;
522
+ function getUint8ArrayMemory0() {
523
+ if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
524
+ cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
525
+ }
526
+ return cachedUint8ArrayMemory0;
527
+ }
528
+
529
+ function getObject(idx) { return heap[idx]; }
530
+
531
+ function handleError(f, args) {
532
+ try {
533
+ return f.apply(this, args);
534
+ } catch (e) {
535
+ wasm.__wbindgen_export3(addHeapObject(e));
536
+ }
537
+ }
538
+
539
+ let heap = new Array(1024).fill(undefined);
540
+ heap.push(undefined, null, true, false);
541
+
542
+ let heap_next = heap.length;
158
543
 
544
+ function isLikeNone(x) {
545
+ return x === undefined || x === null;
546
+ }
547
+
548
+ function passStringToWasm0(arg, malloc, realloc) {
159
549
  if (realloc === undefined) {
160
550
  const buf = cachedTextEncoder.encode(arg);
161
551
  const ptr = malloc(buf.length, 1) >>> 0;
@@ -176,14 +566,13 @@ function passStringToWasm0(arg, malloc, realloc) {
176
566
  if (code > 0x7F) break;
177
567
  mem[ptr + offset] = code;
178
568
  }
179
-
180
569
  if (offset !== len) {
181
570
  if (offset !== 0) {
182
571
  arg = arg.slice(offset);
183
572
  }
184
573
  ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
185
574
  const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
186
- const ret = encodeString(arg, view);
575
+ const ret = cachedTextEncoder.encodeInto(arg, view);
187
576
 
188
577
  offset += ret.written;
189
578
  ptr = realloc(ptr, len, offset, 1) >>> 0;
@@ -193,329 +582,89 @@ function passStringToWasm0(arg, malloc, realloc) {
193
582
  return ptr;
194
583
  }
195
584
 
196
- let cachedDataViewMemory0 = null;
197
-
198
- function getDataViewMemory0() {
199
- if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
200
- cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
201
- }
202
- return cachedDataViewMemory0;
203
- }
204
- /**
205
- * Convert snarkjs public signals JSON to hex bytes for Soroban contract.
206
- * @param {string} public_json
207
- * @returns {string}
208
- */
209
- function publicToHex(public_json) {
210
- let deferred2_0;
211
- let deferred2_1;
212
- try {
213
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
214
- const ptr0 = passStringToWasm0(public_json, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
215
- const len0 = WASM_VECTOR_LEN;
216
- wasm.publicToHex(retptr, ptr0, len0);
217
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
218
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
219
- deferred2_0 = r0;
220
- deferred2_1 = r1;
221
- return getStringFromWasm0(r0, r1);
222
- } finally {
223
- wasm.__wbindgen_add_to_stack_pointer(16);
224
- wasm.__wbindgen_export_3(deferred2_0, deferred2_1, 1);
225
- }
226
- }
227
-
228
- /**
229
- * Calculate nullifier hash from nullifier decimal string.
230
- * Returns hex string (0x...)
231
- * @param {string} nullifier_decimal
232
- * @returns {string}
233
- */
234
- function calculateNullifierHash(nullifier_decimal) {
235
- let deferred3_0;
236
- let deferred3_1;
237
- try {
238
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
239
- const ptr0 = passStringToWasm0(nullifier_decimal, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
240
- const len0 = WASM_VECTOR_LEN;
241
- wasm.calculateNullifierHash(retptr, ptr0, len0);
242
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
243
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
244
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
245
- var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
246
- var ptr2 = r0;
247
- var len2 = r1;
248
- if (r3) {
249
- ptr2 = 0; len2 = 0;
250
- throw takeObject(r2);
251
- }
252
- deferred3_0 = ptr2;
253
- deferred3_1 = len2;
254
- return getStringFromWasm0(ptr2, len2);
255
- } finally {
256
- wasm.__wbindgen_add_to_stack_pointer(16);
257
- wasm.__wbindgen_export_3(deferred3_0, deferred3_1, 1);
258
- }
259
- }
260
-
261
- /**
262
- * Generate withdrawal SNARK input from coin and state JSON strings.
263
- * Returns JSON string of SnarkInput.
264
- * @param {string} coin_json
265
- * @param {string} state_json
266
- * @returns {string}
267
- */
268
- function generateWithdrawalInput(coin_json, state_json) {
269
- let deferred4_0;
270
- let deferred4_1;
271
- try {
272
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
273
- const ptr0 = passStringToWasm0(coin_json, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
274
- const len0 = WASM_VECTOR_LEN;
275
- const ptr1 = passStringToWasm0(state_json, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
276
- const len1 = WASM_VECTOR_LEN;
277
- wasm.generateWithdrawalInput(retptr, ptr0, len0, ptr1, len1);
278
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
279
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
280
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
281
- var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
282
- var ptr3 = r0;
283
- var len3 = r1;
284
- if (r3) {
285
- ptr3 = 0; len3 = 0;
286
- throw takeObject(r2);
287
- }
288
- deferred4_0 = ptr3;
289
- deferred4_1 = len3;
290
- return getStringFromWasm0(ptr3, len3);
291
- } finally {
292
- wasm.__wbindgen_add_to_stack_pointer(16);
293
- wasm.__wbindgen_export_3(deferred4_0, deferred4_1, 1);
294
- }
295
- }
296
-
297
- /**
298
- * Generate a new coin with random nullifier and secret.
299
- * Returns JSON: { coin: { value, nullifier, secret, commitment }, commitment_hex }
300
- * @returns {any}
301
- */
302
- function generateCoin() {
303
- const ret = wasm.generateCoin();
304
- return takeObject(ret);
585
+ function takeObject(idx) {
586
+ const ret = getObject(idx);
587
+ dropObject(idx);
588
+ return ret;
305
589
  }
306
590
 
307
- /**
308
- * Convert snarkjs proof JSON to hex bytes for Soroban contract.
309
- * @param {string} proof_json
310
- * @returns {string}
311
- */
312
- function proofToHex(proof_json) {
313
- let deferred2_0;
314
- let deferred2_1;
315
- try {
316
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
317
- const ptr0 = passStringToWasm0(proof_json, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
318
- const len0 = WASM_VECTOR_LEN;
319
- wasm.proofToHex(retptr, ptr0, len0);
320
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
321
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
322
- deferred2_0 = r0;
323
- deferred2_1 = r1;
324
- return getStringFromWasm0(r0, r1);
325
- } finally {
326
- wasm.__wbindgen_add_to_stack_pointer(16);
327
- wasm.__wbindgen_export_3(deferred2_0, deferred2_1, 1);
591
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
592
+ cachedTextDecoder.decode();
593
+ const MAX_SAFARI_DECODE_BYTES = 2146435072;
594
+ let numBytesDecoded = 0;
595
+ function decodeText(ptr, len) {
596
+ numBytesDecoded += len;
597
+ if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
598
+ cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
599
+ cachedTextDecoder.decode();
600
+ numBytesDecoded = len;
328
601
  }
602
+ return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
329
603
  }
330
604
 
331
- const EXPECTED_RESPONSE_TYPES = new Set(['basic', 'cors', 'default']);
605
+ const cachedTextEncoder = new TextEncoder();
606
+
607
+ if (!('encodeInto' in cachedTextEncoder)) {
608
+ cachedTextEncoder.encodeInto = function (arg, view) {
609
+ const buf = cachedTextEncoder.encode(arg);
610
+ view.set(buf);
611
+ return {
612
+ read: arg.length,
613
+ written: buf.length
614
+ };
615
+ };
616
+ }
617
+
618
+ let WASM_VECTOR_LEN = 0;
619
+
620
+ let wasm;
621
+ function __wbg_finalize_init(instance, module) {
622
+ wasm = instance.exports;
623
+ cachedDataViewMemory0 = null;
624
+ cachedUint8ArrayMemory0 = null;
625
+ return wasm;
626
+ }
332
627
 
333
628
  async function __wbg_load(module, imports) {
334
629
  if (typeof Response === 'function' && module instanceof Response) {
335
630
  if (typeof WebAssembly.instantiateStreaming === 'function') {
336
631
  try {
337
632
  return await WebAssembly.instantiateStreaming(module, imports);
338
-
339
633
  } catch (e) {
340
- const validResponse = module.ok && EXPECTED_RESPONSE_TYPES.has(module.type);
634
+ const validResponse = module.ok && expectedResponseType(module.type);
341
635
 
342
636
  if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
343
637
  console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
344
638
 
345
- } else {
346
- throw e;
347
- }
639
+ } else { throw e; }
348
640
  }
349
641
  }
350
642
 
351
643
  const bytes = await module.arrayBuffer();
352
644
  return await WebAssembly.instantiate(bytes, imports);
353
-
354
645
  } else {
355
646
  const instance = await WebAssembly.instantiate(module, imports);
356
647
 
357
648
  if (instance instanceof WebAssembly.Instance) {
358
649
  return { instance, module };
359
-
360
650
  } else {
361
651
  return instance;
362
652
  }
363
653
  }
364
- }
365
-
366
- function __wbg_get_imports() {
367
- const imports = {};
368
- imports.wbg = {};
369
- imports.wbg.__wbg_buffer_a1a27a0dfa70165d = function(arg0) {
370
- const ret = getObject(arg0).buffer;
371
- return addHeapObject(ret);
372
- };
373
- imports.wbg.__wbg_call_f2db6205e5c51dc8 = function() { return handleError(function (arg0, arg1, arg2) {
374
- const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
375
- return addHeapObject(ret);
376
- }, arguments) };
377
- imports.wbg.__wbg_call_fbe8be8bf6436ce5 = function() { return handleError(function (arg0, arg1) {
378
- const ret = getObject(arg0).call(getObject(arg1));
379
- return addHeapObject(ret);
380
- }, arguments) };
381
- imports.wbg.__wbg_crypto_574e78ad8b13b65f = function(arg0) {
382
- const ret = getObject(arg0).crypto;
383
- return addHeapObject(ret);
384
- };
385
- imports.wbg.__wbg_getRandomValues_b8f5dbd5f3995a9e = function() { return handleError(function (arg0, arg1) {
386
- getObject(arg0).getRandomValues(getObject(arg1));
387
- }, arguments) };
388
- imports.wbg.__wbg_msCrypto_a61aeb35a24c1329 = function(arg0) {
389
- const ret = getObject(arg0).msCrypto;
390
- return addHeapObject(ret);
391
- };
392
- imports.wbg.__wbg_new_07b483f72211fd66 = function() {
393
- const ret = new Object();
394
- return addHeapObject(ret);
395
- };
396
- imports.wbg.__wbg_new_e52b3efaaa774f96 = function(arg0) {
397
- const ret = new Uint8Array(getObject(arg0));
398
- return addHeapObject(ret);
399
- };
400
- imports.wbg.__wbg_newnoargs_ff528e72d35de39a = function(arg0, arg1) {
401
- const ret = new Function(getStringFromWasm0(arg0, arg1));
402
- return addHeapObject(ret);
403
- };
404
- imports.wbg.__wbg_newwithbyteoffsetandlength_3b01ecda099177e8 = function(arg0, arg1, arg2) {
405
- const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
406
- return addHeapObject(ret);
407
- };
408
- imports.wbg.__wbg_newwithlength_08f872dc1e3ada2e = function(arg0) {
409
- const ret = new Uint8Array(arg0 >>> 0);
410
- return addHeapObject(ret);
411
- };
412
- imports.wbg.__wbg_node_905d3e251edff8a2 = function(arg0) {
413
- const ret = getObject(arg0).node;
414
- return addHeapObject(ret);
415
- };
416
- imports.wbg.__wbg_process_dc0fbacc7c1c06f7 = function(arg0) {
417
- const ret = getObject(arg0).process;
418
- return addHeapObject(ret);
419
- };
420
- imports.wbg.__wbg_randomFillSync_ac0988aba3254290 = function() { return handleError(function (arg0, arg1) {
421
- getObject(arg0).randomFillSync(takeObject(arg1));
422
- }, arguments) };
423
- imports.wbg.__wbg_require_60cc747a6bc5215a = function() { return handleError(function () {
424
- const ret = module.require;
425
- return addHeapObject(ret);
426
- }, arguments) };
427
- imports.wbg.__wbg_set_3f1d0b984ed272ed = function(arg0, arg1, arg2) {
428
- getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
429
- };
430
- imports.wbg.__wbg_set_fe4e79d1ed3b0e9b = function(arg0, arg1, arg2) {
431
- getObject(arg0).set(getObject(arg1), arg2 >>> 0);
432
- };
433
- imports.wbg.__wbg_static_accessor_GLOBAL_487c52c58d65314d = function() {
434
- const ret = typeof global === 'undefined' ? null : global;
435
- return isLikeNone(ret) ? 0 : addHeapObject(ret);
436
- };
437
- imports.wbg.__wbg_static_accessor_GLOBAL_THIS_ee9704f328b6b291 = function() {
438
- const ret = typeof globalThis === 'undefined' ? null : globalThis;
439
- return isLikeNone(ret) ? 0 : addHeapObject(ret);
440
- };
441
- imports.wbg.__wbg_static_accessor_SELF_78c9e3071b912620 = function() {
442
- const ret = typeof self === 'undefined' ? null : self;
443
- return isLikeNone(ret) ? 0 : addHeapObject(ret);
444
- };
445
- imports.wbg.__wbg_static_accessor_WINDOW_a093d21393777366 = function() {
446
- const ret = typeof window === 'undefined' ? null : window;
447
- return isLikeNone(ret) ? 0 : addHeapObject(ret);
448
- };
449
- imports.wbg.__wbg_subarray_dd4ade7d53bd8e26 = function(arg0, arg1, arg2) {
450
- const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0);
451
- return addHeapObject(ret);
452
- };
453
- imports.wbg.__wbg_versions_c01dfd4722a88165 = function(arg0) {
454
- const ret = getObject(arg0).versions;
455
- return addHeapObject(ret);
456
- };
457
- imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
458
- const ret = debugString(getObject(arg1));
459
- const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
460
- const len1 = WASM_VECTOR_LEN;
461
- getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
462
- getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
463
- };
464
- imports.wbg.__wbindgen_is_function = function(arg0) {
465
- const ret = typeof(getObject(arg0)) === 'function';
466
- return ret;
467
- };
468
- imports.wbg.__wbindgen_is_object = function(arg0) {
469
- const val = getObject(arg0);
470
- const ret = typeof(val) === 'object' && val !== null;
471
- return ret;
472
- };
473
- imports.wbg.__wbindgen_is_string = function(arg0) {
474
- const ret = typeof(getObject(arg0)) === 'string';
475
- return ret;
476
- };
477
- imports.wbg.__wbindgen_is_undefined = function(arg0) {
478
- const ret = getObject(arg0) === undefined;
479
- return ret;
480
- };
481
- imports.wbg.__wbindgen_memory = function() {
482
- const ret = wasm.memory;
483
- return addHeapObject(ret);
484
- };
485
- imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
486
- const ret = getObject(arg0);
487
- return addHeapObject(ret);
488
- };
489
- imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
490
- takeObject(arg0);
491
- };
492
- imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
493
- const ret = getStringFromWasm0(arg0, arg1);
494
- return addHeapObject(ret);
495
- };
496
- imports.wbg.__wbindgen_throw = function(arg0, arg1) {
497
- throw new Error(getStringFromWasm0(arg0, arg1));
498
- };
499
-
500
- return imports;
501
- }
502
-
503
- function __wbg_finalize_init(instance, module) {
504
- wasm = instance.exports;
505
- __wbg_init.__wbindgen_wasm_module = module;
506
- cachedDataViewMemory0 = null;
507
- cachedUint8ArrayMemory0 = null;
508
-
509
654
 
510
-
511
- return wasm;
655
+ function expectedResponseType(type) {
656
+ switch (type) {
657
+ case 'basic': case 'cors': case 'default': return true;
658
+ }
659
+ return false;
660
+ }
512
661
  }
513
662
 
514
663
  function initSync(module) {
515
664
  if (wasm !== undefined) return wasm;
516
665
 
517
666
 
518
- if (typeof module !== 'undefined') {
667
+ if (module !== undefined) {
519
668
  if (Object.getPrototypeOf(module) === Object.prototype) {
520
669
  ({module} = module);
521
670
  } else {
@@ -524,21 +673,18 @@ function initSync(module) {
524
673
  }
525
674
 
526
675
  const imports = __wbg_get_imports();
527
-
528
676
  if (!(module instanceof WebAssembly.Module)) {
529
677
  module = new WebAssembly.Module(module);
530
678
  }
531
-
532
679
  const instance = new WebAssembly.Instance(module, imports);
533
-
534
- return __wbg_finalize_init(instance, module);
680
+ return __wbg_finalize_init(instance);
535
681
  }
536
682
 
537
683
  async function __wbg_init(module_or_path) {
538
684
  if (wasm !== undefined) return wasm;
539
685
 
540
686
 
541
- if (typeof module_or_path !== 'undefined') {
687
+ if (module_or_path !== undefined) {
542
688
  if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
543
689
  ({module_or_path} = module_or_path);
544
690
  } else {
@@ -546,7 +692,7 @@ async function __wbg_init(module_or_path) {
546
692
  }
547
693
  }
548
694
 
549
- if (typeof module_or_path === 'undefined') {
695
+ if (module_or_path === undefined) {
550
696
  module_or_path = new URL('client_sdk_wasm_bg.wasm', import.meta.url);
551
697
  }
552
698
  const imports = __wbg_get_imports();
@@ -557,15 +703,21 @@ async function __wbg_init(module_or_path) {
557
703
 
558
704
  const { instance, module } = await __wbg_load(await module_or_path, imports);
559
705
 
560
- return __wbg_finalize_init(instance, module);
706
+ return __wbg_finalize_init(instance);
561
707
  }
562
708
 
563
709
  var wasmBindings = /*#__PURE__*/Object.freeze({
564
710
  __proto__: null,
711
+ buildWithdrawMerkleWitness: buildWithdrawMerkleWitness,
565
712
  calculateNullifierHash: calculateNullifierHash,
566
713
  default: __wbg_init,
714
+ ecdhEphemeralPublicKey: ecdhEphemeralPublicKey,
715
+ ecdhEphemeralPublicKeyFromScalarHex: ecdhEphemeralPublicKeyFromScalarHex,
716
+ ecdhSharedKey: ecdhSharedKey,
567
717
  generateCoin: generateCoin,
568
- generateWithdrawalInput: generateWithdrawalInput,
718
+ generateCoinForDepositWithSharedHex: generateCoinForDepositWithSharedHex,
719
+ generateCoinFromDepositEphemeralScalarHex: generateCoinFromDepositEphemeralScalarHex,
720
+ generateCoinWithSharedSecretHex: generateCoinWithSharedSecretHex,
569
721
  initSync: initSync,
570
722
  proofToHex: proofToHex,
571
723
  publicToHex: publicToHex
@@ -578,7 +730,7 @@ async function loadWasm(wasmBinary) {
578
730
  return wasmModule;
579
731
  if (isNode$2) {
580
732
  if (wasmBinary) {
581
- initSync(wasmBinary);
733
+ initSync({ module: wasmBinary });
582
734
  }
583
735
  else {
584
736
  const path = await import('path');
@@ -587,13 +739,13 @@ async function loadWasm(wasmBinary) {
587
739
  const dir = path.dirname(fileURLToPath(import.meta.url));
588
740
  const wasmPath = path.resolve(dir, '..', 'pkg', 'client_sdk_wasm_bg.wasm');
589
741
  const buffer = fs.readFileSync(wasmPath);
590
- initSync(buffer);
742
+ initSync({ module: buffer });
591
743
  }
592
744
  wasmModule = wasmBindings;
593
745
  }
594
746
  else {
595
747
  if (wasmBinary) {
596
- initSync(wasmBinary);
748
+ initSync({ module: wasmBinary });
597
749
  }
598
750
  else {
599
751
  await __wbg_init();
@@ -641,6 +793,8 @@ var witness_calculator = async function builder(code, options) {
641
793
  err = "Not enough memory.\n";
642
794
  } else if (code == 6) {
643
795
  err = "Input signal array access exceeds the size.\n";
796
+ } else if (code == 7) {
797
+ err = "Out of bounds array access.\n";
644
798
  } else {
645
799
  err = "Unknown error.\n";
646
800
  }
@@ -1065,6 +1219,619 @@ async function generateProof(wtns, zkey) {
1065
1219
  return { proof, publicSignals };
1066
1220
  }
1067
1221
 
1222
+ var dist = {};
1223
+
1224
+ Object.defineProperty(dist, "__esModule", { value: true });
1225
+ dist.bech32m = bech32 = dist.bech32 = void 0;
1226
+ const ALPHABET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
1227
+ const ALPHABET_MAP = {};
1228
+ for (let z = 0; z < ALPHABET.length; z++) {
1229
+ const x = ALPHABET.charAt(z);
1230
+ ALPHABET_MAP[x] = z;
1231
+ }
1232
+ function polymodStep(pre) {
1233
+ const b = pre >> 25;
1234
+ return (((pre & 0x1ffffff) << 5) ^
1235
+ (-((b >> 0) & 1) & 0x3b6a57b2) ^
1236
+ (-((b >> 1) & 1) & 0x26508e6d) ^
1237
+ (-((b >> 2) & 1) & 0x1ea119fa) ^
1238
+ (-((b >> 3) & 1) & 0x3d4233dd) ^
1239
+ (-((b >> 4) & 1) & 0x2a1462b3));
1240
+ }
1241
+ function prefixChk(prefix) {
1242
+ let chk = 1;
1243
+ for (let i = 0; i < prefix.length; ++i) {
1244
+ const c = prefix.charCodeAt(i);
1245
+ if (c < 33 || c > 126)
1246
+ return 'Invalid prefix (' + prefix + ')';
1247
+ chk = polymodStep(chk) ^ (c >> 5);
1248
+ }
1249
+ chk = polymodStep(chk);
1250
+ for (let i = 0; i < prefix.length; ++i) {
1251
+ const v = prefix.charCodeAt(i);
1252
+ chk = polymodStep(chk) ^ (v & 0x1f);
1253
+ }
1254
+ return chk;
1255
+ }
1256
+ function convert(data, inBits, outBits, pad) {
1257
+ let value = 0;
1258
+ let bits = 0;
1259
+ const maxV = (1 << outBits) - 1;
1260
+ const result = [];
1261
+ for (let i = 0; i < data.length; ++i) {
1262
+ value = (value << inBits) | data[i];
1263
+ bits += inBits;
1264
+ while (bits >= outBits) {
1265
+ bits -= outBits;
1266
+ result.push((value >> bits) & maxV);
1267
+ }
1268
+ }
1269
+ if (pad) {
1270
+ if (bits > 0) {
1271
+ result.push((value << (outBits - bits)) & maxV);
1272
+ }
1273
+ }
1274
+ else {
1275
+ if (bits >= inBits)
1276
+ return 'Excess padding';
1277
+ if ((value << (outBits - bits)) & maxV)
1278
+ return 'Non-zero padding';
1279
+ }
1280
+ return result;
1281
+ }
1282
+ function toWords(bytes) {
1283
+ return convert(bytes, 8, 5, true);
1284
+ }
1285
+ function fromWordsUnsafe(words) {
1286
+ const res = convert(words, 5, 8, false);
1287
+ if (Array.isArray(res))
1288
+ return res;
1289
+ }
1290
+ function fromWords(words) {
1291
+ const res = convert(words, 5, 8, false);
1292
+ if (Array.isArray(res))
1293
+ return res;
1294
+ throw new Error(res);
1295
+ }
1296
+ function getLibraryFromEncoding(encoding) {
1297
+ let ENCODING_CONST;
1298
+ if (encoding === 'bech32') {
1299
+ ENCODING_CONST = 1;
1300
+ }
1301
+ else {
1302
+ ENCODING_CONST = 0x2bc830a3;
1303
+ }
1304
+ function encode(prefix, words, LIMIT) {
1305
+ LIMIT = LIMIT || 90;
1306
+ if (prefix.length + 7 + words.length > LIMIT)
1307
+ throw new TypeError('Exceeds length limit');
1308
+ prefix = prefix.toLowerCase();
1309
+ // determine chk mod
1310
+ let chk = prefixChk(prefix);
1311
+ if (typeof chk === 'string')
1312
+ throw new Error(chk);
1313
+ let result = prefix + '1';
1314
+ for (let i = 0; i < words.length; ++i) {
1315
+ const x = words[i];
1316
+ if (x >> 5 !== 0)
1317
+ throw new Error('Non 5-bit word');
1318
+ chk = polymodStep(chk) ^ x;
1319
+ result += ALPHABET.charAt(x);
1320
+ }
1321
+ for (let i = 0; i < 6; ++i) {
1322
+ chk = polymodStep(chk);
1323
+ }
1324
+ chk ^= ENCODING_CONST;
1325
+ for (let i = 0; i < 6; ++i) {
1326
+ const v = (chk >> ((5 - i) * 5)) & 0x1f;
1327
+ result += ALPHABET.charAt(v);
1328
+ }
1329
+ return result;
1330
+ }
1331
+ function __decode(str, LIMIT) {
1332
+ LIMIT = LIMIT || 90;
1333
+ if (str.length < 8)
1334
+ return str + ' too short';
1335
+ if (str.length > LIMIT)
1336
+ return 'Exceeds length limit';
1337
+ // don't allow mixed case
1338
+ const lowered = str.toLowerCase();
1339
+ const uppered = str.toUpperCase();
1340
+ if (str !== lowered && str !== uppered)
1341
+ return 'Mixed-case string ' + str;
1342
+ str = lowered;
1343
+ const split = str.lastIndexOf('1');
1344
+ if (split === -1)
1345
+ return 'No separator character for ' + str;
1346
+ if (split === 0)
1347
+ return 'Missing prefix for ' + str;
1348
+ const prefix = str.slice(0, split);
1349
+ const wordChars = str.slice(split + 1);
1350
+ if (wordChars.length < 6)
1351
+ return 'Data too short';
1352
+ let chk = prefixChk(prefix);
1353
+ if (typeof chk === 'string')
1354
+ return chk;
1355
+ const words = [];
1356
+ for (let i = 0; i < wordChars.length; ++i) {
1357
+ const c = wordChars.charAt(i);
1358
+ const v = ALPHABET_MAP[c];
1359
+ if (v === undefined)
1360
+ return 'Unknown character ' + c;
1361
+ chk = polymodStep(chk) ^ v;
1362
+ // not in the checksum?
1363
+ if (i + 6 >= wordChars.length)
1364
+ continue;
1365
+ words.push(v);
1366
+ }
1367
+ if (chk !== ENCODING_CONST)
1368
+ return 'Invalid checksum for ' + str;
1369
+ return { prefix, words };
1370
+ }
1371
+ function decodeUnsafe(str, LIMIT) {
1372
+ const res = __decode(str, LIMIT);
1373
+ if (typeof res === 'object')
1374
+ return res;
1375
+ }
1376
+ function decode(str, LIMIT) {
1377
+ const res = __decode(str, LIMIT);
1378
+ if (typeof res === 'object')
1379
+ return res;
1380
+ throw new Error(res);
1381
+ }
1382
+ return {
1383
+ decodeUnsafe,
1384
+ decode,
1385
+ encode,
1386
+ toWords,
1387
+ fromWordsUnsafe,
1388
+ fromWords,
1389
+ };
1390
+ }
1391
+ var bech32 = dist.bech32 = getLibraryFromEncoding('bech32');
1392
+ dist.bech32m = getLibraryFromEncoding('bech32m');
1393
+
1394
+ /** Bech32 HRP for {@link DecodedEphemeralKey} only (`x ‖ y`, 64 bytes). */
1395
+ const DECODED_EPHEMERAL_HRP = 'epk1';
1396
+ /** Bech32 HRP for {@link DecodedDepositorSharedSecretPreimage} (96 bytes). */
1397
+ const DEPOSITOR_SHARED_SECRET_PREIMAGE_HRP = 'epk_dep_pre1';
1398
+ const FIELD_BYTES = 32;
1399
+ const EPK_POINT_PAYLOAD = FIELD_BYTES * 2;
1400
+ const EPK_DEP_PRE_PAYLOAD = FIELD_BYTES * 3;
1401
+ const BECH32_LONG_LIMIT = 1023;
1402
+ function normalizeHex$2(hex) {
1403
+ const s = hex.trim().replace(/^0x/i, '');
1404
+ if (!/^[0-9a-fA-F]*$/.test(s)) {
1405
+ throw new Error('ephemeral-key: hex must contain only 0-9, a-f');
1406
+ }
1407
+ return s.length % 2 === 0 ? s : `0${s}`;
1408
+ }
1409
+ function hexToBytes$2(hex) {
1410
+ const norm = normalizeHex$2(hex);
1411
+ const out = new Uint8Array(norm.length / 2);
1412
+ for (let i = 0; i < out.length; i++) {
1413
+ out[i] = parseInt(norm.slice(i * 2, i * 2 + 2), 16);
1414
+ }
1415
+ return out;
1416
+ }
1417
+ function bytesToHex$1(bytes) {
1418
+ let s = '';
1419
+ for (let i = 0; i < bytes.length; i++) {
1420
+ s += bytes[i].toString(16).padStart(2, '0');
1421
+ }
1422
+ return s;
1423
+ }
1424
+ function concat2(a, b) {
1425
+ const out = new Uint8Array(a.length + b.length);
1426
+ out.set(a, 0);
1427
+ out.set(b, a.length);
1428
+ return out;
1429
+ }
1430
+ function concat3(a, b, c) {
1431
+ const out = new Uint8Array(a.length + b.length + c.length);
1432
+ out.set(a, 0);
1433
+ out.set(b, a.length);
1434
+ out.set(c, a.length + b.length);
1435
+ return out;
1436
+ }
1437
+ function require32(label, bytes) {
1438
+ if (bytes.length !== FIELD_BYTES) {
1439
+ throw new Error(`ephemeral-key: ${label} must encode exactly ${FIELD_BYTES} bytes, got ${bytes.length}`);
1440
+ }
1441
+ }
1442
+ /**
1443
+ * 32-byte big-endian integer as hex (64 chars), **< 2^253**, so BabyJub ECDH matches
1444
+ * `circuits/encryption.circom` `Num2Bits(253)` and `libs/cryptography` `scalar_mul_253`.
1445
+ */
1446
+ function generateRandomScalarHex32() {
1447
+ const g = globalThis.crypto;
1448
+ if (!g?.getRandomValues) {
1449
+ throw new Error('ephemeral-key: crypto.getRandomValues is required');
1450
+ }
1451
+ const max = 1n << 253n;
1452
+ for (let attempt = 0; attempt < 65536; attempt++) {
1453
+ const b = new Uint8Array(32);
1454
+ g.getRandomValues(b);
1455
+ const hex = bytesToHex$1(b);
1456
+ if (BigInt(`0x${hex}`) < max) {
1457
+ return hex;
1458
+ }
1459
+ }
1460
+ throw new Error('ephemeral-key: failed to sample scalar < 2^253');
1461
+ }
1462
+ /** Bech32 `epk1`: encodes `x ‖ y` (64 bytes). */
1463
+ function encodeDecodedEphemeralKey(decoded) {
1464
+ const xb = hexToBytes$2(decoded.x);
1465
+ const yb = hexToBytes$2(decoded.y);
1466
+ require32('x', xb);
1467
+ require32('y', yb);
1468
+ const payload = concat2(xb, yb);
1469
+ const words = bech32.toWords(payload);
1470
+ return bech32.encode(DECODED_EPHEMERAL_HRP, words, BECH32_LONG_LIMIT);
1471
+ }
1472
+ function decodeDecodedEphemeralKey(encoded) {
1473
+ const { prefix, words } = bech32.decode(encoded, BECH32_LONG_LIMIT);
1474
+ if (prefix !== DECODED_EPHEMERAL_HRP) {
1475
+ throw new Error(`ephemeral-key: expected HRP ${DECODED_EPHEMERAL_HRP}, got ${JSON.stringify(prefix)}`);
1476
+ }
1477
+ const bytes = new Uint8Array(bech32.fromWords(words));
1478
+ if (bytes.length !== EPK_POINT_PAYLOAD) {
1479
+ throw new Error(`ephemeral-key: epk1 payload must be ${EPK_POINT_PAYLOAD} bytes, got ${bytes.length}`);
1480
+ }
1481
+ return {
1482
+ x: bytesToHex$1(bytes.subarray(0, FIELD_BYTES)),
1483
+ y: bytesToHex$1(bytes.subarray(FIELD_BYTES)),
1484
+ };
1485
+ }
1486
+ /** Bech32 `epk_dep_pre1`: `randomNonceScalar ‖ recipient.x ‖ recipient.y`. */
1487
+ function encodeDepositorSharedSecretPreimage(decoded) {
1488
+ const sb = hexToBytes$2(decoded.randomNonceScalar);
1489
+ const xb = hexToBytes$2(decoded.recipientStealthAddress.x);
1490
+ const yb = hexToBytes$2(decoded.recipientStealthAddress.y);
1491
+ require32('randomNonceScalar', sb);
1492
+ require32('recipientStealthAddress.x', xb);
1493
+ require32('recipientStealthAddress.y', yb);
1494
+ const payload = concat3(sb, xb, yb);
1495
+ const words = bech32.toWords(payload);
1496
+ return bech32.encode(DEPOSITOR_SHARED_SECRET_PREIMAGE_HRP, words, BECH32_LONG_LIMIT);
1497
+ }
1498
+ function decodeDepositorSharedSecretPreimage(encoded) {
1499
+ const { prefix, words } = bech32.decode(encoded, BECH32_LONG_LIMIT);
1500
+ if (prefix !== DEPOSITOR_SHARED_SECRET_PREIMAGE_HRP) {
1501
+ throw new Error(`ephemeral-key: expected HRP ${DEPOSITOR_SHARED_SECRET_PREIMAGE_HRP}, got ${JSON.stringify(prefix)}`);
1502
+ }
1503
+ const bytes = new Uint8Array(bech32.fromWords(words));
1504
+ if (bytes.length !== EPK_DEP_PRE_PAYLOAD) {
1505
+ throw new Error(`ephemeral-key: epk_dep_pre1 payload must be ${EPK_DEP_PRE_PAYLOAD} bytes, got ${bytes.length}`);
1506
+ }
1507
+ return {
1508
+ randomNonceScalar: bytesToHex$1(bytes.subarray(0, FIELD_BYTES)),
1509
+ recipientStealthAddress: {
1510
+ x: bytesToHex$1(bytes.subarray(FIELD_BYTES, FIELD_BYTES * 2)),
1511
+ y: bytesToHex$1(bytes.subarray(FIELD_BYTES * 2)),
1512
+ },
1513
+ };
1514
+ }
1515
+
1516
+ /**
1517
+ * Depositor: `randomNonceScalar * recipientStealthPoint` (same as circom `ECDH` with depositor scalar).
1518
+ */
1519
+ function sharedSecretFromDepositorPreimage(ecdhShared, preimage) {
1520
+ const out = ecdhShared(preimage.randomNonceScalar, preimage.recipientStealthAddress.x, preimage.recipientStealthAddress.y);
1521
+ return { x: out.x, y: out.y };
1522
+ }
1523
+ /**
1524
+ * Recipient: `recipientScalar * ephemeralKey` (same shared point as depositor path when keys match).
1525
+ */
1526
+ function sharedSecretFromRecipientPreimage(ecdhShared, preimage) {
1527
+ const out = ecdhShared(preimage.recipientScalar, preimage.ephemeralKey.x, preimage.ephemeralKey.y);
1528
+ return { x: out.x, y: out.y };
1529
+ }
1530
+
1531
+ const STEALTH_ADDRESS_HRP = 'stpl1';
1532
+ /** BIP-173 default 90 is too small for 64-byte payload (32+32 field coords) after 8→5 bit conversion. */
1533
+ const BECH32_STEALTH_LIMIT = 1023;
1534
+ function normalizeHex$1(hex) {
1535
+ const s = hex.trim().replace(/^0x/i, '');
1536
+ if (!/^[0-9a-fA-F]*$/.test(s)) {
1537
+ throw new Error('stealth-address: hex must contain only 0-9, a-f');
1538
+ }
1539
+ return s.length % 2 === 0 ? s : `0${s}`;
1540
+ }
1541
+ function hexToBytes$1(hex) {
1542
+ const norm = normalizeHex$1(hex);
1543
+ const out = new Uint8Array(norm.length / 2);
1544
+ for (let i = 0; i < out.length; i++) {
1545
+ out[i] = parseInt(norm.slice(i * 2, i * 2 + 2), 16);
1546
+ }
1547
+ return out;
1548
+ }
1549
+ function bytesToHex(bytes) {
1550
+ let s = '';
1551
+ for (let i = 0; i < bytes.length; i++) {
1552
+ s += bytes[i].toString(16).padStart(2, '0');
1553
+ }
1554
+ return s;
1555
+ }
1556
+ function concatBytes(a, b) {
1557
+ const out = new Uint8Array(a.length + b.length);
1558
+ out.set(a, 0);
1559
+ out.set(b, a.length);
1560
+ return out;
1561
+ }
1562
+ /**
1563
+ * Encodes `x || y` as Bech32 (BIP-173) with human-readable part {@link STEALTH_ADDRESS_HRP} (`stpl1`).
1564
+ * `x` and `y` must have the same byte length so decoding can split the payload in half.
1565
+ */
1566
+ function encodeStealthAddress(decoded) {
1567
+ const xb = hexToBytes$1(decoded.x);
1568
+ const yb = hexToBytes$1(decoded.y);
1569
+ if (xb.length !== yb.length) {
1570
+ throw new Error('stealth-address: x and y must encode the same number of bytes for a reversible address');
1571
+ }
1572
+ const payload = concatBytes(xb, yb);
1573
+ const words = bech32.toWords(payload);
1574
+ return bech32.encode(STEALTH_ADDRESS_HRP, words, BECH32_STEALTH_LIMIT);
1575
+ }
1576
+ /**
1577
+ * Decodes a `stpl1` Bech32 stealth address into `x` and `y` (each half of the payload, as lowercase hex).
1578
+ */
1579
+ function decodeStealthAddress(address) {
1580
+ const { prefix, words } = bech32.decode(address, BECH32_STEALTH_LIMIT);
1581
+ if (prefix !== STEALTH_ADDRESS_HRP) {
1582
+ throw new Error(`stealth-address: expected HRP ${STEALTH_ADDRESS_HRP}, got ${JSON.stringify(prefix)}`);
1583
+ }
1584
+ const bytes = new Uint8Array(bech32.fromWords(words));
1585
+ if (bytes.length === 0 || bytes.length % 2 !== 0) {
1586
+ throw new Error('stealth-address: payload length must be positive and even');
1587
+ }
1588
+ const mid = bytes.length / 2;
1589
+ return {
1590
+ x: bytesToHex(bytes.subarray(0, mid)),
1591
+ y: bytesToHex(bytes.subarray(mid)),
1592
+ };
1593
+ }
1594
+
1595
+ /** Default nonce when deriving the wallet sign-in message. */
1596
+ const DEFAULT_STEALTH_SIGN_NONCE = 'main address';
1597
+ /**
1598
+ * Plaintext for Stellar wallet message signing (stealth address derivation).
1599
+ * Sign the exact bytes of this string (UTF-8) with the stellar account key.
1600
+ */
1601
+ function buildStealthAddressSignMessage(address, nonce = DEFAULT_STEALTH_SIGN_NONCE) {
1602
+ return `Privacy layer app needs you to sign the message for stealth address derivation with address:\n${address}\n and nonce:\n${nonce}.\n\n This will not authorize any transaction.`;
1603
+ }
1604
+
1605
+ /** Matches `Transaction(20, 2, 2)` in `circuits/main.circom`. */
1606
+ const TRANSACTION_TREE_DEPTH = 20;
1607
+ const TRANSACTION_N_INS = 2;
1608
+ const TRANSACTION_N_OUTS = 2;
1609
+ /** BN254 scalar field modulus (ark `Fr`, circom signals). */
1610
+ const BN254_SCALAR_MOD = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
1611
+ /**
1612
+ * BabyJub ECDH in `circuits/encryption.circom` uses `Num2Bits(253)`; scalars must be < 2^253
1613
+ * (matches `libs/cryptography` `scalar_mul_253`).
1614
+ */
1615
+ const BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE = 1n << 253n;
1616
+ function normalizeHex(hex) {
1617
+ const s = hex.trim().replace(/^0x/i, '');
1618
+ if (!/^[0-9a-fA-F]*$/.test(s)) {
1619
+ throw new Error('withdrawal-transaction-input: invalid hex');
1620
+ }
1621
+ return s.length % 2 === 0 ? s : `0${s}`;
1622
+ }
1623
+ /** 32-byte field coordinate (hex, no 0x) → decimal string mod BN254 scalar field. */
1624
+ function coordHexToDecimal(hex) {
1625
+ const h = normalizeHex(hex);
1626
+ if (h.length > 64) {
1627
+ throw new Error('withdrawal-transaction-input: coordinate hex too long');
1628
+ }
1629
+ const v = BigInt(`0x${h}`);
1630
+ return (v % BN254_SCALAR_MOD).toString(10);
1631
+ }
1632
+ /**
1633
+ * 32-byte big-endian scalar hex → decimal for circom `ephemeralKeyScalar` / ECDH `priv`.
1634
+ * Integer must be < 2^253 (not reduced mod r — values ≥ 2^253 are rejected).
1635
+ */
1636
+ function scalarHexToFrDecimal(hex) {
1637
+ const h = normalizeHex(hex);
1638
+ if (h.length > 64) {
1639
+ throw new Error('withdrawal-transaction-input: scalar hex too long');
1640
+ }
1641
+ const v = BigInt(`0x${h.padStart(64, '0').slice(-64)}`);
1642
+ if (v >= BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE) {
1643
+ throw new Error('depositor ephemeral scalar must be < 2^253 (BabyJub Num2Bits); resample with random-scalar');
1644
+ }
1645
+ return v.toString(10);
1646
+ }
1647
+ /**
1648
+ * Stellar G-address Ed25519 payload (32 bytes as 64 hex, optional 0x) → two circom public decimals
1649
+ * (`withdrawAddressHi` / `withdrawAddressLo`). No mod-r; each half fits in 128 bits.
1650
+ */
1651
+ function ed25519PubkeyPayloadHexToWithdrawFrDecimals(hex) {
1652
+ const h = normalizeHex(hex).padStart(64, '0').slice(-64);
1653
+ const hi = BigInt(`0x${h.slice(0, 32)}`);
1654
+ const lo = BigInt(`0x${h.slice(32, 64)}`);
1655
+ return { hi: hi.toString(10), lo: lo.toString(10) };
1656
+ }
1657
+ /** Uniform random `Fr` as decimal (32 random bytes, mod r). For Poseidon-only inputs (e.g. nullifiers). */
1658
+ function randomFrDecimal() {
1659
+ const hex = generateRandomScalarHex32();
1660
+ const v = BigInt(`0x${normalizeHex(hex)}`);
1661
+ return (v % BN254_SCALAR_MOD).toString(10);
1662
+ }
1663
+ /** Random scalar < 2^253 for BabyJub ECDH / `Num2Bits(253)` (uses {@link generateRandomScalarHex32}). */
1664
+ function randomFrDecimal253() {
1665
+ const hex = generateRandomScalarHex32();
1666
+ return BigInt(`0x${normalizeHex(hex)}`).toString(10);
1667
+ }
1668
+ function zerosTreeSiblings() {
1669
+ return Array(TRANSACTION_TREE_DEPTH).fill('0');
1670
+ }
1671
+ function dummyWithdraw(wasm) {
1672
+ const nullifier = randomFrDecimal();
1673
+ const secretHex = generateRandomScalarHex32();
1674
+ const secret = (BigInt(`0x${normalizeHex(secretHex)}`) % BN254_SCALAR_MOD).toString(10);
1675
+ const pt = wasm.ecdhEphemeralPublicKeyFromScalarHex(secretHex);
1676
+ return {
1677
+ value: '0',
1678
+ nullifier,
1679
+ secret,
1680
+ ephemeralKeys: [coordHexToDecimal(pt.x), coordHexToDecimal(pt.y)],
1681
+ stateSiblings: zerosTreeSiblings(),
1682
+ stateIndex: '0',
1683
+ };
1684
+ }
1685
+ function dummyDeposit(wasm) {
1686
+ const nullifier = randomFrDecimal();
1687
+ const ephemeralKeyScalar = randomFrDecimal253();
1688
+ const skHex = generateRandomScalarHex32();
1689
+ const pt = wasm.ecdhEphemeralPublicKeyFromScalarHex(skHex);
1690
+ return {
1691
+ value: '0',
1692
+ nullifier,
1693
+ ephemeralKeyScalar,
1694
+ recipientPublicKeys: [coordHexToDecimal(pt.x), coordHexToDecimal(pt.y)],
1695
+ };
1696
+ }
1697
+ function resolveWithdraw(slot, wasm) {
1698
+ return slot === 'dummy' ? dummyWithdraw(wasm) : slot;
1699
+ }
1700
+ function resolveDeposit(slot, wasm) {
1701
+ return slot === 'dummy' ? dummyDeposit(wasm) : slot;
1702
+ }
1703
+ function buildTransactionWitnessInput(publicParams, withdrawSlots, depositSlots, wasm) {
1704
+ const w0 = resolveWithdraw(withdrawSlots[0], wasm);
1705
+ const w1 = resolveWithdraw(withdrawSlots[1], wasm);
1706
+ const d0 = resolveDeposit(depositSlots[0], wasm);
1707
+ const d1 = resolveDeposit(depositSlots[1], wasm);
1708
+ return {
1709
+ stateRoot: publicParams.stateRoot,
1710
+ withdrawAddressHi: publicParams.withdrawAddressHi,
1711
+ withdrawAddressLo: publicParams.withdrawAddressLo,
1712
+ privKeyScalar: publicParams.privKeyScalar,
1713
+ withdrawnValues: [w0.value, w1.value],
1714
+ withdrawnNullifiers: [w0.nullifier, w1.nullifier],
1715
+ withdrawnSecrets: [w0.secret, w1.secret],
1716
+ ephemeralKeys: [w0.ephemeralKeys, w1.ephemeralKeys],
1717
+ stateSiblings: [w0.stateSiblings, w1.stateSiblings],
1718
+ stateIndex: [w0.stateIndex, w1.stateIndex],
1719
+ depositedValues: [d0.value, d1.value],
1720
+ depositedNullifiers: [d0.nullifier, d1.nullifier],
1721
+ depositedEphemeralKeyScalars: [d0.ephemeralKeyScalar, d1.ephemeralKeyScalar],
1722
+ depositedRecipientPublicKeys: [d0.recipientPublicKeys, d1.recipientPublicKeys],
1723
+ };
1724
+ }
1725
+ /** `stpl1…` stealth address → `[x, y]` as decimal field strings for `depositedRecipientPublicKeys`. */
1726
+ function recipientPublicKeysDecimalFromStealthAddress(stealthAddress) {
1727
+ const { x, y } = decodeStealthAddress(stealthAddress);
1728
+ return [coordHexToDecimal(x), coordHexToDecimal(y)];
1729
+ }
1730
+ /** First withdraw leg: Merkle witness + depositor ECDH point coordinates (hex). */
1731
+ function withdrawObjectFromMerkleWitness(witness, depositorEphemeralHex) {
1732
+ return {
1733
+ value: witness.value,
1734
+ nullifier: witness.nullifier,
1735
+ secret: witness.secret,
1736
+ ephemeralKeys: [
1737
+ coordHexToDecimal(depositorEphemeralHex.x),
1738
+ coordHexToDecimal(depositorEphemeralHex.y),
1739
+ ],
1740
+ stateSiblings: witness.stateSiblings,
1741
+ stateIndex: witness.stateIndex,
1742
+ };
1743
+ }
1744
+
1745
+ function hexToBytes(hex) {
1746
+ const out = new Uint8Array(hex.length / 2);
1747
+ for (let i = 0; i < out.length; i++) {
1748
+ out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
1749
+ }
1750
+ return out;
1751
+ }
1752
+ function bytesToHexLower(bytes) {
1753
+ let s = '';
1754
+ for (let i = 0; i < bytes.length; i++) {
1755
+ s += bytes[i].toString(16).padStart(2, '0');
1756
+ }
1757
+ return s;
1758
+ }
1759
+ /** Base64 → bytes via `atob` (browsers; Node 16+). No Node `Buffer`. */
1760
+ function decodeBase64ToBytes(s) {
1761
+ const t = s.replace(/\s/g, '');
1762
+ if (typeof atob !== 'function') {
1763
+ throw new Error('Base64 decoding requires atob (browser or Node 16+)');
1764
+ }
1765
+ try {
1766
+ const binary = atob(t);
1767
+ const out = new Uint8Array(binary.length);
1768
+ for (let i = 0; i < binary.length; i++) {
1769
+ out[i] = binary.charCodeAt(i);
1770
+ }
1771
+ return out;
1772
+ }
1773
+ catch {
1774
+ throw new Error('Invalid base64 signature');
1775
+ }
1776
+ }
1777
+ /**
1778
+ * Ed25519 signature as **128 hex chars** (optional `0x`) or **base64** (typically 88 chars for 64 bytes, whitespace ignored).
1779
+ */
1780
+ function parseStellarEd25519SignatureRaw(input) {
1781
+ const trimmed = input.trim();
1782
+ const no0x = trimmed.replace(/^0x/i, '');
1783
+ if (/^[0-9a-fA-F]+$/.test(no0x) && no0x.length === 128) {
1784
+ return hexToBytes(no0x.toLowerCase());
1785
+ }
1786
+ const fromB64 = decodeBase64ToBytes(trimmed);
1787
+ if (fromB64.length !== 64) {
1788
+ throw new Error(`Decoded signature must be 64 bytes (Ed25519); got ${fromB64.length} from base64`);
1789
+ }
1790
+ return fromB64;
1791
+ }
1792
+ /** SHA-256 via Web Crypto only (`crypto.subtle`) — works in browsers and Node 19+ (global `crypto`). */
1793
+ async function sha256(data) {
1794
+ const subtle = globalThis.crypto?.subtle;
1795
+ if (!subtle) {
1796
+ throw new Error('SHA-256 requires crypto.subtle (HTTPS or localhost in browsers, or Node.js 19+).');
1797
+ }
1798
+ const copy = new Uint8Array(data.length);
1799
+ copy.set(data);
1800
+ return new Uint8Array(await subtle.digest('SHA-256', copy));
1801
+ }
1802
+ /**
1803
+ * Stellar Ed25519 signature (hex or base64) → SHA-256(signature bytes) → scalar → WASM ECDH (no UTF-8 seed hash).
1804
+ */
1805
+ async function stealthAddressFromStellarSignature(ecdhFromScalarHex, encodeStealth, signature) {
1806
+ const raw = parseStellarEd25519SignatureRaw(signature);
1807
+ const scalar = await sha256(raw);
1808
+ const scalarHex = bytesToHexLower(scalar);
1809
+ const decoded = ecdhFromScalarHex(scalarHex);
1810
+ return encodeStealth(decoded);
1811
+ }
1812
+ /**
1813
+ * SHA-256(signature) as 32-byte BE integer, truncated to **253 bits** (same effective scalar as
1814
+ * `libs/cryptography` `scalar_mul_253` / circom `Num2Bits(253)`), decimal for `privKeyScalar`.
1815
+ */
1816
+ async function privKeyScalarDecimalFromStellarSignature(signature) {
1817
+ const raw = parseStellarEd25519SignatureRaw(signature);
1818
+ const h = await sha256(raw);
1819
+ let v = 0n;
1820
+ for (let i = 0; i < h.length; i++) {
1821
+ v = (v << 8n) + BigInt(h[i]);
1822
+ }
1823
+ const mask = BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE - 1n;
1824
+ return (v & mask).toString(10);
1825
+ }
1826
+
1827
+ /** Stroops amount as WASM `u64` (`bigint`). */
1828
+ function wasmU64Stroops(amount) {
1829
+ const b = typeof amount === 'bigint' ? amount : BigInt(amount);
1830
+ if (b < 0n || b > 0xffffffffffffffffn) {
1831
+ throw new RangeError('amount must be a non-negative u64 (stroops)');
1832
+ }
1833
+ return b;
1834
+ }
1068
1835
  class PrivacyPoolSDK {
1069
1836
  constructor(wasm, options) {
1070
1837
  this.wasm = wasm;
@@ -1089,20 +1856,70 @@ class PrivacyPoolSDK {
1089
1856
  return new PrivacyPoolSDK(wasm, opts);
1090
1857
  }
1091
1858
  /**
1092
- * Generate a new coin with random nullifier and secret.
1859
+ * Uniform 32-byte scalar as lowercase hex (Web Crypto). Same in browser and Node 19+.
1860
+ */
1861
+ static generateRandomScalarHex32() {
1862
+ return generateRandomScalarHex32();
1863
+ }
1864
+ /**
1865
+ * Text to sign with a Stellar wallet for stealth derivation (UTF-8). No WASM required.
1866
+ */
1867
+ static buildStealthAddressSignMessage(address, nonce = DEFAULT_STEALTH_SIGN_NONCE) {
1868
+ return buildStealthAddressSignMessage(address, nonce);
1869
+ }
1870
+ /**
1871
+ * Generate a new coin with random nullifier, secret, and random shared-secret field elements (dev / self-contained tests).
1872
+ * @param amount Stroops encoded as `bigint` or integer `number` (WASM `u64`).
1873
+ */
1874
+ generateCoin(amount) {
1875
+ return this.wasm.generateCoin(wasmU64Stroops(amount));
1876
+ }
1877
+ /**
1878
+ * Generate a coin with the same commitment shape as on-chain deposit: pass `ecdhSharedKey` output (hex x, y).
1879
+ * @param amount Stroops (`bigint` | `number`).
1880
+ */
1881
+ generateCoinWithSharedSecret(shared, amount) {
1882
+ return this.wasm.generateCoinWithSharedSecretHex(shared.x, shared.y, wasmU64Stroops(amount));
1883
+ }
1884
+ /**
1885
+ * Coin for a depositor `ephemeralKeyScalar` (32-byte hex): `coin.secret = Poseidon255(1)(scalar)` as in `deposit.circom`.
1886
+ * @param amount Stroops (`bigint` | `number`).
1887
+ */
1888
+ generateCoinFromDepositEphemeralScalarHex(scalarHex, amount) {
1889
+ return this.wasm.generateCoinFromDepositEphemeralScalarHex(scalarHex, wasmU64Stroops(amount));
1890
+ }
1891
+ /**
1892
+ * Aligned deposit coin: `secret = Poseidon₁(scalar)` and ECDH shared key from hex coords (e.g. `ecdhSharedKey(scalar, recipient_x, recipient_y)`).
1893
+ * @param amount Stroops (`bigint` | `number`).
1093
1894
  */
1094
- generateCoin() {
1095
- return this.wasm.generateCoin();
1895
+ generateCoinForDepositWithSharedHex(scalarHex, sharedXHex, sharedYHex, amount) {
1896
+ return this.wasm.generateCoinForDepositWithSharedHex(scalarHex, sharedXHex, sharedYHex, wasmU64Stroops(amount));
1096
1897
  }
1097
1898
  /**
1098
- * Generate withdrawal SNARK input from coin data and state.
1899
+ * Merkle root, path, and coin fields for the first withdraw leg (Rust LeanIMT + Poseidon).
1099
1900
  */
1100
- generateWithdrawalInput(coin, state) {
1901
+ buildWithdrawMerkleWitness(coin, state) {
1101
1902
  const coinJson = JSON.stringify(coin);
1102
1903
  const stateJson = JSON.stringify(state);
1103
- const resultJson = this.wasm.generateWithdrawalInput(coinJson, stateJson);
1904
+ const resultJson = this.wasm.buildWithdrawMerkleWitness(coinJson, stateJson);
1104
1905
  return JSON.parse(resultJson);
1105
1906
  }
1907
+ /**
1908
+ * Full `Transaction(20,2,2)` withdrawal proof: one real withdraw + dummies, using coin/state and depositor ECDH point (hex).
1909
+ */
1910
+ async proveWithdrawal(coin, state, params) {
1911
+ const witness = this.buildWithdrawMerkleWitness(coin, state);
1912
+ const w0 = withdrawObjectFromMerkleWitness(witness, {
1913
+ x: params.ephemeralXHex,
1914
+ y: params.ephemeralYHex,
1915
+ });
1916
+ return this.proveTransaction({
1917
+ stateRoot: witness.stateRoot,
1918
+ withdrawAddressHi: params.withdrawAddressHi,
1919
+ withdrawAddressLo: params.withdrawAddressLo,
1920
+ privKeyScalar: params.privKeyScalar,
1921
+ }, [w0, 'dummy'], ['dummy', 'dummy']);
1922
+ }
1106
1923
  /**
1107
1924
  * Convert a snarkjs proof JSON to hex bytes for Soroban.
1108
1925
  */
@@ -1116,16 +1933,33 @@ class PrivacyPoolSDK {
1116
1933
  return this.wasm.publicToHex(JSON.stringify(publicSignals));
1117
1934
  }
1118
1935
  /**
1119
- * Full withdrawal flow: generate input -> witness -> proof -> serialize.
1120
- * Returns proof_hex and public_hex ready for Soroban contract call.
1936
+ * BabyJubJub ephemeral point from a 32-byte scalar (hex). For custom {@link WithdrawObject} / tests.
1937
+ */
1938
+ ecdhEphemeralPublicKeyFromScalarHex(scalarHex) {
1939
+ return this.wasm.ecdhEphemeralPublicKeyFromScalarHex(scalarHex);
1940
+ }
1941
+ /** Circuit `ECDH`: scalar (32-byte hex) × recipient BabyJub point → shared key hex coords. */
1942
+ ecdhSharedKey(scalarHex, recipientPubXHex, recipientPubYHex) {
1943
+ return this.wasm.ecdhSharedKey(scalarHex, recipientPubXHex, recipientPubYHex);
1944
+ }
1945
+ /**
1946
+ * `Transaction(20,2,2)` proof from high-level legs: maps to witness input (incl. `"dummy"` ECDH via WASM), then Groth16 → Soroban hex.
1947
+ *
1948
+ * @param publicParams Public inputs: `stateRoot`, `withdrawAddressHi` / `withdrawAddressLo`, `privKeyScalar` (decimal field strings).
1949
+ * @param withdraws Exactly two withdraw slots (`WithdrawObject` or `"dummy"`).
1950
+ * @param deposits Exactly two deposit slots (`DepositObject` or `"dummy"`).
1121
1951
  */
1122
- async prepareWithdrawal(coin, state) {
1123
- const snarkInput = this.generateWithdrawalInput(coin, state);
1124
- const wtns = await generateWitness(snarkInput, this.options.circuitWasm);
1952
+ async proveTransaction(publicParams, withdraws, deposits) {
1953
+ const wasmEcdh = {
1954
+ ecdhEphemeralPublicKeyFromScalarHex: (h) => this.wasm.ecdhEphemeralPublicKeyFromScalarHex(h),
1955
+ };
1956
+ const witnessInput = buildTransactionWitnessInput(publicParams, withdraws, deposits, wasmEcdh);
1957
+ const wtns = await generateWitness(witnessInput, this.options.circuitWasm);
1125
1958
  const { proof, publicSignals } = await generateProof(wtns, this.options.zkey);
1126
- const proof_hex = this.proofToHex(proof);
1127
- const public_hex = this.publicToHex(publicSignals);
1128
- return { proof_hex, public_hex };
1959
+ return {
1960
+ proof_hex: this.proofToHex(proof),
1961
+ public_hex: this.publicToHex(publicSignals),
1962
+ };
1129
1963
  }
1130
1964
  /**
1131
1965
  * Calculate nullifier hash: Poseidon(nullifier)
@@ -1135,7 +1969,37 @@ class PrivacyPoolSDK {
1135
1969
  calculateNullifierHash(nullifier) {
1136
1970
  return this.wasm.calculateNullifierHash(nullifier);
1137
1971
  }
1972
+ /**
1973
+ * Ed25519 signature from signing {@link buildStealthAddressSignMessage}: **128 hex chars** (optional `0x`)
1974
+ * or **base64** (64 raw bytes after decode). `SHA-256(signature bytes)` → scalar → ECDH → `stpl1` Bech32.
1975
+ */
1976
+ async generateStealthAddressFromStellarSignature(signature) {
1977
+ return stealthAddressFromStellarSignature((h) => this.wasm.ecdhEphemeralPublicKeyFromScalarHex(h), encodeStealthAddress, signature);
1978
+ }
1979
+ encodeDecodedEphemeralKey(decoded) {
1980
+ return encodeDecodedEphemeralKey(decoded);
1981
+ }
1982
+ decodeDecodedEphemeralKey(encoded) {
1983
+ return decodeDecodedEphemeralKey(encoded);
1984
+ }
1985
+ encodeDepositorSharedSecretPreimage(decoded) {
1986
+ return encodeDepositorSharedSecretPreimage(decoded);
1987
+ }
1988
+ decodeDepositorSharedSecretPreimage(encoded) {
1989
+ return decodeDepositorSharedSecretPreimage(encoded);
1990
+ }
1991
+ sharedSecretFromDepositorPreimage(preimage) {
1992
+ return sharedSecretFromDepositorPreimage((a, b, c) => this.wasm.ecdhSharedKey(a, b, c), preimage);
1993
+ }
1994
+ sharedSecretFromRecipientPreimage(preimage) {
1995
+ return sharedSecretFromRecipientPreimage((a, b, c) => this.wasm.ecdhSharedKey(a, b, c), preimage);
1996
+ }
1138
1997
  }
1139
1998
 
1140
- export { PrivacyPoolSDK };
1999
+ /** Pool Merkle tree depth (matches `coin::TREE_DEPTH` / `Transaction` circuit). */
2000
+ const POOL_MERKLE_TREE_DEPTH = 20;
2001
+ /** Default coin value in stroops (1 XLM); matches Rust `coin::COIN_VALUE`. */
2002
+ const COIN_VALUE_STROOPS = 1000000000;
2003
+
2004
+ export { BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE, BN254_SCALAR_MOD, COIN_VALUE_STROOPS, DECODED_EPHEMERAL_HRP, DEFAULT_STEALTH_SIGN_NONCE, DEPOSITOR_SHARED_SECRET_PREIMAGE_HRP, POOL_MERKLE_TREE_DEPTH, PrivacyPoolSDK, STEALTH_ADDRESS_HRP, TRANSACTION_N_INS, TRANSACTION_N_OUTS, TRANSACTION_TREE_DEPTH, buildStealthAddressSignMessage, buildTransactionWitnessInput, coordHexToDecimal, decodeDecodedEphemeralKey, decodeDepositorSharedSecretPreimage, decodeStealthAddress, ed25519PubkeyPayloadHexToWithdrawFrDecimals, encodeDecodedEphemeralKey, encodeDepositorSharedSecretPreimage, encodeStealthAddress, generateRandomScalarHex32, privKeyScalarDecimalFromStellarSignature, randomFrDecimal, randomFrDecimal253, recipientPublicKeysDecimalFromStealthAddress, scalarHexToFrDecimal, sharedSecretFromDepositorPreimage, sharedSecretFromRecipientPreimage, withdrawObjectFromMerkleWitness };
1141
2005
  //# sourceMappingURL=index.mjs.map