@arcanetech/privacy-sdk-stellar 0.2.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,10 @@
1
1
  // src/transact/pool/service.ts
2
2
  import {
3
+ PrivacyPoolSDK as PrivacyPoolSDK2,
3
4
  decodeDecodedEphemeralKey,
4
5
  randomFrDecimal253,
5
6
  scalarHexToFrDecimal as scalarHexToFrDecimal2
6
- } from "@auditable/privacy-pool-zk-sdk";
7
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
7
8
 
8
9
  // src/transact/merkle/field-decimal.ts
9
10
  import { Buffer as Buffer2 } from "buffer";
@@ -26,11 +27,18 @@ import {
26
27
  decodeStealthAddress,
27
28
  encodeStealthAddress,
28
29
  recipientPublicKeysDecimalFromStealthAddress
29
- } from "@auditable/privacy-pool-zk-sdk";
30
- import { DEFAULT_STEALTH_SIGN_NONCE } from "@auditable/privacy-pool-zk-sdk";
31
- function buildPrivateAddressSignMessage(publicKey, nonce) {
30
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
31
+ import { DEFAULT_STEALTH_SIGN_NONCE } from "@arcanetech/stellar-privacy-pool-zk-sdk";
32
+ import {
33
+ OWNER_BOUND_NOTE_SCHEMA_VERSION,
34
+ spendScalarHexFromStellarSignature
35
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
36
+ function buildPrivateAddressSignMessage(publicKey, domain, nonce) {
32
37
  const buildMessage = buildStealthAddressSignMessage;
33
- return buildMessage(publicKey, nonce);
38
+ if (nonce === void 0) {
39
+ return buildMessage(publicKey, domain);
40
+ }
41
+ return buildMessage(publicKey, domain, nonce);
34
42
  }
35
43
  function decodePrivateAddress(value) {
36
44
  const decodeAddress = decodeStealthAddress;
@@ -60,12 +68,12 @@ function privateAddressSdk(sdk) {
60
68
  );
61
69
  }
62
70
  return {
63
- generatePrivateAddressFromStellarSignature: (signature) => generator.call(sdk, signature)
71
+ generatePrivateAddressFromStellarSignature: (signature, domain) => generator.call(sdk, signature, domain)
64
72
  };
65
73
  }
66
74
 
67
75
  // src/transact/proofs/withdraw/transact-proof.ts
68
- import { withdrawObjectFromMerkleWitness as withdrawObjectFromMerkleWitness2 } from "@auditable/privacy-pool-zk-sdk";
76
+ import { withdrawObjectFromMerkleWitness as withdrawObjectFromMerkleWitness2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
69
77
 
70
78
  // src/transact/proofs/transaction-input.ts
71
79
  import { Buffer as Buffer4 } from "buffer";
@@ -105,6 +113,10 @@ function resolveTokenContractId(tokenContractRaw) {
105
113
  }
106
114
 
107
115
  // src/transact/proofs/transaction-input.ts
116
+ var ZERO_PUBLIC_WITHDRAW_ADDRESS = {
117
+ withdrawAddressHi: "0",
118
+ withdrawAddressLo: "0"
119
+ };
108
120
  var CONTRACT_ADDRESS_HALF_BYTES = 16;
109
121
  var CONTRACT_ADDRESS_BYTES = 32;
110
122
  function bytes16ToDecimal(bytes) {
@@ -131,7 +143,25 @@ function withTokenAddressPublicInputs(base, tokenAddress) {
131
143
  return {
132
144
  ...base,
133
145
  tokenAddressHi: hi,
134
- tokenAddressLo: lo
146
+ tokenAddressLo: lo,
147
+ withdrawAddressHi: base.withdrawAddressHi ?? ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressHi,
148
+ withdrawAddressLo: base.withdrawAddressLo ?? ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressLo,
149
+ escrowRecipientHi: base.escrowRecipientHi ?? "0",
150
+ escrowRecipientLo: base.escrowRecipientLo ?? "0",
151
+ sweepOutputOwnerPubX: base.sweepOutputOwnerPubX ?? "0",
152
+ sweepOutputOwnerPubY: base.sweepOutputOwnerPubY ?? "0"
153
+ };
154
+ }
155
+ function publicWithdrawAddressLimbs(parameters) {
156
+ if (parameters.publicWithdrawalAmount === "0") {
157
+ return {
158
+ withdrawAddressHi: ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressHi,
159
+ withdrawAddressLo: ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressLo
160
+ };
161
+ }
162
+ return {
163
+ withdrawAddressHi: parameters.destinationHi,
164
+ withdrawAddressLo: parameters.destinationLo
135
165
  };
136
166
  }
137
167
  function tokenAddressToAssetLeg(tokenAddress) {
@@ -142,91 +172,91 @@ function assetLegToTokenAddress(assetHi, assetLo) {
142
172
  const payload = Buffer4.concat([decimalToBytes16(assetHi), decimalToBytes16(assetLo)]);
143
173
  return StrKey2.encodeContract(payload);
144
174
  }
145
- function buildZeroPublicLegs() {
175
+ function buildZeroPublicLegs(publicNInputs = 1, publicNOutputs = 1) {
146
176
  return {
147
- publicWithdrawnAssets: [["0", "0"]],
148
- publicDepositedAssets: [["0", "0"]],
149
- publicDeposits: ["0"],
150
- publicWithdrawals: ["0"]
177
+ publicWithdrawnAssets: Array.from(
178
+ { length: publicNOutputs },
179
+ () => ["0", "0"]
180
+ ),
181
+ publicDepositedAssets: Array.from(
182
+ { length: publicNInputs },
183
+ () => ["0", "0"]
184
+ ),
185
+ publicDeposits: Array.from({ length: publicNInputs }, () => "0"),
186
+ publicWithdrawals: Array.from({ length: publicNOutputs }, () => "0")
151
187
  };
152
188
  }
153
- function buildPublicDepositLegs(tokenAddress, amount) {
154
- const legs = buildZeroPublicLegs();
189
+ function buildPublicDepositLegs(tokenAddress, amount, publicNInputs = 1, publicNOutputs = 1) {
190
+ const legs = buildZeroPublicLegs(publicNInputs, publicNOutputs);
155
191
  return {
156
192
  ...legs,
157
- publicDepositedAssets: [tokenAddressToAssetLeg(tokenAddress)],
158
- publicDeposits: [amount]
193
+ publicDepositedAssets: [
194
+ tokenAddressToAssetLeg(tokenAddress),
195
+ ...legs.publicDepositedAssets.slice(1)
196
+ ],
197
+ publicDeposits: [amount, ...legs.publicDeposits.slice(1)]
159
198
  };
160
199
  }
161
- function buildPublicWithdrawLegs(tokenAddress, amount) {
162
- const legs = buildZeroPublicLegs();
200
+ function buildPublicWithdrawLegs(tokenAddress, amount, publicNInputs = 1, publicNOutputs = 1) {
201
+ const legs = buildZeroPublicLegs(publicNInputs, publicNOutputs);
163
202
  return {
164
203
  ...legs,
165
- publicWithdrawnAssets: [tokenAddressToAssetLeg(tokenAddress)],
166
- publicWithdrawals: [amount]
204
+ publicWithdrawnAssets: [
205
+ tokenAddressToAssetLeg(tokenAddress),
206
+ ...legs.publicWithdrawnAssets.slice(1)
207
+ ],
208
+ publicWithdrawals: [amount, ...legs.publicWithdrawals.slice(1)]
167
209
  };
168
210
  }
169
211
 
170
- // src/transact/proofs/confidential/helpers.ts
212
+ // src/transact/zk/slots.ts
171
213
  import {
172
- ed25519PubkeyPayloadHexToWithdrawFrDecimals,
173
- withdrawObjectFromMerkleWitness
174
- } from "@auditable/privacy-pool-zk-sdk";
175
- import { StrKey as StrKey3 } from "@stellar/stellar-sdk";
176
- import { Buffer as Buffer5 } from "buffer";
177
-
178
- // src/transact/encoding/priv-key-scalar-from-recipient-hex.ts
179
- import { BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE } from "@auditable/privacy-pool-zk-sdk";
180
- var SCALAR_HEX_CHAR_LENGTH = 64;
181
- var DECIMAL_RADIX = 10;
182
- var BIGINT_ONE = 1n;
183
- function normalizeRecipientScalarHex(hexInput) {
184
- const trimmed = hexInput.trim().replace(/^0x/iu, "");
185
- if (!/^[0-9a-f]*$/iu.test(trimmed)) {
186
- throw new Error("recipient scalar hex must be hexadecimal");
187
- }
188
- const withLeadingNibble = trimmed.length % 2 === 0 ? trimmed : `0${trimmed}`;
189
- const lower = withLeadingNibble.toLowerCase();
190
- const padded = lower.padStart(SCALAR_HEX_CHAR_LENGTH, "0").slice(-SCALAR_HEX_CHAR_LENGTH);
191
- if (padded.length !== SCALAR_HEX_CHAR_LENGTH) {
214
+ padDepositSlots,
215
+ padPublicLegs,
216
+ padWithdrawSlots
217
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
218
+ function padWithdrawSlotsToLayout(sdk, slots) {
219
+ return padWithdrawSlots(slots, sdk.getLayout().nIns);
220
+ }
221
+ function padDepositSlotsToLayout(sdk, slots) {
222
+ return padDepositSlots(slots, sdk.getLayout().nOuts);
223
+ }
224
+ function padPublicLegsToLayout(sdk, legs) {
225
+ const { publicNInputs, publicNOutputs } = sdk.getLayout();
226
+ return padPublicLegs(legs, publicNInputs, publicNOutputs);
227
+ }
228
+ function padStrings(values, length, fill) {
229
+ if (values.length > length) {
192
230
  throw new Error(
193
- `recipient scalar hex must fit 32 bytes (${SCALAR_HEX_CHAR_LENGTH} hex chars)`
231
+ `expected at most ${String(length)} application-id slots, got ${String(values.length)}`
194
232
  );
195
233
  }
196
- return padded;
234
+ return [...values, ...Array.from({ length: length - values.length }, () => fill)];
197
235
  }
198
- function privKeyScalarDecimalFromRecipientScalarHex(hexInput) {
199
- const hex = normalizeRecipientScalarHex(hexInput);
200
- const value = BigInt(`0x${hex}`);
201
- const mask = BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE - BIGINT_ONE;
202
- return (value & mask).toString(DECIMAL_RADIX);
236
+ function buildApplicationIdHints(input) {
237
+ const { nIns, nOuts } = input.sdk.getLayout();
238
+ return [
239
+ ...padStrings(input.inputIds, nIns, "0"),
240
+ ...padStrings(input.outputIds, nOuts, "0")
241
+ ];
242
+ }
243
+ function uniformApplicationIdHints(applicationId, nAuditSlots) {
244
+ return Array.from({ length: nAuditSlots }, () => applicationId);
203
245
  }
204
246
 
205
247
  // src/transact/proofs/confidential/helpers.ts
248
+ import { withdrawObjectFromMerkleWitness } from "@arcanetech/stellar-privacy-pool-zk-sdk";
206
249
  var MIN_CONFIDENTIAL_TRANSFER_STROOPS = 1n;
207
250
  var ZERO_STROOPS = 0n;
208
- function leafEphemeralCoords(xHex, yHex) {
209
- const coords = {};
210
- Object.defineProperty(coords, "x", {
211
- value: xHex,
212
- enumerable: true,
213
- writable: true
214
- });
215
- Object.defineProperty(coords, "y", {
216
- value: yHex,
217
- enumerable: true,
218
- writable: true
219
- });
220
- return coords;
221
- }
222
251
  function withdrawWitnessForCoin(parameters) {
223
- const { sdk, coin, state, xHex, yHex } = parameters;
252
+ const { sdk, coin, state } = parameters;
224
253
  const witness = sdk.buildWithdrawMerkleWitness(coin, state);
225
254
  const withdrawApplicationId = coin.application_id ?? parameters.applicationId;
226
255
  const withdrawObject = withdrawObjectFromMerkleWitness(
227
256
  witness,
228
- leafEphemeralCoords(xHex, yHex),
229
- withdrawApplicationId
257
+ parameters.ownerPubHex,
258
+ withdrawApplicationId,
259
+ parameters.privKeyScalar
230
260
  );
231
261
  return { witness, withdrawObject };
232
262
  }
@@ -235,16 +265,16 @@ function dualWithdrawLegsWithSharedRoot(parameters) {
235
265
  sdk: parameters.sdk,
236
266
  coin: parameters.coinA,
237
267
  state: parameters.state,
238
- xHex: parameters.ephemeralA.xHex,
239
- yHex: parameters.ephemeralA.yHex,
268
+ ownerPubHex: parameters.ownerPubHex,
269
+ privKeyScalar: parameters.privKeyScalar,
240
270
  applicationId: parameters.applicationId
241
271
  });
242
272
  const legB = withdrawWitnessForCoin({
243
273
  sdk: parameters.sdk,
244
274
  coin: parameters.coinB,
245
275
  state: parameters.state,
246
- xHex: parameters.ephemeralB.xHex,
247
- yHex: parameters.ephemeralB.yHex,
276
+ ownerPubHex: parameters.ownerPubHex,
277
+ privKeyScalar: parameters.privKeyScalar,
248
278
  applicationId: parameters.applicationId
249
279
  });
250
280
  if (legA.witness.stateRoot !== legB.witness.stateRoot) {
@@ -252,15 +282,6 @@ function dualWithdrawLegsWithSharedRoot(parameters) {
252
282
  }
253
283
  return { legA, legB };
254
284
  }
255
- function senderWithdrawFrAndScalar(parameters) {
256
- const pkRaw = StrKey3.decodeEd25519PublicKey(parameters.senderGAddress);
257
- const pkHex = Buffer5.from(pkRaw).toString("hex");
258
- const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals(pkHex);
259
- const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
260
- parameters.senderPrivKeyScalarHex
261
- );
262
- return { hi, lo, privKeyScalar };
263
- }
264
285
  function requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange) {
265
286
  if (changeStroops > ZERO_STROOPS) {
266
287
  const stpl1 = selfPrivateAddressStpl1ForChange?.trim() ?? "";
@@ -285,15 +306,15 @@ function changeStroopsAfterDualTransfer(transferStroops, totalNotes) {
285
306
  import {
286
307
  DEMO_AUDIT_PUBLIC_KEY,
287
308
  resolveTransactionAuditParams
288
- } from "@auditable/privacy-pool-zk-sdk";
289
- import { Buffer as Buffer6 } from "buffer";
309
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
310
+ import { Buffer as Buffer5 } from "buffer";
290
311
  var UNCOMPRESSED_PREFIX = "04";
291
312
  var UNCOMPRESSED_HEX_LENGTH = 130;
292
313
  var XY_HEX_LENGTH = 128;
293
314
  var X_OFFSET_END = 32;
294
315
  var Y_OFFSET_START = 32;
295
316
  var Y_OFFSET_END = 64;
296
- var DECIMAL_RADIX2 = 10;
317
+ var DECIMAL_RADIX = 10;
297
318
  var BN254_FR_MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
298
319
  var BABYJUBJUB_A = 168700n;
299
320
  var BABYJUBJUB_D = 168696n;
@@ -313,13 +334,13 @@ function parseAuditPublicKeyFromEnvHex(raw) {
313
334
  "Audit public key must be uncompressed 65-byte hex (04 + X + Y) or 64-byte X+Y hex"
314
335
  );
315
336
  }
316
- const bytes = Buffer6.from(payload, "hex");
337
+ const bytes = Buffer5.from(payload, "hex");
317
338
  const auditPublicKeyXDecimal = BigInt(
318
339
  `0x${bytes.subarray(0, X_OFFSET_END).toString("hex")}`
319
- ).toString(DECIMAL_RADIX2);
340
+ ).toString(DECIMAL_RADIX);
320
341
  const auditPublicKeyYDecimal = BigInt(
321
342
  `0x${bytes.subarray(Y_OFFSET_START, Y_OFFSET_END).toString("hex")}`
322
- ).toString(DECIMAL_RADIX2);
343
+ ).toString(DECIMAL_RADIX);
323
344
  if (!passesBabyJubCurveCheck(
324
345
  BigInt(auditPublicKeyXDecimal),
325
346
  BigInt(auditPublicKeyYDecimal)
@@ -331,7 +352,8 @@ function parseAuditPublicKeyFromEnvHex(raw) {
331
352
  function buildPoolTransactionAuditParameters(input) {
332
353
  return resolveTransactionAuditParams(
333
354
  input.applicationId,
334
- input.auditPublicKey ?? DEMO_AUDIT_PUBLIC_KEY
355
+ input.auditPublicKey ?? DEMO_AUDIT_PUBLIC_KEY,
356
+ input.nAuditSlots
335
357
  );
336
358
  }
337
359
  function resolvePoolApplicationId(applicationId) {
@@ -345,24 +367,24 @@ function resolvePoolApplicationId(applicationId) {
345
367
  }
346
368
 
347
369
  // src/transact/proofs/withdraw/helpers.ts
348
- import { ed25519PubkeyPayloadHexToWithdrawFrDecimals as ed25519PubkeyPayloadHexToWithdrawFrDecimals2 } from "@auditable/privacy-pool-zk-sdk";
370
+ import { ed25519PubkeyPayloadHexToWithdrawFrDecimals } from "@arcanetech/stellar-privacy-pool-zk-sdk";
349
371
 
350
372
  // src/transact/stellar/account.ts
351
- import { StrKey as StrKey4 } from "@stellar/stellar-sdk";
352
- import { Buffer as Buffer7 } from "buffer";
373
+ import { StrKey as StrKey3 } from "@stellar/stellar-sdk";
374
+ import { Buffer as Buffer6 } from "buffer";
353
375
  var MUXED_ACCOUNT_ID_BYTE_LENGTH = 8;
354
376
  var ED25519_PUBLIC_KEY_BYTE_LENGTH = 32;
355
377
  function ed25519HexFromGAddress(trimmed) {
356
378
  try {
357
- const raw = StrKey4.decodeEd25519PublicKey(trimmed);
358
- return Buffer7.from(raw).toString("hex");
379
+ const raw = StrKey3.decodeEd25519PublicKey(trimmed);
380
+ return Buffer6.from(raw).toString("hex");
359
381
  } catch {
360
382
  return void 0;
361
383
  }
362
384
  }
363
385
  function ed25519HexFromMuxedAddress(trimmed) {
364
386
  try {
365
- const raw = StrKey4.decodeMed25519PublicKey(trimmed);
387
+ const raw = StrKey3.decodeMed25519PublicKey(trimmed);
366
388
  if (raw.length === MUXED_ACCOUNT_ID_BYTE_LENGTH + ED25519_PUBLIC_KEY_BYTE_LENGTH) {
367
389
  return raw.subarray(MUXED_ACCOUNT_ID_BYTE_LENGTH).toString("hex");
368
390
  }
@@ -387,26 +409,29 @@ function ed25519PublicKeyHexFromStellarAccount(address) {
387
409
  throw new Error("Invalid destination Stellar address");
388
410
  }
389
411
 
390
- // src/transact/encoding/ephemeral-key.ts
391
- var HEX_64_RE = /^[\da-f]{64}$/iu;
392
- function normalizeCoordinate(value) {
393
- const hex = value.trim().replace(/^0x/iu, "").toLowerCase();
394
- if (!HEX_64_RE.test(hex)) {
395
- throw new Error("Ephemeral key coordinate must be a 32-byte hex string.");
412
+ // src/transact/encoding/priv-key-scalar-from-recipient-hex.ts
413
+ import { canonicalBabyJubScalarFromInteger } from "@arcanetech/stellar-privacy-pool-zk-sdk";
414
+ var SCALAR_HEX_CHAR_LENGTH = 64;
415
+ var DECIMAL_RADIX2 = 10;
416
+ function normalizeRecipientScalarHex(hexInput) {
417
+ const trimmed = hexInput.trim().replace(/^0x/iu, "");
418
+ if (!/^[0-9a-f]*$/iu.test(trimmed)) {
419
+ throw new Error("recipient scalar hex must be hexadecimal");
396
420
  }
397
- return hex;
398
- }
399
- function parseEphemeralKeyString(input) {
400
- const [xRaw, yRaw, extra] = input.split(":");
401
- if (!xRaw || !yRaw || extra !== void 0) {
421
+ const withLeadingNibble = trimmed.length % 2 === 0 ? trimmed : `0${trimmed}`;
422
+ const lower = withLeadingNibble.toLowerCase();
423
+ const padded = lower.padStart(SCALAR_HEX_CHAR_LENGTH, "0").slice(-SCALAR_HEX_CHAR_LENGTH);
424
+ if (padded.length !== SCALAR_HEX_CHAR_LENGTH) {
402
425
  throw new Error(
403
- 'Ephemeral key must be a string in "xHex:yHex" format (32-byte hex each).'
426
+ `recipient scalar hex must fit 32 bytes (${SCALAR_HEX_CHAR_LENGTH} hex chars)`
404
427
  );
405
428
  }
406
- return {
407
- xHex: normalizeCoordinate(xRaw),
408
- yHex: normalizeCoordinate(yRaw)
409
- };
429
+ return padded;
430
+ }
431
+ function privKeyScalarDecimalFromRecipientScalarHex(hexInput) {
432
+ const hex = normalizeRecipientScalarHex(hexInput);
433
+ const value = BigInt(`0x${hex}`);
434
+ return canonicalBabyJubScalarFromInteger(value).toString(DECIMAL_RADIX2);
410
435
  }
411
436
 
412
437
  // src/transact/proofs/withdraw/helpers.ts
@@ -414,7 +439,7 @@ function destinationWithdrawFrAndScalar(parameters) {
414
439
  const pkHex = ed25519PublicKeyHexFromStellarAccount(
415
440
  parameters.destinationStellarAddress
416
441
  );
417
- const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals2(pkHex);
442
+ const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals(pkHex);
418
443
  const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
419
444
  parameters.privKeyScalarHex
420
445
  );
@@ -428,8 +453,11 @@ function buildWithdrawPublicInput(parameters) {
428
453
  return withTokenAddressPublicInputs(
429
454
  {
430
455
  stateRoot: parameters.stateRoot,
431
- withdrawAddressHi: hi,
432
- withdrawAddressLo: lo,
456
+ ...publicWithdrawAddressLimbs({
457
+ publicWithdrawalAmount: parameters.publicWithdrawalAmount,
458
+ destinationHi: hi,
459
+ destinationLo: lo
460
+ }),
433
461
  privKeyScalar
434
462
  },
435
463
  parameters.tokenAddress
@@ -437,7 +465,7 @@ function buildWithdrawPublicInput(parameters) {
437
465
  }
438
466
  async function resolveWithdrawChangeDeposits(parameters) {
439
467
  if (parameters.changeStroops <= ZERO_STROOPS) {
440
- return { deposits: ["dummy", "dummy"] };
468
+ return { deposits: [] };
441
469
  }
442
470
  const stpl1 = parameters.changePrivateAddressStpl1?.trim() ?? "";
443
471
  if (!stpl1) {
@@ -451,7 +479,7 @@ async function resolveWithdrawChangeDeposits(parameters) {
451
479
  tokenAddress: parameters.tokenAddress
452
480
  });
453
481
  return {
454
- deposits: [slot.deposit, "dummy"],
482
+ deposits: [slot.deposit],
455
483
  changeCoin: {
456
484
  commitment_hex: slot.commitment_hex,
457
485
  coin: slot.coin,
@@ -476,14 +504,14 @@ function buildDualWithdrawPublicInput(parameters) {
476
504
  stateRoot: parameters.stateRoot,
477
505
  destinationStellarAddress: parameters.destinationStellarAddress,
478
506
  privKeyScalarHex: parameters.privKeyScalarHex,
479
- tokenAddress: parameters.tokenAddress
507
+ tokenAddress: parameters.tokenAddress,
508
+ publicWithdrawalAmount: parameters.publicWithdrawalAmount
480
509
  });
481
510
  }
482
511
  async function prepareDualWithdrawProofInputs(parameters) {
483
- const totalNotes = BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value);
484
512
  const changeStroops = validateDualWithdrawAmounts(
485
513
  parameters.withdrawAmountStroops,
486
- totalNotes,
514
+ BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value),
487
515
  parameters.changePrivateAddressStpl1
488
516
  );
489
517
  const { legA, legB } = dualWithdrawLegsWithSharedRoot({
@@ -491,8 +519,12 @@ async function prepareDualWithdrawProofInputs(parameters) {
491
519
  coinA: parameters.coinA,
492
520
  coinB: parameters.coinB,
493
521
  state: parameters.state,
494
- ephemeralA: parseEphemeralKeyString(parameters.ephemeralAKey),
495
- ephemeralB: parseEphemeralKeyString(parameters.ephemeralBKey),
522
+ ownerPubHex: parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
523
+ parameters.privKeyScalarHex
524
+ ),
525
+ privKeyScalar: privKeyScalarDecimalFromRecipientScalarHex(
526
+ parameters.privKeyScalarHex
527
+ ),
496
528
  applicationId: parameters.applicationId
497
529
  });
498
530
  const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
@@ -505,17 +537,19 @@ async function prepareDualWithdrawProofInputs(parameters) {
505
537
  destinationStellarAddress: parameters.destinationStellarAddress,
506
538
  privKeyScalarHex: parameters.privKeyScalarHex,
507
539
  tokenAddress: parameters.tokenAddress,
508
- stateRoot: legA.witness.stateRoot
540
+ stateRoot: legA.witness.stateRoot,
541
+ publicWithdrawalAmount: parameters.withdrawAmountStroops.toString()
509
542
  });
510
543
  const audit = buildPoolTransactionAuditParameters({
511
544
  applicationId: parameters.applicationId,
545
+ nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
512
546
  ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
513
547
  });
514
548
  return {
515
549
  publicInput,
516
550
  audit,
517
- withdrawLegs: [legA.withdrawObject, legB.withdrawObject],
518
551
  deposits,
552
+ withdrawLegs: [legA.withdrawObject, legB.withdrawObject],
519
553
  ...changeCoin ? { changeCoin } : {}
520
554
  };
521
555
  }
@@ -533,35 +567,49 @@ function validateSingleWithdrawAmounts(withdrawAmountStroops, noteStroops) {
533
567
  async function proveSingleWithdrawTransaction(parameters) {
534
568
  return parameters.sdk.proveTransaction(
535
569
  parameters.publicInput,
536
- buildPublicWithdrawLegs(
537
- parameters.tokenAddress,
538
- parameters.withdrawAmountStroops.toString()
570
+ padPublicLegsToLayout(
571
+ parameters.sdk,
572
+ buildPublicWithdrawLegs(
573
+ parameters.tokenAddress,
574
+ parameters.withdrawAmountStroops.toString()
575
+ )
539
576
  ),
540
- [parameters.primaryWithdraw, "dummy"],
541
- parameters.deposits,
577
+ padWithdrawSlotsToLayout(parameters.sdk, [parameters.primaryWithdraw]),
578
+ padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
542
579
  parameters.audit
543
580
  );
544
581
  }
545
582
  function buildPrimaryWithdrawForCoin(parameters) {
546
- const ephemeralPoint = parseEphemeralKeyString(parameters.depositorEphemeralKey);
547
583
  const witness = parameters.sdk.buildWithdrawMerkleWitness(
548
584
  parameters.coin,
549
585
  parameters.state
550
586
  );
587
+ const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
588
+ parameters.privKeyScalarHex
589
+ );
590
+ const ownerPubHex = parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
591
+ parameters.privKeyScalarHex
592
+ );
551
593
  const primaryWithdraw = withdrawObjectFromMerkleWitness2(
552
594
  witness,
553
- leafEphemeralCoords(ephemeralPoint.xHex, ephemeralPoint.yHex),
554
- parameters.applicationId
595
+ ownerPubHex,
596
+ parameters.applicationId,
597
+ privKeyScalar
555
598
  );
556
599
  return { witness, primaryWithdraw };
557
600
  }
558
601
  async function prepareSingleWithdrawProofInputs(parameters) {
559
- const noteStroops = BigInt(parameters.coin.value);
560
602
  const changeStroops = validateSingleWithdrawAmounts(
561
603
  parameters.withdrawAmountStroops,
562
- noteStroops
604
+ BigInt(parameters.coin.value)
563
605
  );
564
- const { witness, primaryWithdraw } = buildPrimaryWithdrawForCoin(parameters);
606
+ const { witness, primaryWithdraw } = buildPrimaryWithdrawForCoin({
607
+ sdk: parameters.sdk,
608
+ applicationId: parameters.applicationId,
609
+ coin: parameters.coin,
610
+ state: parameters.state,
611
+ privKeyScalarHex: parameters.privKeyScalarHex
612
+ });
565
613
  const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
566
614
  changeStroops,
567
615
  changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
@@ -572,18 +620,19 @@ async function prepareSingleWithdrawProofInputs(parameters) {
572
620
  stateRoot: witness.stateRoot,
573
621
  destinationStellarAddress: parameters.destinationStellarAddress,
574
622
  privKeyScalarHex: parameters.privKeyScalarHex,
575
- tokenAddress: parameters.tokenAddress
576
- });
577
- const audit = buildPoolTransactionAuditParameters({
578
- applicationId: parameters.applicationId,
579
- ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
623
+ tokenAddress: parameters.tokenAddress,
624
+ publicWithdrawalAmount: parameters.withdrawAmountStroops.toString()
580
625
  });
581
626
  return {
582
627
  primaryWithdraw,
583
628
  deposits,
584
629
  changeCoin,
585
630
  publicInput,
586
- audit
631
+ audit: buildPoolTransactionAuditParameters({
632
+ applicationId: parameters.applicationId,
633
+ nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
634
+ ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
635
+ })
587
636
  };
588
637
  }
589
638
  async function proveWithdrawTransact(parameters) {
@@ -599,12 +648,11 @@ async function proveWithdrawTransact(parameters) {
599
648
  });
600
649
  return {
601
650
  ...proof,
602
- applicationIdsPlaintext: [
603
- parameters.applicationId,
604
- "0",
605
- changeCoin ? parameters.applicationId : "0",
606
- "0"
607
- ],
651
+ applicationIdsPlaintext: buildApplicationIdHints({
652
+ sdk: parameters.sdk,
653
+ inputIds: [parameters.applicationId],
654
+ outputIds: [changeCoin ? parameters.applicationId : "0"]
655
+ }),
608
656
  ...changeCoin ? { changeCoin } : {}
609
657
  };
610
658
  }
@@ -612,33 +660,146 @@ async function proveWithdrawTransactDual(parameters) {
612
660
  const { publicInput, audit, withdrawLegs, deposits, changeCoin } = await prepareDualWithdrawProofInputs(parameters);
613
661
  const proof = await parameters.sdk.proveTransaction(
614
662
  publicInput,
615
- buildPublicWithdrawLegs(
616
- parameters.tokenAddress,
617
- parameters.withdrawAmountStroops.toString()
663
+ padPublicLegsToLayout(
664
+ parameters.sdk,
665
+ buildPublicWithdrawLegs(
666
+ parameters.tokenAddress,
667
+ parameters.withdrawAmountStroops.toString()
668
+ )
618
669
  ),
619
- withdrawLegs,
620
- deposits,
670
+ padWithdrawSlotsToLayout(parameters.sdk, withdrawLegs),
671
+ padDepositSlotsToLayout(parameters.sdk, deposits),
621
672
  audit
622
673
  );
623
674
  return {
624
675
  ...proof,
625
- applicationIdsPlaintext: [
626
- audit.applicationId,
627
- audit.applicationId,
628
- changeCoin ? audit.applicationId : "0",
629
- "0"
630
- ],
676
+ applicationIdsPlaintext: buildApplicationIdHints({
677
+ sdk: parameters.sdk,
678
+ inputIds: [audit.applicationId, audit.applicationId],
679
+ outputIds: [changeCoin ? audit.applicationId : "0"]
680
+ }),
631
681
  ...changeCoin ? { changeCoin } : {}
632
682
  };
633
683
  }
634
684
 
635
685
  // src/transact/pool/service.ts
636
686
  import "buffer";
637
- import { PrivacyPoolSDK as PrivacyPoolSdkClass } from "@auditable/privacy-pool-zk-sdk";
687
+
688
+ // src/transact/zk/circuit-config.ts
689
+ import {
690
+ BundledZkCircuit
691
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
692
+
693
+ // src/transact/environment/zk-config-nonce.ts
694
+ var STANDARD_ZK_CONFIG_NONCE = 0n;
695
+ var COMMITMENT_V2_ZK_NONCE = 2n;
696
+ var BINDING_ZK_NONCE = 3n;
697
+ var SIX_BY_SIX_ZK_NONCE = 6n;
698
+ var SIX_BY_SIX_BINDING_ZK_NONCE = 7n;
699
+ var DEFAULT_ZK_CONFIG_NONCE = BINDING_ZK_NONCE;
700
+ function resolveZkConfigNonce(transactEnvironment) {
701
+ return transactEnvironment.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
702
+ }
703
+
704
+ // src/transact/zk/circuit-config.ts
705
+ import { BundledZkCircuit as BundledZkCircuit2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
706
+ var DEFAULT_STELLAR_ZK_CIRCUITS = {
707
+ [BINDING_ZK_NONCE.toString()]: {
708
+ nIns: 2,
709
+ nOuts: 2,
710
+ publicNInputs: 1,
711
+ publicNOutputs: 1,
712
+ circuit: BundledZkCircuit.TwoByTwo
713
+ },
714
+ [SIX_BY_SIX_BINDING_ZK_NONCE.toString()]: {
715
+ nIns: 6,
716
+ nOuts: 6,
717
+ publicNInputs: 1,
718
+ publicNOutputs: 1,
719
+ circuit: BundledZkCircuit.SixBySix
720
+ }
721
+ };
722
+ function isBundledDefinition(definition) {
723
+ return "circuit" in definition;
724
+ }
725
+ async function fetchBuffer(url) {
726
+ const response = await fetch(url);
727
+ if (!response.ok) {
728
+ throw new Error(`Failed to fetch ZK artifact ${url}: ${String(response.status)}`);
729
+ }
730
+ return response.arrayBuffer();
731
+ }
732
+ async function materializeDefinition(definition) {
733
+ if (isBundledDefinition(definition)) {
734
+ const bundled = {
735
+ nIns: definition.nIns,
736
+ nOuts: definition.nOuts,
737
+ publicNInputs: definition.publicNInputs,
738
+ publicNOutputs: definition.publicNOutputs,
739
+ circuit: definition.circuit
740
+ };
741
+ return bundled;
742
+ }
743
+ const [zkey, circuitGraph, r1cs, provingKey] = await Promise.all([
744
+ fetchBuffer(definition.zkeyUrl),
745
+ fetchBuffer(definition.circuitGraphUrl),
746
+ fetchBuffer(definition.r1csUrl),
747
+ fetchBuffer(definition.provingKeyUrl)
748
+ ]);
749
+ const custom = {
750
+ nIns: definition.nIns,
751
+ nOuts: definition.nOuts,
752
+ publicNInputs: definition.publicNInputs,
753
+ publicNOutputs: definition.publicNOutputs,
754
+ zkey,
755
+ circuitGraph,
756
+ r1cs,
757
+ provingKey
758
+ };
759
+ return custom;
760
+ }
761
+ async function materializeSelectedZkCircuit(circuits, nonce) {
762
+ const map = stellarCircuitsOrDefault(circuits);
763
+ const key = nonce.toString();
764
+ const definition = Object.entries(map).find(([nonceKey]) => nonceKey === key)?.[1];
765
+ if (!definition) {
766
+ throw new Error(`no zk circuit configured for nonce ${key}`);
767
+ }
768
+ return { [key]: await materializeDefinition(definition) };
769
+ }
770
+ function stellarCircuitsOrDefault(circuits) {
771
+ return circuits ?? DEFAULT_STELLAR_ZK_CIRCUITS;
772
+ }
773
+ function optionalZkArtifactBaseUrl(value) {
774
+ if (value === void 0) {
775
+ return {};
776
+ }
777
+ const trimmed = value.trim();
778
+ if (trimmed === "") {
779
+ return {};
780
+ }
781
+ let withoutSlash = trimmed;
782
+ while (withoutSlash.endsWith("/")) {
783
+ withoutSlash = withoutSlash.slice(0, -1);
784
+ }
785
+ return { zkArtifactBaseUrl: withoutSlash };
786
+ }
638
787
 
639
788
  // src/transact/pool/aligned-deposit.ts
640
- import { PrivacyPoolSDK, scalarHexToFrDecimal } from "@auditable/privacy-pool-zk-sdk";
789
+ import {
790
+ PrivacyPoolSDK,
791
+ scalarHexToFrDecimal
792
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
641
793
  var SAMPLE_SCALAR_ATTEMPTS = 10;
794
+ function escrowDepositFields(parameters) {
795
+ if (!parameters.recipientHi || !parameters.recipientLo) {
796
+ return {};
797
+ }
798
+ return {
799
+ ...parameters.escrowNonce ? { escrowNonce: parameters.escrowNonce } : {},
800
+ recipientStellar: [parameters.recipientHi, parameters.recipientLo]
801
+ };
802
+ }
642
803
  function sampleValidDepositScalarHex() {
643
804
  for (let index = 0; index < SAMPLE_SCALAR_ATTEMPTS; index++) {
644
805
  const candidate = PrivacyPoolSDK.generateRandomScalarHex32();
@@ -654,17 +815,12 @@ function sampleValidDepositScalarHex() {
654
815
  async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
655
816
  const privateAddressPoint = decodePrivateAddress(parameters.privateAddressStpl1);
656
817
  const scalarHex = sampleValidDepositScalarHex();
657
- const shared = sdk.ecdhSharedKey(
658
- scalarHex,
659
- privateAddressPoint.x,
660
- privateAddressPoint.y
661
- );
662
818
  const [assetHi, assetLo] = tokenAddressToAssetLeg(parameters.tokenAddress);
663
819
  const resolvedApplicationId = resolvePoolApplicationId(applicationId);
664
- const generated = sdk.generateCoinForDepositWithSharedHex(
820
+ const generated = sdk.generateCoinForDepositWithOwnerPubHex(
665
821
  scalarHex,
666
- shared.x,
667
- shared.y,
822
+ privateAddressPoint.x,
823
+ privateAddressPoint.y,
668
824
  parameters.amountStroops,
669
825
  assetHi,
670
826
  assetLo,
@@ -679,27 +835,34 @@ async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
679
835
  ephemeralKeyScalar: scalarHexToFrDecimal(scalarHex),
680
836
  asset: [generated.coin.asset_hi, generated.coin.asset_lo],
681
837
  applicationId: resolvedApplicationId,
682
- recipientPublicKeys
838
+ recipientPublicKeys,
839
+ ...escrowDepositFields(parameters)
683
840
  };
684
841
  return {
685
842
  deposit,
686
843
  commitment_hex: generated.commitment_hex,
687
844
  coin: generated.coin,
688
845
  depositScalarHex: scalarHex,
689
- precommitementHex: generated.precommitement_hex
846
+ precommitementHex: generated.precommitementHex
690
847
  };
691
848
  }
692
849
 
693
850
  // src/transact/pool/service.ts
694
851
  var PrivacyPoolService = class {
695
- constructor(assets, applicationId, auditPublicKey) {
852
+ constructor(assets, applicationId, auditPublicKey, zkCircuits, zkConfigNonce, zkArtifactBaseUrl) {
696
853
  this.assets = assets;
697
854
  this.applicationId = applicationId;
698
855
  this.auditPublicKey = auditPublicKey;
856
+ this.zkCircuits = zkCircuits;
857
+ this.zkConfigNonce = zkConfigNonce;
858
+ this.zkArtifactBaseUrl = zkArtifactBaseUrl;
699
859
  }
700
860
  assets;
701
861
  applicationId;
702
862
  auditPublicKey;
863
+ zkCircuits;
864
+ zkConfigNonce;
865
+ zkArtifactBaseUrl;
703
866
  sdk = void 0;
704
867
  initPromise = void 0;
705
868
  async ensureInit() {
@@ -715,10 +878,16 @@ var PrivacyPoolService = class {
715
878
  "PrivacyPoolService requires browser ZK assets before initialization."
716
879
  );
717
880
  }
718
- this.sdk = await PrivacyPoolSdkClass.init({
881
+ const zkConfigNonce = this.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
882
+ const zkCircuits = await materializeSelectedZkCircuit(
883
+ this.zkCircuits,
884
+ zkConfigNonce
885
+ );
886
+ this.sdk = await PrivacyPoolSDK2.init({
719
887
  wasmBinary: this.assets.sdkWasm,
720
- circuitWasm: this.assets.circuitWasm,
721
- zkey: this.assets.provingKey
888
+ zkCircuits,
889
+ zkConfigNonce,
890
+ ...optionalZkArtifactBaseUrl(this.zkArtifactBaseUrl)
722
891
  });
723
892
  })();
724
893
  return this.initPromise;
@@ -736,22 +905,17 @@ var PrivacyPoolService = class {
736
905
  getApplicationId() {
737
906
  return resolvePoolApplicationId(this.applicationId);
738
907
  }
739
- async generatePrivateAddressFromStellarSignature(signature) {
740
- await this.ensureInit();
741
- if (!this.sdk) {
742
- throw new Error("SDK not initialized");
743
- }
744
- return privateAddressSdk(this.sdk).generatePrivateAddressFromStellarSignature(
745
- signature
908
+ async generatePrivateAddressFromStellarSignature(signature, domain) {
909
+ const sdk = await this.getInitializedSdk();
910
+ return privateAddressSdk(sdk).generatePrivateAddressFromStellarSignature(
911
+ signature,
912
+ domain
746
913
  );
747
914
  }
748
915
  async sharedSecretX(recipientScalarHex, ephemeralKeyEncoded) {
749
- await this.ensureInit();
750
- if (!this.sdk) {
751
- throw new Error("SDK not initialized");
752
- }
916
+ const sdk = await this.getInitializedSdk();
753
917
  const ephemeralKey = decodeDecodedEphemeralKey(ephemeralKeyEncoded);
754
- const shared = this.sdk.sharedSecretFromRecipientPreimage({
918
+ const shared = sdk.sharedSecretFromRecipientPreimage({
755
919
  recipientScalar: recipientScalarHex,
756
920
  ephemeralKey
757
921
  });
@@ -774,6 +938,7 @@ var PrivacyPoolService = class {
774
938
  const applicationId = this.getApplicationId();
775
939
  const audit = buildPoolTransactionAuditParameters({
776
940
  applicationId,
941
+ nAuditSlots: sdk.getLayout().nAuditSlots,
777
942
  ...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {}
778
943
  });
779
944
  const deposit = {
@@ -787,38 +952,35 @@ var PrivacyPoolService = class {
787
952
  const publicInput = withTokenAddressPublicInputs(
788
953
  {
789
954
  stateRoot,
790
- withdrawAddressHi: "0",
791
- withdrawAddressLo: "0",
792
955
  privKeyScalar: randomFrDecimal253()
793
956
  },
794
957
  parameters.tokenAddress
795
958
  );
796
959
  const proof = await sdk.proveTransaction(
797
960
  publicInput,
798
- buildPublicDepositLegs(parameters.tokenAddress, parameters.coin.value),
799
- ["dummy", "dummy"],
800
- [deposit, "dummy"],
961
+ padPublicLegsToLayout(
962
+ sdk,
963
+ buildPublicDepositLegs(parameters.tokenAddress, parameters.coin.value)
964
+ ),
965
+ padWithdrawSlotsToLayout(sdk, []),
966
+ padDepositSlotsToLayout(sdk, [deposit]),
801
967
  audit
802
968
  );
803
- const applicationIdsPlaintext = [
804
- "0",
805
- "0",
806
- applicationId,
807
- "0"
808
- ];
969
+ const applicationIdsPlaintext = buildApplicationIdHints({
970
+ sdk,
971
+ inputIds: [],
972
+ outputIds: [applicationId]
973
+ });
809
974
  return { ...proof, applicationIdsPlaintext };
810
975
  }
811
- async calculateNullifierHash(nullifier) {
976
+ async calculateNullifierHash(nullifier, privKeyScalar) {
812
977
  const sdk = await this.getInitializedSdk();
813
- return sdk.calculateNullifierHash(nullifier);
978
+ return sdk.calculateNullifierHash(nullifier, privKeyScalar);
814
979
  }
815
980
  async prepareWithdrawTransactProof(parameters) {
816
- await this.ensureInit();
817
- if (!this.sdk) {
818
- throw new Error("SDK not initialized");
819
- }
981
+ const sdk = await this.getInitializedSdk();
820
982
  return proveWithdrawTransact({
821
- sdk: this.sdk,
983
+ sdk,
822
984
  applicationId: this.getApplicationId(),
823
985
  buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
824
986
  ...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
@@ -826,12 +988,9 @@ var PrivacyPoolService = class {
826
988
  });
827
989
  }
828
990
  async prepareWithdrawTransactProofDual(parameters) {
829
- await this.ensureInit();
830
- if (!this.sdk) {
831
- throw new Error("SDK not initialized");
832
- }
991
+ const sdk = await this.getInitializedSdk();
833
992
  return proveWithdrawTransactDual({
834
- sdk: this.sdk,
993
+ sdk,
835
994
  applicationId: this.getApplicationId(),
836
995
  buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
837
996
  ...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
@@ -854,7 +1013,10 @@ function createPrivacyPoolService(input) {
854
1013
  return new PrivacyPoolService(
855
1014
  input?.assets,
856
1015
  input?.applicationId,
857
- input?.auditPublicKey
1016
+ input?.auditPublicKey,
1017
+ input?.zkCircuits,
1018
+ input?.zkConfigNonce,
1019
+ input?.zkArtifactBaseUrl
858
1020
  );
859
1021
  }
860
1022
  var configuredPrivacyPoolService;
@@ -870,146 +1032,476 @@ function getPrivacyPoolService() {
870
1032
  return configuredPrivacyPoolService;
871
1033
  }
872
1034
 
873
- // src/transact/assets/load-browser.ts
874
- async function loadStellarBrowserAssets(input) {
875
- const cacheKey = input.cacheBust ? `?v=${Date.now()}` : "";
876
- const [sdkWasm, circuitWasm, provingKey] = await Promise.all([
877
- fetch(`${input.sdkWasmUrl}${cacheKey}`).then((response) => response.arrayBuffer()),
878
- fetch(input.circuitWasmUrl).then((response) => response.arrayBuffer()),
879
- fetch(input.provingKeyUrl).then((response) => response.arrayBuffer())
880
- ]);
881
- return { sdkWasm, circuitWasm, provingKey };
882
- }
883
- async function loadDefaultStellarBrowserAssets(options) {
884
- await import("@auditable/privacy-pool-zk-sdk");
885
- const sdkWasmUrl = new URL("@auditable/privacy-pool-zk-sdk/sdk.wasm", import.meta.url).href;
886
- const circuitWasmUrl = new URL(
887
- "@auditable/privacy-pool-zk-sdk/witness.wasm",
888
- import.meta.url
889
- ).href;
890
- const provingKeyUrl = new URL(
891
- "@auditable/privacy-pool-zk-sdk/main.zkey",
892
- import.meta.url
893
- ).href;
894
- return loadStellarBrowserAssets({
895
- sdkWasmUrl,
896
- circuitWasmUrl,
897
- provingKeyUrl,
898
- ...options?.cacheBust ? { cacheBust: true } : {}
899
- });
1035
+ // src/transact/escrow/tag-challenge-message.ts
1036
+ function buildBlindedRecipientTagChallengeMessage(fields) {
1037
+ return [
1038
+ "Arcane privacy layer: issue your blinded recipient tags.",
1039
+ "",
1040
+ `Wallet: ${fields.stellarAddress}`,
1041
+ `Network: ${fields.networkPassphrase}`,
1042
+ `Issued: ${fields.issuedAt}`,
1043
+ `Expires: ${fields.expiresAt}`,
1044
+ `Nonce: ${fields.nonce}`,
1045
+ "",
1046
+ "This signature proves you control the wallet. It is the same kind of signed challenge used to derive your private-note spend key."
1047
+ ].join("\n");
900
1048
  }
901
1049
 
902
- // src/transact/onboarding/build-payload.ts
903
- import { Buffer as Buffer9 } from "buffer";
904
- import { PrivacyPoolSDK as PrivacyPoolSDK4 } from "@auditable/privacy-pool-zk-sdk";
1050
+ // src/transact/escrow/derived-escrow-recipient.ts
1051
+ import { Buffer as Buffer8 } from "buffer";
1052
+ import { StrKey as StrKey4 } from "@stellar/stellar-sdk";
1053
+ import {
1054
+ derivedEscrowKey,
1055
+ ed25519PubkeyPayloadHexToWithdrawFrDecimals as ed25519PubkeyPayloadHexToWithdrawFrDecimals2,
1056
+ sampleDerivedEscrowKey
1057
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1058
+ var COORDINATE_HEX_LENGTH = 64;
1059
+ function stellarAccountToFieldLimbs(stellarAddress) {
1060
+ const pkRaw = StrKey4.decodeEd25519PublicKey(stellarAddress.trim());
1061
+ const pkHex = Buffer8.from(pkRaw).toString("hex");
1062
+ const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals2(pkHex);
1063
+ return { recipientHi: hi, recipientLo: lo };
1064
+ }
1065
+ function padCoordinateHex(value) {
1066
+ return value.replace(/^0x/iu, "").padStart(COORDINATE_HEX_LENGTH, "0");
1067
+ }
1068
+ async function deriveEscrowRecipientFromStellarAddress(input) {
1069
+ const recipientStellarAddress = input.recipientStellarAddress.trim();
1070
+ if (!StrKey4.isValidEd25519PublicKey(recipientStellarAddress)) {
1071
+ throw new Error("Escrow recipient must be a Stellar G-address.");
1072
+ }
1073
+ const { recipientHi, recipientLo } = stellarAccountToFieldLimbs(
1074
+ recipientStellarAddress
1075
+ );
1076
+ const deriveKey = input.deriveKey ?? derivedEscrowKey;
1077
+ let nonceDecimal;
1078
+ let key;
1079
+ if (input.nonceDecimal) {
1080
+ nonceDecimal = input.nonceDecimal;
1081
+ key = await deriveKey(
1082
+ BigInt(nonceDecimal),
1083
+ BigInt(recipientHi),
1084
+ BigInt(recipientLo)
1085
+ );
1086
+ } else {
1087
+ const sampled = await sampleDerivedEscrowKey(
1088
+ BigInt(recipientHi),
1089
+ BigInt(recipientLo)
1090
+ );
1091
+ nonceDecimal = sampled.nonce.toString();
1092
+ key = sampled.key;
1093
+ }
1094
+ return {
1095
+ nonceDecimal,
1096
+ recipientHi,
1097
+ recipientLo,
1098
+ recipientStellarAddress,
1099
+ privateAddressStpl1: encodePrivateAddressFromHexCoordinates(
1100
+ padCoordinateHex(key.pointXHex),
1101
+ padCoordinateHex(key.pointYHex)
1102
+ ),
1103
+ scalarHex: padCoordinateHex(key.scalarHex)
1104
+ };
1105
+ }
905
1106
 
906
- // src/transact/encoding/fr-decimal-to-bytes.ts
907
- var BN254_SCALAR_MOD = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
908
- var FIELD_BYTE_LENGTH = 32;
909
- var BYTE_MASK = 0xffn;
910
- var BITS_PER_BYTE = 8n;
911
- function frDecimalToPaddedBytes32(decimal) {
912
- let value = BigInt(decimal.trim());
913
- value = (value % BN254_SCALAR_MOD + BN254_SCALAR_MOD) % BN254_SCALAR_MOD;
914
- const bytes = Buffer.alloc(FIELD_BYTE_LENGTH);
915
- for (let index = FIELD_BYTE_LENGTH - 1; index >= 0; index -= 1) {
916
- bytes[index] = Number(value & BYTE_MASK);
917
- value >>= BITS_PER_BYTE;
1107
+ // src/transact/escrow/assert-escrow-sweep-claimant.ts
1108
+ import { insufficientStateError } from "@arcanetech/privacy-sdk-core";
1109
+ function assertEscrowSweepClaimant(input) {
1110
+ const walletPublicKey = input.walletPublicKey.trim();
1111
+ const claimantAddress = input.claimantAddress.trim();
1112
+ if (!walletPublicKey || walletPublicKey !== claimantAddress) {
1113
+ const error = insufficientStateError(
1114
+ "escrow_sweep_claimant_mismatch",
1115
+ "Escrow sweep requires the connected account that owns the note.",
1116
+ { walletPublicKey, claimantAddress }
1117
+ );
1118
+ throw new Error(error.message, { cause: error });
918
1119
  }
919
- return bytes;
920
1120
  }
921
1121
 
922
- // src/transact/onboarding/recipient.ts
923
- import { PrivacyPoolSDK as PrivacyPoolSDK3 } from "@auditable/privacy-pool-zk-sdk";
924
- var COORDINATE_HEX_LENGTH = 64;
925
- async function generateTemporaryRecipientPrivateAddress() {
926
- await getPrivacyPoolService().getInitializedSdk();
927
- const temporaryScalarHex = PrivacyPoolSDK3.generateRandomScalarHex32();
928
- const sdk = await getPrivacyPoolService().getInitializedSdk();
929
- const point = sdk.ecdhEphemeralPublicKeyFromScalarHex(temporaryScalarHex);
930
- const publicKeyXHex = point.x.padStart(COORDINATE_HEX_LENGTH, "0");
931
- const publicKeyYHex = point.y.padStart(COORDINATE_HEX_LENGTH, "0");
1122
+ // src/transact/escrow/reconstruct-escrow-note.ts
1123
+ var FIELD_HEX_LENGTH = 64;
1124
+ function hexToDecimal(hex) {
1125
+ const clean = hex.trim().replace(/^0x/u, "");
1126
+ return BigInt(`0x${clean || "0"}`).toString();
1127
+ }
1128
+ function padFieldHex(value) {
1129
+ return value.replace(/^0x/iu, "").padStart(FIELD_HEX_LENGTH, "0");
1130
+ }
1131
+ async function defaultDecryptOutputNote(input) {
1132
+ const module = await import("@arcanetech/stellar-privacy-pool-zk-sdk");
1133
+ if (typeof module.decryptOutputNoteEvent !== "function") {
1134
+ throw new TypeError("Output note decryption is not available.");
1135
+ }
1136
+ return module.decryptOutputNoteEvent(input);
1137
+ }
1138
+ async function reconstructEscrowNote(input) {
1139
+ const derived = await deriveEscrowRecipientFromStellarAddress({
1140
+ recipientStellarAddress: input.claimantAddress,
1141
+ nonceDecimal: input.nonceDecimal,
1142
+ ...input.deriveKey ? { deriveKey: input.deriveKey } : {}
1143
+ });
1144
+ const event = input.events.find((entry) => entry.outputIndex === input.seq);
1145
+ if (!event) {
1146
+ throw new Error("Escrow output note event was not found for this sequence.");
1147
+ }
1148
+ const decrypt = input.decrypt ?? defaultDecryptOutputNote;
1149
+ const decrypted = await decrypt({
1150
+ recipientScalarHex: derived.scalarHex,
1151
+ commitmentHashHex: event.commitmentHashHex,
1152
+ createdEphemeralKey: event.createdEphemeralKey,
1153
+ ciphertext: event.ciphertext,
1154
+ tag: event.tag,
1155
+ ownerMode: 1n
1156
+ });
932
1157
  return {
933
- temporaryScalarHex,
934
- temporaryPrivateAddressStpl1: encodePrivateAddressFromHexCoordinates(
935
- publicKeyXHex,
936
- publicKeyYHex
937
- )
1158
+ coin: {
1159
+ value: decrypted.value,
1160
+ nullifier: decrypted.nullifier,
1161
+ secret: decrypted.secret,
1162
+ commitment: hexToDecimal(decrypted.commitmentHex),
1163
+ asset_hi: decrypted.assetHi,
1164
+ asset_lo: decrypted.assetLo,
1165
+ application_id: decrypted.applicationId
1166
+ },
1167
+ scalarHex: derived.scalarHex,
1168
+ privateAddressStpl1: derived.privateAddressStpl1,
1169
+ recipientHi: derived.recipientHi,
1170
+ recipientLo: derived.recipientLo,
1171
+ nonceDecimal: derived.nonceDecimal,
1172
+ tokenAddress: assetLegToTokenAddress(decrypted.assetHi, decrypted.assetLo),
1173
+ commitmentHex: padFieldHex(decrypted.commitmentHex)
938
1174
  };
939
1175
  }
940
1176
 
941
- // src/transact/onboarding/build-payload.ts
942
- var COORDINATE_HEX_LENGTH2 = 64;
943
- function noneOptionalRegistration() {
944
- return { tag: "None", values: void 0 };
1177
+ // src/transact/escrow/prepare-escrow-sweep.ts
1178
+ import { StrKey as StrKey5 } from "@stellar/stellar-sdk";
1179
+ var PRIVATE_DISCLOSURE = {
1180
+ senderAddress: "private",
1181
+ recipientAddress: "private",
1182
+ assetAddress: "private",
1183
+ amount: "private"
1184
+ };
1185
+ function requireRegisteredPrivateAddress(value) {
1186
+ const trimmed = value.trim();
1187
+ if (!trimmed || StrKey5.isValidEd25519PublicKey(trimmed)) {
1188
+ throw new Error("Escrow sweep recipient must be a registered private address.");
1189
+ }
1190
+ return trimmed;
945
1191
  }
946
- function coinToPlaintextNote(coin) {
947
- const [assetHi, assetLo] = tokenAddressToAssetLeg(coin.tokenAddress);
1192
+ function consumedEscrowRecord(input) {
948
1193
  return {
949
- asset_hi: frDecimalToPaddedBytes32(assetHi),
950
- asset_lo: frDecimalToPaddedBytes32(assetLo),
951
- deposited_ephemeral_scalar: void 0,
952
- nullifier: frDecimalToPaddedBytes32(coin.nullifier),
953
- secret: frDecimalToPaddedBytes32(coin.secret),
954
- value: BigInt(coin.value)
1194
+ id: input.reconstructed.commitmentHex,
1195
+ owner: input.walletPublicKey,
1196
+ asset: input.asset,
1197
+ amount: BigInt(input.reconstructed.coin.value),
1198
+ consumed: false,
1199
+ status: "finalized",
1200
+ poolContract: input.poolContract,
1201
+ coinNote: input.reconstructed.coin,
1202
+ privateAddress: input.reconstructed.privateAddressStpl1,
1203
+ commitmentHex: input.reconstructed.commitmentHex
955
1204
  };
956
1205
  }
957
- async function generateRandomDepositScalarHex() {
958
- await getPrivacyPoolService().getInitializedSdk();
959
- return PrivacyPoolSDK4.generateRandomScalarHex32();
960
- }
961
- function buildOnboardingPayload(parameters) {
962
- const notes = parameters.recipientNotes.map((coin) => coinToPlaintextNote(coin));
963
- const temporaryDecoded = decodePrivateAddress(
964
- parameters.temporaryKey.temporaryPrivateAddressStpl1.trim()
965
- );
966
- let privateAddressRegistration = noneOptionalRegistration();
967
- if (parameters.permanentPrivateAddressStpl1?.trim()) {
968
- const decoded = decodePrivateAddress(
969
- parameters.permanentPrivateAddressStpl1.trim()
970
- );
971
- const registration = {
972
- owner: parameters.ownerStellarAddress.trim(),
973
- public_key_x: Buffer9.from(decoded.x.padStart(COORDINATE_HEX_LENGTH2, "0"), "hex"),
974
- public_key_y: Buffer9.from(decoded.y.padStart(COORDINATE_HEX_LENGTH2, "0"), "hex")
975
- };
976
- privateAddressRegistration = { tag: "Some", values: [registration] };
1206
+ function attachEscrowAuthorization(prepared, escrowAuthorization) {
1207
+ const credential = escrowAuthorization.trim();
1208
+ if (!credential) {
1209
+ throw new Error("Escrow sweep requires a signed authorization entry.");
977
1210
  }
978
1211
  return {
979
- owner: parameters.ownerStellarAddress.trim(),
980
- temp_public_key_x: Buffer9.from(
981
- temporaryDecoded.x.padStart(COORDINATE_HEX_LENGTH2, "0"),
982
- "hex"
983
- ),
984
- temp_public_key_y: Buffer9.from(
985
- temporaryDecoded.y.padStart(COORDINATE_HEX_LENGTH2, "0"),
986
- "hex"
987
- ),
988
- encrypted_private_key: Buffer9.from(
989
- parameters.temporaryKey.temporaryScalarHex,
990
- "utf8"
991
- ),
992
- notes: { notes },
993
- private_address_registration: privateAddressRegistration
1212
+ ...prepared,
1213
+ transactArtifacts: {
1214
+ ...prepared.transactArtifacts,
1215
+ escrowAuthorization: credential
1216
+ }
994
1217
  };
995
1218
  }
996
- async function buildTransferOnboardingAtExecute(input) {
997
- return buildOnboardingPayload({
998
- ownerStellarAddress: input.ownerStellarAddress,
999
- temporaryKey: {
1000
- temporaryScalarHex: input.temporaryRecipientKey.temporaryScalarHex,
1001
- temporaryPrivateAddressStpl1: input.temporaryRecipientKey.temporaryPrivateAddressStpl1
1219
+ function sweepTransactArtifacts(input) {
1220
+ return {
1221
+ spendSource: "escrow",
1222
+ escrowRecipient: input.claimantAddress.trim(),
1223
+ escrowSpendScalarHex: input.reconstructed.scalarHex,
1224
+ escrowClaimantLimbs: {
1225
+ recipientHi: input.reconstructed.recipientHi,
1226
+ recipientLo: input.reconstructed.recipientLo,
1227
+ nonceDecimal: input.reconstructed.nonceDecimal
1002
1228
  },
1003
- recipientNotes: [input.recipientNote]
1004
- });
1229
+ executeFinalizeRequired: true,
1230
+ walletPublicKey: input.walletPublicKey
1231
+ };
1005
1232
  }
1006
-
1007
- // src/transact/kyt/inspect-error.ts
1008
- var KytInspectError = class extends Error {
1009
- reasonCode;
1010
- decisionId;
1011
- detailAddress;
1012
- constructor(parameters) {
1233
+ function prepareEscrowSweepOperation(input) {
1234
+ assertEscrowSweepClaimant({
1235
+ walletPublicKey: input.walletPublicKey,
1236
+ claimantAddress: input.claimantAddress
1237
+ });
1238
+ const walletPublicKey = input.walletPublicKey.trim();
1239
+ const registeredPrivateAddress = requireRegisteredPrivateAddress(
1240
+ input.registeredPrivateAddress
1241
+ );
1242
+ const amount = BigInt(input.reconstructed.coin.value);
1243
+ return {
1244
+ kind: "transfer",
1245
+ intent: {
1246
+ from: input.reconstructed.privateAddressStpl1,
1247
+ to: registeredPrivateAddress,
1248
+ asset: input.asset,
1249
+ amount,
1250
+ disclosure: PRIVATE_DISCLOSURE
1251
+ },
1252
+ consumedRecords: [
1253
+ consumedEscrowRecord({
1254
+ reconstructed: input.reconstructed,
1255
+ walletPublicKey,
1256
+ poolContract: input.poolContract,
1257
+ asset: input.asset
1258
+ })
1259
+ ],
1260
+ outputRecords: [],
1261
+ submissionPayload: { operationId: crypto.randomUUID(), signed: false },
1262
+ transactArtifacts: sweepTransactArtifacts({
1263
+ claimantAddress: input.claimantAddress,
1264
+ reconstructed: input.reconstructed,
1265
+ walletPublicKey
1266
+ })
1267
+ };
1268
+ }
1269
+
1270
+ // src/transact/escrow/fetch-output-note-events.ts
1271
+ import { Api } from "@stellar/stellar-sdk/rpc";
1272
+
1273
+ // src/rpc/soroban-transaction-meta.ts
1274
+ import { Address, StrKey as StrKey6 } from "@stellar/stellar-sdk";
1275
+ var TRANSACTION_META_SWITCH_SOROBAN_V3 = 3;
1276
+ var TRANSACTION_META_SWITCH_SOROBAN_V4 = 4;
1277
+ function pushSorobanV3ContractEvents(out, meta) {
1278
+ const soroban = meta.v3().sorobanMeta();
1279
+ if (!soroban) {
1280
+ return;
1281
+ }
1282
+ for (const event of soroban.events()) {
1283
+ out.push(event);
1284
+ }
1285
+ }
1286
+ function pushSorobanV4ContractEvents(out, meta) {
1287
+ const v4 = meta.v4();
1288
+ for (const txEvent of v4.events()) {
1289
+ out.push(txEvent.event());
1290
+ }
1291
+ for (const op of v4.operations()) {
1292
+ for (const event of op.events()) {
1293
+ out.push(event);
1294
+ }
1295
+ }
1296
+ }
1297
+ function collectContractEventsFromMeta(meta) {
1298
+ const out = [];
1299
+ const code = meta.switch();
1300
+ if (code === TRANSACTION_META_SWITCH_SOROBAN_V3) {
1301
+ pushSorobanV3ContractEvents(out, meta);
1302
+ }
1303
+ if (code === TRANSACTION_META_SWITCH_SOROBAN_V4) {
1304
+ pushSorobanV4ContractEvents(out, meta);
1305
+ }
1306
+ return out;
1307
+ }
1308
+
1309
+ // src/rpc/server.ts
1310
+ import { rpc } from "@stellar/stellar-sdk";
1311
+ function createStellarRpcServer(rpcUrl) {
1312
+ return new rpc.Server(rpcUrl.trim(), { allowHttp: true });
1313
+ }
1314
+
1315
+ // src/transact/escrow/parse-output-note-events.ts
1316
+ import { StrKey as StrKey7 } from "@stellar/stellar-sdk";
1317
+ var FIELD_BYTE_LENGTH = 32;
1318
+ var FIELD_HEX_LENGTH2 = 64;
1319
+ var CONTRACT_EVENT_BODY_V0 = 0;
1320
+ var OUTPUT_NOTE_TOPIC_COUNT = 3;
1321
+ function extractSymbol(value) {
1322
+ try {
1323
+ if (value.switch().name === "scvSymbol") {
1324
+ return value.sym().toString();
1325
+ }
1326
+ if (value.switch().name === "scvString") {
1327
+ return value.str().toString();
1328
+ }
1329
+ } catch {
1330
+ return void 0;
1331
+ }
1332
+ return void 0;
1333
+ }
1334
+ function readBytes(value) {
1335
+ if (!value) {
1336
+ return void 0;
1337
+ }
1338
+ try {
1339
+ if (value.switch().name !== "scvBytes") {
1340
+ return void 0;
1341
+ }
1342
+ return Buffer.from(value.bytes());
1343
+ } catch {
1344
+ return void 0;
1345
+ }
1346
+ }
1347
+ function readU32(value) {
1348
+ if (!value) {
1349
+ return void 0;
1350
+ }
1351
+ try {
1352
+ if (value.switch().name !== "scvU32") {
1353
+ return void 0;
1354
+ }
1355
+ return value.u32();
1356
+ } catch {
1357
+ return void 0;
1358
+ }
1359
+ }
1360
+ function fieldHex(bytes) {
1361
+ return bytes.toString("hex").padStart(FIELD_HEX_LENGTH2, "0");
1362
+ }
1363
+ function ciphertextLimbs(bytes) {
1364
+ if (bytes.length === 0 || bytes.length % FIELD_BYTE_LENGTH !== 0) {
1365
+ return [];
1366
+ }
1367
+ const limbs = [];
1368
+ for (let offset = 0; offset < bytes.length; offset += FIELD_BYTE_LENGTH) {
1369
+ limbs.push(fieldHex(bytes.subarray(offset, offset + FIELD_BYTE_LENGTH)));
1370
+ }
1371
+ return limbs;
1372
+ }
1373
+ function payloadMap(data) {
1374
+ const entries = /* @__PURE__ */ new Map();
1375
+ try {
1376
+ if (data.switch().name !== "scvMap") {
1377
+ return entries;
1378
+ }
1379
+ const mapped = data.map();
1380
+ if (!mapped) {
1381
+ return entries;
1382
+ }
1383
+ for (const entry of mapped) {
1384
+ const key = extractSymbol(entry.key());
1385
+ if (key) {
1386
+ entries.set(key, entry.val());
1387
+ }
1388
+ }
1389
+ } catch {
1390
+ return entries;
1391
+ }
1392
+ return entries;
1393
+ }
1394
+ function hashToBuffer(value) {
1395
+ return Buffer.isBuffer(value) ? value : void 0;
1396
+ }
1397
+ function eventContractId(event) {
1398
+ try {
1399
+ const contractId = hashToBuffer(event.contractId());
1400
+ if (!contractId) {
1401
+ return void 0;
1402
+ }
1403
+ return StrKey7.encodeContract(contractId);
1404
+ } catch {
1405
+ return void 0;
1406
+ }
1407
+ }
1408
+ function eventMatchesPool(event, poolAddress) {
1409
+ const contractId = eventContractId(event);
1410
+ return contractId === void 0 || contractId === poolAddress.trim();
1411
+ }
1412
+ function outputNoteEventBody(event) {
1413
+ if (event.type().name !== "contract") {
1414
+ return void 0;
1415
+ }
1416
+ const body = event.body();
1417
+ if (body.switch() !== CONTRACT_EVENT_BODY_V0) {
1418
+ return void 0;
1419
+ }
1420
+ return body.v0();
1421
+ }
1422
+ function outputNoteFromPayload(topics, payload) {
1423
+ const commitment = readBytes(topics[2]);
1424
+ const outputIndex = readU32(payload.get("output_index"));
1425
+ const ephemeralX = readBytes(payload.get("ephemeral_x"));
1426
+ const ephemeralY = readBytes(payload.get("ephemeral_y"));
1427
+ const ciphertextBytes = readBytes(payload.get("ciphertext"));
1428
+ const tag = readBytes(payload.get("tag"));
1429
+ const ciphertext = ciphertextBytes ? ciphertextLimbs(ciphertextBytes) : [];
1430
+ if (!commitment || outputIndex === void 0 || !ephemeralX || !ephemeralY || ciphertext.length === 0 || !tag) {
1431
+ return void 0;
1432
+ }
1433
+ return {
1434
+ outputIndex,
1435
+ commitmentHashHex: fieldHex(commitment),
1436
+ createdEphemeralKey: [fieldHex(ephemeralX), fieldHex(ephemeralY)],
1437
+ ciphertext,
1438
+ tag: fieldHex(tag)
1439
+ };
1440
+ }
1441
+ function parseEscrowOutputNoteEvent(event, poolAddress) {
1442
+ if (!eventMatchesPool(event, poolAddress)) {
1443
+ return void 0;
1444
+ }
1445
+ const v0 = outputNoteEventBody(event);
1446
+ const topics = v0?.topics();
1447
+ if (!v0 || !Array.isArray(topics) || topics.length < OUTPUT_NOTE_TOPIC_COUNT) {
1448
+ return void 0;
1449
+ }
1450
+ if (extractSymbol(topics[0]) !== "audit" || extractSymbol(topics[1]) !== "output_note") {
1451
+ return void 0;
1452
+ }
1453
+ return outputNoteFromPayload(topics, payloadMap(v0.data()));
1454
+ }
1455
+
1456
+ // src/transact/escrow/fetch-output-note-events.ts
1457
+ async function fetchEscrowOutputNoteEvents(input) {
1458
+ const txId = input.txId.trim();
1459
+ if (!txId) {
1460
+ throw new Error("Escrow output-note transaction id is missing.");
1461
+ }
1462
+ const response = await createStellarRpcServer(
1463
+ input.transactEnvironment.network.rpcUrl
1464
+ ).getTransaction(txId);
1465
+ if (response.status !== Api.GetTransactionStatus.SUCCESS) {
1466
+ throw new Error("Escrow output-note transaction was not found.");
1467
+ }
1468
+ const meta = response.resultMetaXdr;
1469
+ if (!meta) {
1470
+ return [];
1471
+ }
1472
+ const events = [];
1473
+ for (const event of collectContractEventsFromMeta(meta)) {
1474
+ const parsed = parseEscrowOutputNoteEvent(event, input.poolAddress);
1475
+ if (parsed) {
1476
+ events.push(parsed);
1477
+ }
1478
+ }
1479
+ return events;
1480
+ }
1481
+
1482
+ // src/transact/escrow/simulate-escrow-authorization.ts
1483
+ import {
1484
+ Account,
1485
+ Address as Address3,
1486
+ Contract,
1487
+ nativeToScVal as nativeToScVal2,
1488
+ TransactionBuilder as TransactionBuilder2,
1489
+ rpc as rpc4
1490
+ } from "@stellar/stellar-sdk";
1491
+ import { Buffer as Buffer10 } from "buffer";
1492
+
1493
+ // src/transact/kyt/passage/inspect.ts
1494
+ import {
1495
+ layoutForKnownNonce,
1496
+ zeroBindingTagsInPublicSignals
1497
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1498
+
1499
+ // src/transact/kyt/inspect-error.ts
1500
+ var KytInspectError = class extends Error {
1501
+ reasonCode;
1502
+ decisionId;
1503
+ detailAddress;
1504
+ constructor(parameters) {
1013
1505
  super(parameters.message);
1014
1506
  this.name = "KytInspectError";
1015
1507
  this.reasonCode = parameters.reasonCode;
@@ -1032,18 +1524,6 @@ function parseKytReasonCode(reasonCode) {
1032
1524
  };
1033
1525
  }
1034
1526
 
1035
- // src/contracts/contract-context.ts
1036
- function requireContractContext(environment) {
1037
- if (!environment || !("contractContext" in environment)) {
1038
- throw new Error("Contract context is not configured on the transact environment.");
1039
- }
1040
- const resolved = environment;
1041
- return resolved.contractContext;
1042
- }
1043
- function readPoolClientFactory(environment) {
1044
- return requireContractContext(environment).createPoolClient;
1045
- }
1046
-
1047
1527
  // src/transact/kyt/passage/poll.ts
1048
1528
  import "@stellar/stellar-sdk";
1049
1529
  var KYT_REGISTER_MAX_POLLS = 60;
@@ -1098,20 +1578,20 @@ async function waitForKytRegistration(parameters) {
1098
1578
  }
1099
1579
 
1100
1580
  // src/transact/kyt/passage/submit.ts
1101
- import { Buffer as Buffer10 } from "buffer";
1102
- import { Operation, TransactionBuilder, rpc as rpc2, xdr } from "@stellar/stellar-sdk";
1581
+ import { Buffer as Buffer9 } from "buffer";
1582
+ import { Operation, TransactionBuilder, rpc as rpc3, xdr as xdr3 } from "@stellar/stellar-sdk";
1103
1583
  var KYT_REGISTER_FEE_STROOPS = "1000000";
1104
1584
  var KYT_REGISTER_TIMEOUT_SECONDS = 300;
1105
1585
  function passageIdToScValue(passageId) {
1106
- return xdr.ScVal.scvBytes(Buffer10.from(passageId.replace(/^0x/, ""), "hex"));
1586
+ return xdr3.ScVal.scvBytes(Buffer9.from(passageId.replace(/^0x/, ""), "hex"));
1107
1587
  }
1108
1588
  function approvalSignatureToBytes(signature) {
1109
1589
  const clean = signature.trim();
1110
- return /^(0x)?[0-9a-fA-F]{128}$/.test(clean) ? Buffer10.from(clean.replace(/^0x/i, ""), "hex") : Buffer10.from(clean, "base64");
1590
+ return /^(0x)?[0-9a-fA-F]{128}$/.test(clean) ? Buffer9.from(clean.replace(/^0x/i, ""), "hex") : Buffer9.from(clean, "base64");
1111
1591
  }
1112
1592
  function signatureToScValue(signature) {
1113
1593
  const bytes = approvalSignatureToBytes(signature);
1114
- return xdr.ScVal.scvBytes(bytes);
1594
+ return xdr3.ScVal.scvBytes(bytes);
1115
1595
  }
1116
1596
  async function registerKytPassage(parameters) {
1117
1597
  const signTransaction = parameters.transactEnvironment.signTransaction;
@@ -1121,7 +1601,7 @@ async function registerKytPassage(parameters) {
1121
1601
  );
1122
1602
  }
1123
1603
  const kytRegistry = parameters.transactEnvironment.kyt.kytPassageRegistryContract;
1124
- const server = new rpc2.Server(parameters.sorobanRpcUrl, { allowHttp: true });
1604
+ const server = new rpc3.Server(parameters.sorobanRpcUrl, { allowHttp: true });
1125
1605
  const sourceAccount = await server.getAccount(parameters.owner);
1126
1606
  const transaction = new TransactionBuilder(sourceAccount, {
1127
1607
  fee: KYT_REGISTER_FEE_STROOPS,
@@ -1132,7 +1612,7 @@ async function registerKytPassage(parameters) {
1132
1612
  function: "register_passage",
1133
1613
  args: [
1134
1614
  passageIdToScValue(parameters.approval.passageId),
1135
- xdr.ScVal.scvU32(parameters.approval.expiresAtLedger),
1615
+ xdr3.ScVal.scvU32(parameters.approval.expiresAtLedger),
1136
1616
  signatureToScValue(parameters.approval.signature)
1137
1617
  ]
1138
1618
  })
@@ -1156,8 +1636,8 @@ async function registerKytPassage(parameters) {
1156
1636
  }
1157
1637
 
1158
1638
  // src/transact/kyt/passage/inspect.ts
1159
- function buildApplicationIdHints(applicationId) {
1160
- return [applicationId, applicationId, applicationId, applicationId];
1639
+ function buildApplicationIdHints2(applicationId, nAuditSlots) {
1640
+ return uniformApplicationIdHints(applicationId, nAuditSlots);
1161
1641
  }
1162
1642
  function buildNonce() {
1163
1643
  return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}`;
@@ -1185,36 +1665,61 @@ function throwKytInspectRejected(body) {
1185
1665
  ...parsed.address ? { detailAddress: parsed.address } : {}
1186
1666
  });
1187
1667
  }
1188
- async function requestKytPassageForPoolInteraction(input) {
1189
- const applicationId = resolvePoolApplicationId(
1190
- input.transactEnvironment.network.applicationId
1191
- );
1192
- const applicationIdsPlaintext = input.applicationIdsPlaintext ?? buildApplicationIdHints(applicationId);
1193
- const kytRegistry = input.transactEnvironment.kyt.kytPassageRegistryContract;
1194
- const currentLedger = await fetchCurrentLedger(input.sorobanRpcUrl);
1668
+ function inspectRequestHeaders(inspectAuthorization) {
1669
+ const token = inspectAuthorization?.trim();
1670
+ return {
1671
+ "content-type": "application/json",
1672
+ ...token ? { authorization: `Bearer ${token}` } : {}
1673
+ };
1674
+ }
1675
+ async function postKytInspect(input, applicationIdsPlaintext, zkConfigNonce, currentLedger) {
1195
1676
  const response = await fetch(
1196
1677
  `${input.transactEnvironment.kyt.apiBaseUrl}/kyt/passages/inspect`,
1197
1678
  {
1198
1679
  method: "POST",
1199
- headers: { "content-type": "application/json" },
1680
+ headers: inspectRequestHeaders(
1681
+ input.transactEnvironment.kyt.inspectAuthorization
1682
+ ),
1200
1683
  body: JSON.stringify(
1201
1684
  {
1202
1685
  owner: input.owner,
1203
1686
  poolContract: input.poolContract,
1204
- kytRegistry,
1687
+ kytRegistry: input.transactEnvironment.kyt.kytPassageRegistryContract,
1205
1688
  proofBytes: input.proofHex,
1206
- publicSignalsBytes: input.publicHex,
1689
+ publicSignalsBytes: zeroBindingTagsInPublicSignals(
1690
+ input.publicHex,
1691
+ zkConfigNonce
1692
+ ).toString("hex"),
1207
1693
  applicationIdsPlaintext,
1208
1694
  decryptedAuditSlots: input.decryptedAuditSlots,
1209
- onboarding: input.onboarding,
1210
1695
  nonce: buildNonce(),
1211
- currentLedger
1696
+ zkConfigNonce,
1697
+ currentLedger,
1698
+ ...input.ciphertextHex ? { ciphertextBytes: input.ciphertextHex } : {},
1699
+ ...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {}
1212
1700
  },
1213
1701
  kytJsonReplacer
1214
1702
  )
1215
1703
  }
1216
1704
  );
1217
- const body = await parseInspectResponse(response);
1705
+ return parseInspectResponse(response);
1706
+ }
1707
+ async function requestKytPassageForPoolInteraction(input) {
1708
+ const applicationId = resolvePoolApplicationId(
1709
+ input.transactEnvironment.network.applicationId
1710
+ );
1711
+ const zkConfigNonce = resolveZkConfigNonce(input.transactEnvironment);
1712
+ const applicationIdsPlaintext = input.applicationIdsPlaintext ?? buildApplicationIdHints2(
1713
+ applicationId,
1714
+ layoutForKnownNonce(zkConfigNonce).nAuditSlots
1715
+ );
1716
+ const currentLedger = await fetchCurrentLedger(input.sorobanRpcUrl);
1717
+ const body = await postKytInspect(
1718
+ input,
1719
+ applicationIdsPlaintext,
1720
+ zkConfigNonce,
1721
+ currentLedger
1722
+ );
1218
1723
  if (body.status !== "approved") {
1219
1724
  throwKytInspectRejected(body);
1220
1725
  }
@@ -1230,6 +1735,216 @@ async function requestKytPassageForPoolInteraction(input) {
1230
1735
  return body;
1231
1736
  }
1232
1737
 
1738
+ // src/transact/escrow/kyt-authorization-sc-value.ts
1739
+ import { nativeToScVal } from "@stellar/stellar-sdk";
1740
+ function kytAuthorizationScValue(parameters) {
1741
+ return nativeToScVal(
1742
+ {
1743
+ expiration_ledger: parameters.expirationLedger,
1744
+ signature: parameters.signature
1745
+ },
1746
+ {
1747
+ type: {
1748
+ expiration_ledger: ["symbol", "u32"],
1749
+ signature: ["symbol", "bytes"]
1750
+ }
1751
+ }
1752
+ );
1753
+ }
1754
+
1755
+ // src/transact/escrow/pick-escrow-authorization.ts
1756
+ import { Address as Address2 } from "@stellar/stellar-sdk";
1757
+ function credentialAddress(entry) {
1758
+ try {
1759
+ const credentials = entry.credentials();
1760
+ if (credentials.switch().name !== "sorobanCredentialsAddress") {
1761
+ return void 0;
1762
+ }
1763
+ return Address2.fromScAddress(credentials.address().address()).toString();
1764
+ } catch {
1765
+ return void 0;
1766
+ }
1767
+ }
1768
+ function pickUnsignedEscrowAuthorization(input) {
1769
+ const claimant = input.claimantAddress.trim();
1770
+ const match = input.auth.find((entry) => credentialAddress(entry) === claimant);
1771
+ if (!match) {
1772
+ throw new Error("Simulation did not return a claimant authorization entry.");
1773
+ }
1774
+ return match.toXDR("base64");
1775
+ }
1776
+
1777
+ // src/transact/escrow/simulate-escrow-authorization.ts
1778
+ var SIMULATE_FEE = "100";
1779
+ var SIMULATE_TIMEOUT_SECONDS = 30;
1780
+ var RECORD_NONROOT_AUTH = "record_allow_nonroot";
1781
+ function hexToBytes(hex) {
1782
+ return Buffer10.from(hex.replace(/^0x/iu, ""), "hex");
1783
+ }
1784
+ function optionalSweepCiphertext(artifacts) {
1785
+ return {
1786
+ ...artifacts?.ciphertextHex ? { ciphertextHex: artifacts.ciphertextHex } : {},
1787
+ ...artifacts?.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: artifacts.outputNoteEphemeralScalars } : {}
1788
+ };
1789
+ }
1790
+ function requireSweepArtifacts(prepared) {
1791
+ const artifacts = prepared.transactArtifacts;
1792
+ const proofHex = artifacts?.proofHex?.trim();
1793
+ const publicHex = artifacts?.publicHex?.trim();
1794
+ const escrowRecipient = artifacts?.escrowRecipient?.trim();
1795
+ if (!proofHex || !publicHex || !escrowRecipient) {
1796
+ throw new Error("Prepared sweep is missing proof, public signals, or claimant.");
1797
+ }
1798
+ return {
1799
+ proofHex,
1800
+ publicHex,
1801
+ escrowRecipient,
1802
+ ...optionalSweepCiphertext(artifacts)
1803
+ };
1804
+ }
1805
+ function requireRelayerPublicKey(value) {
1806
+ const relayerPublicKey = value.trim();
1807
+ if (!relayerPublicKey) {
1808
+ throw new Error("Escrow sweep simulation requires the relayer public key.");
1809
+ }
1810
+ return relayerPublicKey;
1811
+ }
1812
+ async function inspectRelayerSweepKyt(input) {
1813
+ const environment = input.transactEnvironment;
1814
+ return requestKytPassageForPoolInteraction({
1815
+ owner: input.relayerPublicKey,
1816
+ poolContract: environment.network.poolContract,
1817
+ proofHex: input.artifacts.proofHex,
1818
+ publicHex: input.artifacts.publicHex,
1819
+ ...input.artifacts.ciphertextHex ? { ciphertextHex: input.artifacts.ciphertextHex } : {},
1820
+ ...input.artifacts.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.artifacts.outputNoteEphemeralScalars } : {},
1821
+ ...input.prepared.transactArtifacts?.applicationIdsPlaintext ? {
1822
+ applicationIdsPlaintext: input.prepared.transactArtifacts.applicationIdsPlaintext
1823
+ } : {},
1824
+ networkPassphrase: environment.network.networkPassphrase,
1825
+ sorobanRpcUrl: environment.network.rpcUrl,
1826
+ transactEnvironment: environment
1827
+ });
1828
+ }
1829
+ async function simulateSweepAuthEntries(input) {
1830
+ const environment = input.transactEnvironment;
1831
+ const server = createStellarRpcServer(environment.network.rpcUrl);
1832
+ const account = await server.getAccount(input.relayerPublicKey);
1833
+ const operation = new Contract(environment.network.poolContract).call(
1834
+ "transact",
1835
+ new Address3(input.relayerPublicKey).toScVal(),
1836
+ nativeToScVal2(resolveZkConfigNonce(environment), { type: "u64" }),
1837
+ nativeToScVal2(hexToBytes(input.artifacts.proofHex), { type: "bytes" }),
1838
+ nativeToScVal2(hexToBytes(input.artifacts.publicHex), { type: "bytes" }),
1839
+ nativeToScVal2(hexToBytes(input.artifacts.ciphertextHex ?? ""), { type: "bytes" }),
1840
+ kytAuthorizationScValue({
1841
+ expirationLedger: input.approval.expiresAtLedger,
1842
+ signature: approvalSignatureToBytes(input.approval.signature)
1843
+ })
1844
+ );
1845
+ const built = new TransactionBuilder2(
1846
+ new Account(account.accountId(), account.sequenceNumber()),
1847
+ {
1848
+ fee: SIMULATE_FEE,
1849
+ networkPassphrase: environment.network.networkPassphrase
1850
+ }
1851
+ ).addOperation(operation).setTimeout(SIMULATE_TIMEOUT_SECONDS).build();
1852
+ const simulated = await server.simulateTransaction(
1853
+ built,
1854
+ { cpuInstructions: 0 },
1855
+ RECORD_NONROOT_AUTH
1856
+ );
1857
+ if (rpc4.Api.isSimulationError(simulated)) {
1858
+ throw new Error(`Escrow sweep authorization simulation failed: ${simulated.error}`);
1859
+ }
1860
+ return simulated.result?.auth ?? [];
1861
+ }
1862
+ async function unsignedEscrowAuthorizationForSweep(input) {
1863
+ const relayerPublicKey = requireRelayerPublicKey(input.relayerPublicKey);
1864
+ const artifacts = requireSweepArtifacts(input.prepared);
1865
+ const approval = await inspectRelayerSweepKyt({
1866
+ artifacts,
1867
+ prepared: input.prepared,
1868
+ transactEnvironment: input.transactEnvironment,
1869
+ relayerPublicKey
1870
+ });
1871
+ const auth = await simulateSweepAuthEntries({
1872
+ artifacts,
1873
+ transactEnvironment: input.transactEnvironment,
1874
+ relayerPublicKey,
1875
+ approval
1876
+ });
1877
+ return pickUnsignedEscrowAuthorization({
1878
+ auth,
1879
+ claimantAddress: artifacts.escrowRecipient
1880
+ });
1881
+ }
1882
+
1883
+ // src/transact/assets/load-browser.ts
1884
+ async function loadStellarBrowserAssets(input) {
1885
+ const cacheKey = input.cacheBust ? `?v=${Date.now()}` : "";
1886
+ const sdkWasm = await fetch(`${input.sdkWasmUrl}${cacheKey}`).then(
1887
+ (response) => response.arrayBuffer()
1888
+ );
1889
+ return { sdkWasm };
1890
+ }
1891
+ async function loadDefaultStellarBrowserAssets(options) {
1892
+ await import("@arcanetech/stellar-privacy-pool-zk-sdk");
1893
+ const sdkWasmUrl = new URL(
1894
+ "@arcanetech/stellar-privacy-pool-zk-sdk/sdk.wasm",
1895
+ import.meta.url
1896
+ ).href;
1897
+ return loadStellarBrowserAssets({
1898
+ sdkWasmUrl,
1899
+ ...options?.cacheBust ? { cacheBust: true } : {}
1900
+ });
1901
+ }
1902
+
1903
+ // src/transact/private-address/temporary-recipient.ts
1904
+ import { PrivacyPoolSDK as PrivacyPoolSDK3 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1905
+ var COORDINATE_HEX_LENGTH2 = 64;
1906
+ async function generateRandomDepositScalarHex() {
1907
+ await getPrivacyPoolService().getInitializedSdk();
1908
+ return PrivacyPoolSDK3.generateRandomScalarHex32();
1909
+ }
1910
+ async function generateTemporaryRecipientPrivateAddress() {
1911
+ await getPrivacyPoolService().getInitializedSdk();
1912
+ const temporaryScalarHex = PrivacyPoolSDK3.generateRandomScalarHex32();
1913
+ const sdk = await getPrivacyPoolService().getInitializedSdk();
1914
+ const point = sdk.ecdhEphemeralPublicKeyFromScalarHex(temporaryScalarHex);
1915
+ const publicKeyXHex = point.x.padStart(COORDINATE_HEX_LENGTH2, "0");
1916
+ const publicKeyYHex = point.y.padStart(COORDINATE_HEX_LENGTH2, "0");
1917
+ return {
1918
+ temporaryScalarHex,
1919
+ temporaryPrivateAddressStpl1: encodePrivateAddressFromHexCoordinates(
1920
+ publicKeyXHex,
1921
+ publicKeyYHex
1922
+ )
1923
+ };
1924
+ }
1925
+
1926
+ // src/contracts/contract-context.ts
1927
+ function requireContractContext(environment) {
1928
+ if (!environment || !("contractContext" in environment)) {
1929
+ throw new Error("Contract context is not configured on the transact environment.");
1930
+ }
1931
+ const resolved = environment;
1932
+ return resolved.contractContext;
1933
+ }
1934
+ function readPoolClientFactory(environment) {
1935
+ return requireContractContext(environment).createPoolClient;
1936
+ }
1937
+
1938
+ // src/transact/pool/proof-types.ts
1939
+ function ciphertextArtifactsFromProof(proof) {
1940
+ return {
1941
+ ...proof.ciphertext_hex === void 0 ? {} : { ciphertextHex: proof.ciphertext_hex },
1942
+ ...proof.output_note_ephemeral_scalars === void 0 ? {} : {
1943
+ outputNoteEphemeralScalars: [...proof.output_note_ephemeral_scalars]
1944
+ }
1945
+ };
1946
+ }
1947
+
1233
1948
  // src/transact/submit/ttl-preflight.ts
1234
1949
  function getNested(source, path) {
1235
1950
  let cursor = source;
@@ -1274,14 +1989,129 @@ async function runTtlPreflight(assembledTransaction) {
1274
1989
  await maybeCallFunction(assembledTransaction, "simulate");
1275
1990
  }
1276
1991
 
1992
+ // src/transact/submit/zk-config-ttl.ts
1993
+ import {
1994
+ Address as Address4,
1995
+ Operation as Operation2,
1996
+ SorobanDataBuilder,
1997
+ TransactionBuilder as TransactionBuilder3,
1998
+ rpc as rpc5,
1999
+ xdr as xdr5
2000
+ } from "@stellar/stellar-sdk";
2001
+ var ZK_CONFIG_TTL_THRESHOLD_LEDGERS = 1e5;
2002
+ var ZK_CONFIG_TTL_EXTEND_TO_LEDGERS = 5e5;
2003
+ var EXTEND_TTL_FEE_STROOPS = "1000000";
2004
+ var EXTEND_TTL_TIMEOUT_SECONDS = 300;
2005
+ var EXTEND_TTL_MAX_POLLS = 60;
2006
+ var EXTEND_TTL_POLL_INTERVAL_MS = 1e3;
2007
+ async function waitForExtendFootprintTtlConfirmation(parameters) {
2008
+ for (let attempt = 0; attempt < EXTEND_TTL_MAX_POLLS; attempt += 1) {
2009
+ const response = await parameters.server.getTransaction(parameters.hash);
2010
+ if (response.status === "SUCCESS") {
2011
+ return;
2012
+ }
2013
+ if (response.status === "FAILED") {
2014
+ throw new Error("ZK config TTL extension failed on-chain");
2015
+ }
2016
+ await new Promise((resolve) => {
2017
+ setTimeout(resolve, EXTEND_TTL_POLL_INTERVAL_MS);
2018
+ });
2019
+ }
2020
+ throw new Error("ZK config TTL extension was not confirmed in time");
2021
+ }
2022
+ function zkConfigLedgerKey(contractId, nonce) {
2023
+ const configKeyScValue = xdr5.ScVal.scvVec([
2024
+ xdr5.ScVal.scvSymbol("Config"),
2025
+ xdr5.ScVal.scvU64(xdr5.Uint64.fromString(nonce.toString()))
2026
+ ]);
2027
+ return xdr5.LedgerKey.contractData(
2028
+ new xdr5.LedgerKeyContractData({
2029
+ contract: new Address4(contractId).toScAddress(),
2030
+ key: configKeyScValue,
2031
+ durability: xdr5.ContractDataDurability.persistent()
2032
+ })
2033
+ );
2034
+ }
2035
+ async function needsTtlExtension(parameters) {
2036
+ const [entriesResponse, latestLedger] = await Promise.all([
2037
+ parameters.server.getLedgerEntries(parameters.ledgerKey),
2038
+ parameters.server.getLatestLedger()
2039
+ ]);
2040
+ const entry = entriesResponse.entries.at(0);
2041
+ if (!entry || entry.liveUntilLedgerSeq === void 0) {
2042
+ return false;
2043
+ }
2044
+ const remainingLedgers = entry.liveUntilLedgerSeq - latestLedger.sequence;
2045
+ return remainingLedgers < ZK_CONFIG_TTL_THRESHOLD_LEDGERS;
2046
+ }
2047
+ async function submitExtendFootprintTtlTransaction(parameters) {
2048
+ const sourceAccount = await parameters.server.getAccount(parameters.sourcePublicKey);
2049
+ const transaction = new TransactionBuilder3(sourceAccount, {
2050
+ fee: EXTEND_TTL_FEE_STROOPS,
2051
+ networkPassphrase: parameters.networkPassphrase
2052
+ }).addOperation(
2053
+ Operation2.extendFootprintTtl({ extendTo: ZK_CONFIG_TTL_EXTEND_TO_LEDGERS })
2054
+ ).setSorobanData(
2055
+ new SorobanDataBuilder().setReadOnly([parameters.ledgerKey]).build()
2056
+ ).setTimeout(EXTEND_TTL_TIMEOUT_SECONDS).build();
2057
+ const preparedTransaction = await parameters.server.prepareTransaction(transaction);
2058
+ const { signedTxXdr } = await parameters.signTransaction({
2059
+ xdr: preparedTransaction.toXDR(),
2060
+ networkPassphrase: parameters.networkPassphrase,
2061
+ address: parameters.sourcePublicKey
2062
+ });
2063
+ const signedTransaction = TransactionBuilder3.fromXDR(
2064
+ signedTxXdr,
2065
+ parameters.networkPassphrase
2066
+ );
2067
+ const result = await parameters.server.sendTransaction(signedTransaction);
2068
+ const status = String(result.status);
2069
+ if (status !== "PENDING" && status !== "SUCCESS") {
2070
+ throw new Error(`ZK config TTL extension submit failed: ${status}`);
2071
+ }
2072
+ await waitForExtendFootprintTtlConfirmation({
2073
+ server: parameters.server,
2074
+ hash: result.hash
2075
+ });
2076
+ }
2077
+ async function extendZkConfigTtlIfNeeded(parameters) {
2078
+ if (!parameters.signTransaction) {
2079
+ return;
2080
+ }
2081
+ const server = new rpc5.Server(parameters.sorobanRpcUrl, { allowHttp: true });
2082
+ const ledgerKey = zkConfigLedgerKey(parameters.contractId, parameters.nonce);
2083
+ if (!await needsTtlExtension({ server, ledgerKey })) {
2084
+ return;
2085
+ }
2086
+ await submitExtendFootprintTtlTransaction({
2087
+ server,
2088
+ ledgerKey,
2089
+ networkPassphrase: parameters.networkPassphrase,
2090
+ sourcePublicKey: parameters.sourcePublicKey,
2091
+ signTransaction: parameters.signTransaction
2092
+ });
2093
+ }
2094
+
1277
2095
  // src/transact/submit/pool-transact.ts
1278
2096
  import { Buffer as Buffer11 } from "buffer";
1279
2097
  async function submitPoolTransact(parameters) {
2098
+ await extendZkConfigTtlIfNeeded({
2099
+ sorobanRpcUrl: parameters.sorobanRpcUrl,
2100
+ networkPassphrase: parameters.networkPassphrase,
2101
+ contractId: parameters.contractId,
2102
+ nonce: parameters.nonce,
2103
+ sourcePublicKey: parameters.from,
2104
+ signTransaction: parameters.transactEnvironment.signTransaction
2105
+ });
1280
2106
  const assembledTransaction = await parameters.contractClient.transact({
1281
2107
  from: parameters.from,
2108
+ nonce: parameters.nonce,
1282
2109
  proof_bytes: Buffer11.from(parameters.proofHex.replace(/^0x/iu, ""), "hex"),
1283
2110
  pub_signals_bytes: Buffer11.from(parameters.publicHex.replace(/^0x/iu, ""), "hex"),
1284
- onboarding: parameters.onboarding,
2111
+ ciphertext_bytes: Buffer11.from(
2112
+ (parameters.ciphertextHex ?? "").replace(/^0x/iu, ""),
2113
+ "hex"
2114
+ ),
1285
2115
  kyt_authorization: {
1286
2116
  expiration_ledger: parameters.approval.expiresAtLedger,
1287
2117
  signature: approvalSignatureToBytes(parameters.approval.signature)
@@ -1306,29 +2136,37 @@ async function submitSorobanDeposit(input) {
1306
2136
  });
1307
2137
  const merkleTx = await poolClient.get_merkle_root();
1308
2138
  const merkleRootBuffer = merkleTx.result;
1309
- const { applicationIdsPlaintext, proof_hex, public_hex } = await input.privacyPoolService.prepareDepositTransactProof({
2139
+ const proof = await input.privacyPoolService.prepareDepositTransactProof({
1310
2140
  privateAddressStpl1: input.privateAddressStpl1,
1311
2141
  coin: input.coin,
1312
2142
  depositScalarHex: input.depositScalarHex,
1313
2143
  merkleRootBytes: merkleRootBuffer,
1314
2144
  tokenAddress: input.tokenAddress
1315
2145
  });
2146
+ const ciphertext = ciphertextArtifactsFromProof(proof);
1316
2147
  const approval = await requestKytPassageForPoolInteraction({
1317
2148
  owner: input.walletPublicKey,
1318
2149
  poolContract: input.contractId,
1319
- proofHex: proof_hex,
1320
- publicHex: public_hex,
1321
- applicationIdsPlaintext,
2150
+ proofHex: proof.proof_hex,
2151
+ publicHex: proof.public_hex,
2152
+ applicationIdsPlaintext: proof.applicationIdsPlaintext,
2153
+ ...ciphertext,
1322
2154
  networkPassphrase: input.networkPassphrase,
1323
2155
  sorobanRpcUrl: input.sorobanRpcUrl,
1324
2156
  transactEnvironment: input.transactEnvironment
1325
2157
  });
1326
2158
  return submitPoolTransact({
1327
2159
  contractClient: poolClient,
2160
+ contractId: input.contractId,
1328
2161
  from: input.walletPublicKey,
1329
- proofHex: proof_hex,
1330
- publicHex: public_hex,
1331
- approval
2162
+ nonce: resolveZkConfigNonce(input.transactEnvironment),
2163
+ proofHex: proof.proof_hex,
2164
+ publicHex: proof.public_hex,
2165
+ ...ciphertext,
2166
+ approval,
2167
+ networkPassphrase: input.networkPassphrase,
2168
+ sorobanRpcUrl: input.sorobanRpcUrl,
2169
+ transactEnvironment: input.transactEnvironment
1332
2170
  });
1333
2171
  }
1334
2172
 
@@ -1345,7 +2183,8 @@ async function submitSorobanConfidentialTransfer(input) {
1345
2183
  poolContract: input.contractId,
1346
2184
  proofHex: input.proofHex,
1347
2185
  publicHex: input.publicHex,
1348
- ...input.onboarding ? { onboarding: input.onboarding } : {},
2186
+ ...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
2187
+ ...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {},
1349
2188
  ...input.applicationIdsPlaintext ? { applicationIdsPlaintext: input.applicationIdsPlaintext } : {},
1350
2189
  networkPassphrase: input.networkPassphrase,
1351
2190
  sorobanRpcUrl: input.sorobanRpcUrl,
@@ -1353,22 +2192,32 @@ async function submitSorobanConfidentialTransfer(input) {
1353
2192
  });
1354
2193
  return submitPoolTransact({
1355
2194
  contractClient: poolClient,
2195
+ contractId: input.contractId,
1356
2196
  from: input.walletPublicKey,
2197
+ nonce: resolveZkConfigNonce(input.transactEnvironment),
1357
2198
  proofHex: input.proofHex,
1358
2199
  publicHex: input.publicHex,
1359
- ...input.onboarding ? { onboarding: input.onboarding } : {},
1360
- approval
2200
+ ...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
2201
+ approval,
2202
+ networkPassphrase: input.networkPassphrase,
2203
+ sorobanRpcUrl: input.sorobanRpcUrl,
2204
+ transactEnvironment: input.transactEnvironment
1361
2205
  });
1362
2206
  }
1363
2207
 
1364
- // src/transact/onboarding/recipient-change-deposits.ts
1365
- async function buildPaddingDepositPair(recipientPrivateAddressStpl1, tokenAddress, recipientDeposit) {
1366
- const paddingSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
1367
- privateAddressStpl1: recipientPrivateAddressStpl1,
1368
- amountStroops: ZERO_STROOPS,
1369
- tokenAddress
1370
- });
1371
- return [recipientDeposit, paddingSlot.deposit];
2208
+ // src/transact/proofs/confidential/recipient-change-deposits.ts
2209
+ function escrowOutputFields(input) {
2210
+ if (!input.escrowSend) {
2211
+ return {};
2212
+ }
2213
+ return {
2214
+ escrowNonce: input.escrowSend.nonceDecimal,
2215
+ recipientHi: input.escrowSend.recipientHi,
2216
+ recipientLo: input.escrowSend.recipientLo
2217
+ };
2218
+ }
2219
+ function paddingDepositPair(recipientDeposit) {
2220
+ return [recipientDeposit, "dummy"];
1372
2221
  }
1373
2222
  async function buildChangeDepositPair(parameters) {
1374
2223
  const changeSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
@@ -1387,24 +2236,24 @@ async function buildChangeDepositPair(parameters) {
1387
2236
  };
1388
2237
  }
1389
2238
  async function buildRecipientAndOptionalChangeDeposits(parameters) {
2239
+ const escrow = {
2240
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
2241
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
2242
+ };
1390
2243
  const recipientPrivateAddress = parameters.recipientPrivateAddressStpl1.trim();
1391
2244
  const recipientSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
1392
2245
  privateAddressStpl1: recipientPrivateAddress,
1393
2246
  amountStroops: parameters.transferStroops,
1394
- tokenAddress: parameters.tokenAddress
2247
+ tokenAddress: parameters.tokenAddress,
2248
+ ...escrowOutputFields(escrow)
1395
2249
  });
1396
2250
  if (parameters.changeStroops <= ZERO_STROOPS) {
1397
2251
  return {
1398
2252
  recipientSlot,
1399
- deposits: await buildPaddingDepositPair(
1400
- recipientPrivateAddress,
1401
- parameters.tokenAddress,
1402
- recipientSlot.deposit
1403
- )
2253
+ deposits: paddingDepositPair(recipientSlot.deposit)
1404
2254
  };
1405
2255
  }
1406
2256
  const changeResult = await buildChangeDepositPair({
1407
- recipientPrivateAddressStpl1: recipientPrivateAddress,
1408
2257
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
1409
2258
  changeStroops: parameters.changeStroops,
1410
2259
  tokenAddress: parameters.tokenAddress,
@@ -1426,20 +2275,61 @@ function generatedOutputCoinFromSlot(slot) {
1426
2275
  precommitementHex: slot.precommitementHex
1427
2276
  };
1428
2277
  }
2278
+ function publicEscrowRecipientLimbs(parameters) {
2279
+ const limbs = parameters.escrowClaimantLimbs;
2280
+ if (!limbs) {
2281
+ return void 0;
2282
+ }
2283
+ return {
2284
+ escrowRecipientHi: limbs.recipientHi,
2285
+ escrowRecipientLo: limbs.recipientLo
2286
+ };
2287
+ }
2288
+ function sweepWithdrawStamp(parameters) {
2289
+ const publicLimbs = publicEscrowRecipientLimbs(parameters);
2290
+ if (!publicLimbs) {
2291
+ return void 0;
2292
+ }
2293
+ return {
2294
+ ...publicLimbs,
2295
+ ...parameters.escrowClaimantLimbs?.nonceDecimal ? { escrowNonce: parameters.escrowClaimantLimbs.nonceDecimal } : {}
2296
+ };
2297
+ }
2298
+ function stampWithdrawEscrowLimbs(withdrawObject, limbs) {
2299
+ if (!limbs) {
2300
+ return withdrawObject;
2301
+ }
2302
+ return {
2303
+ ...withdrawObject,
2304
+ recipientStellar: [limbs.escrowRecipientHi, limbs.escrowRecipientLo],
2305
+ ...limbs.escrowNonce ? { escrowNonce: limbs.escrowNonce } : {}
2306
+ };
2307
+ }
2308
+ function sweepOutputOwnerFields(parameters) {
2309
+ if (!parameters.escrowClaimantLimbs) {
2310
+ return void 0;
2311
+ }
2312
+ const [sweepOutputOwnerPubX, sweepOutputOwnerPubY] = recipientPublicKeysDecimalFromPrivateAddress(
2313
+ parameters.recipientPrivateAddressStpl1
2314
+ );
2315
+ return { sweepOutputOwnerPubX, sweepOutputOwnerPubY };
2316
+ }
1429
2317
  async function buildTransferDepositsAndPublicInput(parameters) {
1430
2318
  const { recipientSlot, deposits, changeCoin } = await buildRecipientAndOptionalChangeDeposits({
1431
2319
  recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
1432
2320
  transferStroops: parameters.transferStroops,
1433
2321
  changeStroops: parameters.changeStroops,
1434
2322
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
1435
- tokenAddress: parameters.tokenAddress
2323
+ tokenAddress: parameters.tokenAddress,
2324
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
2325
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
1436
2326
  });
1437
2327
  const publicInput = withTokenAddressPublicInputs(
1438
2328
  {
1439
2329
  stateRoot: parameters.stateRoot,
1440
- withdrawAddressHi: parameters.withdrawAddressHi,
1441
- withdrawAddressLo: parameters.withdrawAddressLo,
1442
- privKeyScalar: parameters.privKeyScalar
2330
+ privKeyScalar: parameters.privKeyScalar,
2331
+ ...publicEscrowRecipientLimbs(parameters),
2332
+ ...sweepOutputOwnerFields(parameters)
1443
2333
  },
1444
2334
  parameters.tokenAddress
1445
2335
  );
@@ -1451,10 +2341,6 @@ async function buildTransferDepositsAndPublicInput(parameters) {
1451
2341
  };
1452
2342
  }
1453
2343
  async function buildSenderTransferDepositsAndPublicInput(parameters) {
1454
- const { hi, lo, privKeyScalar } = senderWithdrawFrAndScalar({
1455
- senderGAddress: parameters.senderGAddress,
1456
- senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex
1457
- });
1458
2344
  return buildTransferDepositsAndPublicInput({
1459
2345
  recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
1460
2346
  transferStroops: parameters.transferStroops,
@@ -1462,31 +2348,55 @@ async function buildSenderTransferDepositsAndPublicInput(parameters) {
1462
2348
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
1463
2349
  tokenAddress: parameters.tokenAddress,
1464
2350
  stateRoot: parameters.stateRoot,
1465
- withdrawAddressHi: hi,
1466
- withdrawAddressLo: lo,
1467
- privKeyScalar
2351
+ privKeyScalar: privKeyScalarDecimalFromRecipientScalarHex(
2352
+ parameters.senderPrivKeyScalarHex
2353
+ ),
2354
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
2355
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
1468
2356
  });
1469
2357
  }
1470
2358
 
1471
2359
  // src/transact/proofs/confidential/dual.ts
1472
- function buildDualTransferApplicationIds(applicationId, changeCoin) {
1473
- return [
1474
- applicationId,
1475
- applicationId,
1476
- applicationId,
1477
- changeCoin ? applicationId : "0"
1478
- ];
2360
+ function confidentialEscrowFields(parameters) {
2361
+ return {
2362
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
2363
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
2364
+ };
2365
+ }
2366
+ function stampDualWithdrawLegs(legs, parameters) {
2367
+ const escrowLimbs = sweepWithdrawStamp(confidentialEscrowFields(parameters));
2368
+ return {
2369
+ legA: {
2370
+ ...legs.legA,
2371
+ withdrawObject: stampWithdrawEscrowLimbs(legs.legA.withdrawObject, escrowLimbs)
2372
+ },
2373
+ legB: {
2374
+ ...legs.legB,
2375
+ withdrawObject: stampWithdrawEscrowLimbs(legs.legB.withdrawObject, escrowLimbs)
2376
+ }
2377
+ };
2378
+ }
2379
+ function buildDualTransferApplicationIds(sdk, applicationId, changeCoin) {
2380
+ return buildApplicationIdHints({
2381
+ sdk,
2382
+ inputIds: [applicationId, applicationId],
2383
+ outputIds: [applicationId, changeCoin ? applicationId : "0"]
2384
+ });
1479
2385
  }
1480
2386
  async function proveDualConfidentialTransfer(parameters) {
1481
2387
  const audit = buildPoolTransactionAuditParameters({
1482
2388
  applicationId: parameters.applicationId,
2389
+ nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
1483
2390
  ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
1484
2391
  });
1485
2392
  return parameters.sdk.proveTransaction(
1486
2393
  parameters.publicInput,
1487
- buildZeroPublicLegs(),
1488
- [parameters.legA.withdrawObject, parameters.legB.withdrawObject],
1489
- parameters.deposits,
2394
+ padPublicLegsToLayout(parameters.sdk, buildZeroPublicLegs()),
2395
+ padWithdrawSlotsToLayout(parameters.sdk, [
2396
+ parameters.legA.withdrawObject,
2397
+ parameters.legB.withdrawObject
2398
+ ]),
2399
+ padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
1490
2400
  audit
1491
2401
  );
1492
2402
  }
@@ -1500,24 +2410,33 @@ async function buildDualTransferProofContext(parameters, applicationId, sdk) {
1500
2410
  changeStroops,
1501
2411
  parameters.selfPrivateAddressStpl1ForChange
1502
2412
  );
1503
- const { legA, legB } = dualWithdrawLegsWithSharedRoot({
1504
- sdk,
1505
- coinA: parameters.coinA,
1506
- coinB: parameters.coinB,
1507
- state: parameters.state,
1508
- ephemeralA: parseEphemeralKeyString(parameters.ephemeralAKey),
1509
- ephemeralB: parseEphemeralKeyString(parameters.ephemeralBKey),
1510
- applicationId
1511
- });
2413
+ const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
2414
+ parameters.senderPrivKeyScalarHex
2415
+ );
2416
+ const ownerPubHex = sdk.ecdhEphemeralPublicKeyFromScalarHex(
2417
+ parameters.senderPrivKeyScalarHex
2418
+ );
2419
+ const { legA, legB } = stampDualWithdrawLegs(
2420
+ dualWithdrawLegsWithSharedRoot({
2421
+ sdk,
2422
+ coinA: parameters.coinA,
2423
+ coinB: parameters.coinB,
2424
+ state: parameters.state,
2425
+ ownerPubHex,
2426
+ privKeyScalar,
2427
+ applicationId
2428
+ }),
2429
+ parameters
2430
+ );
1512
2431
  const transferInputs = await buildSenderTransferDepositsAndPublicInput({
1513
- senderGAddress: parameters.senderGAddress,
1514
2432
  senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex,
1515
2433
  recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
1516
2434
  transferStroops: parameters.transferStroops,
1517
2435
  changeStroops,
1518
2436
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
1519
2437
  tokenAddress: parameters.tokenAddress,
1520
- stateRoot: legA.witness.stateRoot
2438
+ stateRoot: legA.witness.stateRoot,
2439
+ ...confidentialEscrowFields(parameters)
1521
2440
  });
1522
2441
  return { legA, legB, applicationId, ...transferInputs };
1523
2442
  }
@@ -1545,7 +2464,11 @@ async function prepareConfidentialTransferProofDual(parameters) {
1545
2464
  }));
1546
2465
  return {
1547
2466
  ...proof,
1548
- applicationIdsPlaintext: buildDualTransferApplicationIds(applicationId, changeCoin),
2467
+ applicationIdsPlaintext: buildDualTransferApplicationIds(
2468
+ sdk,
2469
+ applicationId,
2470
+ changeCoin
2471
+ ),
1549
2472
  recipientCoin: generatedOutputCoinFromSlot(recipientSlot),
1550
2473
  ...changeCoin ? { changeCoin } : {}
1551
2474
  };
@@ -1563,51 +2486,72 @@ function validateSingleCoinTransferAmounts(transferStroops, noteStroops, selfPri
1563
2486
  requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange);
1564
2487
  return changeStroops;
1565
2488
  }
1566
- function buildSingleTransferApplicationIds(applicationId, changeCoin) {
1567
- return [applicationId, "0", applicationId, changeCoin ? applicationId : "0"];
2489
+ function buildSingleTransferApplicationIds(sdk, applicationId, changeCoin) {
2490
+ return buildApplicationIdHints({
2491
+ sdk,
2492
+ inputIds: [applicationId],
2493
+ outputIds: [applicationId, changeCoin ? applicationId : "0"]
2494
+ });
1568
2495
  }
1569
2496
  function buildTransferAuditParameters(parameters) {
1570
2497
  const auditPublicKey = parameters.poolService.getAuditPublicKey();
1571
2498
  return buildPoolTransactionAuditParameters({
1572
2499
  applicationId: parameters.applicationId,
2500
+ nAuditSlots: parameters.nAuditSlots,
1573
2501
  ...auditPublicKey ? { auditPublicKey } : {}
1574
2502
  });
1575
2503
  }
1576
2504
  async function proveTransaction(parameters) {
1577
2505
  return parameters.sdk.proveTransaction(
1578
2506
  parameters.publicInput,
1579
- buildZeroPublicLegs(),
1580
- [parameters.withdrawObject, "dummy"],
1581
- parameters.deposits,
2507
+ padPublicLegsToLayout(parameters.sdk, buildZeroPublicLegs()),
2508
+ padWithdrawSlotsToLayout(parameters.sdk, [parameters.withdrawObject]),
2509
+ padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
1582
2510
  parameters.audit
1583
2511
  );
1584
2512
  }
2513
+ function confidentialEscrowFields2(input) {
2514
+ return {
2515
+ ...input.escrowSend ? { escrowSend: input.escrowSend } : {},
2516
+ ...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
2517
+ };
2518
+ }
1585
2519
  async function buildTransferProofInputs(parameters) {
1586
2520
  const changeStroops = validateSingleCoinTransferAmounts(
1587
2521
  parameters.input.transferStroops,
1588
2522
  parameters.noteStroops,
1589
2523
  parameters.input.selfPrivateAddressStpl1ForChange
1590
2524
  );
2525
+ const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
2526
+ parameters.input.senderPrivKeyScalarHex
2527
+ );
1591
2528
  const { witness, withdrawObject } = withdrawWitnessForCoin({
1592
2529
  sdk: parameters.sdk,
1593
2530
  coin: parameters.input.coin,
1594
2531
  state: parameters.input.state,
1595
- ...parseEphemeralKeyString(parameters.input.depositorEphemeralKey),
2532
+ ownerPubHex: parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
2533
+ parameters.input.senderPrivKeyScalarHex
2534
+ ),
2535
+ privKeyScalar,
1596
2536
  applicationId: parameters.applicationId
1597
2537
  });
2538
+ const stampedWithdraw = stampWithdrawEscrowLimbs(
2539
+ withdrawObject,
2540
+ sweepWithdrawStamp(confidentialEscrowFields2(parameters.input))
2541
+ );
1598
2542
  const { recipientSlot, deposits, changeCoin, publicInput } = await buildSenderTransferDepositsAndPublicInput({
1599
- senderGAddress: parameters.input.senderGAddress,
1600
2543
  senderPrivKeyScalarHex: parameters.input.senderPrivKeyScalarHex,
1601
2544
  recipientPrivateAddressStpl1: parameters.input.recipientPrivateAddressStpl1,
1602
2545
  transferStroops: parameters.input.transferStroops,
1603
2546
  changeStroops,
1604
2547
  selfPrivateAddressStpl1ForChange: parameters.input.selfPrivateAddressStpl1ForChange,
1605
2548
  tokenAddress: parameters.input.tokenAddress,
1606
- stateRoot: witness.stateRoot
2549
+ stateRoot: witness.stateRoot,
2550
+ ...confidentialEscrowFields2(parameters.input)
1607
2551
  });
1608
2552
  return {
1609
2553
  witness,
1610
- withdrawObject,
2554
+ withdrawObject: stampedWithdraw,
1611
2555
  recipientSlot,
1612
2556
  deposits,
1613
2557
  changeCoin,
@@ -1625,7 +2569,11 @@ async function prepareConfidentialTransferProof(parameters) {
1625
2569
  input: parameters,
1626
2570
  noteStroops
1627
2571
  });
1628
- const audit = buildTransferAuditParameters({ poolService, applicationId });
2572
+ const audit = buildTransferAuditParameters({
2573
+ poolService,
2574
+ applicationId,
2575
+ nAuditSlots: sdk.getLayout().nAuditSlots
2576
+ });
1629
2577
  const proof = await proveTransaction({
1630
2578
  sdk,
1631
2579
  publicInput,
@@ -1636,6 +2584,7 @@ async function prepareConfidentialTransferProof(parameters) {
1636
2584
  return {
1637
2585
  ...proof,
1638
2586
  applicationIdsPlaintext: buildSingleTransferApplicationIds(
2587
+ sdk,
1639
2588
  applicationId,
1640
2589
  changeCoin
1641
2590
  ),
@@ -1767,12 +2716,25 @@ async function readLeafEphemeralHex(parameters) {
1767
2716
  return { xHex, yHex };
1768
2717
  }
1769
2718
 
2719
+ // src/transact/encoding/fr-decimal-to-bytes.ts
2720
+ var BN254_SCALAR_MOD = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
2721
+ var FIELD_BYTE_LENGTH2 = 32;
2722
+ var BYTE_MASK = 0xffn;
2723
+ var BITS_PER_BYTE = 8n;
2724
+ function frDecimalToPaddedBytes32(decimal) {
2725
+ let value = BigInt(decimal.trim());
2726
+ value = (value % BN254_SCALAR_MOD + BN254_SCALAR_MOD) % BN254_SCALAR_MOD;
2727
+ const bytes = Buffer.alloc(FIELD_BYTE_LENGTH2);
2728
+ for (let index = FIELD_BYTE_LENGTH2 - 1; index >= 0; index -= 1) {
2729
+ bytes[index] = Number(value & BYTE_MASK);
2730
+ value >>= BITS_PER_BYTE;
2731
+ }
2732
+ return bytes;
2733
+ }
2734
+
1770
2735
  // src/state/foundation/paths.ts
1771
2736
  var STELLAR_STATE_PATHS = {
1772
2737
  privateRecords: "$.privateRecords",
1773
- pendingClaimsItems: "$.pendingClaims.items",
1774
- pendingClaimsPagination: "$.pendingClaims.pagination",
1775
- pendingClaimsCountByOwner: "$.pendingClaims.countByOwner",
1776
2738
  registryPrivateAddresses: "$.registry.privateAddresses",
1777
2739
  registryRegisteredAddresses: "$.registry.registeredAddresses",
1778
2740
  registryLookups: "$.registry.lookups",
@@ -1792,25 +2754,6 @@ var STELLAR_STATE_PATHS = {
1792
2754
 
1793
2755
  // src/state/schemas/shared.ts
1794
2756
  import { z } from "zod";
1795
- var pendingClaimSchema = z.object({
1796
- id: z.string().min(1),
1797
- owner: z.string().min(1),
1798
- asset: z.string().min(1),
1799
- amount: z.coerce.bigint(),
1800
- createdAt: z.string().min(1),
1801
- poolTxId: z.string().optional(),
1802
- commitmentHex: z.string().optional(),
1803
- nullifierHex: z.string().optional(),
1804
- futureNullifierHashHex: z.string().optional(),
1805
- assetHiHex: z.string().optional(),
1806
- assetLoHex: z.string().optional(),
1807
- nullifierFieldHex: z.string().optional(),
1808
- secretHex: z.string().optional(),
1809
- tempPublicKeyXHex: z.string().optional(),
1810
- tempPublicKeyYHex: z.string().optional(),
1811
- encryptedRecoveryBase64: z.string().optional(),
1812
- createdAtLedger: z.number().int().optional()
1813
- });
1814
2757
  var paginationSchema = z.object({
1815
2758
  total: z.number().int().nonnegative(),
1816
2759
  page: z.number().int().positive(),
@@ -1980,26 +2923,6 @@ function normalizePublicBalancesFromEntries(value, owner) {
1980
2923
  }).filter((balance) => balance !== void 0);
1981
2924
  }
1982
2925
 
1983
- // src/state/read/normalize/claims.ts
1984
- function normalizePendingClaimsState(value) {
1985
- if (typeof value !== "object" || value === null) {
1986
- return { items: [] };
1987
- }
1988
- const record = value;
1989
- const items = Array.isArray(record.items) ? record.items.flatMap((item) => {
1990
- const parsed = pendingClaimSchema.safeParse(item);
1991
- return parsed.success ? [withoutUndefinedFields(parsed.data)] : [];
1992
- }) : [];
1993
- const paginationResult = paginationSchema.safeParse(record.pagination);
1994
- if (paginationResult.success) {
1995
- return { items, pagination: paginationResult.data };
1996
- }
1997
- return { items };
1998
- }
1999
- function normalizePendingClaimsCount(value) {
2000
- return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
2001
- }
2002
-
2003
2926
  // src/state/read/normalize/deliveries.ts
2004
2927
  function normalizeIncomingDeliveries(value) {
2005
2928
  const entries = typeof value === "object" && value !== null && !Array.isArray(value) ? Object.values(value) : value;
@@ -2122,8 +3045,7 @@ import { registerArrayFilterItemSchema } from "@arcanetech/privacy-sdk-core/stat
2122
3045
 
2123
3046
  // src/state/filters/ops.ts
2124
3047
  var stellarArrayFilterSchemaKeys = {
2125
- privateRecord: "privateRecord",
2126
- pendingClaim: "pendingClaim"
3048
+ privateRecord: "privateRecord"
2127
3049
  };
2128
3050
  function rejectPrivateRecordsByIds(ids) {
2129
3051
  return {
@@ -2149,56 +3071,6 @@ function rejectConsumedPrivateRecords() {
2149
3071
  }
2150
3072
  };
2151
3073
  }
2152
- function rejectPendingClaimsByOwner(owner) {
2153
- return {
2154
- opType: "arrayFilter",
2155
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2156
- itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
2157
- rejectWhen: {
2158
- op: "fieldEquals",
2159
- field: "owner",
2160
- value: owner
2161
- }
2162
- };
2163
- }
2164
- function rejectPendingClaimsByIds(ids) {
2165
- return {
2166
- opType: "arrayFilter",
2167
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2168
- itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
2169
- rejectWhen: {
2170
- op: "fieldIn",
2171
- field: "id",
2172
- values: ids
2173
- }
2174
- };
2175
- }
2176
- function rejectPendingClaimsByOwnerAndAsset(input) {
2177
- const matches = [];
2178
- if (input.owner !== void 0) {
2179
- matches.push({
2180
- op: "fieldEquals",
2181
- field: "owner",
2182
- value: input.owner
2183
- });
2184
- }
2185
- if (input.asset !== void 0) {
2186
- matches.push({
2187
- op: "fieldEquals",
2188
- field: "asset",
2189
- value: input.asset
2190
- });
2191
- }
2192
- return {
2193
- opType: "arrayFilter",
2194
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2195
- itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
2196
- rejectWhen: {
2197
- op: "and",
2198
- matches
2199
- }
2200
- };
2201
- }
2202
3074
 
2203
3075
  // src/state/filters/register-schemas.ts
2204
3076
  var registered = false;
@@ -2210,24 +3082,12 @@ function registerStellarArrayFilterSchemas() {
2210
3082
  stellarArrayFilterSchemaKeys.privateRecord,
2211
3083
  privateRecordSchema
2212
3084
  );
2213
- registerArrayFilterItemSchema(
2214
- stellarArrayFilterSchemaKeys.pendingClaim,
2215
- pendingClaimSchema
2216
- );
2217
3085
  registered = true;
2218
3086
  }
2219
3087
 
2220
3088
  // src/state/bridge/call-types.ts
2221
3089
  import "@arcanetech/privacy-sdk-core/state";
2222
3090
  var stellarStateCallTypes = {
2223
- pendingClaims: "pendingClaims",
2224
- clearPendingClaims: "clearPendingClaims",
2225
- readPendingClaims: "readPendingClaims",
2226
- replacePendingClaimsPage: "replacePendingClaimsPage",
2227
- upsertPendingClaims: "upsertPendingClaims",
2228
- removePendingClaims: "removePendingClaims",
2229
- setPendingClaimsCount: "setPendingClaimsCount",
2230
- readPendingClaimsCount: "readPendingClaimsCount",
2231
3091
  readStellarAddressRegistered: "readStellarAddressRegistered",
2232
3092
  readCachedPrivateAddress: "readCachedPrivateAddress",
2233
3093
  readRegistryLookup: "readRegistryLookup",
@@ -2454,194 +3314,10 @@ var stellarBalancesStateDefinitions = [
2454
3314
  }
2455
3315
  ];
2456
3316
 
2457
- // src/state/schemas/claims/write.ts
2458
- import { z as z5 } from "zod";
2459
- var pendingClaimsWriteSchema = z5.object({
2460
- type: z5.literal(stellarStateCallTypes.pendingClaims),
2461
- claims: z5.array(pendingClaimSchema),
2462
- paginationInfo: paginationSchema
2463
- }).transform(({ type, claims, paginationInfo }) => ({
2464
- type,
2465
- operations: [
2466
- {
2467
- opType: "arrayPush",
2468
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2469
- items: claims
2470
- },
2471
- {
2472
- opType: "primitiveSet",
2473
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsPagination,
2474
- value: paginationInfo
2475
- }
2476
- ]
2477
- }));
2478
- var clearPendingClaimsSchema = z5.object({
2479
- type: z5.literal(stellarStateCallTypes.clearPendingClaims),
2480
- owner: z5.string().optional(),
2481
- asset: z5.string().optional()
2482
- }).transform(({ type, owner, asset }) => {
2483
- if (owner === void 0 && asset === void 0) {
2484
- return {
2485
- type,
2486
- operations: [
2487
- {
2488
- opType: "arrayClean",
2489
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems
2490
- }
2491
- ]
2492
- };
2493
- }
2494
- return {
2495
- type,
2496
- operations: [rejectPendingClaimsByOwnerAndAsset({ owner, asset })]
2497
- };
2498
- });
2499
- var readPendingClaimsSchema = z5.object({
2500
- type: z5.literal(stellarStateCallTypes.readPendingClaims)
2501
- }).transform(({ type }) => ({
2502
- type,
2503
- operations: [
2504
- {
2505
- opType: "primitiveGet",
2506
- jsonPath: "$.pendingClaims"
2507
- }
2508
- ]
2509
- }));
2510
-
2511
- // src/state/schemas/claims/page.ts
2512
- import { z as z6 } from "zod";
2513
- var pendingClaimBridgeItemSchema = pendingClaimSchema;
2514
- var replacePendingClaimsPageSchema = z6.object({
2515
- type: z6.literal(stellarStateCallTypes.replacePendingClaimsPage),
2516
- owner: z6.string().min(1),
2517
- claims: z6.array(pendingClaimBridgeItemSchema),
2518
- paginationInfo: z6.object({
2519
- total: z6.number().int().nonnegative(),
2520
- page: z6.number().int().positive(),
2521
- pageSize: z6.number().int().positive(),
2522
- hasMore: z6.boolean()
2523
- }),
2524
- count: z6.number().int().nonnegative().optional()
2525
- }).transform(({ type, owner, claims, paginationInfo, count }) => ({
2526
- type,
2527
- operations: [
2528
- rejectPendingClaimsByOwner(owner),
2529
- {
2530
- opType: "arrayPush",
2531
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2532
- items: claims
2533
- },
2534
- {
2535
- opType: "primitiveSet",
2536
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsPagination,
2537
- value: paginationInfo
2538
- },
2539
- {
2540
- opType: "recordSet",
2541
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
2542
- key: owner,
2543
- value: count ?? paginationInfo.total
2544
- }
2545
- ]
2546
- }));
2547
- var upsertPendingClaimsSchema = z6.object({
2548
- type: z6.literal(stellarStateCallTypes.upsertPendingClaims),
2549
- claims: z6.array(pendingClaimBridgeItemSchema)
2550
- }).transform(({ type, claims }) => ({
2551
- type,
2552
- operations: [
2553
- rejectPendingClaimsByIds(claims.map((claim) => claim.id)),
2554
- {
2555
- opType: "arrayPush",
2556
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2557
- items: claims
2558
- }
2559
- ]
2560
- }));
2561
- var removePendingClaimsSchema = z6.object({
2562
- type: z6.literal(stellarStateCallTypes.removePendingClaims),
2563
- ids: z6.array(z6.string().min(1))
2564
- }).transform(({ type, ids }) => ({
2565
- type,
2566
- operations: [rejectPendingClaimsByIds(ids)]
2567
- }));
2568
- var readPendingClaimsCountSchema = z6.object({
2569
- type: z6.literal(stellarStateCallTypes.readPendingClaimsCount),
2570
- owner: z6.string().min(1)
2571
- }).transform(({ type, owner }) => ({
2572
- type,
2573
- operations: [
2574
- {
2575
- opType: "recordGet",
2576
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
2577
- key: owner
2578
- }
2579
- ]
2580
- }));
2581
- var setPendingClaimsCountSchema = z6.object({
2582
- type: z6.literal(stellarStateCallTypes.setPendingClaimsCount),
2583
- owner: z6.string().min(1),
2584
- count: z6.number().int().nonnegative()
2585
- }).transform(({ type, owner, count }) => ({
2586
- type,
2587
- operations: [
2588
- {
2589
- opType: "recordSet",
2590
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
2591
- key: owner,
2592
- value: count
2593
- }
2594
- ]
2595
- }));
2596
-
2597
- // src/state/definitions/claims.ts
2598
- var stellarClaimsStateDefinitions = [
2599
- {
2600
- type: stellarStateCallTypes.pendingClaims,
2601
- mode: "write",
2602
- schema: pendingClaimsWriteSchema
2603
- },
2604
- {
2605
- type: stellarStateCallTypes.clearPendingClaims,
2606
- mode: "write",
2607
- schema: clearPendingClaimsSchema
2608
- },
2609
- {
2610
- type: stellarStateCallTypes.readPendingClaims,
2611
- mode: "read",
2612
- schema: readPendingClaimsSchema
2613
- },
2614
- {
2615
- type: stellarStateCallTypes.replacePendingClaimsPage,
2616
- mode: "write",
2617
- schema: replacePendingClaimsPageSchema
2618
- },
2619
- {
2620
- type: stellarStateCallTypes.upsertPendingClaims,
2621
- mode: "write",
2622
- schema: upsertPendingClaimsSchema
2623
- },
2624
- {
2625
- type: stellarStateCallTypes.removePendingClaims,
2626
- mode: "write",
2627
- schema: removePendingClaimsSchema
2628
- },
2629
- {
2630
- type: stellarStateCallTypes.readPendingClaimsCount,
2631
- mode: "read",
2632
- schema: readPendingClaimsCountSchema
2633
- },
2634
- {
2635
- type: stellarStateCallTypes.setPendingClaimsCount,
2636
- mode: "write",
2637
- schema: setPendingClaimsCountSchema
2638
- }
2639
- ];
2640
-
2641
3317
  // src/state/schemas/claims/deliveries.ts
2642
- import { z as z7 } from "zod";
2643
- var readIncomingDeliveriesSchema = z7.object({
2644
- type: z7.literal(stellarStateCallTypes.readIncomingDeliveries)
3318
+ import { z as z5 } from "zod";
3319
+ var readIncomingDeliveriesSchema = z5.object({
3320
+ type: z5.literal(stellarStateCallTypes.readIncomingDeliveries)
2645
3321
  }).transform(({ type }) => ({
2646
3322
  type,
2647
3323
  operations: [
@@ -2651,9 +3327,9 @@ var readIncomingDeliveriesSchema = z7.object({
2651
3327
  }
2652
3328
  ]
2653
3329
  }));
2654
- var upsertIncomingDeliveriesSchema = z7.object({
2655
- type: z7.literal(stellarStateCallTypes.upsertIncomingDeliveries),
2656
- deliveries: z7.array(incomingDeliverySchema)
3330
+ var upsertIncomingDeliveriesSchema = z5.object({
3331
+ type: z5.literal(stellarStateCallTypes.upsertIncomingDeliveries),
3332
+ deliveries: z5.array(incomingDeliverySchema)
2657
3333
  }).transform(({ type, deliveries }) => ({
2658
3334
  type,
2659
3335
  operations: deliveries.map((delivery) => ({
@@ -2663,10 +3339,10 @@ var upsertIncomingDeliveriesSchema = z7.object({
2663
3339
  value: delivery
2664
3340
  }))
2665
3341
  }));
2666
- var readDeliverySyncStateSchema = z7.object({
2667
- type: z7.literal(stellarStateCallTypes.readDeliverySyncState),
2668
- privateAddress: z7.string().min(1),
2669
- asset: z7.string().min(1)
3342
+ var readDeliverySyncStateSchema = z5.object({
3343
+ type: z5.literal(stellarStateCallTypes.readDeliverySyncState),
3344
+ privateAddress: z5.string().min(1),
3345
+ asset: z5.string().min(1)
2670
3346
  }).transform(({ type, privateAddress, asset }) => ({
2671
3347
  type,
2672
3348
  operations: [
@@ -2677,8 +3353,8 @@ var readDeliverySyncStateSchema = z7.object({
2677
3353
  }
2678
3354
  ]
2679
3355
  }));
2680
- var setDeliverySyncStateSchema = z7.object({
2681
- type: z7.literal(stellarStateCallTypes.setDeliverySyncState),
3356
+ var setDeliverySyncStateSchema = z5.object({
3357
+ type: z5.literal(stellarStateCallTypes.setDeliverySyncState),
2682
3358
  syncState: deliverySyncStateSchema
2683
3359
  }).transform(({ type, syncState }) => ({
2684
3360
  type,
@@ -2717,10 +3393,10 @@ var stellarDeliveriesStateDefinitions = [
2717
3393
  ];
2718
3394
 
2719
3395
  // src/state/schemas/pool/merkle.ts
2720
- import { z as z8 } from "zod";
2721
- var readPoolMerkleStateSchema = z8.object({
2722
- type: z8.literal(stellarStateCallTypes.readPoolMerkleState),
2723
- poolContract: z8.string().min(1)
3396
+ import { z as z6 } from "zod";
3397
+ var readPoolMerkleStateSchema = z6.object({
3398
+ type: z6.literal(stellarStateCallTypes.readPoolMerkleState),
3399
+ poolContract: z6.string().min(1)
2724
3400
  }).transform(({ type, poolContract }) => ({
2725
3401
  type,
2726
3402
  operations: [
@@ -2731,8 +3407,8 @@ var readPoolMerkleStateSchema = z8.object({
2731
3407
  }
2732
3408
  ]
2733
3409
  }));
2734
- var setPoolMerkleStateSchema = z8.object({
2735
- type: z8.literal(stellarStateCallTypes.setPoolMerkleState),
3410
+ var setPoolMerkleStateSchema = z6.object({
3411
+ type: z6.literal(stellarStateCallTypes.setPoolMerkleState),
2736
3412
  state: poolMerkleStateSchema
2737
3413
  }).transform(({ type, state }) => ({
2738
3414
  type,
@@ -2745,10 +3421,10 @@ var setPoolMerkleStateSchema = z8.object({
2745
3421
  }
2746
3422
  ]
2747
3423
  }));
2748
- var readLeafEphemeralSchema = z8.object({
2749
- type: z8.literal(stellarStateCallTypes.readLeafEphemeral),
2750
- poolContract: z8.string().min(1),
2751
- leafIndex: z8.number().int().nonnegative()
3424
+ var readLeafEphemeralSchema = z6.object({
3425
+ type: z6.literal(stellarStateCallTypes.readLeafEphemeral),
3426
+ poolContract: z6.string().min(1),
3427
+ leafIndex: z6.number().int().nonnegative()
2752
3428
  }).transform(({ type, poolContract, leafIndex }) => ({
2753
3429
  type,
2754
3430
  operations: [
@@ -2759,8 +3435,8 @@ var readLeafEphemeralSchema = z8.object({
2759
3435
  }
2760
3436
  ]
2761
3437
  }));
2762
- var setLeafEphemeralSchema = z8.object({
2763
- type: z8.literal(stellarStateCallTypes.setLeafEphemeral),
3438
+ var setLeafEphemeralSchema = z6.object({
3439
+ type: z6.literal(stellarStateCallTypes.setLeafEphemeral),
2764
3440
  ephemeral: leafEphemeralSchema
2765
3441
  }).transform(({ type, ephemeral }) => ({
2766
3442
  type,
@@ -2799,9 +3475,9 @@ var stellarPoolStateDefinitions = [
2799
3475
  ];
2800
3476
 
2801
3477
  // src/state/schemas/records/private.ts
2802
- import { z as z9 } from "zod";
2803
- var listPrivateRecordsSchema = z9.object({
2804
- type: z9.literal(stellarStateCallTypes.listPrivateRecords)
3478
+ import { z as z7 } from "zod";
3479
+ var listPrivateRecordsSchema = z7.object({
3480
+ type: z7.literal(stellarStateCallTypes.listPrivateRecords)
2805
3481
  }).transform(({ type }) => ({
2806
3482
  type,
2807
3483
  operations: [
@@ -2811,9 +3487,9 @@ var listPrivateRecordsSchema = z9.object({
2811
3487
  }
2812
3488
  ]
2813
3489
  }));
2814
- var savePrivateRecordsSchema = z9.object({
2815
- type: z9.literal(stellarStateCallTypes.savePrivateRecords),
2816
- records: z9.array(privateRecordSchema)
3490
+ var savePrivateRecordsSchema = z7.object({
3491
+ type: z7.literal(stellarStateCallTypes.savePrivateRecords),
3492
+ records: z7.array(privateRecordSchema)
2817
3493
  }).transform(({ type, records }) => ({
2818
3494
  type,
2819
3495
  operations: [
@@ -2824,9 +3500,9 @@ var savePrivateRecordsSchema = z9.object({
2824
3500
  }
2825
3501
  ]
2826
3502
  }));
2827
- var replacePrivateRecordsSchema = z9.object({
2828
- type: z9.literal(stellarStateCallTypes.replacePrivateRecords),
2829
- records: z9.array(privateRecordSchema)
3503
+ var replacePrivateRecordsSchema = z7.object({
3504
+ type: z7.literal(stellarStateCallTypes.replacePrivateRecords),
3505
+ records: z7.array(privateRecordSchema)
2830
3506
  }).transform(({ type, records }) => ({
2831
3507
  type,
2832
3508
  operations: [
@@ -2841,18 +3517,18 @@ var replacePrivateRecordsSchema = z9.object({
2841
3517
  }
2842
3518
  ]
2843
3519
  }));
2844
- var pruneConsumedPrivateRecordsSchema = z9.object({
2845
- type: z9.literal(stellarStateCallTypes.pruneConsumedPrivateRecords)
3520
+ var pruneConsumedPrivateRecordsSchema = z7.object({
3521
+ type: z7.literal(stellarStateCallTypes.pruneConsumedPrivateRecords)
2846
3522
  }).transform(({ type }) => ({
2847
3523
  type,
2848
3524
  operations: [rejectConsumedPrivateRecords()]
2849
3525
  }));
2850
3526
 
2851
3527
  // src/state/schemas/records/transactions.ts
2852
- import { z as z10 } from "zod";
2853
- var upsertPrivateRecordsSchema = z10.object({
2854
- type: z10.literal(stellarStateCallTypes.upsertPrivateRecords),
2855
- records: z10.array(privateRecordSchema)
3528
+ import { z as z8 } from "zod";
3529
+ var upsertPrivateRecordsSchema = z8.object({
3530
+ type: z8.literal(stellarStateCallTypes.upsertPrivateRecords),
3531
+ records: z8.array(privateRecordSchema)
2856
3532
  }).transform(({ type, records }) => ({
2857
3533
  type,
2858
3534
  operations: [
@@ -2864,9 +3540,9 @@ var upsertPrivateRecordsSchema = z10.object({
2864
3540
  }
2865
3541
  ]
2866
3542
  }));
2867
- var readTransactionStatusSchema = z10.object({
2868
- type: z10.literal(stellarStateCallTypes.readTransactionStatus),
2869
- txHash: z10.string().min(1)
3543
+ var readTransactionStatusSchema = z8.object({
3544
+ type: z8.literal(stellarStateCallTypes.readTransactionStatus),
3545
+ txHash: z8.string().min(1)
2870
3546
  }).transform(({ type, txHash }) => ({
2871
3547
  type,
2872
3548
  operations: [
@@ -2877,8 +3553,8 @@ var readTransactionStatusSchema = z10.object({
2877
3553
  }
2878
3554
  ]
2879
3555
  }));
2880
- var setTransactionStatusSchema = z10.object({
2881
- type: z10.literal(stellarStateCallTypes.setTransactionStatus),
3556
+ var setTransactionStatusSchema = z8.object({
3557
+ type: z8.literal(stellarStateCallTypes.setTransactionStatus),
2882
3558
  status: transactionStatusSchema
2883
3559
  }).transform(({ type, status }) => ({
2884
3560
  type,
@@ -2891,9 +3567,9 @@ var setTransactionStatusSchema = z10.object({
2891
3567
  }
2892
3568
  ]
2893
3569
  }));
2894
- var clearTransactionStatusSchema = z10.object({
2895
- type: z10.literal(stellarStateCallTypes.clearTransactionStatus),
2896
- txHash: z10.string().min(1)
3570
+ var clearTransactionStatusSchema = z8.object({
3571
+ type: z8.literal(stellarStateCallTypes.clearTransactionStatus),
3572
+ txHash: z8.string().min(1)
2897
3573
  }).transform(({ type, txHash }) => ({
2898
3574
  type,
2899
3575
  operations: [
@@ -2935,10 +3611,10 @@ var stellarRecordsStateDefinitions = [
2935
3611
  ];
2936
3612
 
2937
3613
  // src/state/schemas/registry/lookup.ts
2938
- import { z as z11 } from "zod";
2939
- var readStellarAddressRegisteredSchema = z11.object({
2940
- type: z11.literal(stellarStateCallTypes.readStellarAddressRegistered),
2941
- address: z11.string().min(1)
3614
+ import { z as z9 } from "zod";
3615
+ var readStellarAddressRegisteredSchema = z9.object({
3616
+ type: z9.literal(stellarStateCallTypes.readStellarAddressRegistered),
3617
+ address: z9.string().min(1)
2942
3618
  }).transform(({ type, address }) => ({
2943
3619
  type,
2944
3620
  operations: [
@@ -2949,9 +3625,9 @@ var readStellarAddressRegisteredSchema = z11.object({
2949
3625
  }
2950
3626
  ]
2951
3627
  }));
2952
- var readCachedPrivateAddressSchema = z11.object({
2953
- type: z11.literal(stellarStateCallTypes.readCachedPrivateAddress),
2954
- address: z11.string().min(1)
3628
+ var readCachedPrivateAddressSchema = z9.object({
3629
+ type: z9.literal(stellarStateCallTypes.readCachedPrivateAddress),
3630
+ address: z9.string().min(1)
2955
3631
  }).transform(({ type, address }) => ({
2956
3632
  type,
2957
3633
  operations: [
@@ -2962,11 +3638,11 @@ var readCachedPrivateAddressSchema = z11.object({
2962
3638
  }
2963
3639
  ]
2964
3640
  }));
2965
- var saveRegisteredPrivateAddressSchema = z11.object({
2966
- type: z11.literal(stellarStateCallTypes.saveRegisteredPrivateAddress),
2967
- address: z11.string().min(1),
2968
- privateAddress: z11.string().min(1),
2969
- registered: z11.boolean()
3641
+ var saveRegisteredPrivateAddressSchema = z9.object({
3642
+ type: z9.literal(stellarStateCallTypes.saveRegisteredPrivateAddress),
3643
+ address: z9.string().min(1),
3644
+ privateAddress: z9.string().min(1),
3645
+ registered: z9.boolean()
2970
3646
  }).transform(({ type, address, privateAddress, registered: registered2 }) => {
2971
3647
  const lookup = registryLookupSchema.parse({
2972
3648
  owner: address,
@@ -2998,9 +3674,9 @@ var saveRegisteredPrivateAddressSchema = z11.object({
2998
3674
  ]
2999
3675
  };
3000
3676
  });
3001
- var invalidateRegisteredAddressSchema = z11.object({
3002
- type: z11.literal(stellarStateCallTypes.invalidateRegisteredAddress),
3003
- address: z11.string().min(1)
3677
+ var invalidateRegisteredAddressSchema = z9.object({
3678
+ type: z9.literal(stellarStateCallTypes.invalidateRegisteredAddress),
3679
+ address: z9.string().min(1)
3004
3680
  }).transform(({ type, address }) => ({
3005
3681
  type,
3006
3682
  operations: [
@@ -3021,9 +3697,9 @@ var invalidateRegisteredAddressSchema = z11.object({
3021
3697
  }
3022
3698
  ]
3023
3699
  }));
3024
- var readRegistryLookupSchema = z11.object({
3025
- type: z11.literal(stellarStateCallTypes.readRegistryLookup),
3026
- address: z11.string().min(1)
3700
+ var readRegistryLookupSchema = z9.object({
3701
+ type: z9.literal(stellarStateCallTypes.readRegistryLookup),
3702
+ address: z9.string().min(1)
3027
3703
  }).transform(({ type, address }) => ({
3028
3704
  type,
3029
3705
  operations: [
@@ -3034,8 +3710,8 @@ var readRegistryLookupSchema = z11.object({
3034
3710
  }
3035
3711
  ]
3036
3712
  }));
3037
- var saveRegistryLookupSchema = z11.object({
3038
- type: z11.literal(stellarStateCallTypes.saveRegistryLookup),
3713
+ var saveRegistryLookupSchema = z9.object({
3714
+ type: z9.literal(stellarStateCallTypes.saveRegistryLookup),
3039
3715
  lookup: registryLookupSchema
3040
3716
  }).transform(({ type, lookup }) => {
3041
3717
  const operations = [
@@ -3071,9 +3747,9 @@ var saveRegistryLookupSchema = z11.object({
3071
3747
  }
3072
3748
  return { type, operations };
3073
3749
  });
3074
- var invalidateRegistryLookupSchema = z11.object({
3075
- type: z11.literal(stellarStateCallTypes.invalidateRegistryLookup),
3076
- address: z11.string().min(1)
3750
+ var invalidateRegistryLookupSchema = z9.object({
3751
+ type: z9.literal(stellarStateCallTypes.invalidateRegistryLookup),
3752
+ address: z9.string().min(1)
3077
3753
  }).transform(({ type, address }) => ({
3078
3754
  type,
3079
3755
  operations: [
@@ -3154,9 +3830,9 @@ var stellarTransactionStateDefinitions = [
3154
3830
  ];
3155
3831
 
3156
3832
  // src/state/schemas/wallet/scalar.ts
3157
- import { z as z12 } from "zod";
3158
- var saveWalletPrivateAddressScalarSchema = z12.object({
3159
- type: z12.literal(stellarStateCallTypes.saveWalletPrivateAddressScalar),
3833
+ import { z as z10 } from "zod";
3834
+ var saveWalletPrivateAddressScalarSchema = z10.object({
3835
+ type: z10.literal(stellarStateCallTypes.saveWalletPrivateAddressScalar),
3160
3836
  scalar: walletPrivateAddressScalarSchema
3161
3837
  }).transform(({ type, scalar }) => ({
3162
3838
  type,
@@ -3169,10 +3845,10 @@ var saveWalletPrivateAddressScalarSchema = z12.object({
3169
3845
  }
3170
3846
  ]
3171
3847
  }));
3172
- var readWalletPrivateAddressScalarSchema = z12.object({
3173
- type: z12.literal(stellarStateCallTypes.readWalletPrivateAddressScalar),
3174
- owner: z12.string().min(1),
3175
- nonce: z12.string().min(1)
3848
+ var readWalletPrivateAddressScalarSchema = z10.object({
3849
+ type: z10.literal(stellarStateCallTypes.readWalletPrivateAddressScalar),
3850
+ owner: z10.string().min(1),
3851
+ nonce: z10.string().min(1)
3176
3852
  }).transform(({ type, owner, nonce }) => ({
3177
3853
  type,
3178
3854
  operations: [
@@ -3185,9 +3861,9 @@ var readWalletPrivateAddressScalarSchema = z12.object({
3185
3861
  }));
3186
3862
 
3187
3863
  // src/state/schemas/wallet/private-address.ts
3188
- import { z as z13 } from "zod";
3189
- var saveWalletPrivateAddressRecordSchema = z13.object({
3190
- type: z13.literal(stellarStateCallTypes.saveWalletPrivateAddressRecord),
3864
+ import { z as z11 } from "zod";
3865
+ var saveWalletPrivateAddressRecordSchema = z11.object({
3866
+ type: z11.literal(stellarStateCallTypes.saveWalletPrivateAddressRecord),
3191
3867
  record: walletPrivateAddressRecordSchema
3192
3868
  }).transform(({ type, record }) => ({
3193
3869
  type,
@@ -3200,10 +3876,10 @@ var saveWalletPrivateAddressRecordSchema = z13.object({
3200
3876
  }
3201
3877
  ]
3202
3878
  }));
3203
- var readWalletPrivateAddressRecordSchema = z13.object({
3204
- type: z13.literal(stellarStateCallTypes.readWalletPrivateAddressRecord),
3205
- owner: z13.string().min(1),
3206
- nonce: z13.string().min(1)
3879
+ var readWalletPrivateAddressRecordSchema = z11.object({
3880
+ type: z11.literal(stellarStateCallTypes.readWalletPrivateAddressRecord),
3881
+ owner: z11.string().min(1),
3882
+ nonce: z11.string().min(1)
3207
3883
  }).transform(({ type, owner, nonce }) => ({
3208
3884
  type,
3209
3885
  operations: [
@@ -3214,10 +3890,10 @@ var readWalletPrivateAddressRecordSchema = z13.object({
3214
3890
  }
3215
3891
  ]
3216
3892
  }));
3217
- var setWalletDefaultPrivateAddressNonceSchema = z13.object({
3218
- type: z13.literal(stellarStateCallTypes.setWalletDefaultPrivateAddressNonce),
3219
- owner: z13.string().min(1),
3220
- nonce: z13.string().min(1)
3893
+ var setWalletDefaultPrivateAddressNonceSchema = z11.object({
3894
+ type: z11.literal(stellarStateCallTypes.setWalletDefaultPrivateAddressNonce),
3895
+ owner: z11.string().min(1),
3896
+ nonce: z11.string().min(1)
3221
3897
  }).transform(({ type, owner, nonce }) => ({
3222
3898
  type,
3223
3899
  operations: [
@@ -3229,9 +3905,9 @@ var setWalletDefaultPrivateAddressNonceSchema = z13.object({
3229
3905
  }
3230
3906
  ]
3231
3907
  }));
3232
- var readWalletDefaultPrivateAddressNonceSchema = z13.object({
3233
- type: z13.literal(stellarStateCallTypes.readWalletDefaultPrivateAddressNonce),
3234
- owner: z13.string().min(1)
3908
+ var readWalletDefaultPrivateAddressNonceSchema = z11.object({
3909
+ type: z11.literal(stellarStateCallTypes.readWalletDefaultPrivateAddressNonce),
3910
+ owner: z11.string().min(1)
3235
3911
  }).transform(({ type, owner }) => ({
3236
3912
  type,
3237
3913
  operations: [
@@ -3242,10 +3918,10 @@ var readWalletDefaultPrivateAddressNonceSchema = z13.object({
3242
3918
  }
3243
3919
  ]
3244
3920
  }));
3245
- var deleteWalletPrivateAddressScalarSchema = z13.object({
3246
- type: z13.literal(stellarStateCallTypes.deleteWalletPrivateAddressScalar),
3247
- owner: z13.string().min(1),
3248
- nonce: z13.string().min(1)
3921
+ var deleteWalletPrivateAddressScalarSchema = z11.object({
3922
+ type: z11.literal(stellarStateCallTypes.deleteWalletPrivateAddressScalar),
3923
+ owner: z11.string().min(1),
3924
+ nonce: z11.string().min(1)
3249
3925
  }).transform(({ type, owner, nonce }) => ({
3250
3926
  type,
3251
3927
  operations: [
@@ -3299,7 +3975,6 @@ var stellarWalletStateDefinitions = [
3299
3975
  // src/state/definitions/index.ts
3300
3976
  registerStellarArrayFilterSchemas();
3301
3977
  var stellarStateDefinitions = [
3302
- ...stellarClaimsStateDefinitions,
3303
3978
  ...stellarRegistryStateDefinitions,
3304
3979
  ...stellarAssetsStateDefinitions,
3305
3980
  ...stellarBalancesStateDefinitions,
@@ -3423,112 +4098,10 @@ function createAssetsCatalogMethods(context) {
3423
4098
  }
3424
4099
 
3425
4100
  // src/state/service/assets/index.ts
3426
- function createAssetsService(context) {
3427
- return {
3428
- ...createAssetsCatalogMethods(context),
3429
- ...createPublicBalanceMethods(context)
3430
- };
3431
- }
3432
-
3433
- // src/state/service/claims/read-methods.ts
3434
- function createClaimsReadMethods(context) {
3435
- const { bridge } = context;
3436
- async function getPendingClaims(filter = {}) {
3437
- const value = await bridge.read({
3438
- type: stellarStateCallTypes.readPendingClaims
3439
- });
3440
- const state = normalizePendingClaimsState(value);
3441
- const items = state.items.filter((claim) => {
3442
- if (filter.owner !== void 0 && claim.owner !== filter.owner) {
3443
- return false;
3444
- }
3445
- if (filter.asset !== void 0 && claim.asset !== filter.asset) {
3446
- return false;
3447
- }
3448
- return true;
3449
- });
3450
- if (state.pagination !== void 0) {
3451
- return { items, pagination: state.pagination };
3452
- }
3453
- return { items };
3454
- }
3455
- return {
3456
- getPendingClaims,
3457
- async getPendingClaimsCount(owner) {
3458
- const value = await bridge.read({
3459
- type: stellarStateCallTypes.readPendingClaimsCount,
3460
- owner
3461
- });
3462
- const count = normalizePendingClaimsCount(value);
3463
- if (count !== void 0) {
3464
- return count;
3465
- }
3466
- const claims = await getPendingClaims({ owner });
3467
- return claims.items.length;
3468
- }
3469
- };
3470
- }
3471
-
3472
- // src/state/service/claims/write-methods.ts
3473
- function appendPendingClaims(bridge, claims, paginationInfo) {
3474
- return bridge.write({
3475
- type: stellarStateCallTypes.pendingClaims,
3476
- claims,
3477
- paginationInfo
3478
- });
3479
- }
3480
- function replacePendingClaimsPage(bridge, input) {
3481
- return bridge.write({
3482
- type: stellarStateCallTypes.replacePendingClaimsPage,
3483
- owner: input.owner,
3484
- claims: input.claims,
3485
- paginationInfo: input.paginationInfo,
3486
- ...input.count === void 0 ? {} : { count: input.count }
3487
- });
3488
- }
3489
- function upsertPendingClaims(bridge, claims) {
3490
- return bridge.write({
3491
- type: stellarStateCallTypes.upsertPendingClaims,
3492
- claims
3493
- });
3494
- }
3495
- function removePendingClaims(bridge, ids) {
3496
- return bridge.write({
3497
- type: stellarStateCallTypes.removePendingClaims,
3498
- ids
3499
- });
3500
- }
3501
- function clearPendingClaims(bridge, input = {}) {
3502
- return bridge.write({
3503
- type: stellarStateCallTypes.clearPendingClaims,
3504
- ...input.owner === void 0 ? {} : { owner: input.owner },
3505
- ...input.asset === void 0 ? {} : { asset: input.asset }
3506
- });
3507
- }
3508
- function setPendingClaimsCount(bridge, owner, count) {
3509
- return bridge.write({
3510
- type: stellarStateCallTypes.setPendingClaimsCount,
3511
- owner,
3512
- count
3513
- });
3514
- }
3515
- function createClaimsWriteMethods(context) {
3516
- const { bridge } = context;
3517
- return {
3518
- appendPendingClaims: (claims, paginationInfo) => appendPendingClaims(bridge, claims, paginationInfo),
3519
- replacePendingClaimsPage: (input) => replacePendingClaimsPage(bridge, input),
3520
- upsertPendingClaims: (claims) => upsertPendingClaims(bridge, claims),
3521
- removePendingClaims: (ids) => removePendingClaims(bridge, ids),
3522
- clearPendingClaims: (input = {}) => clearPendingClaims(bridge, input),
3523
- setPendingClaimsCount: (owner, count) => setPendingClaimsCount(bridge, owner, count)
3524
- };
3525
- }
3526
-
3527
- // src/state/service/claims/index.ts
3528
- function createClaimsService(context) {
4101
+ function createAssetsService(context) {
3529
4102
  return {
3530
- ...createClaimsWriteMethods(context),
3531
- ...createClaimsReadMethods(context)
4103
+ ...createAssetsCatalogMethods(context),
4104
+ ...createPublicBalanceMethods(context)
3532
4105
  };
3533
4106
  }
3534
4107
 
@@ -4057,7 +4630,6 @@ function composeStellarStateService(adapter) {
4057
4630
  ...createWalletAddressService(base),
4058
4631
  ...createPoolMerkleService(base),
4059
4632
  ...createPoolEphemeralService(base),
4060
- ...createClaimsService(base),
4061
4633
  ...createDeliveriesService(base),
4062
4634
  ...createRecordsService(base)
4063
4635
  };
@@ -4122,42 +4694,1030 @@ function attachPoolStatePorts(transactEnvironment, state) {
4122
4694
  resolveSenderPrivKeyScalarFromState: createSenderScalarStateResolver(state)
4123
4695
  };
4124
4696
  }
4697
+
4698
+ // src/transact/encoding/ephemeral-key.ts
4699
+ var HEX_64_RE = /^[\da-f]{64}$/iu;
4700
+ function normalizeCoordinate(value) {
4701
+ const hex = value.trim().replace(/^0x/iu, "").toLowerCase();
4702
+ if (!HEX_64_RE.test(hex)) {
4703
+ throw new Error("Ephemeral key coordinate must be a 32-byte hex string.");
4704
+ }
4705
+ return hex;
4706
+ }
4707
+ function serializeEphemeralKeyString(point) {
4708
+ return `${normalizeCoordinate(point.xHex)}:${normalizeCoordinate(point.yHex)}`;
4709
+ }
4710
+
4711
+ // src/transact/private-address/record-coin.ts
4712
+ function requireCoinNoteFromRecord(record) {
4713
+ if (!record.coinNote) {
4714
+ throw new Error(`Private record ${record.id} is missing coin note data.`);
4715
+ }
4716
+ return record.coinNote;
4717
+ }
4718
+ function findCommitmentLeafIndex(commitments, commitment) {
4719
+ return commitments.indexOf(commitment);
4720
+ }
4721
+
4722
+ // src/transact/engine/prepare/shared.ts
4723
+ async function resolveTokenContractId2(environment, assetId) {
4724
+ if (environment.resolveTokenContractId) {
4725
+ return environment.resolveTokenContractId(assetId);
4726
+ }
4727
+ throw new Error(`Token contract is not configured for asset ${assetId}.`);
4728
+ }
4729
+ async function resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
4730
+ const cached = await readSenderPrivKeyScalarHex(
4731
+ environment,
4732
+ privateAddressStpl1,
4733
+ owner
4734
+ );
4735
+ if (cached) {
4736
+ return cached;
4737
+ }
4738
+ if (environment.ensureSenderPrivKeyScalarHex) {
4739
+ return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
4740
+ }
4741
+ if (!environment.resolveSenderPrivKeyScalarHex) {
4742
+ throw new Error("Sender private key scalar resolver is not configured.");
4743
+ }
4744
+ return environment.resolveSenderPrivKeyScalarHex(privateAddressStpl1);
4745
+ }
4746
+ async function readSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
4747
+ if (owner && environment.resolveSenderPrivKeyScalarFromState) {
4748
+ const fromState = await environment.resolveSenderPrivKeyScalarFromState({
4749
+ owner,
4750
+ privateAddressStpl1
4751
+ });
4752
+ if (fromState?.trim()) {
4753
+ return fromState.trim();
4754
+ }
4755
+ }
4756
+ if (environment.readSenderPrivKeyScalarHex) {
4757
+ const cached = await environment.readSenderPrivKeyScalarHex(privateAddressStpl1);
4758
+ if (cached?.trim()) {
4759
+ return cached.trim();
4760
+ }
4761
+ }
4762
+ return void 0;
4763
+ }
4764
+ async function ensureSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
4765
+ const cached = await readSenderPrivKeyScalarHex(
4766
+ environment,
4767
+ privateAddressStpl1,
4768
+ owner
4769
+ );
4770
+ if (cached) {
4771
+ return cached;
4772
+ }
4773
+ if (environment.ensureSenderPrivKeyScalarHex) {
4774
+ return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
4775
+ }
4776
+ return resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner);
4777
+ }
4778
+ async function loadMerkleState(environment, walletPublicKey) {
4779
+ const merged = await fetchAndMergeMerkleState({
4780
+ poolContractId: environment.network.poolContract,
4781
+ walletPublicKey,
4782
+ transactEnvironment: environment,
4783
+ ...environment.poolMerkleState ? { poolMerkleState: environment.poolMerkleState } : {}
4784
+ });
4785
+ return { commitments: merged.commitments };
4786
+ }
4787
+
4788
+ // src/transact/escrow/require-escrow-spend-scalar.ts
4789
+ function isEscrowSweepSpend(artifacts) {
4790
+ return artifacts?.spendSource === "escrow" && artifacts.escrowSend !== true;
4791
+ }
4792
+ function requireEscrowSpendScalarHex(artifacts) {
4793
+ if (!isEscrowSweepSpend(artifacts)) {
4794
+ throw new Error("Escrow sweep requires spendSource escrow.");
4795
+ }
4796
+ const hex = artifacts?.escrowSpendScalarHex?.trim();
4797
+ if (!hex) {
4798
+ throw new Error("Escrow sweep requires the reconstructed note owner scalar.");
4799
+ }
4800
+ return hex;
4801
+ }
4802
+ function nullifierCheckSpendScalarHex(artifacts) {
4803
+ if (!isEscrowSweepSpend(artifacts)) {
4804
+ return void 0;
4805
+ }
4806
+ return requireEscrowSpendScalarHex(artifacts);
4807
+ }
4808
+
4809
+ // src/transact/transfer-source/resolve.ts
4810
+ function readTransferFromPrivateAddress(from) {
4811
+ return from.trim();
4812
+ }
4813
+
4814
+ // src/transact/transfer-source/verify-private-records.ts
4815
+ import { executionError, insufficientStateError as insufficientStateError2 } from "@arcanetech/privacy-sdk-core";
4816
+
4817
+ // src/contracts/pool/pool-domain-service.ts
4818
+ import { Buffer as Buffer14 } from "buffer";
4819
+ function hexToBuffer(hex) {
4820
+ const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
4821
+ return Buffer14.from(clean, "hex");
4822
+ }
4823
+ async function readNullifierConsumedOnChain(input) {
4824
+ const client = input.contractContext.createPoolClient({
4825
+ contractId: input.poolContractId,
4826
+ walletPublicKey: input.walletPublicKey,
4827
+ networkPassphrase: input.contractContext.network.networkPassphrase,
4828
+ sorobanRpcUrl: input.contractContext.network.rpcUrl
4829
+ });
4830
+ const read = await client.is_nulifier_hash_consumed({
4831
+ hash: hexToBuffer(input.nullifierHashHex)
4832
+ });
4833
+ return read.result;
4834
+ }
4835
+
4836
+ // src/transact/transfer-source/verify-private-records.ts
4837
+ async function resolveNullifierSpendScalarHex(input) {
4838
+ const stamped = input.spendScalarHex?.trim();
4839
+ if (stamped) {
4840
+ return stamped;
4841
+ }
4842
+ const privateAddress = input.record.privateAddress?.trim();
4843
+ if (!privateAddress) {
4844
+ throw executionError(
4845
+ "Private record is missing a private address; cannot derive the owner-bound spend scalar.",
4846
+ "validation",
4847
+ {
4848
+ reason: "private_record_missing_private_address",
4849
+ recordId: input.record.id
4850
+ }
4851
+ );
4852
+ }
4853
+ return ensureSenderPrivKeyScalarHex(
4854
+ input.environment,
4855
+ privateAddress,
4856
+ input.walletPublicKey
4857
+ );
4858
+ }
4859
+ async function readPrivateRecordNullifierSpendStatus(input) {
4860
+ const coin = requireCoinNoteFromRecord(input.record);
4861
+ const scalarHex = await resolveNullifierSpendScalarHex(input);
4862
+ const nullifierHashHex = await getPrivacyPoolService().calculateNullifierHash(
4863
+ coin.nullifier,
4864
+ privKeyScalarDecimalFromRecipientScalarHex(scalarHex)
4865
+ );
4866
+ const contractContext = requireContractContext(input.environment);
4867
+ const poolContractId = input.poolContractId?.trim() || contractContext.network.poolContract;
4868
+ const spent = await readNullifierConsumedOnChain({
4869
+ contractContext,
4870
+ poolContractId,
4871
+ walletPublicKey: input.walletPublicKey.trim(),
4872
+ nullifierHashHex
4873
+ });
4874
+ return { spent, nullifierHashHex };
4875
+ }
4876
+ async function verifyPrivateRecordsNullifiersBeforeExecute(input) {
4877
+ for (const record of input.records) {
4878
+ const status = await readPrivateRecordNullifierSpendStatus({
4879
+ record,
4880
+ environment: input.environment,
4881
+ walletPublicKey: input.walletPublicKey,
4882
+ ...input.poolContractId ? { poolContractId: input.poolContractId } : {},
4883
+ ...input.spendScalarHex ? { spendScalarHex: input.spendScalarHex } : {}
4884
+ });
4885
+ if (status.spent) {
4886
+ throw executionError(
4887
+ "Private input note nullifier was already spent on-chain.",
4888
+ "validation",
4889
+ {
4890
+ reason: "private_record_nullifier_spent",
4891
+ recordId: record.id,
4892
+ nullifierHashHex: status.nullifierHashHex
4893
+ }
4894
+ );
4895
+ }
4896
+ }
4897
+ }
4898
+
4899
+ // src/transact/engine/spend-proof-context.ts
4900
+ async function resolveSenderPrivKeyScalarHex2(input) {
4901
+ if (isEscrowSweepSpend(input.prepared.transactArtifacts)) {
4902
+ return requireEscrowSpendScalarHex(input.prepared.transactArtifacts);
4903
+ }
4904
+ if (input.prepared.kind !== "transfer" && input.prepared.kind !== "withdraw") {
4905
+ throw new Error("Spend execution requires a transfer or withdraw intent.");
4906
+ }
4907
+ return ensureSenderPrivKeyScalarHex(
4908
+ input.environment,
4909
+ readTransferFromPrivateAddress(input.prepared.intent.from),
4910
+ input.walletPublicKey
4911
+ );
4912
+ }
4913
+ async function buildSpendProofContextAtExecute(input) {
4914
+ const [primaryRecord] = input.prepared.consumedRecords;
4915
+ if (!primaryRecord) {
4916
+ throw new Error("Spend execution requires at least one private record.");
4917
+ }
4918
+ const walletPublicKey = primaryRecord.owner.trim();
4919
+ if (!walletPublicKey) {
4920
+ throw new Error("Spend execution record owner is missing.");
4921
+ }
4922
+ const senderPrivKeyScalarHex = await resolveSenderPrivKeyScalarHex2({
4923
+ prepared: input.prepared,
4924
+ environment: input.environment,
4925
+ walletPublicKey
4926
+ });
4927
+ const tokenAddress = await resolveTokenContractId2(
4928
+ input.environment,
4929
+ input.prepared.intent.asset
4930
+ );
4931
+ const coin = requireCoinNoteFromRecord(primaryRecord);
4932
+ const { commitments } = await loadMerkleState(input.environment, walletPublicKey);
4933
+ const leafIndex = findCommitmentLeafIndex(commitments, coin.commitment);
4934
+ if (leafIndex < 0) {
4935
+ throw new Error("Coin commitment not found in on-chain Merkle state.");
4936
+ }
4937
+ const ephemeral = await readLeafEphemeralHex({
4938
+ poolContractId: input.environment.network.poolContract,
4939
+ walletPublicKey,
4940
+ leafIndex,
4941
+ transactEnvironment: input.environment,
4942
+ ...input.environment.leafEphemeral ? { leafEphemeral: input.environment.leafEphemeral } : {}
4943
+ });
4944
+ return {
4945
+ walletPublicKey,
4946
+ tokenAddress,
4947
+ coin,
4948
+ commitments,
4949
+ ephemeral,
4950
+ senderPrivKeyScalarHex,
4951
+ recipientPrivateAddressStpl1: input.recipientPrivateAddressStpl1
4952
+ };
4953
+ }
4954
+ async function readCoinEphemeralForRecord(input) {
4955
+ const coin = requireCoinNoteFromRecord(input.record);
4956
+ const leafIndex = findCommitmentLeafIndex(input.commitments, coin.commitment);
4957
+ if (leafIndex < 0) {
4958
+ throw new Error("Coin commitment not found in on-chain Merkle state.");
4959
+ }
4960
+ const ephemeral = await readLeafEphemeralHex({
4961
+ poolContractId: input.environment.network.poolContract,
4962
+ walletPublicKey: input.walletPublicKey,
4963
+ leafIndex,
4964
+ transactEnvironment: input.environment,
4965
+ ...input.environment.leafEphemeral ? { leafEphemeral: input.environment.leafEphemeral } : {}
4966
+ });
4967
+ return { coin, ephemeral };
4968
+ }
4969
+
4970
+ // src/transact/engine/prepare/transfer-helpers.ts
4971
+ import { StrKey as StrKey8 } from "@stellar/stellar-sdk";
4972
+ function isStellarAccountRecipient(prepared) {
4973
+ return prepared.kind === "transfer" && StrKey8.isValidEd25519PublicKey(prepared.intent.to.trim());
4974
+ }
4975
+ async function resolveTransferRecipientForExecute(prepared, environment, walletPublicKey) {
4976
+ if (!isStellarAccountRecipient(prepared)) {
4977
+ return {
4978
+ recipientPrivateAddressStpl1: prepared.intent.to.trim()
4979
+ };
4980
+ }
4981
+ if (!environment.resolveTransferRecipientAtExecute) {
4982
+ throw new Error("Transfer recipient resolver is not configured.");
4983
+ }
4984
+ return environment.resolveTransferRecipientAtExecute({
4985
+ recipientStellarAddress: prepared.intent.to.trim(),
4986
+ walletPublicKey
4987
+ });
4988
+ }
4989
+
4990
+ // src/transact/engine/transfer-proof-at-execute.ts
4991
+ function readChangeRecipient(input, changeStroops) {
4992
+ if (changeStroops <= 0n || input.prepared.kind !== "transfer") {
4993
+ return void 0;
4994
+ }
4995
+ const from = input.prepared.intent.from;
4996
+ return readTransferFromPrivateAddress(from);
4997
+ }
4998
+ function proofEscrowFields(input) {
4999
+ return {
5000
+ ...input.escrowSend ? { escrowSend: input.escrowSend } : {},
5001
+ ...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
5002
+ };
5003
+ }
5004
+ async function buildSingleTransferProofAtExecute(input) {
5005
+ const context = await buildSpendProofContextAtExecute(input);
5006
+ const changeStroops = BigInt(context.coin.value) - input.prepared.intent.amount;
5007
+ const proof = await prepareConfidentialTransferProof({
5008
+ coin: context.coin,
5009
+ state: { commitments: context.commitments },
5010
+ senderPrivKeyScalarHex: context.senderPrivKeyScalarHex,
5011
+ depositorEphemeralKey: serializeEphemeralKeyString({
5012
+ xHex: context.ephemeral.xHex,
5013
+ yHex: context.ephemeral.yHex
5014
+ }),
5015
+ transferStroops: input.prepared.intent.amount,
5016
+ recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
5017
+ selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
5018
+ tokenAddress: context.tokenAddress,
5019
+ ...proofEscrowFields(input)
5020
+ });
5021
+ return { context, proof };
5022
+ }
5023
+ async function buildDualTransferProofAtExecute(input) {
5024
+ const [primaryRecord, secondaryRecord] = input.prepared.consumedRecords;
5025
+ if (!primaryRecord || !secondaryRecord) {
5026
+ throw new Error("Dual transfer execution requires two private input records.");
5027
+ }
5028
+ const context = await buildSpendProofContextAtExecute(input);
5029
+ const secondary = await readCoinEphemeralForRecord({
5030
+ record: secondaryRecord,
5031
+ environment: input.environment,
5032
+ walletPublicKey: context.walletPublicKey,
5033
+ commitments: context.commitments
5034
+ });
5035
+ const totalNotes = BigInt(context.coin.value) + BigInt(secondary.coin.value);
5036
+ const changeStroops = totalNotes - input.prepared.intent.amount;
5037
+ const proof = await prepareConfidentialTransferProofDual({
5038
+ coinA: context.coin,
5039
+ coinB: secondary.coin,
5040
+ state: { commitments: context.commitments },
5041
+ senderPrivKeyScalarHex: context.senderPrivKeyScalarHex,
5042
+ ephemeralAKey: serializeEphemeralKeyString({
5043
+ xHex: context.ephemeral.xHex,
5044
+ yHex: context.ephemeral.yHex
5045
+ }),
5046
+ ephemeralBKey: serializeEphemeralKeyString({
5047
+ xHex: secondary.ephemeral.xHex,
5048
+ yHex: secondary.ephemeral.yHex
5049
+ }),
5050
+ transferStroops: input.prepared.intent.amount,
5051
+ recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
5052
+ selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
5053
+ tokenAddress: context.tokenAddress,
5054
+ ...proofEscrowFields(input)
5055
+ });
5056
+ return { context, proof };
5057
+ }
5058
+ async function buildTransferProofAtExecute(input) {
5059
+ const recordCount = input.prepared.consumedRecords.length;
5060
+ if (recordCount === 1) {
5061
+ return buildSingleTransferProofAtExecute(input);
5062
+ }
5063
+ if (recordCount === 2) {
5064
+ return buildDualTransferProofAtExecute(input);
5065
+ }
5066
+ throw new Error("Confidential transfer execution supports at most two input notes.");
5067
+ }
5068
+
5069
+ // src/transact/engine/transfer-finalize.ts
5070
+ function stampEscrowOutputRecords(input) {
5071
+ if (input.escrowSendPrivateAddress) {
5072
+ const [recipientRecord, ...rest] = input.prepared.outputRecords;
5073
+ if (recipientRecord) {
5074
+ input.prepared.outputRecords = [
5075
+ {
5076
+ ...recipientRecord,
5077
+ privateAddress: input.escrowSendPrivateAddress
5078
+ },
5079
+ ...rest
5080
+ ];
5081
+ }
5082
+ }
5083
+ seedEscrowSweepOutputsFromProof({
5084
+ prepared: input.prepared,
5085
+ proof: input.proof,
5086
+ walletPublicKey: input.walletPublicKey
5087
+ });
5088
+ enrichTransferOutputRecords(input.prepared, input.proof);
5089
+ }
5090
+ function seedEscrowSweepOutputsFromProof(input) {
5091
+ if (input.prepared.transactArtifacts?.spendSource !== "escrow" || input.prepared.outputRecords.length > 0) {
5092
+ return;
5093
+ }
5094
+ input.prepared.outputRecords = [
5095
+ {
5096
+ id: input.proof.recipientCoin.commitment_hex,
5097
+ owner: input.walletPublicKey,
5098
+ privateAddress: input.prepared.intent.to,
5099
+ asset: input.prepared.intent.asset,
5100
+ amount: input.prepared.intent.amount,
5101
+ consumed: false
5102
+ }
5103
+ ];
5104
+ }
5105
+ function enrichTransferOutputRecords(prepared, proof) {
5106
+ if (prepared.outputRecords.length === 0) {
5107
+ return;
5108
+ }
5109
+ const generatedOutputCoins = [
5110
+ proof.recipientCoin,
5111
+ ...proof.changeCoin ? [proof.changeCoin] : []
5112
+ ];
5113
+ prepared.outputRecords = prepared.outputRecords.map((record, index) => {
5114
+ const generatedCoin = generatedOutputCoins.at(index);
5115
+ if (!generatedCoin) {
5116
+ return record;
5117
+ }
5118
+ return {
5119
+ ...record,
5120
+ id: generatedCoin.commitment_hex,
5121
+ commitmentHex: generatedCoin.commitment_hex,
5122
+ coinNote: generatedCoin.coin,
5123
+ depositScalarHex: generatedCoin.depositScalarHex,
5124
+ precommitementHex: generatedCoin.precommitementHex
5125
+ };
5126
+ });
5127
+ }
5128
+ function escrowSpendArtifacts(input) {
5129
+ if (input.escrowSend) {
5130
+ return {
5131
+ escrowSend: true,
5132
+ spendSource: "escrow",
5133
+ ...input.escrowRecipient ? { escrowRecipient: input.escrowRecipient } : {}
5134
+ };
5135
+ }
5136
+ if (input.preparedSpendSource === "escrow") {
5137
+ return {
5138
+ spendSource: "escrow",
5139
+ ...input.escrowRecipient ? { escrowRecipient: input.escrowRecipient } : {},
5140
+ ...input.escrowSpendScalarHex ? { escrowSpendScalarHex: input.escrowSpendScalarHex } : {},
5141
+ ...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
5142
+ };
5143
+ }
5144
+ return {};
5145
+ }
5146
+ function buildTransferFinalizeArtifacts(input) {
5147
+ return {
5148
+ proofHex: input.proof.proof_hex,
5149
+ publicHex: input.proof.public_hex,
5150
+ ...ciphertextArtifactsFromProof(input.proof),
5151
+ applicationIdsPlaintext: input.proof.applicationIdsPlaintext,
5152
+ tokenAddress: input.context.tokenAddress,
5153
+ walletPublicKey: input.context.walletPublicKey,
5154
+ executeFinalizeRequired: false,
5155
+ ...escrowSpendArtifacts(input)
5156
+ };
5157
+ }
5158
+ async function runTransferFinalizeSteps(input) {
5159
+ const recipient = await resolveTransferRecipientForExecute(
5160
+ input.prepared,
5161
+ input.environment,
5162
+ input.walletPublicKey
5163
+ );
5164
+ const spendScalarHex = nullifierCheckSpendScalarHex(input.prepared.transactArtifacts);
5165
+ await verifyPrivateRecordsNullifiersBeforeExecute({
5166
+ records: input.prepared.consumedRecords,
5167
+ environment: input.environment,
5168
+ walletPublicKey: input.walletPublicKey,
5169
+ ...spendScalarHex ? { spendScalarHex } : {}
5170
+ });
5171
+ const { context, proof } = await buildTransferProofAtExecute({
5172
+ prepared: input.prepared,
5173
+ environment: input.environment,
5174
+ recipientPrivateAddressStpl1: recipient.recipientPrivateAddressStpl1,
5175
+ ...recipient.escrowSend ? { escrowSend: recipient.escrowSend } : {},
5176
+ ...input.prepared.transactArtifacts?.escrowClaimantLimbs ? {
5177
+ escrowClaimantLimbs: input.prepared.transactArtifacts.escrowClaimantLimbs
5178
+ } : {}
5179
+ });
5180
+ stampEscrowOutputRecords({
5181
+ prepared: input.prepared,
5182
+ proof,
5183
+ walletPublicKey: input.walletPublicKey,
5184
+ ...recipient.escrowSend ? { escrowSendPrivateAddress: recipient.recipientPrivateAddressStpl1 } : {}
5185
+ });
5186
+ return buildTransferFinalizeArtifacts({
5187
+ proof,
5188
+ context,
5189
+ ...sweepFinalizeStamp(input.prepared, recipient)
5190
+ });
5191
+ }
5192
+ function sweepArtifactStamp(artifacts) {
5193
+ return {
5194
+ ...artifacts?.escrowSpendScalarHex ? { escrowSpendScalarHex: artifacts.escrowSpendScalarHex } : {},
5195
+ ...artifacts?.spendSource ? { preparedSpendSource: artifacts.spendSource } : {},
5196
+ ...artifacts?.escrowClaimantLimbs ? { escrowClaimantLimbs: artifacts.escrowClaimantLimbs } : {}
5197
+ };
5198
+ }
5199
+ function sweepFinalizeStamp(prepared, recipient) {
5200
+ const artifacts = prepared.transactArtifacts;
5201
+ const fromSend = recipient.escrowSend?.recipientStellarAddress?.trim();
5202
+ const escrowRecipient = fromSend || artifacts?.escrowRecipient?.trim();
5203
+ return {
5204
+ ...recipient.escrowSend ? { escrowSend: true } : {},
5205
+ ...escrowRecipient ? { escrowRecipient } : {},
5206
+ ...sweepArtifactStamp(artifacts)
5207
+ };
5208
+ }
5209
+ async function finalizeTransferAtExecute(prepared, environment) {
5210
+ const [primaryRecord] = prepared.consumedRecords;
5211
+ if (!primaryRecord?.owner.trim()) {
5212
+ throw new Error("Transfer execution record owner is missing.");
5213
+ }
5214
+ const walletPublicKey = primaryRecord.owner.trim();
5215
+ return runTransferFinalizeSteps({ prepared, environment, walletPublicKey });
5216
+ }
5217
+
5218
+ // src/transact/engine/execute.ts
5219
+ function enrichWithdrawOutputRecords(prepared, proof) {
5220
+ if (!proof.changeCoin || prepared.outputRecords.length === 0) {
5221
+ return;
5222
+ }
5223
+ const changeCoin = proof.changeCoin;
5224
+ prepared.outputRecords = prepared.outputRecords.map((record) => ({
5225
+ ...record,
5226
+ id: changeCoin.commitment_hex,
5227
+ commitmentHex: changeCoin.commitment_hex,
5228
+ coinNote: changeCoin.coin,
5229
+ depositScalarHex: changeCoin.depositScalarHex,
5230
+ precommitementHex: changeCoin.precommitementHex
5231
+ }));
5232
+ }
5233
+ function buildWithdrawFinalizeArtifacts(proof, context) {
5234
+ return {
5235
+ proofHex: proof.proof_hex,
5236
+ publicHex: proof.public_hex,
5237
+ ...ciphertextArtifactsFromProof(proof),
5238
+ applicationIdsPlaintext: proof.applicationIdsPlaintext,
5239
+ tokenAddress: context.tokenAddress,
5240
+ walletPublicKey: context.walletPublicKey,
5241
+ executeFinalizeRequired: false
5242
+ };
5243
+ }
5244
+ async function finalizeSingleWithdrawAtExecute(prepared, environment, poolService, withdrawFrom) {
5245
+ const context = await buildSpendProofContextAtExecute({
5246
+ prepared,
5247
+ environment,
5248
+ recipientPrivateAddressStpl1: withdrawFrom
5249
+ });
5250
+ const changeStroops = BigInt(context.coin.value) - prepared.intent.amount;
5251
+ const proof = await poolService.prepareWithdrawTransactProof({
5252
+ coin: context.coin,
5253
+ state: { commitments: context.commitments },
5254
+ destinationStellarAddress: prepared.intent.to,
5255
+ privKeyScalarHex: context.senderPrivKeyScalarHex,
5256
+ depositorEphemeralKey: serializeEphemeralKeyString({
5257
+ xHex: context.ephemeral.xHex,
5258
+ yHex: context.ephemeral.yHex
5259
+ }),
5260
+ withdrawAmountStroops: prepared.intent.amount,
5261
+ changePrivateAddressStpl1: changeStroops > 0n ? withdrawFrom : void 0,
5262
+ tokenAddress: context.tokenAddress
5263
+ });
5264
+ enrichWithdrawOutputRecords(prepared, proof);
5265
+ return buildWithdrawFinalizeArtifacts(proof, context);
5266
+ }
5267
+ async function finalizeDualWithdrawAtExecute(prepared, environment, poolService, withdrawFrom) {
5268
+ const [, secondaryRecord] = prepared.consumedRecords;
5269
+ if (!secondaryRecord) {
5270
+ throw new Error("Dual withdraw execution requires two private input records.");
5271
+ }
5272
+ const context = await buildSpendProofContextAtExecute({
5273
+ prepared,
5274
+ environment,
5275
+ recipientPrivateAddressStpl1: withdrawFrom
5276
+ });
5277
+ const secondary = await readCoinEphemeralForRecord({
5278
+ record: secondaryRecord,
5279
+ environment,
5280
+ walletPublicKey: context.walletPublicKey,
5281
+ commitments: context.commitments
5282
+ });
5283
+ const totalNotes = BigInt(context.coin.value) + BigInt(secondary.coin.value);
5284
+ const changeStroops = totalNotes - prepared.intent.amount;
5285
+ const proof = await poolService.prepareWithdrawTransactProofDual({
5286
+ coinA: context.coin,
5287
+ coinB: secondary.coin,
5288
+ state: { commitments: context.commitments },
5289
+ destinationStellarAddress: prepared.intent.to,
5290
+ privKeyScalarHex: context.senderPrivKeyScalarHex,
5291
+ depositorEphemeralAKey: serializeEphemeralKeyString({
5292
+ xHex: context.ephemeral.xHex,
5293
+ yHex: context.ephemeral.yHex
5294
+ }),
5295
+ depositorEphemeralBKey: serializeEphemeralKeyString({
5296
+ xHex: secondary.ephemeral.xHex,
5297
+ yHex: secondary.ephemeral.yHex
5298
+ }),
5299
+ withdrawAmountStroops: prepared.intent.amount,
5300
+ changePrivateAddressStpl1: changeStroops > 0n ? withdrawFrom : void 0,
5301
+ tokenAddress: context.tokenAddress
5302
+ });
5303
+ enrichWithdrawOutputRecords(prepared, proof);
5304
+ return buildWithdrawFinalizeArtifacts(proof, context);
5305
+ }
5306
+ async function finalizeWithdrawAtExecute(prepared, environment, poolService) {
5307
+ if (prepared.kind !== "withdraw") {
5308
+ throw new Error("Withdraw finalize requires a withdraw operation.");
5309
+ }
5310
+ const withdrawIntent = prepared.intent;
5311
+ const withdrawFrom = withdrawIntent.from;
5312
+ const recordCount = prepared.consumedRecords.length;
5313
+ if (recordCount === 1) {
5314
+ return finalizeSingleWithdrawAtExecute(
5315
+ prepared,
5316
+ environment,
5317
+ poolService,
5318
+ withdrawFrom
5319
+ );
5320
+ }
5321
+ if (recordCount === 2) {
5322
+ return finalizeDualWithdrawAtExecute(
5323
+ prepared,
5324
+ environment,
5325
+ poolService,
5326
+ withdrawFrom
5327
+ );
5328
+ }
5329
+ throw new Error("Confidential withdraw execution supports at most two input notes.");
5330
+ }
5331
+ async function finalizeSpendOperationAtExecute(prepared, environment, poolService) {
5332
+ if (prepared.kind !== "transfer" && prepared.kind !== "withdraw") {
5333
+ return prepared;
5334
+ }
5335
+ if (prepared.transactArtifacts?.proofHex) {
5336
+ return prepared;
5337
+ }
5338
+ const artifacts = prepared.kind === "transfer" ? await finalizeTransferAtExecute(prepared, environment) : await finalizeWithdrawAtExecute(prepared, environment, poolService);
5339
+ return {
5340
+ ...prepared,
5341
+ transactArtifacts: {
5342
+ ...prepared.transactArtifacts,
5343
+ ...artifacts
5344
+ }
5345
+ };
5346
+ }
5347
+
5348
+ // src/transact/relay/constants.ts
5349
+ var RELAY_TRANSACT_PACKAGE_VERSION_V1 = 1;
5350
+ var RELAY_TRANSACT_SUPPORTED_SIGNAL_COUNT = 93;
5351
+ var RELAY_TRANSACT_FIELD_BYTES = 32;
5352
+ var RELAY_TRANSACT_SIGNAL_PREFIX_BYTES = 4;
5353
+ var RELAY_SIGNAL_INDEX_NULLIFIER_0 = 0;
5354
+ var RELAY_SIGNAL_INDEX_NULLIFIER_1 = 1;
5355
+ var RELAY_SIGNAL_INDEX_STATE_ROOT = 82;
5356
+ var RELAY_SIGNAL_INDEX_WITHDRAW_ADDRESS_HI = 83;
5357
+ var RELAY_SIGNAL_INDEX_WITHDRAW_ADDRESS_LO = 84;
5358
+ var RELAY_SIGNAL_INDEX_ESCROW_RECIPIENT_HI = 85;
5359
+ var RELAY_SIGNAL_INDEX_ESCROW_RECIPIENT_LO = 86;
5360
+ var RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL_ASSET_HI = 87;
5361
+ var RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL_ASSET_LO = 88;
5362
+ var RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT_ASSET_HI = 89;
5363
+ var RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT_ASSET_LO = 90;
5364
+ var RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT = 91;
5365
+ var RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL = 92;
5366
+
5367
+ // src/transact/relay/signals.ts
5368
+ import { Buffer as Buffer15 } from "buffer";
5369
+
5370
+ // src/transact/relay/layout-profile.ts
5371
+ var FIELD_BYTES = 32;
5372
+ var PREFIX_BYTES = 4;
5373
+ var LEGACY_PUBLIC_INPUT_PREFIX_LEN = 5;
5374
+ var V2_PUBLIC_INPUT_PREFIX_LEN = 7;
5375
+ var EPHEMERAL_COORDINATE_COUNT = 2;
5376
+ var STANDARD_SHAPE = {
5377
+ nIns: 2,
5378
+ nOuts: 2,
5379
+ publicNInputs: 1,
5380
+ publicNOutputs: 1,
5381
+ nAuditSlots: 4,
5382
+ noteAuditLen: 12,
5383
+ noteOutputLen: 6
5384
+ };
5385
+ var SIX_BY_SIX_SHAPE = {
5386
+ nIns: 6,
5387
+ nOuts: 6,
5388
+ publicNInputs: 1,
5389
+ publicNOutputs: 1,
5390
+ nAuditSlots: 12,
5391
+ noteAuditLen: 12,
5392
+ noteOutputLen: 6
5393
+ };
5394
+ function profileFromShape(nonce, shape, publicInputPrefixLength, ciphertextsInPublicSignals) {
5395
+ const auditOffset = shape.nIns + shape.nOuts + shape.nOuts * EPHEMERAL_COORDINATE_COUNT;
5396
+ const outputNoteOffset = ciphertextsInPublicSignals ? auditOffset + shape.nAuditSlots * EPHEMERAL_COORDINATE_COUNT + shape.nAuditSlots * shape.noteAuditLen + shape.nAuditSlots : auditOffset + EPHEMERAL_COORDINATE_COUNT + shape.nAuditSlots;
5397
+ const publicOutputsLength = ciphertextsInPublicSignals ? outputNoteOffset + shape.nOuts * shape.noteOutputLen + shape.nOuts : outputNoteOffset + shape.nOuts;
5398
+ const signalCount = publicOutputsLength + publicInputPrefixLength + EPHEMERAL_COORDINATE_COUNT * shape.publicNInputs + EPHEMERAL_COORDINATE_COUNT * shape.publicNOutputs + shape.publicNInputs + shape.publicNOutputs;
5399
+ const stateRoot = publicOutputsLength;
5400
+ return {
5401
+ nonce,
5402
+ signalCount,
5403
+ fieldBytes: FIELD_BYTES,
5404
+ prefixBytes: PREFIX_BYTES,
5405
+ indices: {
5406
+ nullifier0: 0,
5407
+ nullifier1: 1,
5408
+ stateRoot,
5409
+ withdrawAddressHi: stateRoot + 1,
5410
+ withdrawAddressLo: stateRoot + 2,
5411
+ escrowRecipientHi: stateRoot + 3,
5412
+ escrowRecipientLo: stateRoot + 4,
5413
+ publicWithdrawalAssetHi: stateRoot + publicInputPrefixLength,
5414
+ publicWithdrawalAssetLo: stateRoot + publicInputPrefixLength + 1,
5415
+ publicDepositAssetHi: stateRoot + publicInputPrefixLength + 2,
5416
+ publicDepositAssetLo: stateRoot + publicInputPrefixLength + 3,
5417
+ publicDeposit: stateRoot + publicInputPrefixLength + 4,
5418
+ publicWithdrawal: stateRoot + publicInputPrefixLength + 5
5419
+ }
5420
+ };
5421
+ }
5422
+ function relayLayoutProfileForNonce(nonce) {
5423
+ if (nonce === STANDARD_ZK_CONFIG_NONCE) {
5424
+ return profileFromShape(
5425
+ nonce,
5426
+ STANDARD_SHAPE,
5427
+ LEGACY_PUBLIC_INPUT_PREFIX_LEN,
5428
+ true
5429
+ );
5430
+ }
5431
+ if (nonce === COMMITMENT_V2_ZK_NONCE) {
5432
+ return profileFromShape(nonce, STANDARD_SHAPE, V2_PUBLIC_INPUT_PREFIX_LEN, true);
5433
+ }
5434
+ if (nonce === BINDING_ZK_NONCE) {
5435
+ return profileFromShape(nonce, STANDARD_SHAPE, V2_PUBLIC_INPUT_PREFIX_LEN, false);
5436
+ }
5437
+ if (nonce === SIX_BY_SIX_ZK_NONCE) {
5438
+ return profileFromShape(nonce, SIX_BY_SIX_SHAPE, V2_PUBLIC_INPUT_PREFIX_LEN, true);
5439
+ }
5440
+ if (nonce === SIX_BY_SIX_BINDING_ZK_NONCE) {
5441
+ return profileFromShape(nonce, SIX_BY_SIX_SHAPE, V2_PUBLIC_INPUT_PREFIX_LEN, false);
5442
+ }
5443
+ throw new Error(`Unknown ZK config nonce ${nonce.toString()}`);
5444
+ }
5445
+
5446
+ // src/transact/relay/signals.ts
5447
+ function decodePublicSignalBytes(publicSignals) {
5448
+ return Buffer15.from(publicSignals.replace(/^0x/iu, ""), "hex");
5449
+ }
5450
+ function hasSupportedLengthPrefix(bytes, signalCount) {
5451
+ const expected = RELAY_TRANSACT_SIGNAL_PREFIX_BYTES + signalCount * RELAY_TRANSACT_FIELD_BYTES;
5452
+ if (bytes.length !== expected) {
5453
+ return false;
5454
+ }
5455
+ return bytes.readUInt32BE(0) === signalCount;
5456
+ }
5457
+ function assertSupportedPublicSignals(publicSignals, zkConfigNonce = DEFAULT_ZK_CONFIG_NONCE) {
5458
+ const profile = relayLayoutProfileForNonce(zkConfigNonce);
5459
+ const bytes = decodePublicSignalBytes(publicSignals);
5460
+ const supportedBytes = profile.signalCount * RELAY_TRANSACT_FIELD_BYTES;
5461
+ if (bytes.length === supportedBytes || hasSupportedLengthPrefix(bytes, profile.signalCount)) {
5462
+ return;
5463
+ }
5464
+ throw new Error(
5465
+ `Relay Transact Package V1 requires exactly ${String(profile.signalCount)} packed public signals.`
5466
+ );
5467
+ }
5468
+ function sliceSupportedPublicSignalFields(publicSignals, zkConfigNonce = DEFAULT_ZK_CONFIG_NONCE) {
5469
+ assertSupportedPublicSignals(publicSignals, zkConfigNonce);
5470
+ const profile = relayLayoutProfileForNonce(zkConfigNonce);
5471
+ const bytes = decodePublicSignalBytes(publicSignals);
5472
+ const body = hasSupportedLengthPrefix(bytes, profile.signalCount) ? bytes.subarray(RELAY_TRANSACT_SIGNAL_PREFIX_BYTES) : bytes;
5473
+ return Array.from(
5474
+ { length: profile.signalCount },
5475
+ (_unused, index) => Buffer15.from(
5476
+ body.subarray(
5477
+ index * RELAY_TRANSACT_FIELD_BYTES,
5478
+ (index + 1) * RELAY_TRANSACT_FIELD_BYTES
5479
+ )
5480
+ )
5481
+ );
5482
+ }
5483
+
5484
+ // src/transact/relay/prepare.ts
5485
+ function normalizeHex(value) {
5486
+ return value.replace(/^0x/iu, "").toLowerCase();
5487
+ }
5488
+ function prepareRelayTransactPackage(input) {
5489
+ const zkConfigNonce = input.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
5490
+ assertSupportedPublicSignals(input.publicSignals, zkConfigNonce);
5491
+ const prepared = {
5492
+ version: RELAY_TRANSACT_PACKAGE_VERSION_V1,
5493
+ poolSelector: input.poolSelector,
5494
+ zkConfigNonce,
5495
+ proofBytes: normalizeHex(input.proofBytes),
5496
+ publicSignals: normalizeHex(input.publicSignals),
5497
+ applicationIdHints: input.applicationIdHints
5498
+ };
5499
+ if (input.ciphertextBytes) {
5500
+ prepared.ciphertextBytes = normalizeHex(input.ciphertextBytes);
5501
+ }
5502
+ if (input.outputNoteEphemeralScalars) {
5503
+ prepared.outputNoteEphemeralScalars = [...input.outputNoteEphemeralScalars];
5504
+ }
5505
+ if (input.escrowAuthorization) {
5506
+ prepared.escrowAuthorization = input.escrowAuthorization;
5507
+ }
5508
+ if (input.keyVersionHints) {
5509
+ prepared.keyVersionHints = input.keyVersionHints;
5510
+ }
5511
+ return prepared;
5512
+ }
5513
+
5514
+ // src/transact/relay/from-prepared.ts
5515
+ function requirePreparedArtifacts(prepared) {
5516
+ const artifacts = prepared.transactArtifacts;
5517
+ if (!artifacts?.proofHex || !artifacts.publicHex || !artifacts.applicationIdsPlaintext) {
5518
+ throw new Error("Prepared operation is missing transact artifacts.");
5519
+ }
5520
+ return {
5521
+ proofBytes: artifacts.proofHex,
5522
+ publicSignals: artifacts.publicHex,
5523
+ applicationIdHints: artifacts.applicationIdsPlaintext,
5524
+ ...artifacts.ciphertextHex ? { ciphertextBytes: artifacts.ciphertextHex } : {},
5525
+ ...artifacts.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: artifacts.outputNoteEphemeralScalars } : {},
5526
+ ...artifacts.escrowAuthorization ? { escrowAuthorization: artifacts.escrowAuthorization } : {}
5527
+ };
5528
+ }
5529
+ function prepareRelayTransactPackageFromPrepared(input) {
5530
+ return prepareRelayTransactPackage({
5531
+ poolSelector: input.poolSelector,
5532
+ ...requirePreparedArtifacts(input.prepared),
5533
+ ...input.zkConfigNonce === void 0 ? {} : { zkConfigNonce: input.zkConfigNonce },
5534
+ ...input.keyVersionHints ? { keyVersionHints: input.keyVersionHints } : {}
5535
+ });
5536
+ }
5537
+
5538
+ // src/transact/relay/profile.ts
5539
+ function fieldAt(fields, index) {
5540
+ const field = fields.find((_unused, offset) => offset === index);
5541
+ if (!field) {
5542
+ throw new Error(`Missing packed public signal at index ${String(index)}.`);
5543
+ }
5544
+ return field;
5545
+ }
5546
+ function fieldHex2(fields, index) {
5547
+ return fieldAt(fields, index).toString("hex");
5548
+ }
5549
+ function fieldAmount(fields, index) {
5550
+ return BigInt(`0x${fieldAt(fields, index).toString("hex")}`).toString();
5551
+ }
5552
+ function readRelayTransactSupportedProfile(prepared) {
5553
+ const layout = relayLayoutProfileForNonce(prepared.zkConfigNonce);
5554
+ const fields = sliceSupportedPublicSignalFields(
5555
+ prepared.publicSignals,
5556
+ prepared.zkConfigNonce
5557
+ );
5558
+ const { indices } = layout;
5559
+ return {
5560
+ orderedNullifiers: [
5561
+ fieldHex2(fields, indices.nullifier0),
5562
+ fieldHex2(fields, indices.nullifier1)
5563
+ ],
5564
+ publicLegContext: {
5565
+ stateRoot: fieldHex2(fields, indices.stateRoot),
5566
+ withdrawAddressHi: fieldHex2(fields, indices.withdrawAddressHi),
5567
+ withdrawAddressLo: fieldHex2(fields, indices.withdrawAddressLo),
5568
+ escrowRecipientHi: fieldHex2(fields, indices.escrowRecipientHi),
5569
+ escrowRecipientLo: fieldHex2(fields, indices.escrowRecipientLo),
5570
+ publicWithdrawalAssetHi: fieldHex2(fields, indices.publicWithdrawalAssetHi),
5571
+ publicWithdrawalAssetLo: fieldHex2(fields, indices.publicWithdrawalAssetLo),
5572
+ publicDepositAssetHi: fieldHex2(fields, indices.publicDepositAssetHi),
5573
+ publicDepositAssetLo: fieldHex2(fields, indices.publicDepositAssetLo),
5574
+ publicDepositAmount: fieldAmount(fields, indices.publicDeposit),
5575
+ publicWithdrawalAmount: fieldAmount(fields, indices.publicWithdrawal)
5576
+ }
5577
+ };
5578
+ }
5579
+
5580
+ // src/transact/relay/required-submission-method.ts
5581
+ var ZERO_PUBLIC_DEPOSIT = 0n;
5582
+ var SUBMISSION_METHOD = {
5583
+ direct: "direct",
5584
+ relay: "relay"
5585
+ };
5586
+ var ESCROW_SUBMISSION_REFUSAL = {
5587
+ positivePublicDeposit: "escrow_positive_public_deposit"
5588
+ };
5589
+ var EscrowSubmissionRefusedError = class extends Error {
5590
+ reason;
5591
+ constructor(reason) {
5592
+ super(reason);
5593
+ this.name = "EscrowSubmissionRefusedError";
5594
+ this.reason = reason;
5595
+ }
5596
+ };
5597
+ function isEscrowPreparedOperation(prepared) {
5598
+ return prepared.transactArtifacts?.escrowSend === true || prepared.transactArtifacts?.spendSource === "escrow";
5599
+ }
5600
+ function publicDepositAmountFromPrepared(prepared, zkConfigNonce) {
5601
+ const publicHex = prepared.transactArtifacts?.publicHex;
5602
+ if (!publicHex) {
5603
+ return void 0;
5604
+ }
5605
+ const layout = relayLayoutProfileForNonce(zkConfigNonce);
5606
+ const fields = sliceSupportedPublicSignalFields(publicHex, zkConfigNonce);
5607
+ const field = fields.find(
5608
+ (_unused, offset) => offset === layout.indices.publicDeposit
5609
+ );
5610
+ if (!field) {
5611
+ throw new Error(
5612
+ `Missing packed public signal at index ${String(layout.indices.publicDeposit)}.`
5613
+ );
5614
+ }
5615
+ return BigInt(`0x${field.toString("hex")}`);
5616
+ }
5617
+ function evaluateRequiredSubmissionMethod(prepared, zkConfigNonce = DEFAULT_ZK_CONFIG_NONCE) {
5618
+ const publicDepositAmount = publicDepositAmountFromPrepared(prepared, zkConfigNonce);
5619
+ if (isEscrowPreparedOperation(prepared)) {
5620
+ if (publicDepositAmount !== void 0 && publicDepositAmount > ZERO_PUBLIC_DEPOSIT) {
5621
+ return { refused: ESCROW_SUBMISSION_REFUSAL.positivePublicDeposit };
5622
+ }
5623
+ if (prepared.transactArtifacts?.escrowSend === true) {
5624
+ return { method: SUBMISSION_METHOD.relay };
5625
+ }
5626
+ return { method: SUBMISSION_METHOD.direct };
5627
+ }
5628
+ if (publicDepositAmount === void 0) {
5629
+ throw new Error("Prepared operation is missing transact artifacts.");
5630
+ }
5631
+ return {
5632
+ method: publicDepositAmount > ZERO_PUBLIC_DEPOSIT ? SUBMISSION_METHOD.direct : SUBMISSION_METHOD.relay
5633
+ };
5634
+ }
5635
+ function requiredSubmissionMethod(prepared, zkConfigNonce = DEFAULT_ZK_CONFIG_NONCE) {
5636
+ const result = evaluateRequiredSubmissionMethod(prepared, zkConfigNonce);
5637
+ if ("refused" in result) {
5638
+ throw new EscrowSubmissionRefusedError(result.refused);
5639
+ }
5640
+ return result.method;
5641
+ }
4125
5642
  export {
5643
+ BundledZkCircuit2 as BundledZkCircuit,
5644
+ COMMITMENT_V2_ZK_NONCE,
4126
5645
  DEFAULT_STEALTH_SIGN_NONCE as DEFAULT_PRIVATE_ADDRESS_SIGN_NONCE,
5646
+ DEFAULT_STELLAR_ZK_CIRCUITS,
5647
+ DEFAULT_ZK_CONFIG_NONCE,
5648
+ ESCROW_SUBMISSION_REFUSAL,
5649
+ EscrowSubmissionRefusedError,
4127
5650
  KytInspectError,
4128
5651
  MIN_CONFIDENTIAL_TRANSFER_STROOPS,
5652
+ OWNER_BOUND_NOTE_SCHEMA_VERSION,
4129
5653
  PrivacyPoolService,
5654
+ RELAY_SIGNAL_INDEX_ESCROW_RECIPIENT_HI,
5655
+ RELAY_SIGNAL_INDEX_ESCROW_RECIPIENT_LO,
5656
+ RELAY_SIGNAL_INDEX_NULLIFIER_0,
5657
+ RELAY_SIGNAL_INDEX_NULLIFIER_1,
5658
+ RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT,
5659
+ RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT_ASSET_HI,
5660
+ RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT_ASSET_LO,
5661
+ RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL,
5662
+ RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL_ASSET_HI,
5663
+ RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL_ASSET_LO,
5664
+ RELAY_SIGNAL_INDEX_STATE_ROOT,
5665
+ RELAY_SIGNAL_INDEX_WITHDRAW_ADDRESS_HI,
5666
+ RELAY_SIGNAL_INDEX_WITHDRAW_ADDRESS_LO,
5667
+ RELAY_TRANSACT_FIELD_BYTES,
5668
+ RELAY_TRANSACT_PACKAGE_VERSION_V1,
5669
+ RELAY_TRANSACT_SIGNAL_PREFIX_BYTES,
5670
+ RELAY_TRANSACT_SUPPORTED_SIGNAL_COUNT,
5671
+ SIX_BY_SIX_ZK_NONCE,
5672
+ STANDARD_ZK_CONFIG_NONCE,
5673
+ SUBMISSION_METHOD,
4130
5674
  ZERO_STROOPS,
5675
+ assertEscrowSweepClaimant,
4131
5676
  assetLegToTokenAddress,
5677
+ attachEscrowAuthorization,
4132
5678
  attachPoolStatePorts,
4133
- buildOnboardingPayload,
5679
+ buildBlindedRecipientTagChallengeMessage,
4134
5680
  buildPoolTransactionAuditParameters,
4135
5681
  buildPrivateAddressSignMessage,
4136
- buildTransferOnboardingAtExecute,
4137
5682
  configurePrivacyPoolService,
4138
5683
  createPrivacyPoolService,
4139
5684
  decodePrivateAddress,
5685
+ deriveEscrowRecipientFromStellarAddress,
4140
5686
  encodePrivateAddress,
4141
5687
  encodePrivateAddressFromHexCoordinates,
5688
+ evaluateRequiredSubmissionMethod,
4142
5689
  fetchAndMergeMerkleState,
5690
+ fetchEscrowOutputNoteEvents,
5691
+ finalizeSpendOperationAtExecute,
4143
5692
  frDecimalToPaddedBytes32,
4144
5693
  generateRandomDepositScalarHex,
4145
5694
  generateTemporaryRecipientPrivateAddress,
4146
5695
  getPrivacyPoolService,
5696
+ isEscrowPreparedOperation,
4147
5697
  loadDefaultStellarBrowserAssets,
4148
5698
  loadStellarBrowserAssets,
5699
+ optionalZkArtifactBaseUrl,
4149
5700
  parseAuditPublicKeyFromEnvHex,
4150
5701
  parseKytReasonCode,
4151
5702
  prepareConfidentialTransferProof,
4152
5703
  prepareConfidentialTransferProofDual,
5704
+ prepareEscrowSweepOperation,
5705
+ prepareRelayTransactPackage,
5706
+ prepareRelayTransactPackageFromPrepared,
4153
5707
  privateAddressSdk,
4154
5708
  readLeafEphemeralHex,
5709
+ readRelayTransactSupportedProfile,
4155
5710
  recipientPublicKeysDecimalFromPrivateAddress,
5711
+ reconstructEscrowNote,
4156
5712
  requestKytPassageForPoolInteraction,
5713
+ requiredSubmissionMethod,
4157
5714
  resolvePoolApplicationId,
5715
+ resolveZkConfigNonce,
4158
5716
  runTtlPreflight,
5717
+ spendScalarHexFromStellarSignature,
4159
5718
  submitSorobanConfidentialTransfer,
4160
5719
  submitSorobanDeposit,
4161
- tokenAddressToAssetLeg
5720
+ tokenAddressToAssetLeg,
5721
+ unsignedEscrowAuthorizationForSweep
4162
5722
  };
4163
5723
  //# sourceMappingURL=index.js.map