@arcanetech/privacy-sdk-stellar 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.js CHANGED
@@ -3,12 +3,8 @@ import "@arcanetech/privacy-sdk-core";
3
3
 
4
4
  // src/assets/load-node.ts
5
5
  async function loadNodeAssets(assets) {
6
- const [sdkWasm, circuitWasm, provingKey] = await Promise.all([
7
- readAssetFile(assets.sdkWasmPath),
8
- readAssetFile(assets.circuitWasmPath),
9
- readAssetFile(assets.provingKeyPath)
10
- ]);
11
- return { sdkWasm, circuitWasm, provingKey };
6
+ const sdkWasm = await readAssetFile(assets.sdkWasmPath);
7
+ return { sdkWasm };
12
8
  }
13
9
  async function readAssetFile(path) {
14
10
  const { readFile } = await import("fs/promises");
@@ -62,16 +58,6 @@ import {
62
58
  import {
63
59
  unsupportedDisclosureError
64
60
  } from "@arcanetech/privacy-sdk-core";
65
-
66
- // src/transact/transfer-source/types.ts
67
- function isPendingClaimSource(from) {
68
- return typeof from === "object" && "kind" in from && from.kind === "pendingClaim";
69
- }
70
- function isPrivateAddressTransferFrom(from) {
71
- return typeof from === "string";
72
- }
73
-
74
- // src/policy/disclosure-routes.ts
75
61
  function validatePublicRecipientTransferDisclosure(disclosure) {
76
62
  const errors = [];
77
63
  const fields = [
@@ -98,38 +84,9 @@ function validatePublicRecipientTransferDisclosure(disclosure) {
98
84
  }
99
85
  return errors;
100
86
  }
101
- function validatePendingClaimTransferDisclosure(disclosure) {
102
- const errors = [];
103
- const fields = [
104
- "senderAddress",
105
- "assetAddress",
106
- "amount"
107
- ];
108
- const messages = {
109
- senderAddress: "Pending claim transfers must publish the sender address.",
110
- assetAddress: "Pending claim transfers must publish the asset identifier.",
111
- amount: "Pending claim transfers must publish the transfer amount."
112
- };
113
- for (const field of fields) {
114
- if (disclosure[field] === "private") {
115
- errors.push(
116
- unsupportedDisclosureError(
117
- field,
118
- "private",
119
- ["public"],
120
- messages[field] ?? "This transfer route requires public disclosure."
121
- )
122
- );
123
- }
124
- }
125
- return errors;
126
- }
127
87
  function isPublicStellarRecipientTransfer(intent) {
128
88
  return intent.disclosure.recipientAddress === "public";
129
89
  }
130
- function isPendingClaimTransfer(intent) {
131
- return isPendingClaimSource(intent.from);
132
- }
133
90
 
134
91
  // src/policy/disclosure.ts
135
92
  function isPublicWithdrawRoute(intent) {
@@ -152,9 +109,6 @@ function validateStellarDisclosure(kind, intent) {
152
109
  if (kind === "transfer" && isPublicStellarRecipientTransfer(intent)) {
153
110
  errors.push(...validatePublicRecipientTransferDisclosure(intent.disclosure));
154
111
  }
155
- if (kind === "transfer" && isPendingClaimTransfer(intent)) {
156
- errors.push(...validatePendingClaimTransferDisclosure(intent.disclosure));
157
- }
158
112
  if (kind === "withdraw" && isPublicWithdrawRoute(intent)) {
159
113
  rejectPrivatePublicRouteFields(
160
114
  intent,
@@ -350,118 +304,26 @@ function handleSubmissionFailure(error, options, eventId) {
350
304
  }
351
305
 
352
306
  // src/adapters/record-selection.ts
353
- import { insufficientStateError as insufficientStateError3 } from "@arcanetech/privacy-sdk-core";
307
+ import { insufficientStateError as insufficientStateError2 } from "@arcanetech/privacy-sdk-core";
354
308
 
355
- // src/transact/transfer-source/resolve.ts
356
- import { Buffer as Buffer2 } from "buffer";
357
- import {
358
- insufficientStateError,
359
- invalidIntentError
360
- } from "@arcanetech/privacy-sdk-core";
361
- var FIELD_HEX_LENGTH = 64;
362
- var SCALAR_HEX_PATTERN = new RegExp(`^(0x)?[0-9a-f]{${FIELD_HEX_LENGTH}}$`, "iu");
363
- function hexToDecimal(hex) {
364
- const clean = (hex ?? "").trim().replace(/^0x/u, "");
365
- return BigInt(`0x${clean || "0"}`).toString();
366
- }
367
- function recoveryScalarHexFromClaim(claim) {
368
- const encoded = claim.encryptedRecoveryBase64?.trim();
369
- if (!encoded) {
370
- throw invalidIntentError(
371
- "from",
372
- "Pending claim is missing encrypted recovery data."
373
- );
374
- }
375
- const scalar = Buffer2.from(encoded, "base64").toString("utf8").trim();
376
- if (!SCALAR_HEX_PATTERN.test(scalar)) {
377
- throw invalidIntentError("from", "Pending claim recovery payload is not a scalar.");
378
- }
379
- return scalar.replace(/^0x/iu, "");
380
- }
381
- function pendingClaimToCoin(claim) {
382
- return {
383
- value: claim.amount.toString(),
384
- nullifier: hexToDecimal(claim.nullifierFieldHex),
385
- secret: hexToDecimal(claim.secretHex),
386
- commitment: hexToDecimal(claim.commitmentHex),
387
- asset_hi: hexToDecimal(claim.assetHiHex),
388
- asset_lo: hexToDecimal(claim.assetLoHex)
389
- };
390
- }
391
- function pendingClaimToConsumedRecord(input) {
392
- const coin = pendingClaimToCoin(input.claim);
393
- const nullifierHex = input.claim.nullifierHex ?? input.claim.futureNullifierHashHex;
394
- return {
395
- id: `pending-claim-${input.claim.id}`,
396
- owner: input.walletPublicKey.trim(),
397
- asset: input.claim.asset,
398
- amount: input.claim.amount,
399
- consumed: false,
400
- status: "finalized",
401
- poolContract: input.poolContract,
402
- coinNote: coin,
403
- ...input.claim.commitmentHex ? { commitmentHex: input.claim.commitmentHex } : {},
404
- ...nullifierHex ? { nullifierHex } : {}
405
- };
406
- }
407
- function readPendingClaimFromSource(source) {
408
- if ("claim" in source) {
409
- return source.claim;
410
- }
411
- return void 0;
412
- }
413
- async function resolvePendingClaimSource(input) {
414
- const embedded = readPendingClaimFromSource(input.from);
415
- if (embedded) {
416
- return embedded;
417
- }
418
- if (!("claimId" in input.from)) {
419
- throw invalidIntentError("from", "Pending claim id is required.");
420
- }
421
- const claimId = input.from.claimId.trim();
422
- if (!claimId) {
423
- throw invalidIntentError("from", "Pending claim id is required.");
424
- }
425
- const claims = await input.getPendingClaims();
426
- const claim = claims.items.find((entry) => entry.id === claimId);
427
- if (!claim) {
428
- throw insufficientStateError(
429
- "pending_claim_not_found",
430
- "Pending claim was not found in local state.",
431
- { claimId }
432
- );
433
- }
434
- return claim;
435
- }
436
- function assertPendingClaimOwner(input) {
437
- const owner = input.claim.owner.trim();
438
- const wallet = input.walletPublicKey.trim();
439
- if (owner !== wallet) {
440
- throw insufficientStateError(
441
- "pending_claim_owner_mismatch",
442
- "Pending claim owner does not match the connected wallet.",
443
- { claimOwner: owner, walletPublicKey: wallet }
444
- );
445
- }
309
+ // src/transact/transfer-source/types.ts
310
+ function isPrivateAddressTransferFrom(from) {
311
+ return typeof from === "string";
446
312
  }
313
+
314
+ // src/transact/transfer-source/resolve.ts
447
315
  function readTransferFromPrivateAddress(from) {
448
- if (isPendingClaimSource(from)) {
449
- throw invalidIntentError(
450
- "from",
451
- "Private address is unavailable for a pending claim transfer source."
452
- );
453
- }
454
316
  return from.trim();
455
317
  }
456
318
 
457
- // src/transact/transfer-source/verify.ts
458
- import { executionError as executionError3 } from "@arcanetech/privacy-sdk-core";
319
+ // src/transact/transfer-source/verify-private-records.ts
320
+ import { executionError as executionError3, insufficientStateError } from "@arcanetech/privacy-sdk-core";
459
321
 
460
322
  // src/contracts/pool/pool-domain-service.ts
461
- import { Buffer as Buffer3 } from "buffer";
323
+ import { Buffer as Buffer2 } from "buffer";
462
324
  function hexToBuffer(hex) {
463
325
  const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
464
- return Buffer3.from(clean, "hex");
326
+ return Buffer2.from(clean, "hex");
465
327
  }
466
328
  async function readNullifierConsumedOnChain(input) {
467
329
  const client = input.contractContext.createPoolClient({
@@ -575,15 +437,45 @@ function readPoolClientFactory(environment) {
575
437
  return requireContractContext(environment).createPoolClient;
576
438
  }
577
439
 
440
+ // src/transact/private-address/record-coin.ts
441
+ function requireCoinNoteFromRecord(record) {
442
+ if (!record.coinNote) {
443
+ throw new Error(`Private record ${record.id} is missing coin note data.`);
444
+ }
445
+ return record.coinNote;
446
+ }
447
+ function findCommitmentLeafIndex(commitments, commitment) {
448
+ return commitments.indexOf(commitment);
449
+ }
450
+ function buildPrivateRecordFromDeposit(input) {
451
+ return {
452
+ id: input.commitmentHex,
453
+ owner: input.owner,
454
+ asset: input.assetId,
455
+ amount: input.amount,
456
+ consumed: false,
457
+ status: input.status ?? "pending",
458
+ poolContract: input.poolContract,
459
+ commitmentHex: input.commitmentHex,
460
+ privateAddress: input.privateAddress,
461
+ amountDisplay: input.amountDisplay,
462
+ coinNote: input.coin,
463
+ depositScalarHex: input.depositScalarHex,
464
+ precommitementHex: input.precommitementHex,
465
+ ...input.txHash ? { txHash: input.txHash } : {}
466
+ };
467
+ }
468
+
578
469
  // src/transact/pool/service.ts
579
470
  import {
471
+ PrivacyPoolSDK as PrivacyPoolSDK2,
580
472
  decodeDecodedEphemeralKey,
581
473
  randomFrDecimal253,
582
474
  scalarHexToFrDecimal as scalarHexToFrDecimal2
583
- } from "@auditable/privacy-pool-zk-sdk";
475
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
584
476
 
585
477
  // src/transact/merkle/field-decimal.ts
586
- import { Buffer as Buffer5 } from "buffer";
478
+ import { Buffer as Buffer4 } from "buffer";
587
479
  var BN254 = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
588
480
  var MERKLE_ROOT_BYTE_LENGTH = 32;
589
481
  var DECIMAL_STRING_RADIX = 10;
@@ -593,7 +485,7 @@ function merkleRootBufferToFrDecimal(root) {
593
485
  `expected ${MERKLE_ROOT_BYTE_LENGTH}-byte merkle root, got ${root.length}`
594
486
  );
595
487
  }
596
- const hex = Buffer5.from(root).toString("hex");
488
+ const hex = Buffer4.from(root).toString("hex");
597
489
  return (BigInt(`0x${hex}`) % BN254).toString(DECIMAL_STRING_RADIX);
598
490
  }
599
491
 
@@ -603,8 +495,12 @@ import {
603
495
  decodeStealthAddress,
604
496
  encodeStealthAddress,
605
497
  recipientPublicKeysDecimalFromStealthAddress
606
- } from "@auditable/privacy-pool-zk-sdk";
607
- import { DEFAULT_STEALTH_SIGN_NONCE } from "@auditable/privacy-pool-zk-sdk";
498
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
499
+ import { DEFAULT_STEALTH_SIGN_NONCE } from "@arcanetech/stellar-privacy-pool-zk-sdk";
500
+ import {
501
+ OWNER_BOUND_NOTE_SCHEMA_VERSION,
502
+ spendScalarHexFromStellarSignature
503
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
608
504
  function decodePrivateAddress(value) {
609
505
  const decodeAddress = decodeStealthAddress;
610
506
  return decodeAddress(value);
@@ -633,26 +529,26 @@ function privateAddressSdk(sdk) {
633
529
  );
634
530
  }
635
531
  return {
636
- generatePrivateAddressFromStellarSignature: (signature) => generator.call(sdk, signature)
532
+ generatePrivateAddressFromStellarSignature: (signature, domain) => generator.call(sdk, signature, domain)
637
533
  };
638
534
  }
639
535
 
640
536
  // src/transact/proofs/withdraw/transact-proof.ts
641
- import { withdrawObjectFromMerkleWitness as withdrawObjectFromMerkleWitness2 } from "@auditable/privacy-pool-zk-sdk";
537
+ import { withdrawObjectFromMerkleWitness as withdrawObjectFromMerkleWitness2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
642
538
 
643
539
  // src/transact/proofs/transaction-input.ts
644
- import { Buffer as Buffer7 } from "buffer";
540
+ import { Buffer as Buffer6 } from "buffer";
645
541
  import { StrKey as StrKey2 } from "@stellar/stellar-sdk";
646
542
 
647
543
  // src/transact/stellar/token-contract.ts
648
- import { Buffer as Buffer6 } from "buffer";
544
+ import { Buffer as Buffer5 } from "buffer";
649
545
  import { StrKey } from "@stellar/stellar-sdk";
650
546
  var CONTRACT_ID_BYTE_LENGTH = 32;
651
547
  var HEX_CHARS_PER_BYTE = 2;
652
548
  var CONTRACT_ID_HEX_CHAR_LENGTH = CONTRACT_ID_BYTE_LENGTH * HEX_CHARS_PER_BYTE;
653
549
  var CONTRACT_ID_HEX = /^(?:0x)?([0-9a-f]{64})$/i;
654
550
  function encodeContractFromHex(hexPayload) {
655
- return StrKey.encodeContract(Buffer6.from(hexPayload, "hex"));
551
+ return StrKey.encodeContract(Buffer5.from(hexPayload, "hex"));
656
552
  }
657
553
  function normalizeSorobanContractId(raw) {
658
554
  const trimmed = raw.trim();
@@ -678,10 +574,14 @@ function resolveTokenContractId(tokenContractRaw) {
678
574
  }
679
575
 
680
576
  // src/transact/proofs/transaction-input.ts
577
+ var ZERO_PUBLIC_WITHDRAW_ADDRESS = {
578
+ withdrawAddressHi: "0",
579
+ withdrawAddressLo: "0"
580
+ };
681
581
  var CONTRACT_ADDRESS_HALF_BYTES = 16;
682
582
  var CONTRACT_ADDRESS_BYTES = 32;
683
583
  function bytes16ToDecimal(bytes) {
684
- return BigInt(`0x${Buffer7.from(bytes).toString("hex")}`).toString();
584
+ return BigInt(`0x${Buffer6.from(bytes).toString("hex")}`).toString();
685
585
  }
686
586
  function tokenAddressFrParts(tokenAddress) {
687
587
  const normalized = resolveTokenContractId(tokenAddress);
@@ -697,98 +597,116 @@ function withTokenAddressPublicInputs(base, tokenAddress) {
697
597
  return {
698
598
  ...base,
699
599
  tokenAddressHi: hi,
700
- tokenAddressLo: lo
600
+ tokenAddressLo: lo,
601
+ withdrawAddressHi: base.withdrawAddressHi ?? ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressHi,
602
+ withdrawAddressLo: base.withdrawAddressLo ?? ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressLo,
603
+ escrowRecipientHi: base.escrowRecipientHi ?? "0",
604
+ escrowRecipientLo: base.escrowRecipientLo ?? "0",
605
+ sweepOutputOwnerPubX: base.sweepOutputOwnerPubX ?? "0",
606
+ sweepOutputOwnerPubY: base.sweepOutputOwnerPubY ?? "0"
607
+ };
608
+ }
609
+ function publicWithdrawAddressLimbs(parameters) {
610
+ if (parameters.publicWithdrawalAmount === "0") {
611
+ return {
612
+ withdrawAddressHi: ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressHi,
613
+ withdrawAddressLo: ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressLo
614
+ };
615
+ }
616
+ return {
617
+ withdrawAddressHi: parameters.destinationHi,
618
+ withdrawAddressLo: parameters.destinationLo
701
619
  };
702
620
  }
703
621
  function tokenAddressToAssetLeg(tokenAddress) {
704
622
  const { hi, lo } = tokenAddressFrParts(tokenAddress);
705
623
  return [hi, lo];
706
624
  }
707
- function buildZeroPublicLegs() {
625
+ function buildZeroPublicLegs(publicNInputs = 1, publicNOutputs = 1) {
708
626
  return {
709
- publicWithdrawnAssets: [["0", "0"]],
710
- publicDepositedAssets: [["0", "0"]],
711
- publicDeposits: ["0"],
712
- publicWithdrawals: ["0"]
627
+ publicWithdrawnAssets: Array.from(
628
+ { length: publicNOutputs },
629
+ () => ["0", "0"]
630
+ ),
631
+ publicDepositedAssets: Array.from(
632
+ { length: publicNInputs },
633
+ () => ["0", "0"]
634
+ ),
635
+ publicDeposits: Array.from({ length: publicNInputs }, () => "0"),
636
+ publicWithdrawals: Array.from({ length: publicNOutputs }, () => "0")
713
637
  };
714
638
  }
715
- function buildPublicDepositLegs(tokenAddress, amount) {
716
- const legs = buildZeroPublicLegs();
639
+ function buildPublicDepositLegs(tokenAddress, amount, publicNInputs = 1, publicNOutputs = 1) {
640
+ const legs = buildZeroPublicLegs(publicNInputs, publicNOutputs);
717
641
  return {
718
642
  ...legs,
719
- publicDepositedAssets: [tokenAddressToAssetLeg(tokenAddress)],
720
- publicDeposits: [amount]
643
+ publicDepositedAssets: [
644
+ tokenAddressToAssetLeg(tokenAddress),
645
+ ...legs.publicDepositedAssets.slice(1)
646
+ ],
647
+ publicDeposits: [amount, ...legs.publicDeposits.slice(1)]
721
648
  };
722
649
  }
723
- function buildPublicWithdrawLegs(tokenAddress, amount) {
724
- const legs = buildZeroPublicLegs();
650
+ function buildPublicWithdrawLegs(tokenAddress, amount, publicNInputs = 1, publicNOutputs = 1) {
651
+ const legs = buildZeroPublicLegs(publicNInputs, publicNOutputs);
725
652
  return {
726
653
  ...legs,
727
- publicWithdrawnAssets: [tokenAddressToAssetLeg(tokenAddress)],
728
- publicWithdrawals: [amount]
654
+ publicWithdrawnAssets: [
655
+ tokenAddressToAssetLeg(tokenAddress),
656
+ ...legs.publicWithdrawnAssets.slice(1)
657
+ ],
658
+ publicWithdrawals: [amount, ...legs.publicWithdrawals.slice(1)]
729
659
  };
730
660
  }
731
661
 
732
- // src/transact/proofs/confidential/helpers.ts
662
+ // src/transact/zk/slots.ts
733
663
  import {
734
- ed25519PubkeyPayloadHexToWithdrawFrDecimals,
735
- withdrawObjectFromMerkleWitness
736
- } from "@auditable/privacy-pool-zk-sdk";
737
- import { StrKey as StrKey3 } from "@stellar/stellar-sdk";
738
- import { Buffer as Buffer8 } from "buffer";
739
-
740
- // src/transact/encoding/priv-key-scalar-from-recipient-hex.ts
741
- import { BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE } from "@auditable/privacy-pool-zk-sdk";
742
- var SCALAR_HEX_CHAR_LENGTH = 64;
743
- var DECIMAL_RADIX = 10;
744
- var BIGINT_ONE = 1n;
745
- function normalizeRecipientScalarHex(hexInput) {
746
- const trimmed = hexInput.trim().replace(/^0x/iu, "");
747
- if (!/^[0-9a-f]*$/iu.test(trimmed)) {
748
- throw new Error("recipient scalar hex must be hexadecimal");
749
- }
750
- const withLeadingNibble = trimmed.length % 2 === 0 ? trimmed : `0${trimmed}`;
751
- const lower = withLeadingNibble.toLowerCase();
752
- const padded = lower.padStart(SCALAR_HEX_CHAR_LENGTH, "0").slice(-SCALAR_HEX_CHAR_LENGTH);
753
- if (padded.length !== SCALAR_HEX_CHAR_LENGTH) {
664
+ padDepositSlots,
665
+ padPublicLegs,
666
+ padWithdrawSlots
667
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
668
+ function padWithdrawSlotsToLayout(sdk, slots) {
669
+ return padWithdrawSlots(slots, sdk.getLayout().nIns);
670
+ }
671
+ function padDepositSlotsToLayout(sdk, slots) {
672
+ return padDepositSlots(slots, sdk.getLayout().nOuts);
673
+ }
674
+ function padPublicLegsToLayout(sdk, legs) {
675
+ const { publicNInputs, publicNOutputs } = sdk.getLayout();
676
+ return padPublicLegs(legs, publicNInputs, publicNOutputs);
677
+ }
678
+ function padStrings(values, length, fill) {
679
+ if (values.length > length) {
754
680
  throw new Error(
755
- `recipient scalar hex must fit 32 bytes (${SCALAR_HEX_CHAR_LENGTH} hex chars)`
681
+ `expected at most ${String(length)} application-id slots, got ${String(values.length)}`
756
682
  );
757
683
  }
758
- return padded;
684
+ return [...values, ...Array.from({ length: length - values.length }, () => fill)];
759
685
  }
760
- function privKeyScalarDecimalFromRecipientScalarHex(hexInput) {
761
- const hex = normalizeRecipientScalarHex(hexInput);
762
- const value = BigInt(`0x${hex}`);
763
- const mask = BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE - BIGINT_ONE;
764
- return (value & mask).toString(DECIMAL_RADIX);
686
+ function buildApplicationIdHints(input) {
687
+ const { nIns, nOuts } = input.sdk.getLayout();
688
+ return [
689
+ ...padStrings(input.inputIds, nIns, "0"),
690
+ ...padStrings(input.outputIds, nOuts, "0")
691
+ ];
692
+ }
693
+ function uniformApplicationIdHints(applicationId, nAuditSlots) {
694
+ return Array.from({ length: nAuditSlots }, () => applicationId);
765
695
  }
766
696
 
767
697
  // src/transact/proofs/confidential/helpers.ts
698
+ import { withdrawObjectFromMerkleWitness } from "@arcanetech/stellar-privacy-pool-zk-sdk";
768
699
  var MIN_CONFIDENTIAL_TRANSFER_STROOPS = 1n;
769
700
  var ZERO_STROOPS = 0n;
770
- function leafEphemeralCoords(xHex, yHex) {
771
- const coords = {};
772
- Object.defineProperty(coords, "x", {
773
- value: xHex,
774
- enumerable: true,
775
- writable: true
776
- });
777
- Object.defineProperty(coords, "y", {
778
- value: yHex,
779
- enumerable: true,
780
- writable: true
781
- });
782
- return coords;
783
- }
784
701
  function withdrawWitnessForCoin(parameters) {
785
- const { sdk, coin, state, xHex, yHex } = parameters;
702
+ const { sdk, coin, state } = parameters;
786
703
  const witness = sdk.buildWithdrawMerkleWitness(coin, state);
787
704
  const withdrawApplicationId = coin.application_id ?? parameters.applicationId;
788
705
  const withdrawObject = withdrawObjectFromMerkleWitness(
789
706
  witness,
790
- leafEphemeralCoords(xHex, yHex),
791
- withdrawApplicationId
707
+ parameters.ownerPubHex,
708
+ withdrawApplicationId,
709
+ parameters.privKeyScalar
792
710
  );
793
711
  return { witness, withdrawObject };
794
712
  }
@@ -797,16 +715,16 @@ function dualWithdrawLegsWithSharedRoot(parameters) {
797
715
  sdk: parameters.sdk,
798
716
  coin: parameters.coinA,
799
717
  state: parameters.state,
800
- xHex: parameters.ephemeralA.xHex,
801
- yHex: parameters.ephemeralA.yHex,
718
+ ownerPubHex: parameters.ownerPubHex,
719
+ privKeyScalar: parameters.privKeyScalar,
802
720
  applicationId: parameters.applicationId
803
721
  });
804
722
  const legB = withdrawWitnessForCoin({
805
723
  sdk: parameters.sdk,
806
724
  coin: parameters.coinB,
807
725
  state: parameters.state,
808
- xHex: parameters.ephemeralB.xHex,
809
- yHex: parameters.ephemeralB.yHex,
726
+ ownerPubHex: parameters.ownerPubHex,
727
+ privKeyScalar: parameters.privKeyScalar,
810
728
  applicationId: parameters.applicationId
811
729
  });
812
730
  if (legA.witness.stateRoot !== legB.witness.stateRoot) {
@@ -814,15 +732,6 @@ function dualWithdrawLegsWithSharedRoot(parameters) {
814
732
  }
815
733
  return { legA, legB };
816
734
  }
817
- function senderWithdrawFrAndScalar(parameters) {
818
- const pkRaw = StrKey3.decodeEd25519PublicKey(parameters.senderGAddress);
819
- const pkHex = Buffer8.from(pkRaw).toString("hex");
820
- const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals(pkHex);
821
- const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
822
- parameters.senderPrivKeyScalarHex
823
- );
824
- return { hi, lo, privKeyScalar };
825
- }
826
735
  function requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange) {
827
736
  if (changeStroops > ZERO_STROOPS) {
828
737
  const stpl1 = selfPrivateAddressStpl1ForChange?.trim() ?? "";
@@ -847,15 +756,15 @@ function changeStroopsAfterDualTransfer(transferStroops, totalNotes) {
847
756
  import {
848
757
  DEMO_AUDIT_PUBLIC_KEY,
849
758
  resolveTransactionAuditParams
850
- } from "@auditable/privacy-pool-zk-sdk";
851
- import { Buffer as Buffer9 } from "buffer";
759
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
760
+ import { Buffer as Buffer7 } from "buffer";
852
761
  var UNCOMPRESSED_PREFIX = "04";
853
762
  var UNCOMPRESSED_HEX_LENGTH = 130;
854
763
  var XY_HEX_LENGTH = 128;
855
764
  var X_OFFSET_END = 32;
856
765
  var Y_OFFSET_START = 32;
857
766
  var Y_OFFSET_END = 64;
858
- var DECIMAL_RADIX2 = 10;
767
+ var DECIMAL_RADIX = 10;
859
768
  var BN254_FR_MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
860
769
  var BABYJUBJUB_A = 168700n;
861
770
  var BABYJUBJUB_D = 168696n;
@@ -875,13 +784,13 @@ function parseAuditPublicKeyFromEnvHex(raw) {
875
784
  "Audit public key must be uncompressed 65-byte hex (04 + X + Y) or 64-byte X+Y hex"
876
785
  );
877
786
  }
878
- const bytes = Buffer9.from(payload, "hex");
787
+ const bytes = Buffer7.from(payload, "hex");
879
788
  const auditPublicKeyXDecimal = BigInt(
880
789
  `0x${bytes.subarray(0, X_OFFSET_END).toString("hex")}`
881
- ).toString(DECIMAL_RADIX2);
790
+ ).toString(DECIMAL_RADIX);
882
791
  const auditPublicKeyYDecimal = BigInt(
883
792
  `0x${bytes.subarray(Y_OFFSET_START, Y_OFFSET_END).toString("hex")}`
884
- ).toString(DECIMAL_RADIX2);
793
+ ).toString(DECIMAL_RADIX);
885
794
  if (!passesBabyJubCurveCheck(
886
795
  BigInt(auditPublicKeyXDecimal),
887
796
  BigInt(auditPublicKeyYDecimal)
@@ -893,7 +802,8 @@ function parseAuditPublicKeyFromEnvHex(raw) {
893
802
  function buildPoolTransactionAuditParameters(input) {
894
803
  return resolveTransactionAuditParams(
895
804
  input.applicationId,
896
- input.auditPublicKey ?? DEMO_AUDIT_PUBLIC_KEY
805
+ input.auditPublicKey ?? DEMO_AUDIT_PUBLIC_KEY,
806
+ input.nAuditSlots
897
807
  );
898
808
  }
899
809
  function resolvePoolApplicationId(applicationId) {
@@ -907,24 +817,24 @@ function resolvePoolApplicationId(applicationId) {
907
817
  }
908
818
 
909
819
  // src/transact/proofs/withdraw/helpers.ts
910
- import { ed25519PubkeyPayloadHexToWithdrawFrDecimals as ed25519PubkeyPayloadHexToWithdrawFrDecimals2 } from "@auditable/privacy-pool-zk-sdk";
820
+ import { ed25519PubkeyPayloadHexToWithdrawFrDecimals } from "@arcanetech/stellar-privacy-pool-zk-sdk";
911
821
 
912
822
  // src/transact/stellar/account.ts
913
- import { StrKey as StrKey4 } from "@stellar/stellar-sdk";
914
- import { Buffer as Buffer10 } from "buffer";
823
+ import { StrKey as StrKey3 } from "@stellar/stellar-sdk";
824
+ import { Buffer as Buffer8 } from "buffer";
915
825
  var MUXED_ACCOUNT_ID_BYTE_LENGTH = 8;
916
826
  var ED25519_PUBLIC_KEY_BYTE_LENGTH = 32;
917
827
  function ed25519HexFromGAddress(trimmed) {
918
828
  try {
919
- const raw = StrKey4.decodeEd25519PublicKey(trimmed);
920
- return Buffer10.from(raw).toString("hex");
829
+ const raw = StrKey3.decodeEd25519PublicKey(trimmed);
830
+ return Buffer8.from(raw).toString("hex");
921
831
  } catch {
922
832
  return void 0;
923
833
  }
924
834
  }
925
835
  function ed25519HexFromMuxedAddress(trimmed) {
926
836
  try {
927
- const raw = StrKey4.decodeMed25519PublicKey(trimmed);
837
+ const raw = StrKey3.decodeMed25519PublicKey(trimmed);
928
838
  if (raw.length === MUXED_ACCOUNT_ID_BYTE_LENGTH + ED25519_PUBLIC_KEY_BYTE_LENGTH) {
929
839
  return raw.subarray(MUXED_ACCOUNT_ID_BYTE_LENGTH).toString("hex");
930
840
  }
@@ -949,29 +859,29 @@ function ed25519PublicKeyHexFromStellarAccount(address) {
949
859
  throw new Error("Invalid destination Stellar address");
950
860
  }
951
861
 
952
- // src/transact/encoding/ephemeral-key.ts
953
- var HEX_64_RE = /^[\da-f]{64}$/iu;
954
- function normalizeCoordinate(value) {
955
- const hex = value.trim().replace(/^0x/iu, "").toLowerCase();
956
- if (!HEX_64_RE.test(hex)) {
957
- throw new Error("Ephemeral key coordinate must be a 32-byte hex string.");
862
+ // src/transact/encoding/priv-key-scalar-from-recipient-hex.ts
863
+ import { canonicalBabyJubScalarFromInteger } from "@arcanetech/stellar-privacy-pool-zk-sdk";
864
+ var SCALAR_HEX_CHAR_LENGTH = 64;
865
+ var DECIMAL_RADIX2 = 10;
866
+ function normalizeRecipientScalarHex(hexInput) {
867
+ const trimmed = hexInput.trim().replace(/^0x/iu, "");
868
+ if (!/^[0-9a-f]*$/iu.test(trimmed)) {
869
+ throw new Error("recipient scalar hex must be hexadecimal");
958
870
  }
959
- return hex;
960
- }
961
- function parseEphemeralKeyString(input) {
962
- const [xRaw, yRaw, extra] = input.split(":");
963
- if (!xRaw || !yRaw || extra !== void 0) {
871
+ const withLeadingNibble = trimmed.length % 2 === 0 ? trimmed : `0${trimmed}`;
872
+ const lower = withLeadingNibble.toLowerCase();
873
+ const padded = lower.padStart(SCALAR_HEX_CHAR_LENGTH, "0").slice(-SCALAR_HEX_CHAR_LENGTH);
874
+ if (padded.length !== SCALAR_HEX_CHAR_LENGTH) {
964
875
  throw new Error(
965
- 'Ephemeral key must be a string in "xHex:yHex" format (32-byte hex each).'
876
+ `recipient scalar hex must fit 32 bytes (${SCALAR_HEX_CHAR_LENGTH} hex chars)`
966
877
  );
967
878
  }
968
- return {
969
- xHex: normalizeCoordinate(xRaw),
970
- yHex: normalizeCoordinate(yRaw)
971
- };
879
+ return padded;
972
880
  }
973
- function serializeEphemeralKeyString(point) {
974
- return `${normalizeCoordinate(point.xHex)}:${normalizeCoordinate(point.yHex)}`;
881
+ function privKeyScalarDecimalFromRecipientScalarHex(hexInput) {
882
+ const hex = normalizeRecipientScalarHex(hexInput);
883
+ const value = BigInt(`0x${hex}`);
884
+ return canonicalBabyJubScalarFromInteger(value).toString(DECIMAL_RADIX2);
975
885
  }
976
886
 
977
887
  // src/transact/proofs/withdraw/helpers.ts
@@ -979,7 +889,7 @@ function destinationWithdrawFrAndScalar(parameters) {
979
889
  const pkHex = ed25519PublicKeyHexFromStellarAccount(
980
890
  parameters.destinationStellarAddress
981
891
  );
982
- const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals2(pkHex);
892
+ const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals(pkHex);
983
893
  const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
984
894
  parameters.privKeyScalarHex
985
895
  );
@@ -993,8 +903,11 @@ function buildWithdrawPublicInput(parameters) {
993
903
  return withTokenAddressPublicInputs(
994
904
  {
995
905
  stateRoot: parameters.stateRoot,
996
- withdrawAddressHi: hi,
997
- withdrawAddressLo: lo,
906
+ ...publicWithdrawAddressLimbs({
907
+ publicWithdrawalAmount: parameters.publicWithdrawalAmount,
908
+ destinationHi: hi,
909
+ destinationLo: lo
910
+ }),
998
911
  privKeyScalar
999
912
  },
1000
913
  parameters.tokenAddress
@@ -1002,7 +915,7 @@ function buildWithdrawPublicInput(parameters) {
1002
915
  }
1003
916
  async function resolveWithdrawChangeDeposits(parameters) {
1004
917
  if (parameters.changeStroops <= ZERO_STROOPS) {
1005
- return { deposits: ["dummy", "dummy"] };
918
+ return { deposits: [] };
1006
919
  }
1007
920
  const stpl1 = parameters.changePrivateAddressStpl1?.trim() ?? "";
1008
921
  if (!stpl1) {
@@ -1016,7 +929,7 @@ async function resolveWithdrawChangeDeposits(parameters) {
1016
929
  tokenAddress: parameters.tokenAddress
1017
930
  });
1018
931
  return {
1019
- deposits: [slot.deposit, "dummy"],
932
+ deposits: [slot.deposit],
1020
933
  changeCoin: {
1021
934
  commitment_hex: slot.commitment_hex,
1022
935
  coin: slot.coin,
@@ -1041,14 +954,14 @@ function buildDualWithdrawPublicInput(parameters) {
1041
954
  stateRoot: parameters.stateRoot,
1042
955
  destinationStellarAddress: parameters.destinationStellarAddress,
1043
956
  privKeyScalarHex: parameters.privKeyScalarHex,
1044
- tokenAddress: parameters.tokenAddress
957
+ tokenAddress: parameters.tokenAddress,
958
+ publicWithdrawalAmount: parameters.publicWithdrawalAmount
1045
959
  });
1046
960
  }
1047
961
  async function prepareDualWithdrawProofInputs(parameters) {
1048
- const totalNotes = BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value);
1049
962
  const changeStroops = validateDualWithdrawAmounts(
1050
963
  parameters.withdrawAmountStroops,
1051
- totalNotes,
964
+ BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value),
1052
965
  parameters.changePrivateAddressStpl1
1053
966
  );
1054
967
  const { legA, legB } = dualWithdrawLegsWithSharedRoot({
@@ -1056,8 +969,12 @@ async function prepareDualWithdrawProofInputs(parameters) {
1056
969
  coinA: parameters.coinA,
1057
970
  coinB: parameters.coinB,
1058
971
  state: parameters.state,
1059
- ephemeralA: parseEphemeralKeyString(parameters.ephemeralAKey),
1060
- ephemeralB: parseEphemeralKeyString(parameters.ephemeralBKey),
972
+ ownerPubHex: parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
973
+ parameters.privKeyScalarHex
974
+ ),
975
+ privKeyScalar: privKeyScalarDecimalFromRecipientScalarHex(
976
+ parameters.privKeyScalarHex
977
+ ),
1061
978
  applicationId: parameters.applicationId
1062
979
  });
1063
980
  const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
@@ -1070,17 +987,19 @@ async function prepareDualWithdrawProofInputs(parameters) {
1070
987
  destinationStellarAddress: parameters.destinationStellarAddress,
1071
988
  privKeyScalarHex: parameters.privKeyScalarHex,
1072
989
  tokenAddress: parameters.tokenAddress,
1073
- stateRoot: legA.witness.stateRoot
990
+ stateRoot: legA.witness.stateRoot,
991
+ publicWithdrawalAmount: parameters.withdrawAmountStroops.toString()
1074
992
  });
1075
993
  const audit = buildPoolTransactionAuditParameters({
1076
994
  applicationId: parameters.applicationId,
995
+ nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
1077
996
  ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
1078
997
  });
1079
998
  return {
1080
999
  publicInput,
1081
1000
  audit,
1082
- withdrawLegs: [legA.withdrawObject, legB.withdrawObject],
1083
1001
  deposits,
1002
+ withdrawLegs: [legA.withdrawObject, legB.withdrawObject],
1084
1003
  ...changeCoin ? { changeCoin } : {}
1085
1004
  };
1086
1005
  }
@@ -1098,35 +1017,49 @@ function validateSingleWithdrawAmounts(withdrawAmountStroops, noteStroops) {
1098
1017
  async function proveSingleWithdrawTransaction(parameters) {
1099
1018
  return parameters.sdk.proveTransaction(
1100
1019
  parameters.publicInput,
1101
- buildPublicWithdrawLegs(
1102
- parameters.tokenAddress,
1103
- parameters.withdrawAmountStroops.toString()
1020
+ padPublicLegsToLayout(
1021
+ parameters.sdk,
1022
+ buildPublicWithdrawLegs(
1023
+ parameters.tokenAddress,
1024
+ parameters.withdrawAmountStroops.toString()
1025
+ )
1104
1026
  ),
1105
- [parameters.primaryWithdraw, "dummy"],
1106
- parameters.deposits,
1027
+ padWithdrawSlotsToLayout(parameters.sdk, [parameters.primaryWithdraw]),
1028
+ padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
1107
1029
  parameters.audit
1108
1030
  );
1109
1031
  }
1110
1032
  function buildPrimaryWithdrawForCoin(parameters) {
1111
- const ephemeralPoint = parseEphemeralKeyString(parameters.depositorEphemeralKey);
1112
1033
  const witness = parameters.sdk.buildWithdrawMerkleWitness(
1113
1034
  parameters.coin,
1114
1035
  parameters.state
1115
1036
  );
1037
+ const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
1038
+ parameters.privKeyScalarHex
1039
+ );
1040
+ const ownerPubHex = parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
1041
+ parameters.privKeyScalarHex
1042
+ );
1116
1043
  const primaryWithdraw = withdrawObjectFromMerkleWitness2(
1117
1044
  witness,
1118
- leafEphemeralCoords(ephemeralPoint.xHex, ephemeralPoint.yHex),
1119
- parameters.applicationId
1045
+ ownerPubHex,
1046
+ parameters.applicationId,
1047
+ privKeyScalar
1120
1048
  );
1121
1049
  return { witness, primaryWithdraw };
1122
1050
  }
1123
1051
  async function prepareSingleWithdrawProofInputs(parameters) {
1124
- const noteStroops = BigInt(parameters.coin.value);
1125
1052
  const changeStroops = validateSingleWithdrawAmounts(
1126
1053
  parameters.withdrawAmountStroops,
1127
- noteStroops
1054
+ BigInt(parameters.coin.value)
1128
1055
  );
1129
- const { witness, primaryWithdraw } = buildPrimaryWithdrawForCoin(parameters);
1056
+ const { witness, primaryWithdraw } = buildPrimaryWithdrawForCoin({
1057
+ sdk: parameters.sdk,
1058
+ applicationId: parameters.applicationId,
1059
+ coin: parameters.coin,
1060
+ state: parameters.state,
1061
+ privKeyScalarHex: parameters.privKeyScalarHex
1062
+ });
1130
1063
  const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
1131
1064
  changeStroops,
1132
1065
  changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
@@ -1137,18 +1070,19 @@ async function prepareSingleWithdrawProofInputs(parameters) {
1137
1070
  stateRoot: witness.stateRoot,
1138
1071
  destinationStellarAddress: parameters.destinationStellarAddress,
1139
1072
  privKeyScalarHex: parameters.privKeyScalarHex,
1140
- tokenAddress: parameters.tokenAddress
1141
- });
1142
- const audit = buildPoolTransactionAuditParameters({
1143
- applicationId: parameters.applicationId,
1144
- ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
1073
+ tokenAddress: parameters.tokenAddress,
1074
+ publicWithdrawalAmount: parameters.withdrawAmountStroops.toString()
1145
1075
  });
1146
1076
  return {
1147
1077
  primaryWithdraw,
1148
1078
  deposits,
1149
1079
  changeCoin,
1150
1080
  publicInput,
1151
- audit
1081
+ audit: buildPoolTransactionAuditParameters({
1082
+ applicationId: parameters.applicationId,
1083
+ nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
1084
+ ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
1085
+ })
1152
1086
  };
1153
1087
  }
1154
1088
  async function proveWithdrawTransact(parameters) {
@@ -1164,12 +1098,11 @@ async function proveWithdrawTransact(parameters) {
1164
1098
  });
1165
1099
  return {
1166
1100
  ...proof,
1167
- applicationIdsPlaintext: [
1168
- parameters.applicationId,
1169
- "0",
1170
- changeCoin ? parameters.applicationId : "0",
1171
- "0"
1172
- ],
1101
+ applicationIdsPlaintext: buildApplicationIdHints({
1102
+ sdk: parameters.sdk,
1103
+ inputIds: [parameters.applicationId],
1104
+ outputIds: [changeCoin ? parameters.applicationId : "0"]
1105
+ }),
1173
1106
  ...changeCoin ? { changeCoin } : {}
1174
1107
  };
1175
1108
  }
@@ -1177,59 +1110,269 @@ async function proveWithdrawTransactDual(parameters) {
1177
1110
  const { publicInput, audit, withdrawLegs, deposits, changeCoin } = await prepareDualWithdrawProofInputs(parameters);
1178
1111
  const proof = await parameters.sdk.proveTransaction(
1179
1112
  publicInput,
1180
- buildPublicWithdrawLegs(
1181
- parameters.tokenAddress,
1182
- parameters.withdrawAmountStroops.toString()
1113
+ padPublicLegsToLayout(
1114
+ parameters.sdk,
1115
+ buildPublicWithdrawLegs(
1116
+ parameters.tokenAddress,
1117
+ parameters.withdrawAmountStroops.toString()
1118
+ )
1183
1119
  ),
1184
- withdrawLegs,
1185
- deposits,
1120
+ padWithdrawSlotsToLayout(parameters.sdk, withdrawLegs),
1121
+ padDepositSlotsToLayout(parameters.sdk, deposits),
1186
1122
  audit
1187
1123
  );
1188
1124
  return {
1189
1125
  ...proof,
1190
- applicationIdsPlaintext: [
1191
- audit.applicationId,
1192
- audit.applicationId,
1193
- changeCoin ? audit.applicationId : "0",
1194
- "0"
1195
- ],
1126
+ applicationIdsPlaintext: buildApplicationIdHints({
1127
+ sdk: parameters.sdk,
1128
+ inputIds: [audit.applicationId, audit.applicationId],
1129
+ outputIds: [changeCoin ? audit.applicationId : "0"]
1130
+ }),
1196
1131
  ...changeCoin ? { changeCoin } : {}
1197
1132
  };
1198
1133
  }
1199
1134
 
1200
1135
  // src/transact/pool/service.ts
1201
1136
  import "buffer";
1202
- import { PrivacyPoolSDK as PrivacyPoolSdkClass } from "@auditable/privacy-pool-zk-sdk";
1203
1137
 
1204
- // src/transact/pool/aligned-deposit.ts
1205
- import { PrivacyPoolSDK, scalarHexToFrDecimal } from "@auditable/privacy-pool-zk-sdk";
1206
- var SAMPLE_SCALAR_ATTEMPTS = 10;
1207
- function sampleValidDepositScalarHex() {
1208
- for (let index = 0; index < SAMPLE_SCALAR_ATTEMPTS; index++) {
1209
- const candidate = PrivacyPoolSDK.generateRandomScalarHex32();
1210
- try {
1211
- scalarHexToFrDecimal(candidate);
1212
- return candidate;
1213
- } catch {
1214
- continue;
1138
+ // src/transact/zk/circuit-config.ts
1139
+ import {
1140
+ BundledZkCircuit
1141
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1142
+
1143
+ // src/transact/environment/zk-config-nonce.ts
1144
+ var BINDING_ZK_NONCE = 3n;
1145
+ var SIX_BY_SIX_BINDING_ZK_NONCE = 7n;
1146
+ var DEFAULT_ZK_CONFIG_NONCE = BINDING_ZK_NONCE;
1147
+ function resolveZkConfigNonce(transactEnvironment) {
1148
+ return transactEnvironment.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
1149
+ }
1150
+
1151
+ // src/transact/zk/browser-artifact-cache.ts
1152
+ import { ZK_SDK_PACKAGE_VERSION } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1153
+ var ZK_ARTIFACT_CACHE_NAME = `privacy-sdk-stellar-zk-artifacts:${ZK_SDK_PACKAGE_VERSION}`;
1154
+ function isBrowserCacheApiAvailable() {
1155
+ return browserCacheStorage() !== void 0;
1156
+ }
1157
+ function readCaches() {
1158
+ return globalThis.caches;
1159
+ }
1160
+ function browserCacheStorage() {
1161
+ const cachesValue = readCaches();
1162
+ if (cachesValue === void 0 || cachesValue === null) {
1163
+ return void 0;
1164
+ }
1165
+ return cachesValue;
1166
+ }
1167
+ function absoluteArtifactUrl(url) {
1168
+ if (/^[a-z][a-z0-9+.-]*:/i.test(url)) {
1169
+ return url;
1170
+ }
1171
+ const href = globalThis.location?.href;
1172
+ if (href === void 0) {
1173
+ return url;
1174
+ }
1175
+ return new URL(url, href).href;
1176
+ }
1177
+ async function rememberResponse(url, response) {
1178
+ const storage = browserCacheStorage();
1179
+ if (storage === void 0) {
1180
+ return;
1181
+ }
1182
+ try {
1183
+ const cache = await storage.open(ZK_ARTIFACT_CACHE_NAME);
1184
+ await cache.put(url, response.clone());
1185
+ } catch {
1186
+ return;
1187
+ }
1188
+ }
1189
+ async function fetchNetworkArrayBuffer(url) {
1190
+ const response = await fetch(url);
1191
+ if (!response.ok) {
1192
+ throw new Error(`Failed to fetch ZK artifact ${url}: ${String(response.status)}`);
1193
+ }
1194
+ await rememberResponse(url, response);
1195
+ return response.arrayBuffer();
1196
+ }
1197
+ async function fetchArrayBufferWithBrowserCache(url) {
1198
+ const requestUrl = absoluteArtifactUrl(url);
1199
+ const storage = browserCacheStorage();
1200
+ if (storage !== void 0) {
1201
+ const cache = await storage.open(ZK_ARTIFACT_CACHE_NAME);
1202
+ const cached = await cache.match(requestUrl);
1203
+ if (cached?.ok === true) {
1204
+ return cached.arrayBuffer();
1215
1205
  }
1216
1206
  }
1217
- throw new Error("could not sample valid depositor ephemeral scalar");
1207
+ return fetchNetworkArrayBuffer(requestUrl);
1218
1208
  }
1219
- async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
1220
- const privateAddressPoint = decodePrivateAddress(parameters.privateAddressStpl1);
1221
- const scalarHex = sampleValidDepositScalarHex();
1222
- const shared = sdk.ecdhSharedKey(
1223
- scalarHex,
1224
- privateAddressPoint.x,
1225
- privateAddressPoint.y
1226
- );
1209
+
1210
+ // src/transact/zk/prefetch-bundled-circuit.ts
1211
+ import {
1212
+ bundledCircuitFileNames,
1213
+ defaultZkArtifactBaseUrl
1214
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1215
+ function resolveArtifactBaseUrl(explicit) {
1216
+ const trimmed = explicit?.trim();
1217
+ if (trimmed === void 0 || trimmed === "") {
1218
+ return defaultZkArtifactBaseUrl();
1219
+ }
1220
+ let withoutSlash = trimmed;
1221
+ while (withoutSlash.endsWith("/")) {
1222
+ withoutSlash = withoutSlash.slice(0, -1);
1223
+ }
1224
+ return withoutSlash;
1225
+ }
1226
+ function artifactHref(base, fileName) {
1227
+ const withSlash = `${base}/`;
1228
+ if (/^https?:\/\//i.test(withSlash) || withSlash.startsWith("file:")) {
1229
+ return new URL(fileName, withSlash).href;
1230
+ }
1231
+ const href = globalThis.location?.href;
1232
+ if (href !== void 0) {
1233
+ return new URL(fileName, new URL(withSlash, href)).href;
1234
+ }
1235
+ return `${withSlash}${fileName}`;
1236
+ }
1237
+ async function materializeBundledCircuitWithBrowserCache(definition, zkArtifactBaseUrl) {
1238
+ const base = resolveArtifactBaseUrl(zkArtifactBaseUrl);
1239
+ const names = bundledCircuitFileNames(definition.circuit);
1240
+ const [circuitGraph, r1cs, provingKey] = await Promise.all([
1241
+ fetchArrayBufferWithBrowserCache(artifactHref(base, names.graphFileName)),
1242
+ fetchArrayBufferWithBrowserCache(artifactHref(base, names.r1csFileName)),
1243
+ fetchArrayBufferWithBrowserCache(artifactHref(base, names.provingKeyFileName))
1244
+ ]);
1245
+ return {
1246
+ nIns: definition.nIns,
1247
+ nOuts: definition.nOuts,
1248
+ publicNInputs: definition.publicNInputs,
1249
+ publicNOutputs: definition.publicNOutputs,
1250
+ circuitGraph,
1251
+ r1cs,
1252
+ provingKey
1253
+ };
1254
+ }
1255
+
1256
+ // src/transact/zk/circuit-config.ts
1257
+ import { BundledZkCircuit as BundledZkCircuit2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1258
+ var DEFAULT_STELLAR_ZK_CIRCUITS = {
1259
+ [BINDING_ZK_NONCE.toString()]: {
1260
+ nIns: 2,
1261
+ nOuts: 2,
1262
+ publicNInputs: 1,
1263
+ publicNOutputs: 1,
1264
+ circuit: BundledZkCircuit.TwoByTwo
1265
+ },
1266
+ [SIX_BY_SIX_BINDING_ZK_NONCE.toString()]: {
1267
+ nIns: 6,
1268
+ nOuts: 6,
1269
+ publicNInputs: 1,
1270
+ publicNOutputs: 1,
1271
+ circuit: BundledZkCircuit.SixBySix
1272
+ }
1273
+ };
1274
+ function isBundledDefinition(definition) {
1275
+ return "circuit" in definition;
1276
+ }
1277
+ function bundledConfig(definition) {
1278
+ return {
1279
+ nIns: definition.nIns,
1280
+ nOuts: definition.nOuts,
1281
+ publicNInputs: definition.publicNInputs,
1282
+ publicNOutputs: definition.publicNOutputs,
1283
+ circuit: definition.circuit
1284
+ };
1285
+ }
1286
+ async function materializeCustomDefinition(definition) {
1287
+ const [zkey, circuitGraph, r1cs, provingKey] = await Promise.all([
1288
+ fetchArrayBufferWithBrowserCache(definition.zkeyUrl),
1289
+ fetchArrayBufferWithBrowserCache(definition.circuitGraphUrl),
1290
+ fetchArrayBufferWithBrowserCache(definition.r1csUrl),
1291
+ fetchArrayBufferWithBrowserCache(definition.provingKeyUrl)
1292
+ ]);
1293
+ return {
1294
+ nIns: definition.nIns,
1295
+ nOuts: definition.nOuts,
1296
+ publicNInputs: definition.publicNInputs,
1297
+ publicNOutputs: definition.publicNOutputs,
1298
+ zkey,
1299
+ circuitGraph,
1300
+ r1cs,
1301
+ provingKey
1302
+ };
1303
+ }
1304
+ async function materializeDefinition(definition, zkArtifactBaseUrl) {
1305
+ if (!isBundledDefinition(definition)) {
1306
+ return materializeCustomDefinition(definition);
1307
+ }
1308
+ if (isBrowserCacheApiAvailable()) {
1309
+ return materializeBundledCircuitWithBrowserCache(definition, zkArtifactBaseUrl);
1310
+ }
1311
+ return bundledConfig(definition);
1312
+ }
1313
+ async function materializeSelectedZkCircuit(circuits, nonce, zkArtifactBaseUrl) {
1314
+ const map = stellarCircuitsOrDefault(circuits);
1315
+ const key = nonce.toString();
1316
+ const definition = Object.entries(map).find(([nonceKey]) => nonceKey === key)?.[1];
1317
+ if (!definition) {
1318
+ throw new Error(`no zk circuit configured for nonce ${key}`);
1319
+ }
1320
+ return { [key]: await materializeDefinition(definition, zkArtifactBaseUrl) };
1321
+ }
1322
+ function stellarCircuitsOrDefault(circuits) {
1323
+ return circuits ?? DEFAULT_STELLAR_ZK_CIRCUITS;
1324
+ }
1325
+ function optionalZkArtifactBaseUrl(value) {
1326
+ if (value === void 0) {
1327
+ return {};
1328
+ }
1329
+ const trimmed = value.trim();
1330
+ if (trimmed === "") {
1331
+ return {};
1332
+ }
1333
+ let withoutSlash = trimmed;
1334
+ while (withoutSlash.endsWith("/")) {
1335
+ withoutSlash = withoutSlash.slice(0, -1);
1336
+ }
1337
+ return { zkArtifactBaseUrl: withoutSlash };
1338
+ }
1339
+
1340
+ // src/transact/pool/aligned-deposit.ts
1341
+ import {
1342
+ PrivacyPoolSDK,
1343
+ scalarHexToFrDecimal
1344
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1345
+ var SAMPLE_SCALAR_ATTEMPTS = 10;
1346
+ function escrowDepositFields(parameters) {
1347
+ if (!parameters.recipientHi || !parameters.recipientLo) {
1348
+ return {};
1349
+ }
1350
+ return {
1351
+ ...parameters.escrowNonce ? { escrowNonce: parameters.escrowNonce } : {},
1352
+ recipientStellar: [parameters.recipientHi, parameters.recipientLo]
1353
+ };
1354
+ }
1355
+ function sampleValidDepositScalarHex() {
1356
+ for (let index = 0; index < SAMPLE_SCALAR_ATTEMPTS; index++) {
1357
+ const candidate = PrivacyPoolSDK.generateRandomScalarHex32();
1358
+ try {
1359
+ scalarHexToFrDecimal(candidate);
1360
+ return candidate;
1361
+ } catch {
1362
+ continue;
1363
+ }
1364
+ }
1365
+ throw new Error("could not sample valid depositor ephemeral scalar");
1366
+ }
1367
+ async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
1368
+ const privateAddressPoint = decodePrivateAddress(parameters.privateAddressStpl1);
1369
+ const scalarHex = sampleValidDepositScalarHex();
1227
1370
  const [assetHi, assetLo] = tokenAddressToAssetLeg(parameters.tokenAddress);
1228
1371
  const resolvedApplicationId = resolvePoolApplicationId(applicationId);
1229
- const generated = sdk.generateCoinForDepositWithSharedHex(
1372
+ const generated = sdk.generateCoinForDepositWithOwnerPubHex(
1230
1373
  scalarHex,
1231
- shared.x,
1232
- shared.y,
1374
+ privateAddressPoint.x,
1375
+ privateAddressPoint.y,
1233
1376
  parameters.amountStroops,
1234
1377
  assetHi,
1235
1378
  assetLo,
@@ -1244,27 +1387,34 @@ async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
1244
1387
  ephemeralKeyScalar: scalarHexToFrDecimal(scalarHex),
1245
1388
  asset: [generated.coin.asset_hi, generated.coin.asset_lo],
1246
1389
  applicationId: resolvedApplicationId,
1247
- recipientPublicKeys
1390
+ recipientPublicKeys,
1391
+ ...escrowDepositFields(parameters)
1248
1392
  };
1249
1393
  return {
1250
1394
  deposit,
1251
1395
  commitment_hex: generated.commitment_hex,
1252
1396
  coin: generated.coin,
1253
1397
  depositScalarHex: scalarHex,
1254
- precommitementHex: generated.precommitement_hex
1398
+ precommitementHex: generated.precommitementHex
1255
1399
  };
1256
1400
  }
1257
1401
 
1258
1402
  // src/transact/pool/service.ts
1259
1403
  var PrivacyPoolService = class {
1260
- constructor(assets, applicationId, auditPublicKey) {
1404
+ constructor(assets, applicationId, auditPublicKey, zkCircuits, zkConfigNonce, zkArtifactBaseUrl) {
1261
1405
  this.assets = assets;
1262
1406
  this.applicationId = applicationId;
1263
1407
  this.auditPublicKey = auditPublicKey;
1408
+ this.zkCircuits = zkCircuits;
1409
+ this.zkConfigNonce = zkConfigNonce;
1410
+ this.zkArtifactBaseUrl = zkArtifactBaseUrl;
1264
1411
  }
1265
1412
  assets;
1266
1413
  applicationId;
1267
1414
  auditPublicKey;
1415
+ zkCircuits;
1416
+ zkConfigNonce;
1417
+ zkArtifactBaseUrl;
1268
1418
  sdk = void 0;
1269
1419
  initPromise = void 0;
1270
1420
  async ensureInit() {
@@ -1280,10 +1430,17 @@ var PrivacyPoolService = class {
1280
1430
  "PrivacyPoolService requires browser ZK assets before initialization."
1281
1431
  );
1282
1432
  }
1283
- this.sdk = await PrivacyPoolSdkClass.init({
1433
+ const zkConfigNonce = this.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
1434
+ const zkCircuits = await materializeSelectedZkCircuit(
1435
+ this.zkCircuits,
1436
+ zkConfigNonce,
1437
+ this.zkArtifactBaseUrl
1438
+ );
1439
+ this.sdk = await PrivacyPoolSDK2.init({
1284
1440
  wasmBinary: this.assets.sdkWasm,
1285
- circuitWasm: this.assets.circuitWasm,
1286
- zkey: this.assets.provingKey
1441
+ zkCircuits,
1442
+ zkConfigNonce,
1443
+ ...optionalZkArtifactBaseUrl(this.zkArtifactBaseUrl)
1287
1444
  });
1288
1445
  })();
1289
1446
  return this.initPromise;
@@ -1301,22 +1458,17 @@ var PrivacyPoolService = class {
1301
1458
  getApplicationId() {
1302
1459
  return resolvePoolApplicationId(this.applicationId);
1303
1460
  }
1304
- async generatePrivateAddressFromStellarSignature(signature) {
1305
- await this.ensureInit();
1306
- if (!this.sdk) {
1307
- throw new Error("SDK not initialized");
1308
- }
1309
- return privateAddressSdk(this.sdk).generatePrivateAddressFromStellarSignature(
1310
- signature
1461
+ async generatePrivateAddressFromStellarSignature(signature, domain) {
1462
+ const sdk = await this.getInitializedSdk();
1463
+ return privateAddressSdk(sdk).generatePrivateAddressFromStellarSignature(
1464
+ signature,
1465
+ domain
1311
1466
  );
1312
1467
  }
1313
1468
  async sharedSecretX(recipientScalarHex, ephemeralKeyEncoded) {
1314
- await this.ensureInit();
1315
- if (!this.sdk) {
1316
- throw new Error("SDK not initialized");
1317
- }
1469
+ const sdk = await this.getInitializedSdk();
1318
1470
  const ephemeralKey = decodeDecodedEphemeralKey(ephemeralKeyEncoded);
1319
- const shared = this.sdk.sharedSecretFromRecipientPreimage({
1471
+ const shared = sdk.sharedSecretFromRecipientPreimage({
1320
1472
  recipientScalar: recipientScalarHex,
1321
1473
  ephemeralKey
1322
1474
  });
@@ -1339,6 +1491,7 @@ var PrivacyPoolService = class {
1339
1491
  const applicationId = this.getApplicationId();
1340
1492
  const audit = buildPoolTransactionAuditParameters({
1341
1493
  applicationId,
1494
+ nAuditSlots: sdk.getLayout().nAuditSlots,
1342
1495
  ...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {}
1343
1496
  });
1344
1497
  const deposit = {
@@ -1352,38 +1505,35 @@ var PrivacyPoolService = class {
1352
1505
  const publicInput = withTokenAddressPublicInputs(
1353
1506
  {
1354
1507
  stateRoot,
1355
- withdrawAddressHi: "0",
1356
- withdrawAddressLo: "0",
1357
1508
  privKeyScalar: randomFrDecimal253()
1358
1509
  },
1359
1510
  parameters.tokenAddress
1360
1511
  );
1361
1512
  const proof = await sdk.proveTransaction(
1362
1513
  publicInput,
1363
- buildPublicDepositLegs(parameters.tokenAddress, parameters.coin.value),
1364
- ["dummy", "dummy"],
1365
- [deposit, "dummy"],
1514
+ padPublicLegsToLayout(
1515
+ sdk,
1516
+ buildPublicDepositLegs(parameters.tokenAddress, parameters.coin.value)
1517
+ ),
1518
+ padWithdrawSlotsToLayout(sdk, []),
1519
+ padDepositSlotsToLayout(sdk, [deposit]),
1366
1520
  audit
1367
1521
  );
1368
- const applicationIdsPlaintext = [
1369
- "0",
1370
- "0",
1371
- applicationId,
1372
- "0"
1373
- ];
1522
+ const applicationIdsPlaintext = buildApplicationIdHints({
1523
+ sdk,
1524
+ inputIds: [],
1525
+ outputIds: [applicationId]
1526
+ });
1374
1527
  return { ...proof, applicationIdsPlaintext };
1375
1528
  }
1376
- async calculateNullifierHash(nullifier) {
1529
+ async calculateNullifierHash(nullifier, privKeyScalar) {
1377
1530
  const sdk = await this.getInitializedSdk();
1378
- return sdk.calculateNullifierHash(nullifier);
1531
+ return sdk.calculateNullifierHash(nullifier, privKeyScalar);
1379
1532
  }
1380
1533
  async prepareWithdrawTransactProof(parameters) {
1381
- await this.ensureInit();
1382
- if (!this.sdk) {
1383
- throw new Error("SDK not initialized");
1384
- }
1534
+ const sdk = await this.getInitializedSdk();
1385
1535
  return proveWithdrawTransact({
1386
- sdk: this.sdk,
1536
+ sdk,
1387
1537
  applicationId: this.getApplicationId(),
1388
1538
  buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
1389
1539
  ...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
@@ -1391,12 +1541,9 @@ var PrivacyPoolService = class {
1391
1541
  });
1392
1542
  }
1393
1543
  async prepareWithdrawTransactProofDual(parameters) {
1394
- await this.ensureInit();
1395
- if (!this.sdk) {
1396
- throw new Error("SDK not initialized");
1397
- }
1544
+ const sdk = await this.getInitializedSdk();
1398
1545
  return proveWithdrawTransactDual({
1399
- sdk: this.sdk,
1546
+ sdk,
1400
1547
  applicationId: this.getApplicationId(),
1401
1548
  buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
1402
1549
  ...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
@@ -1419,7 +1566,10 @@ function createPrivacyPoolService(input) {
1419
1566
  return new PrivacyPoolService(
1420
1567
  input?.assets,
1421
1568
  input?.applicationId,
1422
- input?.auditPublicKey
1569
+ input?.auditPublicKey,
1570
+ input?.zkCircuits,
1571
+ input?.zkConfigNonce,
1572
+ input?.zkArtifactBaseUrl
1423
1573
  );
1424
1574
  }
1425
1575
  var configuredPrivacyPoolService;
@@ -1435,81 +1585,245 @@ function getPrivacyPoolService() {
1435
1585
  return configuredPrivacyPoolService;
1436
1586
  }
1437
1587
 
1438
- // src/transact/transfer-source/verify.ts
1439
- async function verifyPendingClaimBeforeExecute(input) {
1440
- try {
1441
- assertPendingClaimOwner({
1442
- claim: input.claim,
1443
- walletPublicKey: input.walletPublicKey
1588
+ // src/transact/merkle/fetch-contract.ts
1589
+ import { Buffer as Buffer11 } from "buffer";
1590
+
1591
+ // src/transact/merkle/encoding.ts
1592
+ import "buffer";
1593
+ var FR_ORDER = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n;
1594
+ function bufferToDecimal(buf) {
1595
+ const hex = buf.toString("hex");
1596
+ const bigintFromHex = BigInt(`0x${hex}`);
1597
+ const reduced = bigintFromHex % FR_ORDER;
1598
+ return reduced.toString();
1599
+ }
1600
+ function commitmentsBuffersToDecimal(buffers) {
1601
+ return buffers.map((bufferRow) => bufferToDecimal(bufferRow));
1602
+ }
1603
+
1604
+ // src/transact/merkle/state-port.ts
1605
+ function poolMerkleStateToCachedView(state) {
1606
+ return {
1607
+ commitments: state.commitments,
1608
+ updatedAt: state.updatedAt,
1609
+ merkleRootHex: state.merkleRootHex
1610
+ };
1611
+ }
1612
+
1613
+ // src/transact/merkle/fetch-contract.ts
1614
+ function normalizeCommitmentBuffers(rawBuffers) {
1615
+ return rawBuffers.map(
1616
+ (bufferRow) => Buffer11.isBuffer(bufferRow) ? bufferRow : Buffer11.from(bufferRow)
1617
+ );
1618
+ }
1619
+ function mergeContractMerkleWithCache(parameters) {
1620
+ const cachedCount = parameters.cachedState?.commitments.length ?? 0;
1621
+ const shouldPreferContract = parameters.contractCount > cachedCount || !parameters.cachedState || cachedCount === 0;
1622
+ if (shouldPreferContract) {
1623
+ const updatedAt = Date.now();
1624
+ void parameters.poolMerkleState?.set({
1625
+ poolContract: parameters.poolContractId,
1626
+ commitments: parameters.contractCommitments,
1627
+ commitmentCount: parameters.contractCount,
1628
+ merkleRootHex: parameters.merkleRootHex,
1629
+ updatedAt
1444
1630
  });
1445
- const coin = pendingClaimToCoin(input.claim);
1446
- const nullifierHashHex = await getPrivacyPoolService().calculateNullifierHash(
1447
- coin.nullifier
1448
- );
1449
- const contractContext = requireContractContext(input.environment);
1450
- const poolContractId = input.poolContractId?.trim() || contractContext.network.poolContract;
1451
- const spent = await readNullifierConsumedOnChain({
1452
- contractContext,
1453
- poolContractId,
1454
- walletPublicKey: input.walletPublicKey.trim(),
1455
- nullifierHashHex
1631
+ return {
1632
+ commitments: parameters.contractCommitments,
1633
+ updatedAt,
1634
+ merkleRootHex: parameters.merkleRootHex,
1635
+ commitmentCount: parameters.contractCount
1636
+ };
1637
+ }
1638
+ return {
1639
+ commitments: parameters.cachedState.commitments,
1640
+ updatedAt: parameters.cachedState.updatedAt,
1641
+ merkleRootHex: parameters.cachedState.merkleRootHex ?? parameters.merkleRootHex,
1642
+ commitmentCount: parameters.cachedState.commitments.length
1643
+ };
1644
+ }
1645
+ async function readCachedPoolMerkleView(poolMerkleState, poolContractId) {
1646
+ if (!poolMerkleState) {
1647
+ return void 0;
1648
+ }
1649
+ const cached = await poolMerkleState.get(poolContractId);
1650
+ return cached ? poolMerkleStateToCachedView(cached) : void 0;
1651
+ }
1652
+ async function fetchAndMergeMerkleState(parameters) {
1653
+ const client = readPoolClientFactory(parameters.transactEnvironment)({
1654
+ contractId: parameters.poolContractId,
1655
+ walletPublicKey: parameters.walletPublicKey,
1656
+ networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
1657
+ sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
1658
+ });
1659
+ const commitmentsRead = await client.get_commitments();
1660
+ const rawBuffers = commitmentsRead.result;
1661
+ const buffers = normalizeCommitmentBuffers(rawBuffers);
1662
+ const contractCommitments = commitmentsBuffersToDecimal(buffers);
1663
+ const contractCount = contractCommitments.length;
1664
+ const rootRead = await client.get_merkle_root();
1665
+ const merkleRootBuffer = rootRead.result;
1666
+ const merkleRootHex = Buffer11.from(merkleRootBuffer).toString("hex");
1667
+ const cachedState = await readCachedPoolMerkleView(
1668
+ parameters.poolMerkleState,
1669
+ parameters.poolContractId
1670
+ );
1671
+ return mergeContractMerkleWithCache({
1672
+ poolContractId: parameters.poolContractId,
1673
+ contractCommitments,
1674
+ contractCount,
1675
+ merkleRootHex,
1676
+ cachedState,
1677
+ ...parameters.poolMerkleState ? { poolMerkleState: parameters.poolMerkleState } : {}
1678
+ });
1679
+ }
1680
+ async function readLeafEphemeralHex(parameters) {
1681
+ const cached = await parameters.leafEphemeral?.get({
1682
+ poolContract: parameters.poolContractId,
1683
+ leafIndex: parameters.leafIndex
1684
+ });
1685
+ if (cached?.xHex && cached.yHex) {
1686
+ return { xHex: cached.xHex, yHex: cached.yHex };
1687
+ }
1688
+ const client = readPoolClientFactory(parameters.transactEnvironment)({
1689
+ contractId: parameters.poolContractId,
1690
+ walletPublicKey: parameters.walletPublicKey,
1691
+ networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
1692
+ sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
1693
+ });
1694
+ const read = await client.get_leaf_ephemeral({ leaf_index: parameters.leafIndex });
1695
+ const coords = read.result;
1696
+ if (!coords?.x || !coords?.y) {
1697
+ throw new Error("Missing leaf ephemeral key on contract");
1698
+ }
1699
+ const xHex = Buffer11.from(coords.x).toString("hex");
1700
+ const yHex = Buffer11.from(coords.y).toString("hex");
1701
+ await parameters.leafEphemeral?.set({
1702
+ poolContract: parameters.poolContractId,
1703
+ leafIndex: parameters.leafIndex,
1704
+ xHex,
1705
+ yHex,
1706
+ cachedAt: (/* @__PURE__ */ new Date()).toISOString()
1707
+ });
1708
+ return { xHex, yHex };
1709
+ }
1710
+
1711
+ // src/transact/engine/prepare/shared.ts
1712
+ async function resolveTokenContractId2(environment, assetId) {
1713
+ if (environment.resolveTokenContractId) {
1714
+ return environment.resolveTokenContractId(assetId);
1715
+ }
1716
+ throw new Error(`Token contract is not configured for asset ${assetId}.`);
1717
+ }
1718
+ async function resolveWalletPublicKey(environment, prepared) {
1719
+ if (environment.resolveWalletPublicKey) {
1720
+ return environment.resolveWalletPublicKey();
1721
+ }
1722
+ if (prepared.kind === "deposit") {
1723
+ const depositIntent = prepared.intent;
1724
+ return depositIntent.from;
1725
+ }
1726
+ throw new Error("Wallet public key resolver is not configured.");
1727
+ }
1728
+ async function resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
1729
+ const cached = await readSenderPrivKeyScalarHex(
1730
+ environment,
1731
+ privateAddressStpl1,
1732
+ owner
1733
+ );
1734
+ if (cached) {
1735
+ return cached;
1736
+ }
1737
+ if (environment.ensureSenderPrivKeyScalarHex) {
1738
+ return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
1739
+ }
1740
+ if (!environment.resolveSenderPrivKeyScalarHex) {
1741
+ throw new Error("Sender private key scalar resolver is not configured.");
1742
+ }
1743
+ return environment.resolveSenderPrivKeyScalarHex(privateAddressStpl1);
1744
+ }
1745
+ async function readSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
1746
+ if (owner && environment.resolveSenderPrivKeyScalarFromState) {
1747
+ const fromState = await environment.resolveSenderPrivKeyScalarFromState({
1748
+ owner,
1749
+ privateAddressStpl1
1456
1750
  });
1457
- if (spent) {
1458
- throw executionError3(
1459
- "Pending claim nullifier was already spent on-chain.",
1460
- "validation",
1461
- { reason: "pending_claim_nullifier_spent" }
1462
- );
1751
+ if (fromState?.trim()) {
1752
+ return fromState.trim();
1463
1753
  }
1464
- } catch (error) {
1465
- if (typeof error === "object" && error !== null && "code" in error && error.code === "insufficient_state") {
1466
- throw executionError3(
1467
- error instanceof Error ? error.message : "Pending claim owner mismatch.",
1468
- "validation",
1469
- { reason: "pending_claim_owner_mismatch" }
1470
- );
1754
+ }
1755
+ if (environment.readSenderPrivKeyScalarHex) {
1756
+ const cached = await environment.readSenderPrivKeyScalarHex(privateAddressStpl1);
1757
+ if (cached?.trim()) {
1758
+ return cached.trim();
1471
1759
  }
1472
- throw error;
1473
1760
  }
1761
+ return void 0;
1474
1762
  }
1475
-
1476
- // src/transact/transfer-source/verify-private-records.ts
1477
- import { executionError as executionError4, insufficientStateError as insufficientStateError2 } from "@arcanetech/privacy-sdk-core";
1478
-
1479
- // src/transact/private-address/record-coin.ts
1480
- function requireCoinNoteFromRecord(record) {
1481
- if (!record.coinNote) {
1482
- throw new Error(`Private record ${record.id} is missing coin note data.`);
1763
+ async function ensureSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
1764
+ const cached = await readSenderPrivKeyScalarHex(
1765
+ environment,
1766
+ privateAddressStpl1,
1767
+ owner
1768
+ );
1769
+ if (cached) {
1770
+ return cached;
1483
1771
  }
1484
- return record.coinNote;
1772
+ if (environment.ensureSenderPrivKeyScalarHex) {
1773
+ return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
1774
+ }
1775
+ return resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner);
1485
1776
  }
1486
- function findCommitmentLeafIndex(commitments, commitment) {
1487
- return commitments.indexOf(commitment);
1777
+ async function loadMerkleState(environment, walletPublicKey) {
1778
+ const merged = await fetchAndMergeMerkleState({
1779
+ poolContractId: environment.network.poolContract,
1780
+ walletPublicKey,
1781
+ transactEnvironment: environment,
1782
+ ...environment.poolMerkleState ? { poolMerkleState: environment.poolMerkleState } : {}
1783
+ });
1784
+ return { commitments: merged.commitments };
1488
1785
  }
1489
- function buildPrivateRecordFromDeposit(input) {
1786
+ function enrichPreparedOperation(prepared, outputRecords, artifacts) {
1490
1787
  return {
1491
- id: input.commitmentHex,
1492
- owner: input.owner,
1493
- asset: input.assetId,
1494
- amount: input.amount,
1495
- consumed: false,
1496
- status: input.status ?? "pending",
1497
- poolContract: input.poolContract,
1498
- commitmentHex: input.commitmentHex,
1499
- privateAddress: input.privateAddress,
1500
- amountDisplay: input.amountDisplay,
1501
- coinNote: input.coin,
1502
- depositScalarHex: input.depositScalarHex,
1503
- precommitementHex: input.precommitementHex,
1504
- ...input.txHash ? { txHash: input.txHash } : {}
1788
+ ...prepared,
1789
+ outputRecords,
1790
+ transactArtifacts: artifacts,
1791
+ submissionPayload: {
1792
+ operationId: crypto.randomUUID(),
1793
+ signed: false
1794
+ }
1505
1795
  };
1506
1796
  }
1507
1797
 
1508
1798
  // src/transact/transfer-source/verify-private-records.ts
1799
+ async function resolveNullifierSpendScalarHex(input) {
1800
+ const stamped = input.spendScalarHex?.trim();
1801
+ if (stamped) {
1802
+ return stamped;
1803
+ }
1804
+ const privateAddress = input.record.privateAddress?.trim();
1805
+ if (!privateAddress) {
1806
+ throw executionError3(
1807
+ "Private record is missing a private address; cannot derive the owner-bound spend scalar.",
1808
+ "validation",
1809
+ {
1810
+ reason: "private_record_missing_private_address",
1811
+ recordId: input.record.id
1812
+ }
1813
+ );
1814
+ }
1815
+ return ensureSenderPrivKeyScalarHex(
1816
+ input.environment,
1817
+ privateAddress,
1818
+ input.walletPublicKey
1819
+ );
1820
+ }
1509
1821
  async function readPrivateRecordNullifierSpendStatus(input) {
1510
1822
  const coin = requireCoinNoteFromRecord(input.record);
1823
+ const scalarHex = await resolveNullifierSpendScalarHex(input);
1511
1824
  const nullifierHashHex = await getPrivacyPoolService().calculateNullifierHash(
1512
- coin.nullifier
1825
+ coin.nullifier,
1826
+ privKeyScalarDecimalFromRecipientScalarHex(scalarHex)
1513
1827
  );
1514
1828
  const contractContext = requireContractContext(input.environment);
1515
1829
  const poolContractId = input.poolContractId?.trim() || contractContext.network.poolContract;
@@ -1527,10 +1841,11 @@ async function verifyPrivateRecordsNullifiersBeforeExecute(input) {
1527
1841
  record,
1528
1842
  environment: input.environment,
1529
1843
  walletPublicKey: input.walletPublicKey,
1530
- ...input.poolContractId ? { poolContractId: input.poolContractId } : {}
1844
+ ...input.poolContractId ? { poolContractId: input.poolContractId } : {},
1845
+ ...input.spendScalarHex ? { spendScalarHex: input.spendScalarHex } : {}
1531
1846
  });
1532
1847
  if (status.spent) {
1533
- throw executionError4(
1848
+ throw executionError3(
1534
1849
  "Private input note nullifier was already spent on-chain.",
1535
1850
  "validation",
1536
1851
  {
@@ -1550,10 +1865,11 @@ async function assertPrivateRecordsNullifiersAvailable(input) {
1550
1865
  const coin = requireCoinNoteFromRecord(record);
1551
1866
  const spent = await input.checkNullifierSpent({
1552
1867
  nullifier: coin.nullifier,
1553
- walletPublicKey: input.walletPublicKey
1868
+ walletPublicKey: input.walletPublicKey,
1869
+ ...record.privateAddress ? { privateAddressStpl1: record.privateAddress } : {}
1554
1870
  });
1555
1871
  if (spent) {
1556
- throw insufficientStateError2(
1872
+ throw insufficientStateError(
1557
1873
  "private_record_nullifier_spent",
1558
1874
  "Private input note nullifier was already spent on-chain.",
1559
1875
  { recordId: record.id }
@@ -1565,15 +1881,6 @@ async function assertPrivateRecordsNullifiersAvailable(input) {
1565
1881
  // src/adapters/transfer-output-records.ts
1566
1882
  function buildTransferOutputRecords(intent, consumedTotal, walletPublicKey) {
1567
1883
  const recipientOwner = recipientOutputOwner(intent, walletPublicKey);
1568
- if (isPendingClaimSource(intent.from)) {
1569
- return [
1570
- createOutputRecord({
1571
- ...recipientOwner,
1572
- asset: intent.asset,
1573
- amount: intent.amount
1574
- })
1575
- ];
1576
- }
1577
1884
  const changeAmount = consumedTotal - intent.amount;
1578
1885
  const outputs = [
1579
1886
  createOutputRecord({
@@ -1680,7 +1987,8 @@ async function filterUnspentPrivateRecords(input) {
1680
1987
  const coin = requireCoinNoteFromRecord(record);
1681
1988
  const spent = await input.checkNullifierSpent({
1682
1989
  nullifier: coin.nullifier,
1683
- walletPublicKey: input.walletPublicKey
1990
+ walletPublicKey: input.walletPublicKey,
1991
+ ...record.privateAddress ? { privateAddressStpl1: record.privateAddress } : {}
1684
1992
  });
1685
1993
  if (!spent) {
1686
1994
  unspent.push(record);
@@ -1698,14 +2006,14 @@ function pickRecordsForSpendAmount(input) {
1698
2006
  return selected;
1699
2007
  }
1700
2008
  if ((input.kind === "transfer" || input.kind === "withdraw") && selected.length >= 2) {
1701
- throw insufficientStateError3(
2009
+ throw insufficientStateError2(
1702
2010
  "missing_private_records",
1703
2011
  "Storage does not contain enough private records for this operation.",
1704
2012
  { requestedAmount: input.amount, availableAmount: selectedTotal }
1705
2013
  );
1706
2014
  }
1707
2015
  }
1708
- throw insufficientStateError3(
2016
+ throw insufficientStateError2(
1709
2017
  "missing_private_records",
1710
2018
  "Storage does not contain enough private records for this operation.",
1711
2019
  { requestedAmount: input.amount, availableAmount: selectedTotal }
@@ -1714,7 +2022,7 @@ function pickRecordsForSpendAmount(input) {
1714
2022
  async function selectPrivateRecords(input) {
1715
2023
  const from = input.intent.from;
1716
2024
  if (!isPrivateAddressTransferFrom(from)) {
1717
- throw insufficientStateError3(
2025
+ throw insufficientStateError2(
1718
2026
  "invalid_transfer_source",
1719
2027
  "Private record selection requires a private address transfer source."
1720
2028
  );
@@ -1732,7 +2040,7 @@ async function selectPrivateRecords(input) {
1732
2040
  checkNullifierSpent: input.checkNullifierSpent
1733
2041
  }) : locallyAvailable;
1734
2042
  if (available.length === 0) {
1735
- throw insufficientStateError3(
2043
+ throw insufficientStateError2(
1736
2044
  "missing_private_records",
1737
2045
  "Storage does not contain enough private records for this operation.",
1738
2046
  { requestedAmount: input.intent.amount, availableAmount: 0n }
@@ -1760,11 +2068,10 @@ function buildSpendOutputRecords(input) {
1760
2068
  }
1761
2069
 
1762
2070
  // src/adapters/transfer-prepare.ts
1763
- import { insufficientStateError as insufficientStateError4 } from "@arcanetech/privacy-sdk-core";
1764
2071
  async function prepareTransferOperation(intent, deps) {
2072
+ const spend = await resolvePrivateAddressSpend(intent, deps);
1765
2073
  const walletAddress = await deps.wallet.getAddress();
1766
2074
  const walletPublicKey = walletAddress.trim();
1767
- const spend = isPendingClaimSource(intent.from) ? await resolvePendingClaimSpend(intent, deps, walletPublicKey) : await resolvePrivateAddressSpend(intent, deps);
1768
2075
  const consumedTotal = sumRecordAmounts(spend.consumedRecords);
1769
2076
  const prepared = {
1770
2077
  kind: "transfer",
@@ -1779,40 +2086,6 @@ async function prepareTransferOperation(intent, deps) {
1779
2086
  };
1780
2087
  return deps.engine.prepare(prepared);
1781
2088
  }
1782
- async function resolvePendingClaimSpend(intent, deps, walletPublicKey) {
1783
- if (!deps.getPendingClaims) {
1784
- throw insufficientStateError4(
1785
- "pending_claim_state_unavailable",
1786
- "Pending claim state is not available for this transfer."
1787
- );
1788
- }
1789
- const claim = await resolvePendingClaimSource({
1790
- from: intent.from,
1791
- walletPublicKey,
1792
- getPendingClaims: deps.getPendingClaims
1793
- });
1794
- assertPendingClaimOwner({ claim, walletPublicKey });
1795
- await assertPendingClaimNullifierAvailable({
1796
- claim,
1797
- walletPublicKey,
1798
- ...deps.checkNullifierSpent ? { checkNullifierSpent: deps.checkNullifierSpent } : {}
1799
- });
1800
- validatePendingClaimIntentMatches(claim, intent);
1801
- return {
1802
- consumedRecords: [
1803
- pendingClaimToConsumedRecord({
1804
- claim,
1805
- walletPublicKey,
1806
- poolContract: deps.poolContract
1807
- })
1808
- ],
1809
- transactArtifacts: {
1810
- pendingClaim: claim,
1811
- spendSource: "pendingClaim",
1812
- executeFinalizeRequired: true
1813
- }
1814
- };
1815
- }
1816
2089
  async function resolvePrivateAddressSpend(intent, deps) {
1817
2090
  const walletAddress = await deps.wallet.getAddress();
1818
2091
  const walletPublicKey = walletAddress.trim();
@@ -1835,37 +2108,6 @@ async function resolvePrivateAddressSpend(intent, deps) {
1835
2108
  }
1836
2109
  };
1837
2110
  }
1838
- function validatePendingClaimIntentMatches(claim, intent) {
1839
- if (claim.amount !== intent.amount) {
1840
- throw insufficientStateError4(
1841
- "pending_claim_amount_mismatch",
1842
- "Transfer amount must match the pending claim amount.",
1843
- { claimAmount: claim.amount, requestedAmount: intent.amount }
1844
- );
1845
- }
1846
- if (claim.asset !== intent.asset) {
1847
- throw insufficientStateError4(
1848
- "pending_claim_asset_mismatch",
1849
- "Transfer asset must match the pending claim asset."
1850
- );
1851
- }
1852
- }
1853
- async function assertPendingClaimNullifierAvailable(input) {
1854
- if (!input.checkNullifierSpent) {
1855
- return;
1856
- }
1857
- const nullifier = pendingClaimToCoin(input.claim).nullifier;
1858
- const spent = await input.checkNullifierSpent({
1859
- nullifier,
1860
- walletPublicKey: input.walletPublicKey
1861
- });
1862
- if (spent) {
1863
- throw insufficientStateError4(
1864
- "pending_claim_nullifier_spent",
1865
- "Pending claim nullifier was already spent on-chain."
1866
- );
1867
- }
1868
- }
1869
2111
 
1870
2112
  // src/adapters/network.ts
1871
2113
  function createStellarNetworkAdapter(deps) {
@@ -1949,9 +2191,6 @@ async function prepareOperation(input) {
1949
2191
  // src/state/foundation/paths.ts
1950
2192
  var STELLAR_STATE_PATHS = {
1951
2193
  privateRecords: "$.privateRecords",
1952
- pendingClaimsItems: "$.pendingClaims.items",
1953
- pendingClaimsPagination: "$.pendingClaims.pagination",
1954
- pendingClaimsCountByOwner: "$.pendingClaims.countByOwner",
1955
2194
  registryPrivateAddresses: "$.registry.privateAddresses",
1956
2195
  registryRegisteredAddresses: "$.registry.registeredAddresses",
1957
2196
  registryLookups: "$.registry.lookups",
@@ -1971,25 +2210,6 @@ var STELLAR_STATE_PATHS = {
1971
2210
 
1972
2211
  // src/state/schemas/shared.ts
1973
2212
  import { z } from "zod";
1974
- var pendingClaimSchema = z.object({
1975
- id: z.string().min(1),
1976
- owner: z.string().min(1),
1977
- asset: z.string().min(1),
1978
- amount: z.coerce.bigint(),
1979
- createdAt: z.string().min(1),
1980
- poolTxId: z.string().optional(),
1981
- commitmentHex: z.string().optional(),
1982
- nullifierHex: z.string().optional(),
1983
- futureNullifierHashHex: z.string().optional(),
1984
- assetHiHex: z.string().optional(),
1985
- assetLoHex: z.string().optional(),
1986
- nullifierFieldHex: z.string().optional(),
1987
- secretHex: z.string().optional(),
1988
- tempPublicKeyXHex: z.string().optional(),
1989
- tempPublicKeyYHex: z.string().optional(),
1990
- encryptedRecoveryBase64: z.string().optional(),
1991
- createdAtLedger: z.number().int().optional()
1992
- });
1993
2213
  var paginationSchema = z.object({
1994
2214
  total: z.number().int().nonnegative(),
1995
2215
  page: z.number().int().positive(),
@@ -2159,26 +2379,6 @@ function normalizePublicBalancesFromEntries(value, owner) {
2159
2379
  }).filter((balance) => balance !== void 0);
2160
2380
  }
2161
2381
 
2162
- // src/state/read/normalize/claims.ts
2163
- function normalizePendingClaimsState(value) {
2164
- if (typeof value !== "object" || value === null) {
2165
- return { items: [] };
2166
- }
2167
- const record = value;
2168
- const items = Array.isArray(record.items) ? record.items.flatMap((item) => {
2169
- const parsed = pendingClaimSchema.safeParse(item);
2170
- return parsed.success ? [withoutUndefinedFields(parsed.data)] : [];
2171
- }) : [];
2172
- const paginationResult = paginationSchema.safeParse(record.pagination);
2173
- if (paginationResult.success) {
2174
- return { items, pagination: paginationResult.data };
2175
- }
2176
- return { items };
2177
- }
2178
- function normalizePendingClaimsCount(value) {
2179
- return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
2180
- }
2181
-
2182
2382
  // src/state/read/normalize/deliveries.ts
2183
2383
  function normalizeIncomingDeliveries(value) {
2184
2384
  const entries = typeof value === "object" && value !== null && !Array.isArray(value) ? Object.values(value) : value;
@@ -2301,8 +2501,7 @@ import { registerArrayFilterItemSchema } from "@arcanetech/privacy-sdk-core/stat
2301
2501
 
2302
2502
  // src/state/filters/ops.ts
2303
2503
  var stellarArrayFilterSchemaKeys = {
2304
- privateRecord: "privateRecord",
2305
- pendingClaim: "pendingClaim"
2504
+ privateRecord: "privateRecord"
2306
2505
  };
2307
2506
  function rejectPrivateRecordsByIds(ids) {
2308
2507
  return {
@@ -2328,56 +2527,6 @@ function rejectConsumedPrivateRecords() {
2328
2527
  }
2329
2528
  };
2330
2529
  }
2331
- function rejectPendingClaimsByOwner(owner) {
2332
- return {
2333
- opType: "arrayFilter",
2334
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2335
- itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
2336
- rejectWhen: {
2337
- op: "fieldEquals",
2338
- field: "owner",
2339
- value: owner
2340
- }
2341
- };
2342
- }
2343
- function rejectPendingClaimsByIds(ids) {
2344
- return {
2345
- opType: "arrayFilter",
2346
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2347
- itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
2348
- rejectWhen: {
2349
- op: "fieldIn",
2350
- field: "id",
2351
- values: ids
2352
- }
2353
- };
2354
- }
2355
- function rejectPendingClaimsByOwnerAndAsset(input) {
2356
- const matches = [];
2357
- if (input.owner !== void 0) {
2358
- matches.push({
2359
- op: "fieldEquals",
2360
- field: "owner",
2361
- value: input.owner
2362
- });
2363
- }
2364
- if (input.asset !== void 0) {
2365
- matches.push({
2366
- op: "fieldEquals",
2367
- field: "asset",
2368
- value: input.asset
2369
- });
2370
- }
2371
- return {
2372
- opType: "arrayFilter",
2373
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2374
- itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
2375
- rejectWhen: {
2376
- op: "and",
2377
- matches
2378
- }
2379
- };
2380
- }
2381
2530
 
2382
2531
  // src/state/filters/register-schemas.ts
2383
2532
  var registered = false;
@@ -2389,24 +2538,12 @@ function registerStellarArrayFilterSchemas() {
2389
2538
  stellarArrayFilterSchemaKeys.privateRecord,
2390
2539
  privateRecordSchema
2391
2540
  );
2392
- registerArrayFilterItemSchema(
2393
- stellarArrayFilterSchemaKeys.pendingClaim,
2394
- pendingClaimSchema
2395
- );
2396
2541
  registered = true;
2397
2542
  }
2398
2543
 
2399
2544
  // src/state/bridge/call-types.ts
2400
2545
  import "@arcanetech/privacy-sdk-core/state";
2401
2546
  var stellarStateCallTypes = {
2402
- pendingClaims: "pendingClaims",
2403
- clearPendingClaims: "clearPendingClaims",
2404
- readPendingClaims: "readPendingClaims",
2405
- replacePendingClaimsPage: "replacePendingClaimsPage",
2406
- upsertPendingClaims: "upsertPendingClaims",
2407
- removePendingClaims: "removePendingClaims",
2408
- setPendingClaimsCount: "setPendingClaimsCount",
2409
- readPendingClaimsCount: "readPendingClaimsCount",
2410
2547
  readStellarAddressRegistered: "readStellarAddressRegistered",
2411
2548
  readCachedPrivateAddress: "readCachedPrivateAddress",
2412
2549
  readRegistryLookup: "readRegistryLookup",
@@ -2633,194 +2770,10 @@ var stellarBalancesStateDefinitions = [
2633
2770
  }
2634
2771
  ];
2635
2772
 
2636
- // src/state/schemas/claims/write.ts
2637
- import { z as z5 } from "zod";
2638
- var pendingClaimsWriteSchema = z5.object({
2639
- type: z5.literal(stellarStateCallTypes.pendingClaims),
2640
- claims: z5.array(pendingClaimSchema),
2641
- paginationInfo: paginationSchema
2642
- }).transform(({ type, claims, paginationInfo }) => ({
2643
- type,
2644
- operations: [
2645
- {
2646
- opType: "arrayPush",
2647
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2648
- items: claims
2649
- },
2650
- {
2651
- opType: "primitiveSet",
2652
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsPagination,
2653
- value: paginationInfo
2654
- }
2655
- ]
2656
- }));
2657
- var clearPendingClaimsSchema = z5.object({
2658
- type: z5.literal(stellarStateCallTypes.clearPendingClaims),
2659
- owner: z5.string().optional(),
2660
- asset: z5.string().optional()
2661
- }).transform(({ type, owner, asset }) => {
2662
- if (owner === void 0 && asset === void 0) {
2663
- return {
2664
- type,
2665
- operations: [
2666
- {
2667
- opType: "arrayClean",
2668
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems
2669
- }
2670
- ]
2671
- };
2672
- }
2673
- return {
2674
- type,
2675
- operations: [rejectPendingClaimsByOwnerAndAsset({ owner, asset })]
2676
- };
2677
- });
2678
- var readPendingClaimsSchema = z5.object({
2679
- type: z5.literal(stellarStateCallTypes.readPendingClaims)
2680
- }).transform(({ type }) => ({
2681
- type,
2682
- operations: [
2683
- {
2684
- opType: "primitiveGet",
2685
- jsonPath: "$.pendingClaims"
2686
- }
2687
- ]
2688
- }));
2689
-
2690
- // src/state/schemas/claims/page.ts
2691
- import { z as z6 } from "zod";
2692
- var pendingClaimBridgeItemSchema = pendingClaimSchema;
2693
- var replacePendingClaimsPageSchema = z6.object({
2694
- type: z6.literal(stellarStateCallTypes.replacePendingClaimsPage),
2695
- owner: z6.string().min(1),
2696
- claims: z6.array(pendingClaimBridgeItemSchema),
2697
- paginationInfo: z6.object({
2698
- total: z6.number().int().nonnegative(),
2699
- page: z6.number().int().positive(),
2700
- pageSize: z6.number().int().positive(),
2701
- hasMore: z6.boolean()
2702
- }),
2703
- count: z6.number().int().nonnegative().optional()
2704
- }).transform(({ type, owner, claims, paginationInfo, count }) => ({
2705
- type,
2706
- operations: [
2707
- rejectPendingClaimsByOwner(owner),
2708
- {
2709
- opType: "arrayPush",
2710
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2711
- items: claims
2712
- },
2713
- {
2714
- opType: "primitiveSet",
2715
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsPagination,
2716
- value: paginationInfo
2717
- },
2718
- {
2719
- opType: "recordSet",
2720
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
2721
- key: owner,
2722
- value: count ?? paginationInfo.total
2723
- }
2724
- ]
2725
- }));
2726
- var upsertPendingClaimsSchema = z6.object({
2727
- type: z6.literal(stellarStateCallTypes.upsertPendingClaims),
2728
- claims: z6.array(pendingClaimBridgeItemSchema)
2729
- }).transform(({ type, claims }) => ({
2730
- type,
2731
- operations: [
2732
- rejectPendingClaimsByIds(claims.map((claim) => claim.id)),
2733
- {
2734
- opType: "arrayPush",
2735
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2736
- items: claims
2737
- }
2738
- ]
2739
- }));
2740
- var removePendingClaimsSchema = z6.object({
2741
- type: z6.literal(stellarStateCallTypes.removePendingClaims),
2742
- ids: z6.array(z6.string().min(1))
2743
- }).transform(({ type, ids }) => ({
2744
- type,
2745
- operations: [rejectPendingClaimsByIds(ids)]
2746
- }));
2747
- var readPendingClaimsCountSchema = z6.object({
2748
- type: z6.literal(stellarStateCallTypes.readPendingClaimsCount),
2749
- owner: z6.string().min(1)
2750
- }).transform(({ type, owner }) => ({
2751
- type,
2752
- operations: [
2753
- {
2754
- opType: "recordGet",
2755
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
2756
- key: owner
2757
- }
2758
- ]
2759
- }));
2760
- var setPendingClaimsCountSchema = z6.object({
2761
- type: z6.literal(stellarStateCallTypes.setPendingClaimsCount),
2762
- owner: z6.string().min(1),
2763
- count: z6.number().int().nonnegative()
2764
- }).transform(({ type, owner, count }) => ({
2765
- type,
2766
- operations: [
2767
- {
2768
- opType: "recordSet",
2769
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
2770
- key: owner,
2771
- value: count
2772
- }
2773
- ]
2774
- }));
2775
-
2776
- // src/state/definitions/claims.ts
2777
- var stellarClaimsStateDefinitions = [
2778
- {
2779
- type: stellarStateCallTypes.pendingClaims,
2780
- mode: "write",
2781
- schema: pendingClaimsWriteSchema
2782
- },
2783
- {
2784
- type: stellarStateCallTypes.clearPendingClaims,
2785
- mode: "write",
2786
- schema: clearPendingClaimsSchema
2787
- },
2788
- {
2789
- type: stellarStateCallTypes.readPendingClaims,
2790
- mode: "read",
2791
- schema: readPendingClaimsSchema
2792
- },
2793
- {
2794
- type: stellarStateCallTypes.replacePendingClaimsPage,
2795
- mode: "write",
2796
- schema: replacePendingClaimsPageSchema
2797
- },
2798
- {
2799
- type: stellarStateCallTypes.upsertPendingClaims,
2800
- mode: "write",
2801
- schema: upsertPendingClaimsSchema
2802
- },
2803
- {
2804
- type: stellarStateCallTypes.removePendingClaims,
2805
- mode: "write",
2806
- schema: removePendingClaimsSchema
2807
- },
2808
- {
2809
- type: stellarStateCallTypes.readPendingClaimsCount,
2810
- mode: "read",
2811
- schema: readPendingClaimsCountSchema
2812
- },
2813
- {
2814
- type: stellarStateCallTypes.setPendingClaimsCount,
2815
- mode: "write",
2816
- schema: setPendingClaimsCountSchema
2817
- }
2818
- ];
2819
-
2820
2773
  // src/state/schemas/claims/deliveries.ts
2821
- import { z as z7 } from "zod";
2822
- var readIncomingDeliveriesSchema = z7.object({
2823
- type: z7.literal(stellarStateCallTypes.readIncomingDeliveries)
2774
+ import { z as z5 } from "zod";
2775
+ var readIncomingDeliveriesSchema = z5.object({
2776
+ type: z5.literal(stellarStateCallTypes.readIncomingDeliveries)
2824
2777
  }).transform(({ type }) => ({
2825
2778
  type,
2826
2779
  operations: [
@@ -2830,9 +2783,9 @@ var readIncomingDeliveriesSchema = z7.object({
2830
2783
  }
2831
2784
  ]
2832
2785
  }));
2833
- var upsertIncomingDeliveriesSchema = z7.object({
2834
- type: z7.literal(stellarStateCallTypes.upsertIncomingDeliveries),
2835
- deliveries: z7.array(incomingDeliverySchema)
2786
+ var upsertIncomingDeliveriesSchema = z5.object({
2787
+ type: z5.literal(stellarStateCallTypes.upsertIncomingDeliveries),
2788
+ deliveries: z5.array(incomingDeliverySchema)
2836
2789
  }).transform(({ type, deliveries }) => ({
2837
2790
  type,
2838
2791
  operations: deliveries.map((delivery) => ({
@@ -2842,10 +2795,10 @@ var upsertIncomingDeliveriesSchema = z7.object({
2842
2795
  value: delivery
2843
2796
  }))
2844
2797
  }));
2845
- var readDeliverySyncStateSchema = z7.object({
2846
- type: z7.literal(stellarStateCallTypes.readDeliverySyncState),
2847
- privateAddress: z7.string().min(1),
2848
- asset: z7.string().min(1)
2798
+ var readDeliverySyncStateSchema = z5.object({
2799
+ type: z5.literal(stellarStateCallTypes.readDeliverySyncState),
2800
+ privateAddress: z5.string().min(1),
2801
+ asset: z5.string().min(1)
2849
2802
  }).transform(({ type, privateAddress, asset }) => ({
2850
2803
  type,
2851
2804
  operations: [
@@ -2856,8 +2809,8 @@ var readDeliverySyncStateSchema = z7.object({
2856
2809
  }
2857
2810
  ]
2858
2811
  }));
2859
- var setDeliverySyncStateSchema = z7.object({
2860
- type: z7.literal(stellarStateCallTypes.setDeliverySyncState),
2812
+ var setDeliverySyncStateSchema = z5.object({
2813
+ type: z5.literal(stellarStateCallTypes.setDeliverySyncState),
2861
2814
  syncState: deliverySyncStateSchema
2862
2815
  }).transform(({ type, syncState }) => ({
2863
2816
  type,
@@ -2896,10 +2849,10 @@ var stellarDeliveriesStateDefinitions = [
2896
2849
  ];
2897
2850
 
2898
2851
  // src/state/schemas/pool/merkle.ts
2899
- import { z as z8 } from "zod";
2900
- var readPoolMerkleStateSchema = z8.object({
2901
- type: z8.literal(stellarStateCallTypes.readPoolMerkleState),
2902
- poolContract: z8.string().min(1)
2852
+ import { z as z6 } from "zod";
2853
+ var readPoolMerkleStateSchema = z6.object({
2854
+ type: z6.literal(stellarStateCallTypes.readPoolMerkleState),
2855
+ poolContract: z6.string().min(1)
2903
2856
  }).transform(({ type, poolContract }) => ({
2904
2857
  type,
2905
2858
  operations: [
@@ -2910,8 +2863,8 @@ var readPoolMerkleStateSchema = z8.object({
2910
2863
  }
2911
2864
  ]
2912
2865
  }));
2913
- var setPoolMerkleStateSchema = z8.object({
2914
- type: z8.literal(stellarStateCallTypes.setPoolMerkleState),
2866
+ var setPoolMerkleStateSchema = z6.object({
2867
+ type: z6.literal(stellarStateCallTypes.setPoolMerkleState),
2915
2868
  state: poolMerkleStateSchema
2916
2869
  }).transform(({ type, state }) => ({
2917
2870
  type,
@@ -2924,10 +2877,10 @@ var setPoolMerkleStateSchema = z8.object({
2924
2877
  }
2925
2878
  ]
2926
2879
  }));
2927
- var readLeafEphemeralSchema = z8.object({
2928
- type: z8.literal(stellarStateCallTypes.readLeafEphemeral),
2929
- poolContract: z8.string().min(1),
2930
- leafIndex: z8.number().int().nonnegative()
2880
+ var readLeafEphemeralSchema = z6.object({
2881
+ type: z6.literal(stellarStateCallTypes.readLeafEphemeral),
2882
+ poolContract: z6.string().min(1),
2883
+ leafIndex: z6.number().int().nonnegative()
2931
2884
  }).transform(({ type, poolContract, leafIndex }) => ({
2932
2885
  type,
2933
2886
  operations: [
@@ -2938,8 +2891,8 @@ var readLeafEphemeralSchema = z8.object({
2938
2891
  }
2939
2892
  ]
2940
2893
  }));
2941
- var setLeafEphemeralSchema = z8.object({
2942
- type: z8.literal(stellarStateCallTypes.setLeafEphemeral),
2894
+ var setLeafEphemeralSchema = z6.object({
2895
+ type: z6.literal(stellarStateCallTypes.setLeafEphemeral),
2943
2896
  ephemeral: leafEphemeralSchema
2944
2897
  }).transform(({ type, ephemeral }) => ({
2945
2898
  type,
@@ -2978,9 +2931,9 @@ var stellarPoolStateDefinitions = [
2978
2931
  ];
2979
2932
 
2980
2933
  // src/state/schemas/records/private.ts
2981
- import { z as z9 } from "zod";
2982
- var listPrivateRecordsSchema = z9.object({
2983
- type: z9.literal(stellarStateCallTypes.listPrivateRecords)
2934
+ import { z as z7 } from "zod";
2935
+ var listPrivateRecordsSchema = z7.object({
2936
+ type: z7.literal(stellarStateCallTypes.listPrivateRecords)
2984
2937
  }).transform(({ type }) => ({
2985
2938
  type,
2986
2939
  operations: [
@@ -2990,9 +2943,9 @@ var listPrivateRecordsSchema = z9.object({
2990
2943
  }
2991
2944
  ]
2992
2945
  }));
2993
- var savePrivateRecordsSchema = z9.object({
2994
- type: z9.literal(stellarStateCallTypes.savePrivateRecords),
2995
- records: z9.array(privateRecordSchema)
2946
+ var savePrivateRecordsSchema = z7.object({
2947
+ type: z7.literal(stellarStateCallTypes.savePrivateRecords),
2948
+ records: z7.array(privateRecordSchema)
2996
2949
  }).transform(({ type, records }) => ({
2997
2950
  type,
2998
2951
  operations: [
@@ -3003,9 +2956,9 @@ var savePrivateRecordsSchema = z9.object({
3003
2956
  }
3004
2957
  ]
3005
2958
  }));
3006
- var replacePrivateRecordsSchema = z9.object({
3007
- type: z9.literal(stellarStateCallTypes.replacePrivateRecords),
3008
- records: z9.array(privateRecordSchema)
2959
+ var replacePrivateRecordsSchema = z7.object({
2960
+ type: z7.literal(stellarStateCallTypes.replacePrivateRecords),
2961
+ records: z7.array(privateRecordSchema)
3009
2962
  }).transform(({ type, records }) => ({
3010
2963
  type,
3011
2964
  operations: [
@@ -3020,18 +2973,18 @@ var replacePrivateRecordsSchema = z9.object({
3020
2973
  }
3021
2974
  ]
3022
2975
  }));
3023
- var pruneConsumedPrivateRecordsSchema = z9.object({
3024
- type: z9.literal(stellarStateCallTypes.pruneConsumedPrivateRecords)
2976
+ var pruneConsumedPrivateRecordsSchema = z7.object({
2977
+ type: z7.literal(stellarStateCallTypes.pruneConsumedPrivateRecords)
3025
2978
  }).transform(({ type }) => ({
3026
2979
  type,
3027
2980
  operations: [rejectConsumedPrivateRecords()]
3028
2981
  }));
3029
2982
 
3030
2983
  // src/state/schemas/records/transactions.ts
3031
- import { z as z10 } from "zod";
3032
- var upsertPrivateRecordsSchema = z10.object({
3033
- type: z10.literal(stellarStateCallTypes.upsertPrivateRecords),
3034
- records: z10.array(privateRecordSchema)
2984
+ import { z as z8 } from "zod";
2985
+ var upsertPrivateRecordsSchema = z8.object({
2986
+ type: z8.literal(stellarStateCallTypes.upsertPrivateRecords),
2987
+ records: z8.array(privateRecordSchema)
3035
2988
  }).transform(({ type, records }) => ({
3036
2989
  type,
3037
2990
  operations: [
@@ -3043,9 +2996,9 @@ var upsertPrivateRecordsSchema = z10.object({
3043
2996
  }
3044
2997
  ]
3045
2998
  }));
3046
- var readTransactionStatusSchema = z10.object({
3047
- type: z10.literal(stellarStateCallTypes.readTransactionStatus),
3048
- txHash: z10.string().min(1)
2999
+ var readTransactionStatusSchema = z8.object({
3000
+ type: z8.literal(stellarStateCallTypes.readTransactionStatus),
3001
+ txHash: z8.string().min(1)
3049
3002
  }).transform(({ type, txHash }) => ({
3050
3003
  type,
3051
3004
  operations: [
@@ -3056,8 +3009,8 @@ var readTransactionStatusSchema = z10.object({
3056
3009
  }
3057
3010
  ]
3058
3011
  }));
3059
- var setTransactionStatusSchema = z10.object({
3060
- type: z10.literal(stellarStateCallTypes.setTransactionStatus),
3012
+ var setTransactionStatusSchema = z8.object({
3013
+ type: z8.literal(stellarStateCallTypes.setTransactionStatus),
3061
3014
  status: transactionStatusSchema
3062
3015
  }).transform(({ type, status }) => ({
3063
3016
  type,
@@ -3070,9 +3023,9 @@ var setTransactionStatusSchema = z10.object({
3070
3023
  }
3071
3024
  ]
3072
3025
  }));
3073
- var clearTransactionStatusSchema = z10.object({
3074
- type: z10.literal(stellarStateCallTypes.clearTransactionStatus),
3075
- txHash: z10.string().min(1)
3026
+ var clearTransactionStatusSchema = z8.object({
3027
+ type: z8.literal(stellarStateCallTypes.clearTransactionStatus),
3028
+ txHash: z8.string().min(1)
3076
3029
  }).transform(({ type, txHash }) => ({
3077
3030
  type,
3078
3031
  operations: [
@@ -3114,10 +3067,10 @@ var stellarRecordsStateDefinitions = [
3114
3067
  ];
3115
3068
 
3116
3069
  // src/state/schemas/registry/lookup.ts
3117
- import { z as z11 } from "zod";
3118
- var readStellarAddressRegisteredSchema = z11.object({
3119
- type: z11.literal(stellarStateCallTypes.readStellarAddressRegistered),
3120
- address: z11.string().min(1)
3070
+ import { z as z9 } from "zod";
3071
+ var readStellarAddressRegisteredSchema = z9.object({
3072
+ type: z9.literal(stellarStateCallTypes.readStellarAddressRegistered),
3073
+ address: z9.string().min(1)
3121
3074
  }).transform(({ type, address }) => ({
3122
3075
  type,
3123
3076
  operations: [
@@ -3128,9 +3081,9 @@ var readStellarAddressRegisteredSchema = z11.object({
3128
3081
  }
3129
3082
  ]
3130
3083
  }));
3131
- var readCachedPrivateAddressSchema = z11.object({
3132
- type: z11.literal(stellarStateCallTypes.readCachedPrivateAddress),
3133
- address: z11.string().min(1)
3084
+ var readCachedPrivateAddressSchema = z9.object({
3085
+ type: z9.literal(stellarStateCallTypes.readCachedPrivateAddress),
3086
+ address: z9.string().min(1)
3134
3087
  }).transform(({ type, address }) => ({
3135
3088
  type,
3136
3089
  operations: [
@@ -3141,11 +3094,11 @@ var readCachedPrivateAddressSchema = z11.object({
3141
3094
  }
3142
3095
  ]
3143
3096
  }));
3144
- var saveRegisteredPrivateAddressSchema = z11.object({
3145
- type: z11.literal(stellarStateCallTypes.saveRegisteredPrivateAddress),
3146
- address: z11.string().min(1),
3147
- privateAddress: z11.string().min(1),
3148
- registered: z11.boolean()
3097
+ var saveRegisteredPrivateAddressSchema = z9.object({
3098
+ type: z9.literal(stellarStateCallTypes.saveRegisteredPrivateAddress),
3099
+ address: z9.string().min(1),
3100
+ privateAddress: z9.string().min(1),
3101
+ registered: z9.boolean()
3149
3102
  }).transform(({ type, address, privateAddress, registered: registered2 }) => {
3150
3103
  const lookup = registryLookupSchema.parse({
3151
3104
  owner: address,
@@ -3177,9 +3130,9 @@ var saveRegisteredPrivateAddressSchema = z11.object({
3177
3130
  ]
3178
3131
  };
3179
3132
  });
3180
- var invalidateRegisteredAddressSchema = z11.object({
3181
- type: z11.literal(stellarStateCallTypes.invalidateRegisteredAddress),
3182
- address: z11.string().min(1)
3133
+ var invalidateRegisteredAddressSchema = z9.object({
3134
+ type: z9.literal(stellarStateCallTypes.invalidateRegisteredAddress),
3135
+ address: z9.string().min(1)
3183
3136
  }).transform(({ type, address }) => ({
3184
3137
  type,
3185
3138
  operations: [
@@ -3200,9 +3153,9 @@ var invalidateRegisteredAddressSchema = z11.object({
3200
3153
  }
3201
3154
  ]
3202
3155
  }));
3203
- var readRegistryLookupSchema = z11.object({
3204
- type: z11.literal(stellarStateCallTypes.readRegistryLookup),
3205
- address: z11.string().min(1)
3156
+ var readRegistryLookupSchema = z9.object({
3157
+ type: z9.literal(stellarStateCallTypes.readRegistryLookup),
3158
+ address: z9.string().min(1)
3206
3159
  }).transform(({ type, address }) => ({
3207
3160
  type,
3208
3161
  operations: [
@@ -3213,8 +3166,8 @@ var readRegistryLookupSchema = z11.object({
3213
3166
  }
3214
3167
  ]
3215
3168
  }));
3216
- var saveRegistryLookupSchema = z11.object({
3217
- type: z11.literal(stellarStateCallTypes.saveRegistryLookup),
3169
+ var saveRegistryLookupSchema = z9.object({
3170
+ type: z9.literal(stellarStateCallTypes.saveRegistryLookup),
3218
3171
  lookup: registryLookupSchema
3219
3172
  }).transform(({ type, lookup }) => {
3220
3173
  const operations = [
@@ -3250,9 +3203,9 @@ var saveRegistryLookupSchema = z11.object({
3250
3203
  }
3251
3204
  return { type, operations };
3252
3205
  });
3253
- var invalidateRegistryLookupSchema = z11.object({
3254
- type: z11.literal(stellarStateCallTypes.invalidateRegistryLookup),
3255
- address: z11.string().min(1)
3206
+ var invalidateRegistryLookupSchema = z9.object({
3207
+ type: z9.literal(stellarStateCallTypes.invalidateRegistryLookup),
3208
+ address: z9.string().min(1)
3256
3209
  }).transform(({ type, address }) => ({
3257
3210
  type,
3258
3211
  operations: [
@@ -3333,9 +3286,9 @@ var stellarTransactionStateDefinitions = [
3333
3286
  ];
3334
3287
 
3335
3288
  // src/state/schemas/wallet/scalar.ts
3336
- import { z as z12 } from "zod";
3337
- var saveWalletPrivateAddressScalarSchema = z12.object({
3338
- type: z12.literal(stellarStateCallTypes.saveWalletPrivateAddressScalar),
3289
+ import { z as z10 } from "zod";
3290
+ var saveWalletPrivateAddressScalarSchema = z10.object({
3291
+ type: z10.literal(stellarStateCallTypes.saveWalletPrivateAddressScalar),
3339
3292
  scalar: walletPrivateAddressScalarSchema
3340
3293
  }).transform(({ type, scalar }) => ({
3341
3294
  type,
@@ -3348,10 +3301,10 @@ var saveWalletPrivateAddressScalarSchema = z12.object({
3348
3301
  }
3349
3302
  ]
3350
3303
  }));
3351
- var readWalletPrivateAddressScalarSchema = z12.object({
3352
- type: z12.literal(stellarStateCallTypes.readWalletPrivateAddressScalar),
3353
- owner: z12.string().min(1),
3354
- nonce: z12.string().min(1)
3304
+ var readWalletPrivateAddressScalarSchema = z10.object({
3305
+ type: z10.literal(stellarStateCallTypes.readWalletPrivateAddressScalar),
3306
+ owner: z10.string().min(1),
3307
+ nonce: z10.string().min(1)
3355
3308
  }).transform(({ type, owner, nonce }) => ({
3356
3309
  type,
3357
3310
  operations: [
@@ -3364,9 +3317,9 @@ var readWalletPrivateAddressScalarSchema = z12.object({
3364
3317
  }));
3365
3318
 
3366
3319
  // src/state/schemas/wallet/private-address.ts
3367
- import { z as z13 } from "zod";
3368
- var saveWalletPrivateAddressRecordSchema = z13.object({
3369
- type: z13.literal(stellarStateCallTypes.saveWalletPrivateAddressRecord),
3320
+ import { z as z11 } from "zod";
3321
+ var saveWalletPrivateAddressRecordSchema = z11.object({
3322
+ type: z11.literal(stellarStateCallTypes.saveWalletPrivateAddressRecord),
3370
3323
  record: walletPrivateAddressRecordSchema
3371
3324
  }).transform(({ type, record }) => ({
3372
3325
  type,
@@ -3379,10 +3332,10 @@ var saveWalletPrivateAddressRecordSchema = z13.object({
3379
3332
  }
3380
3333
  ]
3381
3334
  }));
3382
- var readWalletPrivateAddressRecordSchema = z13.object({
3383
- type: z13.literal(stellarStateCallTypes.readWalletPrivateAddressRecord),
3384
- owner: z13.string().min(1),
3385
- nonce: z13.string().min(1)
3335
+ var readWalletPrivateAddressRecordSchema = z11.object({
3336
+ type: z11.literal(stellarStateCallTypes.readWalletPrivateAddressRecord),
3337
+ owner: z11.string().min(1),
3338
+ nonce: z11.string().min(1)
3386
3339
  }).transform(({ type, owner, nonce }) => ({
3387
3340
  type,
3388
3341
  operations: [
@@ -3393,10 +3346,10 @@ var readWalletPrivateAddressRecordSchema = z13.object({
3393
3346
  }
3394
3347
  ]
3395
3348
  }));
3396
- var setWalletDefaultPrivateAddressNonceSchema = z13.object({
3397
- type: z13.literal(stellarStateCallTypes.setWalletDefaultPrivateAddressNonce),
3398
- owner: z13.string().min(1),
3399
- nonce: z13.string().min(1)
3349
+ var setWalletDefaultPrivateAddressNonceSchema = z11.object({
3350
+ type: z11.literal(stellarStateCallTypes.setWalletDefaultPrivateAddressNonce),
3351
+ owner: z11.string().min(1),
3352
+ nonce: z11.string().min(1)
3400
3353
  }).transform(({ type, owner, nonce }) => ({
3401
3354
  type,
3402
3355
  operations: [
@@ -3408,9 +3361,9 @@ var setWalletDefaultPrivateAddressNonceSchema = z13.object({
3408
3361
  }
3409
3362
  ]
3410
3363
  }));
3411
- var readWalletDefaultPrivateAddressNonceSchema = z13.object({
3412
- type: z13.literal(stellarStateCallTypes.readWalletDefaultPrivateAddressNonce),
3413
- owner: z13.string().min(1)
3364
+ var readWalletDefaultPrivateAddressNonceSchema = z11.object({
3365
+ type: z11.literal(stellarStateCallTypes.readWalletDefaultPrivateAddressNonce),
3366
+ owner: z11.string().min(1)
3414
3367
  }).transform(({ type, owner }) => ({
3415
3368
  type,
3416
3369
  operations: [
@@ -3421,10 +3374,10 @@ var readWalletDefaultPrivateAddressNonceSchema = z13.object({
3421
3374
  }
3422
3375
  ]
3423
3376
  }));
3424
- var deleteWalletPrivateAddressScalarSchema = z13.object({
3425
- type: z13.literal(stellarStateCallTypes.deleteWalletPrivateAddressScalar),
3426
- owner: z13.string().min(1),
3427
- nonce: z13.string().min(1)
3377
+ var deleteWalletPrivateAddressScalarSchema = z11.object({
3378
+ type: z11.literal(stellarStateCallTypes.deleteWalletPrivateAddressScalar),
3379
+ owner: z11.string().min(1),
3380
+ nonce: z11.string().min(1)
3428
3381
  }).transform(({ type, owner, nonce }) => ({
3429
3382
  type,
3430
3383
  operations: [
@@ -3478,7 +3431,6 @@ var stellarWalletStateDefinitions = [
3478
3431
  // src/state/definitions/index.ts
3479
3432
  registerStellarArrayFilterSchemas();
3480
3433
  var stellarStateDefinitions = [
3481
- ...stellarClaimsStateDefinitions,
3482
3434
  ...stellarRegistryStateDefinitions,
3483
3435
  ...stellarAssetsStateDefinitions,
3484
3436
  ...stellarBalancesStateDefinitions,
@@ -3609,108 +3561,6 @@ function createAssetsService(context) {
3609
3561
  };
3610
3562
  }
3611
3563
 
3612
- // src/state/service/claims/read-methods.ts
3613
- function createClaimsReadMethods(context) {
3614
- const { bridge } = context;
3615
- async function getPendingClaims(filter = {}) {
3616
- const value = await bridge.read({
3617
- type: stellarStateCallTypes.readPendingClaims
3618
- });
3619
- const state = normalizePendingClaimsState(value);
3620
- const items = state.items.filter((claim) => {
3621
- if (filter.owner !== void 0 && claim.owner !== filter.owner) {
3622
- return false;
3623
- }
3624
- if (filter.asset !== void 0 && claim.asset !== filter.asset) {
3625
- return false;
3626
- }
3627
- return true;
3628
- });
3629
- if (state.pagination !== void 0) {
3630
- return { items, pagination: state.pagination };
3631
- }
3632
- return { items };
3633
- }
3634
- return {
3635
- getPendingClaims,
3636
- async getPendingClaimsCount(owner) {
3637
- const value = await bridge.read({
3638
- type: stellarStateCallTypes.readPendingClaimsCount,
3639
- owner
3640
- });
3641
- const count = normalizePendingClaimsCount(value);
3642
- if (count !== void 0) {
3643
- return count;
3644
- }
3645
- const claims = await getPendingClaims({ owner });
3646
- return claims.items.length;
3647
- }
3648
- };
3649
- }
3650
-
3651
- // src/state/service/claims/write-methods.ts
3652
- function appendPendingClaims(bridge, claims, paginationInfo) {
3653
- return bridge.write({
3654
- type: stellarStateCallTypes.pendingClaims,
3655
- claims,
3656
- paginationInfo
3657
- });
3658
- }
3659
- function replacePendingClaimsPage(bridge, input) {
3660
- return bridge.write({
3661
- type: stellarStateCallTypes.replacePendingClaimsPage,
3662
- owner: input.owner,
3663
- claims: input.claims,
3664
- paginationInfo: input.paginationInfo,
3665
- ...input.count === void 0 ? {} : { count: input.count }
3666
- });
3667
- }
3668
- function upsertPendingClaims(bridge, claims) {
3669
- return bridge.write({
3670
- type: stellarStateCallTypes.upsertPendingClaims,
3671
- claims
3672
- });
3673
- }
3674
- function removePendingClaims(bridge, ids) {
3675
- return bridge.write({
3676
- type: stellarStateCallTypes.removePendingClaims,
3677
- ids
3678
- });
3679
- }
3680
- function clearPendingClaims(bridge, input = {}) {
3681
- return bridge.write({
3682
- type: stellarStateCallTypes.clearPendingClaims,
3683
- ...input.owner === void 0 ? {} : { owner: input.owner },
3684
- ...input.asset === void 0 ? {} : { asset: input.asset }
3685
- });
3686
- }
3687
- function setPendingClaimsCount(bridge, owner, count) {
3688
- return bridge.write({
3689
- type: stellarStateCallTypes.setPendingClaimsCount,
3690
- owner,
3691
- count
3692
- });
3693
- }
3694
- function createClaimsWriteMethods(context) {
3695
- const { bridge } = context;
3696
- return {
3697
- appendPendingClaims: (claims, paginationInfo) => appendPendingClaims(bridge, claims, paginationInfo),
3698
- replacePendingClaimsPage: (input) => replacePendingClaimsPage(bridge, input),
3699
- upsertPendingClaims: (claims) => upsertPendingClaims(bridge, claims),
3700
- removePendingClaims: (ids) => removePendingClaims(bridge, ids),
3701
- clearPendingClaims: (input = {}) => clearPendingClaims(bridge, input),
3702
- setPendingClaimsCount: (owner, count) => setPendingClaimsCount(bridge, owner, count)
3703
- };
3704
- }
3705
-
3706
- // src/state/service/claims/index.ts
3707
- function createClaimsService(context) {
3708
- return {
3709
- ...createClaimsWriteMethods(context),
3710
- ...createClaimsReadMethods(context)
3711
- };
3712
- }
3713
-
3714
3564
  // src/state/service/deliveries/incoming-methods.ts
3715
3565
  function createIncomingDeliveryMethods(context) {
3716
3566
  const { bridge } = context;
@@ -4236,7 +4086,6 @@ function composeStellarStateService(adapter) {
4236
4086
  ...createWalletAddressService(base),
4237
4087
  ...createPoolMerkleService(base),
4238
4088
  ...createPoolEphemeralService(base),
4239
- ...createClaimsService(base),
4240
4089
  ...createDeliveriesService(base),
4241
4090
  ...createRecordsService(base)
4242
4091
  };
@@ -4403,22 +4252,63 @@ async function registerPrivateAddressOnChain(input) {
4403
4252
  return transactionHash;
4404
4253
  }
4405
4254
 
4406
- // src/transact/onboarding/recipient.ts
4407
- import { PrivacyPoolSDK as PrivacyPoolSDK3 } from "@auditable/privacy-pool-zk-sdk";
4255
+ // src/contracts/registry/resolve-transfer-recipient.ts
4256
+ import { StrKey as StrKey5 } from "@stellar/stellar-sdk";
4257
+
4258
+ // src/transact/escrow/derived-escrow-recipient.ts
4259
+ import { Buffer as Buffer13 } from "buffer";
4260
+ import { StrKey as StrKey4 } from "@stellar/stellar-sdk";
4261
+ import {
4262
+ derivedEscrowKey,
4263
+ ed25519PubkeyPayloadHexToWithdrawFrDecimals as ed25519PubkeyPayloadHexToWithdrawFrDecimals2,
4264
+ sampleDerivedEscrowKey
4265
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
4408
4266
  var COORDINATE_HEX_LENGTH2 = 64;
4409
- async function generateTemporaryRecipientPrivateAddress() {
4410
- await getPrivacyPoolService().getInitializedSdk();
4411
- const temporaryScalarHex = PrivacyPoolSDK3.generateRandomScalarHex32();
4412
- const sdk = await getPrivacyPoolService().getInitializedSdk();
4413
- const point = sdk.ecdhEphemeralPublicKeyFromScalarHex(temporaryScalarHex);
4414
- const publicKeyXHex = point.x.padStart(COORDINATE_HEX_LENGTH2, "0");
4415
- const publicKeyYHex = point.y.padStart(COORDINATE_HEX_LENGTH2, "0");
4267
+ function stellarAccountToFieldLimbs(stellarAddress) {
4268
+ const pkRaw = StrKey4.decodeEd25519PublicKey(stellarAddress.trim());
4269
+ const pkHex = Buffer13.from(pkRaw).toString("hex");
4270
+ const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals2(pkHex);
4271
+ return { recipientHi: hi, recipientLo: lo };
4272
+ }
4273
+ function padCoordinateHex(value) {
4274
+ return value.replace(/^0x/iu, "").padStart(COORDINATE_HEX_LENGTH2, "0");
4275
+ }
4276
+ async function deriveEscrowRecipientFromStellarAddress(input) {
4277
+ const recipientStellarAddress = input.recipientStellarAddress.trim();
4278
+ if (!StrKey4.isValidEd25519PublicKey(recipientStellarAddress)) {
4279
+ throw new Error("Escrow recipient must be a Stellar G-address.");
4280
+ }
4281
+ const { recipientHi, recipientLo } = stellarAccountToFieldLimbs(
4282
+ recipientStellarAddress
4283
+ );
4284
+ const deriveKey = input.deriveKey ?? derivedEscrowKey;
4285
+ let nonceDecimal;
4286
+ let key;
4287
+ if (input.nonceDecimal) {
4288
+ nonceDecimal = input.nonceDecimal;
4289
+ key = await deriveKey(
4290
+ BigInt(nonceDecimal),
4291
+ BigInt(recipientHi),
4292
+ BigInt(recipientLo)
4293
+ );
4294
+ } else {
4295
+ const sampled = await sampleDerivedEscrowKey(
4296
+ BigInt(recipientHi),
4297
+ BigInt(recipientLo)
4298
+ );
4299
+ nonceDecimal = sampled.nonce.toString();
4300
+ key = sampled.key;
4301
+ }
4416
4302
  return {
4417
- temporaryScalarHex,
4418
- temporaryPrivateAddressStpl1: encodePrivateAddressFromHexCoordinates(
4419
- publicKeyXHex,
4420
- publicKeyYHex
4421
- )
4303
+ nonceDecimal,
4304
+ recipientHi,
4305
+ recipientLo,
4306
+ recipientStellarAddress,
4307
+ privateAddressStpl1: encodePrivateAddressFromHexCoordinates(
4308
+ padCoordinateHex(key.pointXHex),
4309
+ padCoordinateHex(key.pointYHex)
4310
+ ),
4311
+ scalarHex: padCoordinateHex(key.scalarHex)
4422
4312
  };
4423
4313
  }
4424
4314
 
@@ -4437,11 +4327,23 @@ async function resolveTransferRecipientFromChain(input) {
4437
4327
  recipientStellarAddress
4438
4328
  };
4439
4329
  }
4440
- const temporaryKey = await generateTemporaryRecipientPrivateAddress();
4330
+ if (!StrKey5.isValidEd25519PublicKey(recipientStellarAddress)) {
4331
+ throw new Error(
4332
+ "Transfers to unregistered recipients require a Stellar G-address."
4333
+ );
4334
+ }
4335
+ const escrow = await deriveEscrowRecipientFromStellarAddress({
4336
+ recipientStellarAddress
4337
+ });
4441
4338
  return {
4442
- recipientPrivateAddressStpl1: temporaryKey.temporaryPrivateAddressStpl1,
4339
+ recipientPrivateAddressStpl1: escrow.privateAddressStpl1,
4443
4340
  recipientStellarAddress,
4444
- temporaryRecipientKey: temporaryKey
4341
+ escrowSend: {
4342
+ nonceDecimal: escrow.nonceDecimal,
4343
+ recipientHi: escrow.recipientHi,
4344
+ recipientLo: escrow.recipientLo,
4345
+ recipientStellarAddress
4346
+ }
4445
4347
  };
4446
4348
  }
4447
4349
 
@@ -4449,7 +4351,7 @@ async function resolveTransferRecipientFromChain(input) {
4449
4351
  import { Api } from "@stellar/stellar-sdk/rpc";
4450
4352
 
4451
4353
  // src/rpc/soroban-transaction-meta.ts
4452
- import { Address, StrKey as StrKey5 } from "@stellar/stellar-sdk";
4354
+ import { Address, StrKey as StrKey6 } from "@stellar/stellar-sdk";
4453
4355
  var BIGINT_SHIFT_64 = 64n;
4454
4356
  var TRANSACTION_META_SWITCH_SOROBAN_V3 = 3;
4455
4357
  var TRANSACTION_META_SWITCH_SOROBAN_V4 = 4;
@@ -4493,7 +4395,7 @@ function extractAmountFromScValue(value) {
4493
4395
  return void 0;
4494
4396
  }
4495
4397
  function contractIdToString(contractId) {
4496
- return StrKey5.encodeContract(Buffer.from(contractId));
4398
+ return StrKey6.encodeContract(Buffer.from(contractId));
4497
4399
  }
4498
4400
  function scAddressToContractString(address) {
4499
4401
  if (address.switch().name !== "scAddressTypeContract") {
@@ -4817,7 +4719,8 @@ async function checkPrivateRecordSpendStatusWithEnvironment(input) {
4817
4719
  const environment = requireNetworkEnvironment(input.transactEnvironment);
4818
4720
  const contractContext = requireContractContext(environment);
4819
4721
  const nullifierHashHex = await getPrivacyPoolService().calculateNullifierHash(
4820
- input.nullifier
4722
+ input.nullifier,
4723
+ privKeyScalarDecimalFromRecipientScalarHex(input.privKeyScalarHex)
4821
4724
  );
4822
4725
  const poolContractId = input.poolContractId?.trim() || contractContext.network.poolContract;
4823
4726
  const spent = await readNullifierConsumedOnChain({
@@ -4876,140 +4779,30 @@ function createNullifierSpentChecker(transactEnvironment) {
4876
4779
  }
4877
4780
  return async ({
4878
4781
  nullifier,
4879
- walletPublicKey
4782
+ walletPublicKey,
4783
+ privKeyScalarHex,
4784
+ privateAddressStpl1
4880
4785
  }) => {
4786
+ const addressHint = privateAddressStpl1?.trim() ?? "";
4787
+ const resolvedFromEnsure = transactEnvironment.ensureSenderPrivKeyScalarHex ? await transactEnvironment.ensureSenderPrivKeyScalarHex(addressHint) : void 0;
4788
+ const resolvedFromState = addressHint && transactEnvironment.resolveSenderPrivKeyScalarFromState ? await transactEnvironment.resolveSenderPrivKeyScalarFromState({
4789
+ owner: walletPublicKey,
4790
+ privateAddressStpl1: addressHint
4791
+ }) : void 0;
4792
+ const resolvedScalarHex = privKeyScalarHex?.trim() || resolvedFromEnsure?.trim() || resolvedFromState?.trim();
4793
+ if (!resolvedScalarHex) {
4794
+ throw new Error("Spend scalar is required to check owner-bound nullifiers.");
4795
+ }
4881
4796
  const status = await checkPrivateRecordSpendStatusWithEnvironment({
4882
4797
  transactEnvironment,
4883
4798
  nullifier,
4884
- walletPublicKey
4799
+ walletPublicKey,
4800
+ privKeyScalarHex: resolvedScalarHex
4885
4801
  });
4886
4802
  return status.spent;
4887
4803
  };
4888
4804
  }
4889
4805
 
4890
- // src/transact/merkle/fetch-contract.ts
4891
- import { Buffer as Buffer14 } from "buffer";
4892
-
4893
- // src/transact/merkle/encoding.ts
4894
- import "buffer";
4895
- var FR_ORDER = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n;
4896
- function bufferToDecimal(buf) {
4897
- const hex = buf.toString("hex");
4898
- const bigintFromHex = BigInt(`0x${hex}`);
4899
- const reduced = bigintFromHex % FR_ORDER;
4900
- return reduced.toString();
4901
- }
4902
- function commitmentsBuffersToDecimal(buffers) {
4903
- return buffers.map((bufferRow) => bufferToDecimal(bufferRow));
4904
- }
4905
-
4906
- // src/transact/merkle/state-port.ts
4907
- function poolMerkleStateToCachedView(state) {
4908
- return {
4909
- commitments: state.commitments,
4910
- updatedAt: state.updatedAt,
4911
- merkleRootHex: state.merkleRootHex
4912
- };
4913
- }
4914
-
4915
- // src/transact/merkle/fetch-contract.ts
4916
- function normalizeCommitmentBuffers(rawBuffers) {
4917
- return rawBuffers.map(
4918
- (bufferRow) => Buffer14.isBuffer(bufferRow) ? bufferRow : Buffer14.from(bufferRow)
4919
- );
4920
- }
4921
- function mergeContractMerkleWithCache(parameters) {
4922
- const cachedCount = parameters.cachedState?.commitments.length ?? 0;
4923
- const shouldPreferContract = parameters.contractCount > cachedCount || !parameters.cachedState || cachedCount === 0;
4924
- if (shouldPreferContract) {
4925
- const updatedAt = Date.now();
4926
- void parameters.poolMerkleState?.set({
4927
- poolContract: parameters.poolContractId,
4928
- commitments: parameters.contractCommitments,
4929
- commitmentCount: parameters.contractCount,
4930
- merkleRootHex: parameters.merkleRootHex,
4931
- updatedAt
4932
- });
4933
- return {
4934
- commitments: parameters.contractCommitments,
4935
- updatedAt,
4936
- merkleRootHex: parameters.merkleRootHex,
4937
- commitmentCount: parameters.contractCount
4938
- };
4939
- }
4940
- return {
4941
- commitments: parameters.cachedState.commitments,
4942
- updatedAt: parameters.cachedState.updatedAt,
4943
- merkleRootHex: parameters.cachedState.merkleRootHex ?? parameters.merkleRootHex,
4944
- commitmentCount: parameters.cachedState.commitments.length
4945
- };
4946
- }
4947
- async function readCachedPoolMerkleView(poolMerkleState, poolContractId) {
4948
- if (!poolMerkleState) {
4949
- return void 0;
4950
- }
4951
- const cached = await poolMerkleState.get(poolContractId);
4952
- return cached ? poolMerkleStateToCachedView(cached) : void 0;
4953
- }
4954
- async function fetchAndMergeMerkleState(parameters) {
4955
- const client = readPoolClientFactory(parameters.transactEnvironment)({
4956
- contractId: parameters.poolContractId,
4957
- walletPublicKey: parameters.walletPublicKey,
4958
- networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
4959
- sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
4960
- });
4961
- const commitmentsRead = await client.get_commitments();
4962
- const rawBuffers = commitmentsRead.result;
4963
- const buffers = normalizeCommitmentBuffers(rawBuffers);
4964
- const contractCommitments = commitmentsBuffersToDecimal(buffers);
4965
- const contractCount = contractCommitments.length;
4966
- const rootRead = await client.get_merkle_root();
4967
- const merkleRootBuffer = rootRead.result;
4968
- const merkleRootHex = Buffer14.from(merkleRootBuffer).toString("hex");
4969
- const cachedState = await readCachedPoolMerkleView(
4970
- parameters.poolMerkleState,
4971
- parameters.poolContractId
4972
- );
4973
- return mergeContractMerkleWithCache({
4974
- poolContractId: parameters.poolContractId,
4975
- contractCommitments,
4976
- contractCount,
4977
- merkleRootHex,
4978
- cachedState,
4979
- ...parameters.poolMerkleState ? { poolMerkleState: parameters.poolMerkleState } : {}
4980
- });
4981
- }
4982
- async function readLeafEphemeralHex(parameters) {
4983
- const cached = await parameters.leafEphemeral?.get({
4984
- poolContract: parameters.poolContractId,
4985
- leafIndex: parameters.leafIndex
4986
- });
4987
- if (cached?.xHex && cached.yHex) {
4988
- return { xHex: cached.xHex, yHex: cached.yHex };
4989
- }
4990
- const client = readPoolClientFactory(parameters.transactEnvironment)({
4991
- contractId: parameters.poolContractId,
4992
- walletPublicKey: parameters.walletPublicKey,
4993
- networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
4994
- sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
4995
- });
4996
- const read = await client.get_leaf_ephemeral({ leaf_index: parameters.leafIndex });
4997
- const coords = read.result;
4998
- if (!coords?.x || !coords?.y) {
4999
- throw new Error("Missing leaf ephemeral key on contract");
5000
- }
5001
- const xHex = Buffer14.from(coords.x).toString("hex");
5002
- const yHex = Buffer14.from(coords.y).toString("hex");
5003
- await parameters.leafEphemeral?.set({
5004
- poolContract: parameters.poolContractId,
5005
- leafIndex: parameters.leafIndex,
5006
- xHex,
5007
- yHex,
5008
- cachedAt: (/* @__PURE__ */ new Date()).toISOString()
5009
- });
5010
- return { xHex, yHex };
5011
- }
5012
-
5013
4806
  // src/client/pool-sync.ts
5014
4807
  function requireTransactEnvironment(transactEnvironment) {
5015
4808
  if (!transactEnvironment) {
@@ -5132,7 +4925,6 @@ function createOperationsFacet(config, state) {
5132
4925
  wallet: config.wallet,
5133
4926
  engine: config.transactEngine,
5134
4927
  poolContract: config.network.poolContract,
5135
- getPendingClaims: () => state.getPendingClaims(),
5136
4928
  ...checkNullifierSpent ? { checkNullifierSpent } : {}
5137
4929
  }),
5138
4930
  policy: createStellarPolicyAdapter(config.policy)
@@ -5176,103 +4968,6 @@ function createAssetsStateDelegates(state) {
5176
4968
  };
5177
4969
  }
5178
4970
 
5179
- // src/state/claims/backend.ts
5180
- var DEFAULT_PENDING_CLAIMS_PAGE_SIZE = 20;
5181
- async function fetchPendingClaimsBackendPage(input) {
5182
- const page = input.page ?? 1;
5183
- const limit = input.pageSize ?? DEFAULT_PENDING_CLAIMS_PAGE_SIZE;
5184
- const params = new URLSearchParams({
5185
- ownerAddress: input.ownerAddress,
5186
- page: String(page),
5187
- limit: String(limit)
5188
- });
5189
- const baseUrl = input.backendBaseUrl.replace(/\/$/, "");
5190
- const response = await fetch(`${baseUrl}/pending-claims?${params.toString()}`);
5191
- if (!response.ok) {
5192
- throw new Error(`Pending claims request failed: ${response.status}`);
5193
- }
5194
- return response.json();
5195
- }
5196
- async function fetchPendingClaimsBackendCount(input) {
5197
- const params = new URLSearchParams({
5198
- ownerAddress: input.ownerAddress
5199
- });
5200
- const baseUrl = input.backendBaseUrl.replace(/\/$/, "");
5201
- const response = await fetch(`${baseUrl}/pending-claims/count?${params.toString()}`);
5202
- if (!response.ok) {
5203
- throw new Error(`Pending claims count request failed: ${response.status}`);
5204
- }
5205
- const payload = await response.json();
5206
- return payload.count;
5207
- }
5208
- function mapBackendPendingClaimItem(item, asset = "") {
5209
- return {
5210
- id: String(item.id),
5211
- owner: item.ownerAddress,
5212
- asset,
5213
- amount: BigInt(item.noteValue),
5214
- createdAt: item.createdAt,
5215
- poolTxId: item.poolTxId,
5216
- commitmentHex: item.commitmentHex,
5217
- nullifierHex: item.nullifierHex,
5218
- futureNullifierHashHex: item.futureNullifierHashHex,
5219
- assetHiHex: item.assetHiHex,
5220
- assetLoHex: item.assetLoHex,
5221
- nullifierFieldHex: item.nullifierFieldHex,
5222
- secretHex: item.secretHex,
5223
- tempPublicKeyXHex: item.tempPublicKeyXHex,
5224
- tempPublicKeyYHex: item.tempPublicKeyYHex,
5225
- encryptedRecoveryBase64: item.encryptedRecoveryBase64,
5226
- createdAtLedger: item.createdAtLedger
5227
- };
5228
- }
5229
- function mapBackendPendingClaimsPage(response, asset = "") {
5230
- return {
5231
- claims: response.data.map((item) => mapBackendPendingClaimItem(item, asset)),
5232
- paginationInfo: {
5233
- total: response.meta.total,
5234
- page: response.meta.page,
5235
- pageSize: response.meta.limit,
5236
- hasMore: response.meta.page < response.meta.totalPages
5237
- }
5238
- };
5239
- }
5240
-
5241
- // src/state/claims/sync-from-backend.ts
5242
- async function syncPendingClaimsFromBackend(stateService, input) {
5243
- const response = await fetchPendingClaimsBackendPage(input);
5244
- const { claims, paginationInfo } = mapBackendPendingClaimsPage(
5245
- response,
5246
- input.asset ?? ""
5247
- );
5248
- await stateService.replacePendingClaimsPage({
5249
- owner: input.ownerAddress,
5250
- claims,
5251
- paginationInfo,
5252
- count: paginationInfo.total
5253
- });
5254
- }
5255
- async function syncPendingClaimsCountFromBackend(stateService, ownerAddress, input) {
5256
- const count = await fetchPendingClaimsBackendCount(input);
5257
- await stateService.setPendingClaimsCount(ownerAddress, count);
5258
- }
5259
-
5260
- // src/client/state-delegates/claims.ts
5261
- function createClaimsStateDelegates(state) {
5262
- return {
5263
- appendPendingClaims: (claims, paginationInfo) => state.appendPendingClaims(claims, paginationInfo),
5264
- loadPendingClaimsFromBackend: (input) => syncPendingClaimsFromBackend(state, input),
5265
- loadPendingClaimsCountFromBackend: (input) => syncPendingClaimsCountFromBackend(state, input.ownerAddress, input),
5266
- replacePendingClaimsPage: (input) => state.replacePendingClaimsPage(input),
5267
- upsertPendingClaims: (claims) => state.upsertPendingClaims(claims),
5268
- removePendingClaims: (ids) => state.removePendingClaims(ids),
5269
- clearPendingClaims: (input = {}) => state.clearPendingClaims(input),
5270
- getPendingClaims: (filter = {}) => state.getPendingClaims(filter),
5271
- getPendingClaimsCount: (owner) => state.getPendingClaimsCount(owner),
5272
- setPendingClaimsCount: (owner, count) => state.setPendingClaimsCount(owner, count)
5273
- };
5274
- }
5275
-
5276
4971
  // src/client/state-delegates/deliveries.ts
5277
4972
  function createDeliveriesStateDelegates(state) {
5278
4973
  return {
@@ -5337,7 +5032,6 @@ function createStateDelegates(state) {
5337
5032
  ...createAssetsStateDelegates(state),
5338
5033
  ...createRegistryStateDelegates(state),
5339
5034
  ...createPoolStateDelegates(state),
5340
- ...createClaimsStateDelegates(state),
5341
5035
  ...createDeliveriesStateDelegates(state),
5342
5036
  ...createRecordsStateDelegates(state)
5343
5037
  };
@@ -5464,91 +5158,14 @@ function createStellarPrivacyClientFromResolvedConfig(config) {
5464
5158
  }
5465
5159
 
5466
5160
  // src/transact/engine/default-factory.ts
5467
- import { PrivacyPoolSDK as PrivacyPoolSDK4 } from "@auditable/privacy-pool-zk-sdk";
5161
+ import { PrivacyPoolSDK as PrivacyPoolSDK3 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
5468
5162
 
5469
- // src/transact/engine/prepare/shared.ts
5470
- async function resolveTokenContractId2(environment, assetId) {
5471
- if (environment.resolveTokenContractId) {
5472
- return environment.resolveTokenContractId(assetId);
5473
- }
5474
- throw new Error(`Token contract is not configured for asset ${assetId}.`);
5475
- }
5476
- async function resolveWalletPublicKey(environment, prepared) {
5477
- if (environment.resolveWalletPublicKey) {
5478
- return environment.resolveWalletPublicKey();
5479
- }
5480
- if (prepared.kind === "deposit") {
5481
- const depositIntent = prepared.intent;
5482
- return depositIntent.from;
5483
- }
5484
- throw new Error("Wallet public key resolver is not configured.");
5485
- }
5486
- async function resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
5487
- const cached = await readSenderPrivKeyScalarHex(
5488
- environment,
5489
- privateAddressStpl1,
5490
- owner
5491
- );
5492
- if (cached) {
5493
- return cached;
5494
- }
5495
- if (environment.ensureSenderPrivKeyScalarHex) {
5496
- return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
5497
- }
5498
- if (!environment.resolveSenderPrivKeyScalarHex) {
5499
- throw new Error("Sender private key scalar resolver is not configured.");
5500
- }
5501
- return environment.resolveSenderPrivKeyScalarHex(privateAddressStpl1);
5502
- }
5503
- async function readSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
5504
- if (owner && environment.resolveSenderPrivKeyScalarFromState) {
5505
- const fromState = await environment.resolveSenderPrivKeyScalarFromState({
5506
- owner,
5507
- privateAddressStpl1
5508
- });
5509
- if (fromState?.trim()) {
5510
- return fromState.trim();
5511
- }
5512
- }
5513
- if (environment.readSenderPrivKeyScalarHex) {
5514
- const cached = await environment.readSenderPrivKeyScalarHex(privateAddressStpl1);
5515
- if (cached?.trim()) {
5516
- return cached.trim();
5517
- }
5518
- }
5519
- return void 0;
5520
- }
5521
- async function ensureSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
5522
- const cached = await readSenderPrivKeyScalarHex(
5523
- environment,
5524
- privateAddressStpl1,
5525
- owner
5526
- );
5527
- if (cached) {
5528
- return cached;
5529
- }
5530
- if (environment.ensureSenderPrivKeyScalarHex) {
5531
- return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
5532
- }
5533
- return resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner);
5534
- }
5535
- async function loadMerkleState(environment, walletPublicKey) {
5536
- const merged = await fetchAndMergeMerkleState({
5537
- poolContractId: environment.network.poolContract,
5538
- walletPublicKey,
5539
- transactEnvironment: environment,
5540
- ...environment.poolMerkleState ? { poolMerkleState: environment.poolMerkleState } : {}
5541
- });
5542
- return { commitments: merged.commitments };
5543
- }
5544
- function enrichPreparedOperation(prepared, outputRecords, artifacts) {
5163
+ // src/transact/pool/proof-types.ts
5164
+ function ciphertextArtifactsFromProof(proof) {
5545
5165
  return {
5546
- ...prepared,
5547
- outputRecords,
5548
- transactArtifacts: artifacts,
5549
- submissionPayload: {
5550
- operationId: crypto.randomUUID(),
5551
- signed: false
5166
+ ...proof.ciphertext_hex === void 0 ? {} : { ciphertextHex: proof.ciphertext_hex },
5167
+ ...proof.output_note_ephemeral_scalars === void 0 ? {} : {
5168
+ outputNoteEphemeralScalars: [...proof.output_note_ephemeral_scalars]
5552
5169
  }
5553
5170
  };
5554
5171
  }
@@ -5603,6 +5220,7 @@ async function prepareDepositOperation(prepared, environment, poolService) {
5603
5220
  return enrichPreparedOperation(prepared, [outputRecord], {
5604
5221
  proofHex: depositProof.proof.proof_hex,
5605
5222
  publicHex: depositProof.proof.public_hex,
5223
+ ...ciphertextArtifactsFromProof(depositProof.proof),
5606
5224
  applicationIdsPlaintext: depositProof.proof.applicationIdsPlaintext,
5607
5225
  tokenAddress,
5608
5226
  depositScalarHex: depositProof.depositScalarHex,
@@ -5612,6 +5230,42 @@ async function prepareDepositOperation(prepared, environment, poolService) {
5612
5230
  });
5613
5231
  }
5614
5232
 
5233
+ // src/transact/engine/prepare/transfer-helpers.ts
5234
+ import { StrKey as StrKey7 } from "@stellar/stellar-sdk";
5235
+ function isStellarAccountRecipient(prepared) {
5236
+ return prepared.kind === "transfer" && StrKey7.isValidEd25519PublicKey(prepared.intent.to.trim());
5237
+ }
5238
+ async function stampEscrowSendArtifacts(prepared, environment, walletPublicKey) {
5239
+ if (!isStellarAccountRecipient(prepared)) {
5240
+ return {};
5241
+ }
5242
+ if (!environment.resolveTransferRecipientAtExecute) {
5243
+ return {};
5244
+ }
5245
+ const recipient = await environment.resolveTransferRecipientAtExecute({
5246
+ recipientStellarAddress: prepared.intent.to.trim(),
5247
+ walletPublicKey
5248
+ });
5249
+ if (!recipient.escrowSend) {
5250
+ return {};
5251
+ }
5252
+ return { escrowSend: true, spendSource: "escrow" };
5253
+ }
5254
+ async function resolveTransferRecipientForExecute(prepared, environment, walletPublicKey) {
5255
+ if (!isStellarAccountRecipient(prepared)) {
5256
+ return {
5257
+ recipientPrivateAddressStpl1: prepared.intent.to.trim()
5258
+ };
5259
+ }
5260
+ if (!environment.resolveTransferRecipientAtExecute) {
5261
+ throw new Error("Transfer recipient resolver is not configured.");
5262
+ }
5263
+ return environment.resolveTransferRecipientAtExecute({
5264
+ recipientStellarAddress: prepared.intent.to.trim(),
5265
+ walletPublicKey
5266
+ });
5267
+ }
5268
+
5615
5269
  // src/transact/engine/prepare/spend.ts
5616
5270
  async function prepareSpendOperation(prepared, environment) {
5617
5271
  const walletPublicKey = await resolveWalletPublicKey(environment, prepared);
@@ -5622,18 +5276,52 @@ async function prepareSpendOperation(prepared, environment) {
5622
5276
  ...prepared.transactArtifacts,
5623
5277
  tokenAddress,
5624
5278
  walletPublicKey,
5625
- executeFinalizeRequired: true
5279
+ executeFinalizeRequired: true,
5280
+ ...await stampEscrowSendArtifacts(prepared, environment, walletPublicKey)
5626
5281
  }
5627
5282
  };
5628
5283
  }
5629
5284
  var prepareTransferOperation2 = prepareSpendOperation;
5630
5285
  var prepareWithdrawOperation = prepareSpendOperation;
5631
5286
 
5287
+ // src/transact/encoding/ephemeral-key.ts
5288
+ var HEX_64_RE = /^[\da-f]{64}$/iu;
5289
+ function normalizeCoordinate(value) {
5290
+ const hex = value.trim().replace(/^0x/iu, "").toLowerCase();
5291
+ if (!HEX_64_RE.test(hex)) {
5292
+ throw new Error("Ephemeral key coordinate must be a 32-byte hex string.");
5293
+ }
5294
+ return hex;
5295
+ }
5296
+ function serializeEphemeralKeyString(point) {
5297
+ return `${normalizeCoordinate(point.xHex)}:${normalizeCoordinate(point.yHex)}`;
5298
+ }
5299
+
5300
+ // src/transact/escrow/require-escrow-spend-scalar.ts
5301
+ function isEscrowSweepSpend(artifacts) {
5302
+ return artifacts?.spendSource === "escrow" && artifacts.escrowSend !== true;
5303
+ }
5304
+ function requireEscrowSpendScalarHex(artifacts) {
5305
+ if (!isEscrowSweepSpend(artifacts)) {
5306
+ throw new Error("Escrow sweep requires spendSource escrow.");
5307
+ }
5308
+ const hex = artifacts?.escrowSpendScalarHex?.trim();
5309
+ if (!hex) {
5310
+ throw new Error("Escrow sweep requires the reconstructed note owner scalar.");
5311
+ }
5312
+ return hex;
5313
+ }
5314
+ function nullifierCheckSpendScalarHex(artifacts) {
5315
+ if (!isEscrowSweepSpend(artifacts)) {
5316
+ return void 0;
5317
+ }
5318
+ return requireEscrowSpendScalarHex(artifacts);
5319
+ }
5320
+
5632
5321
  // src/transact/engine/spend-proof-context.ts
5633
5322
  async function resolveSenderPrivKeyScalarHex2(input) {
5634
- const pendingClaim = input.prepared.transactArtifacts?.pendingClaim;
5635
- if (pendingClaim) {
5636
- return recoveryScalarHexFromClaim(pendingClaim);
5323
+ if (isEscrowSweepSpend(input.prepared.transactArtifacts)) {
5324
+ return requireEscrowSpendScalarHex(input.prepared.transactArtifacts);
5637
5325
  }
5638
5326
  if (input.prepared.kind !== "transfer" && input.prepared.kind !== "withdraw") {
5639
5327
  throw new Error("Spend execution requires a transfer or withdraw intent.");
@@ -5682,8 +5370,7 @@ async function buildSpendProofContextAtExecute(input) {
5682
5370
  commitments,
5683
5371
  ephemeral,
5684
5372
  senderPrivKeyScalarHex,
5685
- recipientPrivateAddressStpl1: input.recipientPrivateAddressStpl1,
5686
- pendingClaim: input.prepared.transactArtifacts?.pendingClaim
5373
+ recipientPrivateAddressStpl1: input.recipientPrivateAddressStpl1
5687
5374
  };
5688
5375
  }
5689
5376
  async function readCoinEphemeralForRecord(input) {
@@ -5702,14 +5389,19 @@ async function readCoinEphemeralForRecord(input) {
5702
5389
  return { coin, ephemeral };
5703
5390
  }
5704
5391
 
5705
- // src/transact/onboarding/recipient-change-deposits.ts
5706
- async function buildPaddingDepositPair(recipientPrivateAddressStpl1, tokenAddress, recipientDeposit) {
5707
- const paddingSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
5708
- privateAddressStpl1: recipientPrivateAddressStpl1,
5709
- amountStroops: ZERO_STROOPS,
5710
- tokenAddress
5711
- });
5712
- return [recipientDeposit, paddingSlot.deposit];
5392
+ // src/transact/proofs/confidential/recipient-change-deposits.ts
5393
+ function escrowOutputFields(input) {
5394
+ if (!input.escrowSend) {
5395
+ return {};
5396
+ }
5397
+ return {
5398
+ escrowNonce: input.escrowSend.nonceDecimal,
5399
+ recipientHi: input.escrowSend.recipientHi,
5400
+ recipientLo: input.escrowSend.recipientLo
5401
+ };
5402
+ }
5403
+ function paddingDepositPair(recipientDeposit) {
5404
+ return [recipientDeposit, "dummy"];
5713
5405
  }
5714
5406
  async function buildChangeDepositPair(parameters) {
5715
5407
  const changeSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
@@ -5728,24 +5420,24 @@ async function buildChangeDepositPair(parameters) {
5728
5420
  };
5729
5421
  }
5730
5422
  async function buildRecipientAndOptionalChangeDeposits(parameters) {
5423
+ const escrow = {
5424
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
5425
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
5426
+ };
5731
5427
  const recipientPrivateAddress = parameters.recipientPrivateAddressStpl1.trim();
5732
5428
  const recipientSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
5733
5429
  privateAddressStpl1: recipientPrivateAddress,
5734
5430
  amountStroops: parameters.transferStroops,
5735
- tokenAddress: parameters.tokenAddress
5431
+ tokenAddress: parameters.tokenAddress,
5432
+ ...escrowOutputFields(escrow)
5736
5433
  });
5737
5434
  if (parameters.changeStroops <= ZERO_STROOPS) {
5738
5435
  return {
5739
5436
  recipientSlot,
5740
- deposits: await buildPaddingDepositPair(
5741
- recipientPrivateAddress,
5742
- parameters.tokenAddress,
5743
- recipientSlot.deposit
5744
- )
5437
+ deposits: paddingDepositPair(recipientSlot.deposit)
5745
5438
  };
5746
5439
  }
5747
5440
  const changeResult = await buildChangeDepositPair({
5748
- recipientPrivateAddressStpl1: recipientPrivateAddress,
5749
5441
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
5750
5442
  changeStroops: parameters.changeStroops,
5751
5443
  tokenAddress: parameters.tokenAddress,
@@ -5767,20 +5459,61 @@ function generatedOutputCoinFromSlot(slot) {
5767
5459
  precommitementHex: slot.precommitementHex
5768
5460
  };
5769
5461
  }
5462
+ function publicEscrowRecipientLimbs(parameters) {
5463
+ const limbs = parameters.escrowClaimantLimbs;
5464
+ if (!limbs) {
5465
+ return void 0;
5466
+ }
5467
+ return {
5468
+ escrowRecipientHi: limbs.recipientHi,
5469
+ escrowRecipientLo: limbs.recipientLo
5470
+ };
5471
+ }
5472
+ function sweepWithdrawStamp(parameters) {
5473
+ const publicLimbs = publicEscrowRecipientLimbs(parameters);
5474
+ if (!publicLimbs) {
5475
+ return void 0;
5476
+ }
5477
+ return {
5478
+ ...publicLimbs,
5479
+ ...parameters.escrowClaimantLimbs?.nonceDecimal ? { escrowNonce: parameters.escrowClaimantLimbs.nonceDecimal } : {}
5480
+ };
5481
+ }
5482
+ function stampWithdrawEscrowLimbs(withdrawObject, limbs) {
5483
+ if (!limbs) {
5484
+ return withdrawObject;
5485
+ }
5486
+ return {
5487
+ ...withdrawObject,
5488
+ recipientStellar: [limbs.escrowRecipientHi, limbs.escrowRecipientLo],
5489
+ ...limbs.escrowNonce ? { escrowNonce: limbs.escrowNonce } : {}
5490
+ };
5491
+ }
5492
+ function sweepOutputOwnerFields(parameters) {
5493
+ if (!parameters.escrowClaimantLimbs) {
5494
+ return void 0;
5495
+ }
5496
+ const [sweepOutputOwnerPubX, sweepOutputOwnerPubY] = recipientPublicKeysDecimalFromPrivateAddress(
5497
+ parameters.recipientPrivateAddressStpl1
5498
+ );
5499
+ return { sweepOutputOwnerPubX, sweepOutputOwnerPubY };
5500
+ }
5770
5501
  async function buildTransferDepositsAndPublicInput(parameters) {
5771
5502
  const { recipientSlot, deposits, changeCoin } = await buildRecipientAndOptionalChangeDeposits({
5772
5503
  recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
5773
5504
  transferStroops: parameters.transferStroops,
5774
5505
  changeStroops: parameters.changeStroops,
5775
5506
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
5776
- tokenAddress: parameters.tokenAddress
5507
+ tokenAddress: parameters.tokenAddress,
5508
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
5509
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
5777
5510
  });
5778
5511
  const publicInput = withTokenAddressPublicInputs(
5779
5512
  {
5780
5513
  stateRoot: parameters.stateRoot,
5781
- withdrawAddressHi: parameters.withdrawAddressHi,
5782
- withdrawAddressLo: parameters.withdrawAddressLo,
5783
- privKeyScalar: parameters.privKeyScalar
5514
+ privKeyScalar: parameters.privKeyScalar,
5515
+ ...publicEscrowRecipientLimbs(parameters),
5516
+ ...sweepOutputOwnerFields(parameters)
5784
5517
  },
5785
5518
  parameters.tokenAddress
5786
5519
  );
@@ -5792,10 +5525,6 @@ async function buildTransferDepositsAndPublicInput(parameters) {
5792
5525
  };
5793
5526
  }
5794
5527
  async function buildSenderTransferDepositsAndPublicInput(parameters) {
5795
- const { hi, lo, privKeyScalar } = senderWithdrawFrAndScalar({
5796
- senderGAddress: parameters.senderGAddress,
5797
- senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex
5798
- });
5799
5528
  return buildTransferDepositsAndPublicInput({
5800
5529
  recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
5801
5530
  transferStroops: parameters.transferStroops,
@@ -5803,31 +5532,55 @@ async function buildSenderTransferDepositsAndPublicInput(parameters) {
5803
5532
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
5804
5533
  tokenAddress: parameters.tokenAddress,
5805
5534
  stateRoot: parameters.stateRoot,
5806
- withdrawAddressHi: hi,
5807
- withdrawAddressLo: lo,
5808
- privKeyScalar
5535
+ privKeyScalar: privKeyScalarDecimalFromRecipientScalarHex(
5536
+ parameters.senderPrivKeyScalarHex
5537
+ ),
5538
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
5539
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
5809
5540
  });
5810
5541
  }
5811
5542
 
5812
5543
  // src/transact/proofs/confidential/dual.ts
5813
- function buildDualTransferApplicationIds(applicationId, changeCoin) {
5814
- return [
5815
- applicationId,
5816
- applicationId,
5817
- applicationId,
5818
- changeCoin ? applicationId : "0"
5819
- ];
5544
+ function confidentialEscrowFields(parameters) {
5545
+ return {
5546
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
5547
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
5548
+ };
5549
+ }
5550
+ function stampDualWithdrawLegs(legs, parameters) {
5551
+ const escrowLimbs = sweepWithdrawStamp(confidentialEscrowFields(parameters));
5552
+ return {
5553
+ legA: {
5554
+ ...legs.legA,
5555
+ withdrawObject: stampWithdrawEscrowLimbs(legs.legA.withdrawObject, escrowLimbs)
5556
+ },
5557
+ legB: {
5558
+ ...legs.legB,
5559
+ withdrawObject: stampWithdrawEscrowLimbs(legs.legB.withdrawObject, escrowLimbs)
5560
+ }
5561
+ };
5562
+ }
5563
+ function buildDualTransferApplicationIds(sdk, applicationId, changeCoin) {
5564
+ return buildApplicationIdHints({
5565
+ sdk,
5566
+ inputIds: [applicationId, applicationId],
5567
+ outputIds: [applicationId, changeCoin ? applicationId : "0"]
5568
+ });
5820
5569
  }
5821
5570
  async function proveDualConfidentialTransfer(parameters) {
5822
5571
  const audit = buildPoolTransactionAuditParameters({
5823
5572
  applicationId: parameters.applicationId,
5573
+ nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
5824
5574
  ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
5825
5575
  });
5826
5576
  return parameters.sdk.proveTransaction(
5827
5577
  parameters.publicInput,
5828
- buildZeroPublicLegs(),
5829
- [parameters.legA.withdrawObject, parameters.legB.withdrawObject],
5830
- parameters.deposits,
5578
+ padPublicLegsToLayout(parameters.sdk, buildZeroPublicLegs()),
5579
+ padWithdrawSlotsToLayout(parameters.sdk, [
5580
+ parameters.legA.withdrawObject,
5581
+ parameters.legB.withdrawObject
5582
+ ]),
5583
+ padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
5831
5584
  audit
5832
5585
  );
5833
5586
  }
@@ -5841,24 +5594,33 @@ async function buildDualTransferProofContext(parameters, applicationId, sdk) {
5841
5594
  changeStroops,
5842
5595
  parameters.selfPrivateAddressStpl1ForChange
5843
5596
  );
5844
- const { legA, legB } = dualWithdrawLegsWithSharedRoot({
5845
- sdk,
5846
- coinA: parameters.coinA,
5847
- coinB: parameters.coinB,
5848
- state: parameters.state,
5849
- ephemeralA: parseEphemeralKeyString(parameters.ephemeralAKey),
5850
- ephemeralB: parseEphemeralKeyString(parameters.ephemeralBKey),
5851
- applicationId
5852
- });
5597
+ const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
5598
+ parameters.senderPrivKeyScalarHex
5599
+ );
5600
+ const ownerPubHex = sdk.ecdhEphemeralPublicKeyFromScalarHex(
5601
+ parameters.senderPrivKeyScalarHex
5602
+ );
5603
+ const { legA, legB } = stampDualWithdrawLegs(
5604
+ dualWithdrawLegsWithSharedRoot({
5605
+ sdk,
5606
+ coinA: parameters.coinA,
5607
+ coinB: parameters.coinB,
5608
+ state: parameters.state,
5609
+ ownerPubHex,
5610
+ privKeyScalar,
5611
+ applicationId
5612
+ }),
5613
+ parameters
5614
+ );
5853
5615
  const transferInputs = await buildSenderTransferDepositsAndPublicInput({
5854
- senderGAddress: parameters.senderGAddress,
5855
5616
  senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex,
5856
5617
  recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
5857
5618
  transferStroops: parameters.transferStroops,
5858
5619
  changeStroops,
5859
5620
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
5860
5621
  tokenAddress: parameters.tokenAddress,
5861
- stateRoot: legA.witness.stateRoot
5622
+ stateRoot: legA.witness.stateRoot,
5623
+ ...confidentialEscrowFields(parameters)
5862
5624
  });
5863
5625
  return { legA, legB, applicationId, ...transferInputs };
5864
5626
  }
@@ -5886,7 +5648,11 @@ async function prepareConfidentialTransferProofDual(parameters) {
5886
5648
  }));
5887
5649
  return {
5888
5650
  ...proof,
5889
- applicationIdsPlaintext: buildDualTransferApplicationIds(applicationId, changeCoin),
5651
+ applicationIdsPlaintext: buildDualTransferApplicationIds(
5652
+ sdk,
5653
+ applicationId,
5654
+ changeCoin
5655
+ ),
5890
5656
  recipientCoin: generatedOutputCoinFromSlot(recipientSlot),
5891
5657
  ...changeCoin ? { changeCoin } : {}
5892
5658
  };
@@ -5904,51 +5670,72 @@ function validateSingleCoinTransferAmounts(transferStroops, noteStroops, selfPri
5904
5670
  requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange);
5905
5671
  return changeStroops;
5906
5672
  }
5907
- function buildSingleTransferApplicationIds(applicationId, changeCoin) {
5908
- return [applicationId, "0", applicationId, changeCoin ? applicationId : "0"];
5673
+ function buildSingleTransferApplicationIds(sdk, applicationId, changeCoin) {
5674
+ return buildApplicationIdHints({
5675
+ sdk,
5676
+ inputIds: [applicationId],
5677
+ outputIds: [applicationId, changeCoin ? applicationId : "0"]
5678
+ });
5909
5679
  }
5910
5680
  function buildTransferAuditParameters(parameters) {
5911
5681
  const auditPublicKey = parameters.poolService.getAuditPublicKey();
5912
5682
  return buildPoolTransactionAuditParameters({
5913
5683
  applicationId: parameters.applicationId,
5684
+ nAuditSlots: parameters.nAuditSlots,
5914
5685
  ...auditPublicKey ? { auditPublicKey } : {}
5915
5686
  });
5916
5687
  }
5917
5688
  async function proveTransaction(parameters) {
5918
5689
  return parameters.sdk.proveTransaction(
5919
5690
  parameters.publicInput,
5920
- buildZeroPublicLegs(),
5921
- [parameters.withdrawObject, "dummy"],
5922
- parameters.deposits,
5691
+ padPublicLegsToLayout(parameters.sdk, buildZeroPublicLegs()),
5692
+ padWithdrawSlotsToLayout(parameters.sdk, [parameters.withdrawObject]),
5693
+ padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
5923
5694
  parameters.audit
5924
5695
  );
5925
5696
  }
5697
+ function confidentialEscrowFields2(input) {
5698
+ return {
5699
+ ...input.escrowSend ? { escrowSend: input.escrowSend } : {},
5700
+ ...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
5701
+ };
5702
+ }
5926
5703
  async function buildTransferProofInputs(parameters) {
5927
5704
  const changeStroops = validateSingleCoinTransferAmounts(
5928
5705
  parameters.input.transferStroops,
5929
5706
  parameters.noteStroops,
5930
5707
  parameters.input.selfPrivateAddressStpl1ForChange
5931
5708
  );
5709
+ const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
5710
+ parameters.input.senderPrivKeyScalarHex
5711
+ );
5932
5712
  const { witness, withdrawObject } = withdrawWitnessForCoin({
5933
5713
  sdk: parameters.sdk,
5934
5714
  coin: parameters.input.coin,
5935
5715
  state: parameters.input.state,
5936
- ...parseEphemeralKeyString(parameters.input.depositorEphemeralKey),
5716
+ ownerPubHex: parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
5717
+ parameters.input.senderPrivKeyScalarHex
5718
+ ),
5719
+ privKeyScalar,
5937
5720
  applicationId: parameters.applicationId
5938
5721
  });
5722
+ const stampedWithdraw = stampWithdrawEscrowLimbs(
5723
+ withdrawObject,
5724
+ sweepWithdrawStamp(confidentialEscrowFields2(parameters.input))
5725
+ );
5939
5726
  const { recipientSlot, deposits, changeCoin, publicInput } = await buildSenderTransferDepositsAndPublicInput({
5940
- senderGAddress: parameters.input.senderGAddress,
5941
5727
  senderPrivKeyScalarHex: parameters.input.senderPrivKeyScalarHex,
5942
5728
  recipientPrivateAddressStpl1: parameters.input.recipientPrivateAddressStpl1,
5943
5729
  transferStroops: parameters.input.transferStroops,
5944
5730
  changeStroops,
5945
5731
  selfPrivateAddressStpl1ForChange: parameters.input.selfPrivateAddressStpl1ForChange,
5946
5732
  tokenAddress: parameters.input.tokenAddress,
5947
- stateRoot: witness.stateRoot
5733
+ stateRoot: witness.stateRoot,
5734
+ ...confidentialEscrowFields2(parameters.input)
5948
5735
  });
5949
5736
  return {
5950
5737
  witness,
5951
- withdrawObject,
5738
+ withdrawObject: stampedWithdraw,
5952
5739
  recipientSlot,
5953
5740
  deposits,
5954
5741
  changeCoin,
@@ -5966,7 +5753,11 @@ async function prepareConfidentialTransferProof(parameters) {
5966
5753
  input: parameters,
5967
5754
  noteStroops
5968
5755
  });
5969
- const audit = buildTransferAuditParameters({ poolService, applicationId });
5756
+ const audit = buildTransferAuditParameters({
5757
+ poolService,
5758
+ applicationId,
5759
+ nAuditSlots: sdk.getLayout().nAuditSlots
5760
+ });
5970
5761
  const proof = await proveTransaction({
5971
5762
  sdk,
5972
5763
  publicInput,
@@ -5977,6 +5768,7 @@ async function prepareConfidentialTransferProof(parameters) {
5977
5768
  return {
5978
5769
  ...proof,
5979
5770
  applicationIdsPlaintext: buildSingleTransferApplicationIds(
5771
+ sdk,
5980
5772
  applicationId,
5981
5773
  changeCoin
5982
5774
  ),
@@ -5985,95 +5777,26 @@ async function prepareConfidentialTransferProof(parameters) {
5985
5777
  };
5986
5778
  }
5987
5779
 
5988
- // src/transact/engine/prepare/transfer-helpers.ts
5989
- function isPublicRecipientTransfer(prepared) {
5990
- return prepared.kind === "transfer" && prepared.intent.disclosure.recipientAddress === "public";
5991
- }
5992
- async function resolveTransferRecipientForExecute(prepared, environment, walletPublicKey) {
5993
- if (!isPublicRecipientTransfer(prepared)) {
5994
- return {
5995
- recipientPrivateAddressStpl1: prepared.intent.to.trim()
5996
- };
5997
- }
5998
- if (!environment.resolveTransferRecipientAtExecute) {
5999
- throw new Error("Transfer recipient resolver is not configured.");
6000
- }
6001
- return environment.resolveTransferRecipientAtExecute({
6002
- recipientStellarAddress: prepared.intent.to.trim(),
6003
- walletPublicKey
6004
- });
6005
- }
6006
- async function resolveTransferOnboardingAtExecute(input) {
6007
- if (input.prepared.transactArtifacts?.onboarding) {
6008
- return input.prepared.transactArtifacts.onboarding;
6009
- }
6010
- if (!input.recipient.temporaryRecipientKey || !input.environment.buildTransferOnboardingAtExecute) {
6011
- return;
6012
- }
6013
- return input.environment.buildTransferOnboardingAtExecute({
6014
- ownerStellarAddress: input.recipient.recipientStellarAddress ?? input.prepared.intent.to.trim(),
6015
- temporaryRecipientKey: input.recipient.temporaryRecipientKey,
6016
- recipientNote: {
6017
- tokenAddress: input.tokenAddress,
6018
- nullifier: input.recipientCoin.nullifier,
6019
- secret: input.recipientCoin.secret,
6020
- value: input.recipientCoin.value
6021
- }
6022
- });
6023
- }
6024
-
6025
- // src/transact/onboarding/build-pending-claim-payload.ts
6026
- import { Buffer as Buffer15 } from "buffer";
6027
- var FIELD_HEX_LENGTH2 = 64;
6028
- function hexToBuffer2(hex) {
6029
- const clean = hex.trim().replace(/^0x/u, "");
6030
- return Buffer15.from(clean.padStart(FIELD_HEX_LENGTH2, "0"), "hex");
6031
- }
6032
- function buildPendingClaimOnboardingPayload(input) {
6033
- const ownerAddress = input.claim.owner.trim();
6034
- const permanentPrivateAddress = input.permanentPrivateAddressStpl1.trim();
6035
- const decoded = decodePrivateAddress(permanentPrivateAddress);
6036
- const encryptedRecovery = input.claim.encryptedRecoveryBase64?.trim();
6037
- if (!encryptedRecovery) {
6038
- throw new Error("Pending claim is missing encrypted recovery data.");
6039
- }
6040
- return {
6041
- owner: ownerAddress,
6042
- temp_public_key_x: hexToBuffer2(input.claim.tempPublicKeyXHex ?? ""),
6043
- temp_public_key_y: hexToBuffer2(input.claim.tempPublicKeyYHex ?? ""),
6044
- encrypted_private_key: Buffer15.from(encryptedRecovery, "base64"),
6045
- notes: { notes: [] },
6046
- private_address_registration: {
6047
- tag: "Some",
6048
- values: [
6049
- {
6050
- owner: ownerAddress,
6051
- public_key_x: hexToBuffer2(decoded.x),
6052
- public_key_y: hexToBuffer2(decoded.y)
6053
- }
6054
- ]
6055
- }
6056
- };
6057
- }
6058
-
6059
5780
  // src/transact/engine/transfer-proof-at-execute.ts
6060
5781
  function readChangeRecipient(input, changeStroops) {
6061
5782
  if (changeStroops <= 0n || input.prepared.kind !== "transfer") {
6062
5783
  return void 0;
6063
5784
  }
6064
5785
  const from = input.prepared.intent.from;
6065
- if (isPendingClaimSource(from)) {
6066
- return void 0;
6067
- }
6068
5786
  return readTransferFromPrivateAddress(from);
6069
5787
  }
5788
+ function proofEscrowFields(input) {
5789
+ return {
5790
+ ...input.escrowSend ? { escrowSend: input.escrowSend } : {},
5791
+ ...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
5792
+ };
5793
+ }
6070
5794
  async function buildSingleTransferProofAtExecute(input) {
6071
5795
  const context = await buildSpendProofContextAtExecute(input);
6072
- const changeStroops = context.pendingClaim ? 0n : BigInt(context.coin.value) - input.prepared.intent.amount;
5796
+ const changeStroops = BigInt(context.coin.value) - input.prepared.intent.amount;
6073
5797
  const proof = await prepareConfidentialTransferProof({
6074
5798
  coin: context.coin,
6075
5799
  state: { commitments: context.commitments },
6076
- senderGAddress: context.walletPublicKey,
6077
5800
  senderPrivKeyScalarHex: context.senderPrivKeyScalarHex,
6078
5801
  depositorEphemeralKey: serializeEphemeralKeyString({
6079
5802
  xHex: context.ephemeral.xHex,
@@ -6082,7 +5805,8 @@ async function buildSingleTransferProofAtExecute(input) {
6082
5805
  transferStroops: input.prepared.intent.amount,
6083
5806
  recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
6084
5807
  selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
6085
- tokenAddress: context.tokenAddress
5808
+ tokenAddress: context.tokenAddress,
5809
+ ...proofEscrowFields(input)
6086
5810
  });
6087
5811
  return { context, proof };
6088
5812
  }
@@ -6104,7 +5828,6 @@ async function buildDualTransferProofAtExecute(input) {
6104
5828
  coinA: context.coin,
6105
5829
  coinB: secondary.coin,
6106
5830
  state: { commitments: context.commitments },
6107
- senderGAddress: context.walletPublicKey,
6108
5831
  senderPrivKeyScalarHex: context.senderPrivKeyScalarHex,
6109
5832
  ephemeralAKey: serializeEphemeralKeyString({
6110
5833
  xHex: context.ephemeral.xHex,
@@ -6117,7 +5840,8 @@ async function buildDualTransferProofAtExecute(input) {
6117
5840
  transferStroops: input.prepared.intent.amount,
6118
5841
  recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
6119
5842
  selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
6120
- tokenAddress: context.tokenAddress
5843
+ tokenAddress: context.tokenAddress,
5844
+ ...proofEscrowFields(input)
6121
5845
  });
6122
5846
  return { context, proof };
6123
5847
  }
@@ -6133,6 +5857,41 @@ async function buildTransferProofAtExecute(input) {
6133
5857
  }
6134
5858
 
6135
5859
  // src/transact/engine/transfer-finalize.ts
5860
+ function stampEscrowOutputRecords(input) {
5861
+ if (input.escrowSendPrivateAddress) {
5862
+ const [recipientRecord, ...rest] = input.prepared.outputRecords;
5863
+ if (recipientRecord) {
5864
+ input.prepared.outputRecords = [
5865
+ {
5866
+ ...recipientRecord,
5867
+ privateAddress: input.escrowSendPrivateAddress
5868
+ },
5869
+ ...rest
5870
+ ];
5871
+ }
5872
+ }
5873
+ seedEscrowSweepOutputsFromProof({
5874
+ prepared: input.prepared,
5875
+ proof: input.proof,
5876
+ walletPublicKey: input.walletPublicKey
5877
+ });
5878
+ enrichTransferOutputRecords(input.prepared, input.proof);
5879
+ }
5880
+ function seedEscrowSweepOutputsFromProof(input) {
5881
+ if (input.prepared.transactArtifacts?.spendSource !== "escrow" || input.prepared.outputRecords.length > 0) {
5882
+ return;
5883
+ }
5884
+ input.prepared.outputRecords = [
5885
+ {
5886
+ id: input.proof.recipientCoin.commitment_hex,
5887
+ owner: input.walletPublicKey,
5888
+ privateAddress: input.prepared.intent.to,
5889
+ asset: input.prepared.intent.asset,
5890
+ amount: input.prepared.intent.amount,
5891
+ consumed: false
5892
+ }
5893
+ ];
5894
+ }
6136
5895
  function enrichTransferOutputRecords(prepared, proof) {
6137
5896
  if (prepared.outputRecords.length === 0) {
6138
5897
  return;
@@ -6156,65 +5915,34 @@ function enrichTransferOutputRecords(prepared, proof) {
6156
5915
  };
6157
5916
  });
6158
5917
  }
6159
- async function resolvePendingClaimOnboardingAtExecute(input) {
6160
- const claim = input.prepared.transactArtifacts?.pendingClaim;
6161
- if (!claim || input.prepared.kind !== "transfer") {
6162
- return;
6163
- }
6164
- const contractContext = requireContractContext(input.environment);
6165
- const lookup = await readRegistryLookupFromChain({
6166
- contractContext,
6167
- owner: input.walletPublicKey.trim(),
6168
- walletPublicKey: input.walletPublicKey.trim()
6169
- });
6170
- if (lookup.status === "registered") {
6171
- return;
6172
- }
6173
- return buildPendingClaimOnboardingPayload({
6174
- claim,
6175
- permanentPrivateAddressStpl1: input.prepared.intent.to.trim()
6176
- });
6177
- }
6178
- async function ensurePendingClaimReadyForExecute(input) {
6179
- const pendingClaim = input.prepared.transactArtifacts?.pendingClaim;
6180
- if (!pendingClaim) {
6181
- return;
5918
+ function escrowSpendArtifacts(input) {
5919
+ if (input.escrowSend) {
5920
+ return {
5921
+ escrowSend: true,
5922
+ spendSource: "escrow",
5923
+ ...input.escrowRecipient ? { escrowRecipient: input.escrowRecipient } : {}
5924
+ };
6182
5925
  }
6183
- await verifyPendingClaimBeforeExecute({
6184
- claim: pendingClaim,
6185
- environment: input.environment,
6186
- walletPublicKey: input.walletPublicKey
6187
- });
6188
- }
6189
- async function resolveTransferOnboardingBundle(input) {
6190
- const pendingClaim = input.prepared.transactArtifacts?.pendingClaim;
6191
- if (pendingClaim) {
6192
- const pendingOnboarding = await resolvePendingClaimOnboardingAtExecute({
6193
- prepared: input.prepared,
6194
- environment: input.environment,
6195
- walletPublicKey: input.walletPublicKey
6196
- });
6197
- if (pendingOnboarding) {
6198
- return pendingOnboarding;
6199
- }
5926
+ if (input.preparedSpendSource === "escrow") {
5927
+ return {
5928
+ spendSource: "escrow",
5929
+ ...input.escrowRecipient ? { escrowRecipient: input.escrowRecipient } : {},
5930
+ ...input.escrowSpendScalarHex ? { escrowSpendScalarHex: input.escrowSpendScalarHex } : {},
5931
+ ...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
5932
+ };
6200
5933
  }
6201
- return resolveTransferOnboardingAtExecute({
6202
- prepared: input.prepared,
6203
- environment: input.environment,
6204
- recipient: input.recipient,
6205
- recipientCoin: input.recipientCoin,
6206
- tokenAddress: input.tokenAddress
6207
- });
5934
+ return {};
6208
5935
  }
6209
5936
  function buildTransferFinalizeArtifacts(input) {
6210
5937
  return {
6211
5938
  proofHex: input.proof.proof_hex,
6212
5939
  publicHex: input.proof.public_hex,
5940
+ ...ciphertextArtifactsFromProof(input.proof),
6213
5941
  applicationIdsPlaintext: input.proof.applicationIdsPlaintext,
6214
5942
  tokenAddress: input.context.tokenAddress,
6215
5943
  walletPublicKey: input.context.walletPublicKey,
6216
- onboarding: input.onboarding,
6217
- executeFinalizeRequired: false
5944
+ executeFinalizeRequired: false,
5945
+ ...escrowSpendArtifacts(input)
6218
5946
  };
6219
5947
  }
6220
5948
  async function runTransferFinalizeSteps(input) {
@@ -6223,26 +5951,50 @@ async function runTransferFinalizeSteps(input) {
6223
5951
  input.environment,
6224
5952
  input.walletPublicKey
6225
5953
  );
5954
+ const spendScalarHex = nullifierCheckSpendScalarHex(input.prepared.transactArtifacts);
6226
5955
  await verifyPrivateRecordsNullifiersBeforeExecute({
6227
5956
  records: input.prepared.consumedRecords,
6228
5957
  environment: input.environment,
6229
- walletPublicKey: input.walletPublicKey
5958
+ walletPublicKey: input.walletPublicKey,
5959
+ ...spendScalarHex ? { spendScalarHex } : {}
6230
5960
  });
6231
5961
  const { context, proof } = await buildTransferProofAtExecute({
6232
5962
  prepared: input.prepared,
6233
5963
  environment: input.environment,
6234
- recipientPrivateAddressStpl1: recipient.recipientPrivateAddressStpl1
5964
+ recipientPrivateAddressStpl1: recipient.recipientPrivateAddressStpl1,
5965
+ ...recipient.escrowSend ? { escrowSend: recipient.escrowSend } : {},
5966
+ ...input.prepared.transactArtifacts?.escrowClaimantLimbs ? {
5967
+ escrowClaimantLimbs: input.prepared.transactArtifacts.escrowClaimantLimbs
5968
+ } : {}
6235
5969
  });
6236
- const onboarding = await resolveTransferOnboardingBundle({
5970
+ stampEscrowOutputRecords({
6237
5971
  prepared: input.prepared,
6238
- environment: input.environment,
5972
+ proof,
6239
5973
  walletPublicKey: input.walletPublicKey,
6240
- recipient,
6241
- recipientCoin: proof.recipientCoin.coin,
6242
- tokenAddress: context.tokenAddress
5974
+ ...recipient.escrowSend ? { escrowSendPrivateAddress: recipient.recipientPrivateAddressStpl1 } : {}
6243
5975
  });
6244
- enrichTransferOutputRecords(input.prepared, proof);
6245
- return buildTransferFinalizeArtifacts({ proof, context, onboarding });
5976
+ return buildTransferFinalizeArtifacts({
5977
+ proof,
5978
+ context,
5979
+ ...sweepFinalizeStamp(input.prepared, recipient)
5980
+ });
5981
+ }
5982
+ function sweepArtifactStamp(artifacts) {
5983
+ return {
5984
+ ...artifacts?.escrowSpendScalarHex ? { escrowSpendScalarHex: artifacts.escrowSpendScalarHex } : {},
5985
+ ...artifacts?.spendSource ? { preparedSpendSource: artifacts.spendSource } : {},
5986
+ ...artifacts?.escrowClaimantLimbs ? { escrowClaimantLimbs: artifacts.escrowClaimantLimbs } : {}
5987
+ };
5988
+ }
5989
+ function sweepFinalizeStamp(prepared, recipient) {
5990
+ const artifacts = prepared.transactArtifacts;
5991
+ const fromSend = recipient.escrowSend?.recipientStellarAddress?.trim();
5992
+ const escrowRecipient = fromSend || artifacts?.escrowRecipient?.trim();
5993
+ return {
5994
+ ...recipient.escrowSend ? { escrowSend: true } : {},
5995
+ ...escrowRecipient ? { escrowRecipient } : {},
5996
+ ...sweepArtifactStamp(artifacts)
5997
+ };
6246
5998
  }
6247
5999
  async function finalizeTransferAtExecute(prepared, environment) {
6248
6000
  const [primaryRecord] = prepared.consumedRecords;
@@ -6250,11 +6002,6 @@ async function finalizeTransferAtExecute(prepared, environment) {
6250
6002
  throw new Error("Transfer execution record owner is missing.");
6251
6003
  }
6252
6004
  const walletPublicKey = primaryRecord.owner.trim();
6253
- await ensurePendingClaimReadyForExecute({
6254
- prepared,
6255
- environment,
6256
- walletPublicKey
6257
- });
6258
6005
  return runTransferFinalizeSteps({ prepared, environment, walletPublicKey });
6259
6006
  }
6260
6007
 
@@ -6277,6 +6024,7 @@ function buildWithdrawFinalizeArtifacts(proof, context) {
6277
6024
  return {
6278
6025
  proofHex: proof.proof_hex,
6279
6026
  publicHex: proof.public_hex,
6027
+ ...ciphertextArtifactsFromProof(proof),
6280
6028
  applicationIdsPlaintext: proof.applicationIdsPlaintext,
6281
6029
  tokenAddress: context.tokenAddress,
6282
6030
  walletPublicKey: context.walletPublicKey,
@@ -6387,6 +6135,12 @@ async function finalizeSpendOperationAtExecute(prepared, environment, poolServic
6387
6135
  };
6388
6136
  }
6389
6137
 
6138
+ // src/transact/kyt/passage/inspect.ts
6139
+ import {
6140
+ layoutForKnownNonce,
6141
+ zeroBindingTagsInPublicSignals
6142
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
6143
+
6390
6144
  // src/transact/kyt/inspect-error.ts
6391
6145
  var KytInspectError = class extends Error {
6392
6146
  reasonCode;
@@ -6469,16 +6223,16 @@ async function waitForKytRegistration(parameters) {
6469
6223
  }
6470
6224
 
6471
6225
  // src/transact/kyt/passage/submit.ts
6472
- import { Buffer as Buffer16 } from "buffer";
6226
+ import { Buffer as Buffer14 } from "buffer";
6473
6227
  import { Operation, TransactionBuilder, rpc as rpc3, xdr as xdr2 } from "@stellar/stellar-sdk";
6474
6228
  var KYT_REGISTER_FEE_STROOPS = "1000000";
6475
6229
  var KYT_REGISTER_TIMEOUT_SECONDS = 300;
6476
6230
  function passageIdToScValue(passageId) {
6477
- return xdr2.ScVal.scvBytes(Buffer16.from(passageId.replace(/^0x/, ""), "hex"));
6231
+ return xdr2.ScVal.scvBytes(Buffer14.from(passageId.replace(/^0x/, ""), "hex"));
6478
6232
  }
6479
6233
  function approvalSignatureToBytes(signature) {
6480
6234
  const clean = signature.trim();
6481
- return /^(0x)?[0-9a-fA-F]{128}$/.test(clean) ? Buffer16.from(clean.replace(/^0x/i, ""), "hex") : Buffer16.from(clean, "base64");
6235
+ return /^(0x)?[0-9a-fA-F]{128}$/.test(clean) ? Buffer14.from(clean.replace(/^0x/i, ""), "hex") : Buffer14.from(clean, "base64");
6482
6236
  }
6483
6237
  function signatureToScValue(signature) {
6484
6238
  const bytes = approvalSignatureToBytes(signature);
@@ -6526,15 +6280,9 @@ async function registerKytPassage(parameters) {
6526
6280
  await waitForKytRegistration({ server, hash: result.hash });
6527
6281
  }
6528
6282
 
6529
- // src/transact/environment/zk-config-nonce.ts
6530
- var DEFAULT_ZK_CONFIG_NONCE = 0n;
6531
- function resolveZkConfigNonce(transactEnvironment) {
6532
- return transactEnvironment.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
6533
- }
6534
-
6535
6283
  // src/transact/kyt/passage/inspect.ts
6536
- function buildApplicationIdHints(applicationId) {
6537
- return [applicationId, applicationId, applicationId, applicationId];
6284
+ function buildApplicationIdHints2(applicationId, nAuditSlots) {
6285
+ return uniformApplicationIdHints(applicationId, nAuditSlots);
6538
6286
  }
6539
6287
  function buildNonce() {
6540
6288
  return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}`;
@@ -6562,37 +6310,61 @@ function throwKytInspectRejected(body) {
6562
6310
  ...parsed.address ? { detailAddress: parsed.address } : {}
6563
6311
  });
6564
6312
  }
6565
- async function requestKytPassageForPoolInteraction(input) {
6566
- const applicationId = resolvePoolApplicationId(
6567
- input.transactEnvironment.network.applicationId
6568
- );
6569
- const applicationIdsPlaintext = input.applicationIdsPlaintext ?? buildApplicationIdHints(applicationId);
6570
- const kytRegistry = input.transactEnvironment.kyt.kytPassageRegistryContract;
6571
- const currentLedger = await fetchCurrentLedger(input.sorobanRpcUrl);
6313
+ function inspectRequestHeaders(inspectAuthorization) {
6314
+ const token = inspectAuthorization?.trim();
6315
+ return {
6316
+ "content-type": "application/json",
6317
+ ...token ? { authorization: `Bearer ${token}` } : {}
6318
+ };
6319
+ }
6320
+ async function postKytInspect(input, applicationIdsPlaintext, zkConfigNonce, currentLedger) {
6572
6321
  const response = await fetch(
6573
6322
  `${input.transactEnvironment.kyt.apiBaseUrl}/kyt/passages/inspect`,
6574
6323
  {
6575
6324
  method: "POST",
6576
- headers: { "content-type": "application/json" },
6325
+ headers: inspectRequestHeaders(
6326
+ input.transactEnvironment.kyt.inspectAuthorization
6327
+ ),
6577
6328
  body: JSON.stringify(
6578
6329
  {
6579
6330
  owner: input.owner,
6580
6331
  poolContract: input.poolContract,
6581
- kytRegistry,
6332
+ kytRegistry: input.transactEnvironment.kyt.kytPassageRegistryContract,
6582
6333
  proofBytes: input.proofHex,
6583
- publicSignalsBytes: input.publicHex,
6334
+ publicSignalsBytes: zeroBindingTagsInPublicSignals(
6335
+ input.publicHex,
6336
+ zkConfigNonce
6337
+ ).toString("hex"),
6584
6338
  applicationIdsPlaintext,
6585
6339
  decryptedAuditSlots: input.decryptedAuditSlots,
6586
- onboarding: input.onboarding,
6587
6340
  nonce: buildNonce(),
6588
- zkConfigNonce: resolveZkConfigNonce(input.transactEnvironment),
6589
- currentLedger
6341
+ zkConfigNonce,
6342
+ currentLedger,
6343
+ ...input.ciphertextHex ? { ciphertextBytes: input.ciphertextHex } : {},
6344
+ ...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {}
6590
6345
  },
6591
6346
  kytJsonReplacer
6592
6347
  )
6593
6348
  }
6594
6349
  );
6595
- const body = await parseInspectResponse(response);
6350
+ return parseInspectResponse(response);
6351
+ }
6352
+ async function requestKytPassageForPoolInteraction(input) {
6353
+ const applicationId = resolvePoolApplicationId(
6354
+ input.transactEnvironment.network.applicationId
6355
+ );
6356
+ const zkConfigNonce = resolveZkConfigNonce(input.transactEnvironment);
6357
+ const applicationIdsPlaintext = input.applicationIdsPlaintext ?? buildApplicationIdHints2(
6358
+ applicationId,
6359
+ layoutForKnownNonce(zkConfigNonce).nAuditSlots
6360
+ );
6361
+ const currentLedger = await fetchCurrentLedger(input.sorobanRpcUrl);
6362
+ const body = await postKytInspect(
6363
+ input,
6364
+ applicationIdsPlaintext,
6365
+ zkConfigNonce,
6366
+ currentLedger
6367
+ );
6596
6368
  if (body.status !== "approved") {
6597
6369
  throwKytInspectRejected(body);
6598
6370
  }
@@ -6712,7 +6484,7 @@ async function extendZkConfigTtlIfNeeded(parameters) {
6712
6484
  }
6713
6485
 
6714
6486
  // src/transact/submit/pool-transact.ts
6715
- import { Buffer as Buffer17 } from "buffer";
6487
+ import { Buffer as Buffer15 } from "buffer";
6716
6488
  async function submitPoolTransact(parameters) {
6717
6489
  await extendZkConfigTtlIfNeeded({
6718
6490
  sorobanRpcUrl: parameters.sorobanRpcUrl,
@@ -6725,9 +6497,12 @@ async function submitPoolTransact(parameters) {
6725
6497
  const assembledTransaction = await parameters.contractClient.transact({
6726
6498
  from: parameters.from,
6727
6499
  nonce: parameters.nonce,
6728
- proof_bytes: Buffer17.from(parameters.proofHex.replace(/^0x/iu, ""), "hex"),
6729
- pub_signals_bytes: Buffer17.from(parameters.publicHex.replace(/^0x/iu, ""), "hex"),
6730
- onboarding: parameters.onboarding,
6500
+ proof_bytes: Buffer15.from(parameters.proofHex.replace(/^0x/iu, ""), "hex"),
6501
+ pub_signals_bytes: Buffer15.from(parameters.publicHex.replace(/^0x/iu, ""), "hex"),
6502
+ ciphertext_bytes: Buffer15.from(
6503
+ (parameters.ciphertextHex ?? "").replace(/^0x/iu, ""),
6504
+ "hex"
6505
+ ),
6731
6506
  kyt_authorization: {
6732
6507
  expiration_ledger: parameters.approval.expiresAtLedger,
6733
6508
  signature: approvalSignatureToBytes(parameters.approval.signature)
@@ -6755,7 +6530,8 @@ async function submitSorobanConfidentialTransfer(input) {
6755
6530
  poolContract: input.contractId,
6756
6531
  proofHex: input.proofHex,
6757
6532
  publicHex: input.publicHex,
6758
- ...input.onboarding ? { onboarding: input.onboarding } : {},
6533
+ ...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
6534
+ ...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {},
6759
6535
  ...input.applicationIdsPlaintext ? { applicationIdsPlaintext: input.applicationIdsPlaintext } : {},
6760
6536
  networkPassphrase: input.networkPassphrase,
6761
6537
  sorobanRpcUrl: input.sorobanRpcUrl,
@@ -6768,7 +6544,7 @@ async function submitSorobanConfidentialTransfer(input) {
6768
6544
  nonce: resolveZkConfigNonce(input.transactEnvironment),
6769
6545
  proofHex: input.proofHex,
6770
6546
  publicHex: input.publicHex,
6771
- ...input.onboarding ? { onboarding: input.onboarding } : {},
6547
+ ...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
6772
6548
  approval,
6773
6549
  networkPassphrase: input.networkPassphrase,
6774
6550
  sorobanRpcUrl: input.sorobanRpcUrl,
@@ -6777,6 +6553,13 @@ async function submitSorobanConfidentialTransfer(input) {
6777
6553
  }
6778
6554
 
6779
6555
  // src/transact/engine/submit.ts
6556
+ function optionalInspectCiphertext(artifacts) {
6557
+ return {
6558
+ ...artifacts.ciphertextHex ? { ciphertextHex: artifacts.ciphertextHex } : {},
6559
+ ...artifacts.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: artifacts.outputNoteEphemeralScalars } : {},
6560
+ ...artifacts.applicationIdsPlaintext ? { applicationIdsPlaintext: artifacts.applicationIdsPlaintext } : {}
6561
+ };
6562
+ }
6780
6563
  async function submitPreparedDeposit(prepared, environment) {
6781
6564
  const artifacts = prepared.transactArtifacts;
6782
6565
  const outputRecord = prepared.outputRecords[0];
@@ -6794,7 +6577,7 @@ async function submitPreparedDeposit(prepared, environment) {
6794
6577
  poolContract: environment.network.poolContract,
6795
6578
  proofHex: artifacts.proofHex,
6796
6579
  publicHex: artifacts.publicHex,
6797
- ...artifacts.applicationIdsPlaintext ? { applicationIdsPlaintext: artifacts.applicationIdsPlaintext } : {},
6580
+ ...optionalInspectCiphertext(artifacts),
6798
6581
  networkPassphrase: environment.network.networkPassphrase,
6799
6582
  sorobanRpcUrl: environment.network.rpcUrl,
6800
6583
  transactEnvironment: environment
@@ -6806,6 +6589,7 @@ async function submitPreparedDeposit(prepared, environment) {
6806
6589
  nonce: resolveZkConfigNonce(environment),
6807
6590
  proofHex: artifacts.proofHex,
6808
6591
  publicHex: artifacts.publicHex,
6592
+ ...artifacts.ciphertextHex ? { ciphertextHex: artifacts.ciphertextHex } : {},
6809
6593
  approval,
6810
6594
  networkPassphrase: environment.network.networkPassphrase,
6811
6595
  sorobanRpcUrl: environment.network.rpcUrl,
@@ -6822,8 +6606,7 @@ async function submitPreparedPoolTransact(prepared, environment) {
6822
6606
  walletPublicKey: artifacts.walletPublicKey,
6823
6607
  proofHex: artifacts.proofHex,
6824
6608
  publicHex: artifacts.publicHex,
6825
- ...artifacts.onboarding ? { onboarding: artifacts.onboarding } : {},
6826
- ...artifacts.applicationIdsPlaintext ? { applicationIdsPlaintext: artifacts.applicationIdsPlaintext } : {},
6609
+ ...optionalInspectCiphertext(artifacts),
6827
6610
  networkPassphrase: environment.network.networkPassphrase,
6828
6611
  sorobanRpcUrl: environment.network.rpcUrl,
6829
6612
  transactEnvironment: environment
@@ -6861,18 +6644,34 @@ function createBrowserStellarTransactEngine(input) {
6861
6644
  }
6862
6645
 
6863
6646
  // src/transact/engine/default-factory.ts
6864
- async function createDefaultTransactEngine(assets, transactEnvironment) {
6865
- await PrivacyPoolSDK4.init({
6647
+ async function privacyPoolInitOptions(assets, transactEnvironment) {
6648
+ if (!transactEnvironment) {
6649
+ return { wasmBinary: assets.sdkWasm };
6650
+ }
6651
+ const zkConfigNonce = resolveZkConfigNonce(transactEnvironment);
6652
+ const zkCircuits = await materializeSelectedZkCircuit(
6653
+ transactEnvironment.zkCircuits,
6654
+ zkConfigNonce,
6655
+ transactEnvironment.zkArtifactBaseUrl
6656
+ );
6657
+ return {
6866
6658
  wasmBinary: assets.sdkWasm,
6867
- circuitWasm: assets.circuitWasm,
6868
- zkey: assets.provingKey
6869
- });
6659
+ zkCircuits,
6660
+ zkConfigNonce,
6661
+ ...optionalZkArtifactBaseUrl(transactEnvironment.zkArtifactBaseUrl)
6662
+ };
6663
+ }
6664
+ async function createDefaultTransactEngine(assets, transactEnvironment) {
6665
+ await PrivacyPoolSDK3.init(await privacyPoolInitOptions(assets, transactEnvironment));
6870
6666
  if (transactEnvironment) {
6871
6667
  configurePrivacyPoolService(
6872
6668
  createPrivacyPoolService({
6873
6669
  assets,
6874
6670
  applicationId: transactEnvironment.network.applicationId,
6875
- ...transactEnvironment.auditPublicKey ? { auditPublicKey: transactEnvironment.auditPublicKey } : {}
6671
+ ...transactEnvironment.auditPublicKey ? { auditPublicKey: transactEnvironment.auditPublicKey } : {},
6672
+ ...transactEnvironment.zkCircuits ? { zkCircuits: transactEnvironment.zkCircuits } : {},
6673
+ ...transactEnvironment.zkConfigNonce === void 0 ? {} : { zkConfigNonce: transactEnvironment.zkConfigNonce },
6674
+ ...optionalZkArtifactBaseUrl(transactEnvironment.zkArtifactBaseUrl)
6876
6675
  })
6877
6676
  );
6878
6677
  return createBrowserStellarTransactEngine({
@@ -6915,7 +6714,7 @@ async function createStellarPrivacyClientFromNodeConfig(config) {
6915
6714
  return input.transactEngine;
6916
6715
  }
6917
6716
  const browserAssets = await loadNodeAssets(input.assets);
6918
- return createDefaultTransactEngine(browserAssets);
6717
+ return createDefaultTransactEngine(browserAssets, input.transactEnvironment);
6919
6718
  });
6920
6719
  if (!resolved.ok) {
6921
6720
  return resolved.result;