@arcanetech/privacy-sdk-stellar 0.2.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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({
@@ -504,7 +366,7 @@ function createInternalPoolContractClient(input) {
504
366
  networkPassphrase: input.networkPassphrase,
505
367
  walletPublicKey: input.walletPublicKey
506
368
  });
507
- return new PrivacyPoolContractClient({
369
+ const client = new PrivacyPoolContractClient({
508
370
  contractId: input.contractId,
509
371
  networkPassphrase: input.networkPassphrase,
510
372
  rpcUrl: input.sorobanRpcUrl,
@@ -512,6 +374,7 @@ function createInternalPoolContractClient(input) {
512
374
  publicKey: input.walletPublicKey,
513
375
  signTransaction: signBinding
514
376
  });
377
+ return client;
515
378
  }
516
379
 
517
380
  // src/contracts/registry/create-registry-client.ts
@@ -574,15 +437,45 @@ function readPoolClientFactory(environment) {
574
437
  return requireContractContext(environment).createPoolClient;
575
438
  }
576
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
+
577
469
  // src/transact/pool/service.ts
578
470
  import {
471
+ PrivacyPoolSDK as PrivacyPoolSDK2,
579
472
  decodeDecodedEphemeralKey,
580
473
  randomFrDecimal253,
581
474
  scalarHexToFrDecimal as scalarHexToFrDecimal2
582
- } from "@auditable/privacy-pool-zk-sdk";
475
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
583
476
 
584
477
  // src/transact/merkle/field-decimal.ts
585
- import { Buffer as Buffer5 } from "buffer";
478
+ import { Buffer as Buffer4 } from "buffer";
586
479
  var BN254 = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
587
480
  var MERKLE_ROOT_BYTE_LENGTH = 32;
588
481
  var DECIMAL_STRING_RADIX = 10;
@@ -592,7 +485,7 @@ function merkleRootBufferToFrDecimal(root) {
592
485
  `expected ${MERKLE_ROOT_BYTE_LENGTH}-byte merkle root, got ${root.length}`
593
486
  );
594
487
  }
595
- const hex = Buffer5.from(root).toString("hex");
488
+ const hex = Buffer4.from(root).toString("hex");
596
489
  return (BigInt(`0x${hex}`) % BN254).toString(DECIMAL_STRING_RADIX);
597
490
  }
598
491
 
@@ -602,8 +495,12 @@ import {
602
495
  decodeStealthAddress,
603
496
  encodeStealthAddress,
604
497
  recipientPublicKeysDecimalFromStealthAddress
605
- } from "@auditable/privacy-pool-zk-sdk";
606
- 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";
607
504
  function decodePrivateAddress(value) {
608
505
  const decodeAddress = decodeStealthAddress;
609
506
  return decodeAddress(value);
@@ -632,26 +529,26 @@ function privateAddressSdk(sdk) {
632
529
  );
633
530
  }
634
531
  return {
635
- generatePrivateAddressFromStellarSignature: (signature) => generator.call(sdk, signature)
532
+ generatePrivateAddressFromStellarSignature: (signature, domain) => generator.call(sdk, signature, domain)
636
533
  };
637
534
  }
638
535
 
639
536
  // src/transact/proofs/withdraw/transact-proof.ts
640
- import { withdrawObjectFromMerkleWitness as withdrawObjectFromMerkleWitness2 } from "@auditable/privacy-pool-zk-sdk";
537
+ import { withdrawObjectFromMerkleWitness as withdrawObjectFromMerkleWitness2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
641
538
 
642
539
  // src/transact/proofs/transaction-input.ts
643
- import { Buffer as Buffer7 } from "buffer";
540
+ import { Buffer as Buffer6 } from "buffer";
644
541
  import { StrKey as StrKey2 } from "@stellar/stellar-sdk";
645
542
 
646
543
  // src/transact/stellar/token-contract.ts
647
- import { Buffer as Buffer6 } from "buffer";
544
+ import { Buffer as Buffer5 } from "buffer";
648
545
  import { StrKey } from "@stellar/stellar-sdk";
649
546
  var CONTRACT_ID_BYTE_LENGTH = 32;
650
547
  var HEX_CHARS_PER_BYTE = 2;
651
548
  var CONTRACT_ID_HEX_CHAR_LENGTH = CONTRACT_ID_BYTE_LENGTH * HEX_CHARS_PER_BYTE;
652
549
  var CONTRACT_ID_HEX = /^(?:0x)?([0-9a-f]{64})$/i;
653
550
  function encodeContractFromHex(hexPayload) {
654
- return StrKey.encodeContract(Buffer6.from(hexPayload, "hex"));
551
+ return StrKey.encodeContract(Buffer5.from(hexPayload, "hex"));
655
552
  }
656
553
  function normalizeSorobanContractId(raw) {
657
554
  const trimmed = raw.trim();
@@ -677,10 +574,14 @@ function resolveTokenContractId(tokenContractRaw) {
677
574
  }
678
575
 
679
576
  // src/transact/proofs/transaction-input.ts
577
+ var ZERO_PUBLIC_WITHDRAW_ADDRESS = {
578
+ withdrawAddressHi: "0",
579
+ withdrawAddressLo: "0"
580
+ };
680
581
  var CONTRACT_ADDRESS_HALF_BYTES = 16;
681
582
  var CONTRACT_ADDRESS_BYTES = 32;
682
583
  function bytes16ToDecimal(bytes) {
683
- return BigInt(`0x${Buffer7.from(bytes).toString("hex")}`).toString();
584
+ return BigInt(`0x${Buffer6.from(bytes).toString("hex")}`).toString();
684
585
  }
685
586
  function tokenAddressFrParts(tokenAddress) {
686
587
  const normalized = resolveTokenContractId(tokenAddress);
@@ -696,98 +597,116 @@ function withTokenAddressPublicInputs(base, tokenAddress) {
696
597
  return {
697
598
  ...base,
698
599
  tokenAddressHi: hi,
699
- 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
700
619
  };
701
620
  }
702
621
  function tokenAddressToAssetLeg(tokenAddress) {
703
622
  const { hi, lo } = tokenAddressFrParts(tokenAddress);
704
623
  return [hi, lo];
705
624
  }
706
- function buildZeroPublicLegs() {
625
+ function buildZeroPublicLegs(publicNInputs = 1, publicNOutputs = 1) {
707
626
  return {
708
- publicWithdrawnAssets: [["0", "0"]],
709
- publicDepositedAssets: [["0", "0"]],
710
- publicDeposits: ["0"],
711
- 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")
712
637
  };
713
638
  }
714
- function buildPublicDepositLegs(tokenAddress, amount) {
715
- const legs = buildZeroPublicLegs();
639
+ function buildPublicDepositLegs(tokenAddress, amount, publicNInputs = 1, publicNOutputs = 1) {
640
+ const legs = buildZeroPublicLegs(publicNInputs, publicNOutputs);
716
641
  return {
717
642
  ...legs,
718
- publicDepositedAssets: [tokenAddressToAssetLeg(tokenAddress)],
719
- publicDeposits: [amount]
643
+ publicDepositedAssets: [
644
+ tokenAddressToAssetLeg(tokenAddress),
645
+ ...legs.publicDepositedAssets.slice(1)
646
+ ],
647
+ publicDeposits: [amount, ...legs.publicDeposits.slice(1)]
720
648
  };
721
649
  }
722
- function buildPublicWithdrawLegs(tokenAddress, amount) {
723
- const legs = buildZeroPublicLegs();
650
+ function buildPublicWithdrawLegs(tokenAddress, amount, publicNInputs = 1, publicNOutputs = 1) {
651
+ const legs = buildZeroPublicLegs(publicNInputs, publicNOutputs);
724
652
  return {
725
653
  ...legs,
726
- publicWithdrawnAssets: [tokenAddressToAssetLeg(tokenAddress)],
727
- publicWithdrawals: [amount]
654
+ publicWithdrawnAssets: [
655
+ tokenAddressToAssetLeg(tokenAddress),
656
+ ...legs.publicWithdrawnAssets.slice(1)
657
+ ],
658
+ publicWithdrawals: [amount, ...legs.publicWithdrawals.slice(1)]
728
659
  };
729
660
  }
730
661
 
731
- // src/transact/proofs/confidential/helpers.ts
662
+ // src/transact/zk/slots.ts
732
663
  import {
733
- ed25519PubkeyPayloadHexToWithdrawFrDecimals,
734
- withdrawObjectFromMerkleWitness
735
- } from "@auditable/privacy-pool-zk-sdk";
736
- import { StrKey as StrKey3 } from "@stellar/stellar-sdk";
737
- import { Buffer as Buffer8 } from "buffer";
738
-
739
- // src/transact/encoding/priv-key-scalar-from-recipient-hex.ts
740
- import { BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE } from "@auditable/privacy-pool-zk-sdk";
741
- var SCALAR_HEX_CHAR_LENGTH = 64;
742
- var DECIMAL_RADIX = 10;
743
- var BIGINT_ONE = 1n;
744
- function normalizeRecipientScalarHex(hexInput) {
745
- const trimmed = hexInput.trim().replace(/^0x/iu, "");
746
- if (!/^[0-9a-f]*$/iu.test(trimmed)) {
747
- throw new Error("recipient scalar hex must be hexadecimal");
748
- }
749
- const withLeadingNibble = trimmed.length % 2 === 0 ? trimmed : `0${trimmed}`;
750
- const lower = withLeadingNibble.toLowerCase();
751
- const padded = lower.padStart(SCALAR_HEX_CHAR_LENGTH, "0").slice(-SCALAR_HEX_CHAR_LENGTH);
752
- 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) {
753
680
  throw new Error(
754
- `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)}`
755
682
  );
756
683
  }
757
- return padded;
684
+ return [...values, ...Array.from({ length: length - values.length }, () => fill)];
758
685
  }
759
- function privKeyScalarDecimalFromRecipientScalarHex(hexInput) {
760
- const hex = normalizeRecipientScalarHex(hexInput);
761
- const value = BigInt(`0x${hex}`);
762
- const mask = BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE - BIGINT_ONE;
763
- 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);
764
695
  }
765
696
 
766
697
  // src/transact/proofs/confidential/helpers.ts
698
+ import { withdrawObjectFromMerkleWitness } from "@arcanetech/stellar-privacy-pool-zk-sdk";
767
699
  var MIN_CONFIDENTIAL_TRANSFER_STROOPS = 1n;
768
700
  var ZERO_STROOPS = 0n;
769
- function leafEphemeralCoords(xHex, yHex) {
770
- const coords = {};
771
- Object.defineProperty(coords, "x", {
772
- value: xHex,
773
- enumerable: true,
774
- writable: true
775
- });
776
- Object.defineProperty(coords, "y", {
777
- value: yHex,
778
- enumerable: true,
779
- writable: true
780
- });
781
- return coords;
782
- }
783
701
  function withdrawWitnessForCoin(parameters) {
784
- const { sdk, coin, state, xHex, yHex } = parameters;
702
+ const { sdk, coin, state } = parameters;
785
703
  const witness = sdk.buildWithdrawMerkleWitness(coin, state);
786
704
  const withdrawApplicationId = coin.application_id ?? parameters.applicationId;
787
705
  const withdrawObject = withdrawObjectFromMerkleWitness(
788
706
  witness,
789
- leafEphemeralCoords(xHex, yHex),
790
- withdrawApplicationId
707
+ parameters.ownerPubHex,
708
+ withdrawApplicationId,
709
+ parameters.privKeyScalar
791
710
  );
792
711
  return { witness, withdrawObject };
793
712
  }
@@ -796,16 +715,16 @@ function dualWithdrawLegsWithSharedRoot(parameters) {
796
715
  sdk: parameters.sdk,
797
716
  coin: parameters.coinA,
798
717
  state: parameters.state,
799
- xHex: parameters.ephemeralA.xHex,
800
- yHex: parameters.ephemeralA.yHex,
718
+ ownerPubHex: parameters.ownerPubHex,
719
+ privKeyScalar: parameters.privKeyScalar,
801
720
  applicationId: parameters.applicationId
802
721
  });
803
722
  const legB = withdrawWitnessForCoin({
804
723
  sdk: parameters.sdk,
805
724
  coin: parameters.coinB,
806
725
  state: parameters.state,
807
- xHex: parameters.ephemeralB.xHex,
808
- yHex: parameters.ephemeralB.yHex,
726
+ ownerPubHex: parameters.ownerPubHex,
727
+ privKeyScalar: parameters.privKeyScalar,
809
728
  applicationId: parameters.applicationId
810
729
  });
811
730
  if (legA.witness.stateRoot !== legB.witness.stateRoot) {
@@ -813,15 +732,6 @@ function dualWithdrawLegsWithSharedRoot(parameters) {
813
732
  }
814
733
  return { legA, legB };
815
734
  }
816
- function senderWithdrawFrAndScalar(parameters) {
817
- const pkRaw = StrKey3.decodeEd25519PublicKey(parameters.senderGAddress);
818
- const pkHex = Buffer8.from(pkRaw).toString("hex");
819
- const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals(pkHex);
820
- const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
821
- parameters.senderPrivKeyScalarHex
822
- );
823
- return { hi, lo, privKeyScalar };
824
- }
825
735
  function requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange) {
826
736
  if (changeStroops > ZERO_STROOPS) {
827
737
  const stpl1 = selfPrivateAddressStpl1ForChange?.trim() ?? "";
@@ -846,15 +756,15 @@ function changeStroopsAfterDualTransfer(transferStroops, totalNotes) {
846
756
  import {
847
757
  DEMO_AUDIT_PUBLIC_KEY,
848
758
  resolveTransactionAuditParams
849
- } from "@auditable/privacy-pool-zk-sdk";
850
- import { Buffer as Buffer9 } from "buffer";
759
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
760
+ import { Buffer as Buffer7 } from "buffer";
851
761
  var UNCOMPRESSED_PREFIX = "04";
852
762
  var UNCOMPRESSED_HEX_LENGTH = 130;
853
763
  var XY_HEX_LENGTH = 128;
854
764
  var X_OFFSET_END = 32;
855
765
  var Y_OFFSET_START = 32;
856
766
  var Y_OFFSET_END = 64;
857
- var DECIMAL_RADIX2 = 10;
767
+ var DECIMAL_RADIX = 10;
858
768
  var BN254_FR_MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
859
769
  var BABYJUBJUB_A = 168700n;
860
770
  var BABYJUBJUB_D = 168696n;
@@ -874,13 +784,13 @@ function parseAuditPublicKeyFromEnvHex(raw) {
874
784
  "Audit public key must be uncompressed 65-byte hex (04 + X + Y) or 64-byte X+Y hex"
875
785
  );
876
786
  }
877
- const bytes = Buffer9.from(payload, "hex");
787
+ const bytes = Buffer7.from(payload, "hex");
878
788
  const auditPublicKeyXDecimal = BigInt(
879
789
  `0x${bytes.subarray(0, X_OFFSET_END).toString("hex")}`
880
- ).toString(DECIMAL_RADIX2);
790
+ ).toString(DECIMAL_RADIX);
881
791
  const auditPublicKeyYDecimal = BigInt(
882
792
  `0x${bytes.subarray(Y_OFFSET_START, Y_OFFSET_END).toString("hex")}`
883
- ).toString(DECIMAL_RADIX2);
793
+ ).toString(DECIMAL_RADIX);
884
794
  if (!passesBabyJubCurveCheck(
885
795
  BigInt(auditPublicKeyXDecimal),
886
796
  BigInt(auditPublicKeyYDecimal)
@@ -892,7 +802,8 @@ function parseAuditPublicKeyFromEnvHex(raw) {
892
802
  function buildPoolTransactionAuditParameters(input) {
893
803
  return resolveTransactionAuditParams(
894
804
  input.applicationId,
895
- input.auditPublicKey ?? DEMO_AUDIT_PUBLIC_KEY
805
+ input.auditPublicKey ?? DEMO_AUDIT_PUBLIC_KEY,
806
+ input.nAuditSlots
896
807
  );
897
808
  }
898
809
  function resolvePoolApplicationId(applicationId) {
@@ -906,24 +817,24 @@ function resolvePoolApplicationId(applicationId) {
906
817
  }
907
818
 
908
819
  // src/transact/proofs/withdraw/helpers.ts
909
- import { ed25519PubkeyPayloadHexToWithdrawFrDecimals as ed25519PubkeyPayloadHexToWithdrawFrDecimals2 } from "@auditable/privacy-pool-zk-sdk";
820
+ import { ed25519PubkeyPayloadHexToWithdrawFrDecimals } from "@arcanetech/stellar-privacy-pool-zk-sdk";
910
821
 
911
822
  // src/transact/stellar/account.ts
912
- import { StrKey as StrKey4 } from "@stellar/stellar-sdk";
913
- import { Buffer as Buffer10 } from "buffer";
823
+ import { StrKey as StrKey3 } from "@stellar/stellar-sdk";
824
+ import { Buffer as Buffer8 } from "buffer";
914
825
  var MUXED_ACCOUNT_ID_BYTE_LENGTH = 8;
915
826
  var ED25519_PUBLIC_KEY_BYTE_LENGTH = 32;
916
827
  function ed25519HexFromGAddress(trimmed) {
917
828
  try {
918
- const raw = StrKey4.decodeEd25519PublicKey(trimmed);
919
- return Buffer10.from(raw).toString("hex");
829
+ const raw = StrKey3.decodeEd25519PublicKey(trimmed);
830
+ return Buffer8.from(raw).toString("hex");
920
831
  } catch {
921
832
  return void 0;
922
833
  }
923
834
  }
924
835
  function ed25519HexFromMuxedAddress(trimmed) {
925
836
  try {
926
- const raw = StrKey4.decodeMed25519PublicKey(trimmed);
837
+ const raw = StrKey3.decodeMed25519PublicKey(trimmed);
927
838
  if (raw.length === MUXED_ACCOUNT_ID_BYTE_LENGTH + ED25519_PUBLIC_KEY_BYTE_LENGTH) {
928
839
  return raw.subarray(MUXED_ACCOUNT_ID_BYTE_LENGTH).toString("hex");
929
840
  }
@@ -948,29 +859,29 @@ function ed25519PublicKeyHexFromStellarAccount(address) {
948
859
  throw new Error("Invalid destination Stellar address");
949
860
  }
950
861
 
951
- // src/transact/encoding/ephemeral-key.ts
952
- var HEX_64_RE = /^[\da-f]{64}$/iu;
953
- function normalizeCoordinate(value) {
954
- const hex = value.trim().replace(/^0x/iu, "").toLowerCase();
955
- if (!HEX_64_RE.test(hex)) {
956
- 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");
957
870
  }
958
- return hex;
959
- }
960
- function parseEphemeralKeyString(input) {
961
- const [xRaw, yRaw, extra] = input.split(":");
962
- 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) {
963
875
  throw new Error(
964
- '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)`
965
877
  );
966
878
  }
967
- return {
968
- xHex: normalizeCoordinate(xRaw),
969
- yHex: normalizeCoordinate(yRaw)
970
- };
879
+ return padded;
971
880
  }
972
- function serializeEphemeralKeyString(point) {
973
- 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);
974
885
  }
975
886
 
976
887
  // src/transact/proofs/withdraw/helpers.ts
@@ -978,7 +889,7 @@ function destinationWithdrawFrAndScalar(parameters) {
978
889
  const pkHex = ed25519PublicKeyHexFromStellarAccount(
979
890
  parameters.destinationStellarAddress
980
891
  );
981
- const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals2(pkHex);
892
+ const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals(pkHex);
982
893
  const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
983
894
  parameters.privKeyScalarHex
984
895
  );
@@ -992,8 +903,11 @@ function buildWithdrawPublicInput(parameters) {
992
903
  return withTokenAddressPublicInputs(
993
904
  {
994
905
  stateRoot: parameters.stateRoot,
995
- withdrawAddressHi: hi,
996
- withdrawAddressLo: lo,
906
+ ...publicWithdrawAddressLimbs({
907
+ publicWithdrawalAmount: parameters.publicWithdrawalAmount,
908
+ destinationHi: hi,
909
+ destinationLo: lo
910
+ }),
997
911
  privKeyScalar
998
912
  },
999
913
  parameters.tokenAddress
@@ -1001,7 +915,7 @@ function buildWithdrawPublicInput(parameters) {
1001
915
  }
1002
916
  async function resolveWithdrawChangeDeposits(parameters) {
1003
917
  if (parameters.changeStroops <= ZERO_STROOPS) {
1004
- return { deposits: ["dummy", "dummy"] };
918
+ return { deposits: [] };
1005
919
  }
1006
920
  const stpl1 = parameters.changePrivateAddressStpl1?.trim() ?? "";
1007
921
  if (!stpl1) {
@@ -1015,7 +929,7 @@ async function resolveWithdrawChangeDeposits(parameters) {
1015
929
  tokenAddress: parameters.tokenAddress
1016
930
  });
1017
931
  return {
1018
- deposits: [slot.deposit, "dummy"],
932
+ deposits: [slot.deposit],
1019
933
  changeCoin: {
1020
934
  commitment_hex: slot.commitment_hex,
1021
935
  coin: slot.coin,
@@ -1040,14 +954,14 @@ function buildDualWithdrawPublicInput(parameters) {
1040
954
  stateRoot: parameters.stateRoot,
1041
955
  destinationStellarAddress: parameters.destinationStellarAddress,
1042
956
  privKeyScalarHex: parameters.privKeyScalarHex,
1043
- tokenAddress: parameters.tokenAddress
957
+ tokenAddress: parameters.tokenAddress,
958
+ publicWithdrawalAmount: parameters.publicWithdrawalAmount
1044
959
  });
1045
960
  }
1046
961
  async function prepareDualWithdrawProofInputs(parameters) {
1047
- const totalNotes = BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value);
1048
962
  const changeStroops = validateDualWithdrawAmounts(
1049
963
  parameters.withdrawAmountStroops,
1050
- totalNotes,
964
+ BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value),
1051
965
  parameters.changePrivateAddressStpl1
1052
966
  );
1053
967
  const { legA, legB } = dualWithdrawLegsWithSharedRoot({
@@ -1055,8 +969,12 @@ async function prepareDualWithdrawProofInputs(parameters) {
1055
969
  coinA: parameters.coinA,
1056
970
  coinB: parameters.coinB,
1057
971
  state: parameters.state,
1058
- ephemeralA: parseEphemeralKeyString(parameters.ephemeralAKey),
1059
- ephemeralB: parseEphemeralKeyString(parameters.ephemeralBKey),
972
+ ownerPubHex: parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
973
+ parameters.privKeyScalarHex
974
+ ),
975
+ privKeyScalar: privKeyScalarDecimalFromRecipientScalarHex(
976
+ parameters.privKeyScalarHex
977
+ ),
1060
978
  applicationId: parameters.applicationId
1061
979
  });
1062
980
  const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
@@ -1069,17 +987,19 @@ async function prepareDualWithdrawProofInputs(parameters) {
1069
987
  destinationStellarAddress: parameters.destinationStellarAddress,
1070
988
  privKeyScalarHex: parameters.privKeyScalarHex,
1071
989
  tokenAddress: parameters.tokenAddress,
1072
- stateRoot: legA.witness.stateRoot
990
+ stateRoot: legA.witness.stateRoot,
991
+ publicWithdrawalAmount: parameters.withdrawAmountStroops.toString()
1073
992
  });
1074
993
  const audit = buildPoolTransactionAuditParameters({
1075
994
  applicationId: parameters.applicationId,
995
+ nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
1076
996
  ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
1077
997
  });
1078
998
  return {
1079
999
  publicInput,
1080
1000
  audit,
1081
- withdrawLegs: [legA.withdrawObject, legB.withdrawObject],
1082
1001
  deposits,
1002
+ withdrawLegs: [legA.withdrawObject, legB.withdrawObject],
1083
1003
  ...changeCoin ? { changeCoin } : {}
1084
1004
  };
1085
1005
  }
@@ -1097,35 +1017,49 @@ function validateSingleWithdrawAmounts(withdrawAmountStroops, noteStroops) {
1097
1017
  async function proveSingleWithdrawTransaction(parameters) {
1098
1018
  return parameters.sdk.proveTransaction(
1099
1019
  parameters.publicInput,
1100
- buildPublicWithdrawLegs(
1101
- parameters.tokenAddress,
1102
- parameters.withdrawAmountStroops.toString()
1020
+ padPublicLegsToLayout(
1021
+ parameters.sdk,
1022
+ buildPublicWithdrawLegs(
1023
+ parameters.tokenAddress,
1024
+ parameters.withdrawAmountStroops.toString()
1025
+ )
1103
1026
  ),
1104
- [parameters.primaryWithdraw, "dummy"],
1105
- parameters.deposits,
1027
+ padWithdrawSlotsToLayout(parameters.sdk, [parameters.primaryWithdraw]),
1028
+ padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
1106
1029
  parameters.audit
1107
1030
  );
1108
1031
  }
1109
1032
  function buildPrimaryWithdrawForCoin(parameters) {
1110
- const ephemeralPoint = parseEphemeralKeyString(parameters.depositorEphemeralKey);
1111
1033
  const witness = parameters.sdk.buildWithdrawMerkleWitness(
1112
1034
  parameters.coin,
1113
1035
  parameters.state
1114
1036
  );
1037
+ const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
1038
+ parameters.privKeyScalarHex
1039
+ );
1040
+ const ownerPubHex = parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
1041
+ parameters.privKeyScalarHex
1042
+ );
1115
1043
  const primaryWithdraw = withdrawObjectFromMerkleWitness2(
1116
1044
  witness,
1117
- leafEphemeralCoords(ephemeralPoint.xHex, ephemeralPoint.yHex),
1118
- parameters.applicationId
1045
+ ownerPubHex,
1046
+ parameters.applicationId,
1047
+ privKeyScalar
1119
1048
  );
1120
1049
  return { witness, primaryWithdraw };
1121
1050
  }
1122
1051
  async function prepareSingleWithdrawProofInputs(parameters) {
1123
- const noteStroops = BigInt(parameters.coin.value);
1124
1052
  const changeStroops = validateSingleWithdrawAmounts(
1125
1053
  parameters.withdrawAmountStroops,
1126
- noteStroops
1054
+ BigInt(parameters.coin.value)
1127
1055
  );
1128
- 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
+ });
1129
1063
  const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
1130
1064
  changeStroops,
1131
1065
  changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
@@ -1136,18 +1070,19 @@ async function prepareSingleWithdrawProofInputs(parameters) {
1136
1070
  stateRoot: witness.stateRoot,
1137
1071
  destinationStellarAddress: parameters.destinationStellarAddress,
1138
1072
  privKeyScalarHex: parameters.privKeyScalarHex,
1139
- tokenAddress: parameters.tokenAddress
1140
- });
1141
- const audit = buildPoolTransactionAuditParameters({
1142
- applicationId: parameters.applicationId,
1143
- ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
1073
+ tokenAddress: parameters.tokenAddress,
1074
+ publicWithdrawalAmount: parameters.withdrawAmountStroops.toString()
1144
1075
  });
1145
1076
  return {
1146
1077
  primaryWithdraw,
1147
1078
  deposits,
1148
1079
  changeCoin,
1149
1080
  publicInput,
1150
- audit
1081
+ audit: buildPoolTransactionAuditParameters({
1082
+ applicationId: parameters.applicationId,
1083
+ nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
1084
+ ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
1085
+ })
1151
1086
  };
1152
1087
  }
1153
1088
  async function proveWithdrawTransact(parameters) {
@@ -1163,12 +1098,11 @@ async function proveWithdrawTransact(parameters) {
1163
1098
  });
1164
1099
  return {
1165
1100
  ...proof,
1166
- applicationIdsPlaintext: [
1167
- parameters.applicationId,
1168
- "0",
1169
- changeCoin ? parameters.applicationId : "0",
1170
- "0"
1171
- ],
1101
+ applicationIdsPlaintext: buildApplicationIdHints({
1102
+ sdk: parameters.sdk,
1103
+ inputIds: [parameters.applicationId],
1104
+ outputIds: [changeCoin ? parameters.applicationId : "0"]
1105
+ }),
1172
1106
  ...changeCoin ? { changeCoin } : {}
1173
1107
  };
1174
1108
  }
@@ -1176,33 +1110,143 @@ async function proveWithdrawTransactDual(parameters) {
1176
1110
  const { publicInput, audit, withdrawLegs, deposits, changeCoin } = await prepareDualWithdrawProofInputs(parameters);
1177
1111
  const proof = await parameters.sdk.proveTransaction(
1178
1112
  publicInput,
1179
- buildPublicWithdrawLegs(
1180
- parameters.tokenAddress,
1181
- parameters.withdrawAmountStroops.toString()
1113
+ padPublicLegsToLayout(
1114
+ parameters.sdk,
1115
+ buildPublicWithdrawLegs(
1116
+ parameters.tokenAddress,
1117
+ parameters.withdrawAmountStroops.toString()
1118
+ )
1182
1119
  ),
1183
- withdrawLegs,
1184
- deposits,
1120
+ padWithdrawSlotsToLayout(parameters.sdk, withdrawLegs),
1121
+ padDepositSlotsToLayout(parameters.sdk, deposits),
1185
1122
  audit
1186
1123
  );
1187
1124
  return {
1188
1125
  ...proof,
1189
- applicationIdsPlaintext: [
1190
- audit.applicationId,
1191
- audit.applicationId,
1192
- changeCoin ? audit.applicationId : "0",
1193
- "0"
1194
- ],
1126
+ applicationIdsPlaintext: buildApplicationIdHints({
1127
+ sdk: parameters.sdk,
1128
+ inputIds: [audit.applicationId, audit.applicationId],
1129
+ outputIds: [changeCoin ? audit.applicationId : "0"]
1130
+ }),
1195
1131
  ...changeCoin ? { changeCoin } : {}
1196
1132
  };
1197
1133
  }
1198
1134
 
1199
1135
  // src/transact/pool/service.ts
1200
1136
  import "buffer";
1201
- import { PrivacyPoolSDK as PrivacyPoolSdkClass } from "@auditable/privacy-pool-zk-sdk";
1137
+
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/circuit-config.ts
1152
+ import { BundledZkCircuit as BundledZkCircuit2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1153
+ var DEFAULT_STELLAR_ZK_CIRCUITS = {
1154
+ [BINDING_ZK_NONCE.toString()]: {
1155
+ nIns: 2,
1156
+ nOuts: 2,
1157
+ publicNInputs: 1,
1158
+ publicNOutputs: 1,
1159
+ circuit: BundledZkCircuit.TwoByTwo
1160
+ },
1161
+ [SIX_BY_SIX_BINDING_ZK_NONCE.toString()]: {
1162
+ nIns: 6,
1163
+ nOuts: 6,
1164
+ publicNInputs: 1,
1165
+ publicNOutputs: 1,
1166
+ circuit: BundledZkCircuit.SixBySix
1167
+ }
1168
+ };
1169
+ function isBundledDefinition(definition) {
1170
+ return "circuit" in definition;
1171
+ }
1172
+ async function fetchBuffer(url) {
1173
+ const response = await fetch(url);
1174
+ if (!response.ok) {
1175
+ throw new Error(`Failed to fetch ZK artifact ${url}: ${String(response.status)}`);
1176
+ }
1177
+ return response.arrayBuffer();
1178
+ }
1179
+ async function materializeDefinition(definition) {
1180
+ if (isBundledDefinition(definition)) {
1181
+ const bundled = {
1182
+ nIns: definition.nIns,
1183
+ nOuts: definition.nOuts,
1184
+ publicNInputs: definition.publicNInputs,
1185
+ publicNOutputs: definition.publicNOutputs,
1186
+ circuit: definition.circuit
1187
+ };
1188
+ return bundled;
1189
+ }
1190
+ const [zkey, circuitGraph, r1cs, provingKey] = await Promise.all([
1191
+ fetchBuffer(definition.zkeyUrl),
1192
+ fetchBuffer(definition.circuitGraphUrl),
1193
+ fetchBuffer(definition.r1csUrl),
1194
+ fetchBuffer(definition.provingKeyUrl)
1195
+ ]);
1196
+ const custom = {
1197
+ nIns: definition.nIns,
1198
+ nOuts: definition.nOuts,
1199
+ publicNInputs: definition.publicNInputs,
1200
+ publicNOutputs: definition.publicNOutputs,
1201
+ zkey,
1202
+ circuitGraph,
1203
+ r1cs,
1204
+ provingKey
1205
+ };
1206
+ return custom;
1207
+ }
1208
+ async function materializeSelectedZkCircuit(circuits, nonce) {
1209
+ const map = stellarCircuitsOrDefault(circuits);
1210
+ const key = nonce.toString();
1211
+ const definition = Object.entries(map).find(([nonceKey]) => nonceKey === key)?.[1];
1212
+ if (!definition) {
1213
+ throw new Error(`no zk circuit configured for nonce ${key}`);
1214
+ }
1215
+ return { [key]: await materializeDefinition(definition) };
1216
+ }
1217
+ function stellarCircuitsOrDefault(circuits) {
1218
+ return circuits ?? DEFAULT_STELLAR_ZK_CIRCUITS;
1219
+ }
1220
+ function optionalZkArtifactBaseUrl(value) {
1221
+ if (value === void 0) {
1222
+ return {};
1223
+ }
1224
+ const trimmed = value.trim();
1225
+ if (trimmed === "") {
1226
+ return {};
1227
+ }
1228
+ let withoutSlash = trimmed;
1229
+ while (withoutSlash.endsWith("/")) {
1230
+ withoutSlash = withoutSlash.slice(0, -1);
1231
+ }
1232
+ return { zkArtifactBaseUrl: withoutSlash };
1233
+ }
1202
1234
 
1203
1235
  // src/transact/pool/aligned-deposit.ts
1204
- import { PrivacyPoolSDK, scalarHexToFrDecimal } from "@auditable/privacy-pool-zk-sdk";
1236
+ import {
1237
+ PrivacyPoolSDK,
1238
+ scalarHexToFrDecimal
1239
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
1205
1240
  var SAMPLE_SCALAR_ATTEMPTS = 10;
1241
+ function escrowDepositFields(parameters) {
1242
+ if (!parameters.recipientHi || !parameters.recipientLo) {
1243
+ return {};
1244
+ }
1245
+ return {
1246
+ ...parameters.escrowNonce ? { escrowNonce: parameters.escrowNonce } : {},
1247
+ recipientStellar: [parameters.recipientHi, parameters.recipientLo]
1248
+ };
1249
+ }
1206
1250
  function sampleValidDepositScalarHex() {
1207
1251
  for (let index = 0; index < SAMPLE_SCALAR_ATTEMPTS; index++) {
1208
1252
  const candidate = PrivacyPoolSDK.generateRandomScalarHex32();
@@ -1218,17 +1262,12 @@ function sampleValidDepositScalarHex() {
1218
1262
  async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
1219
1263
  const privateAddressPoint = decodePrivateAddress(parameters.privateAddressStpl1);
1220
1264
  const scalarHex = sampleValidDepositScalarHex();
1221
- const shared = sdk.ecdhSharedKey(
1222
- scalarHex,
1223
- privateAddressPoint.x,
1224
- privateAddressPoint.y
1225
- );
1226
1265
  const [assetHi, assetLo] = tokenAddressToAssetLeg(parameters.tokenAddress);
1227
1266
  const resolvedApplicationId = resolvePoolApplicationId(applicationId);
1228
- const generated = sdk.generateCoinForDepositWithSharedHex(
1267
+ const generated = sdk.generateCoinForDepositWithOwnerPubHex(
1229
1268
  scalarHex,
1230
- shared.x,
1231
- shared.y,
1269
+ privateAddressPoint.x,
1270
+ privateAddressPoint.y,
1232
1271
  parameters.amountStroops,
1233
1272
  assetHi,
1234
1273
  assetLo,
@@ -1243,27 +1282,34 @@ async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
1243
1282
  ephemeralKeyScalar: scalarHexToFrDecimal(scalarHex),
1244
1283
  asset: [generated.coin.asset_hi, generated.coin.asset_lo],
1245
1284
  applicationId: resolvedApplicationId,
1246
- recipientPublicKeys
1285
+ recipientPublicKeys,
1286
+ ...escrowDepositFields(parameters)
1247
1287
  };
1248
1288
  return {
1249
1289
  deposit,
1250
1290
  commitment_hex: generated.commitment_hex,
1251
1291
  coin: generated.coin,
1252
1292
  depositScalarHex: scalarHex,
1253
- precommitementHex: generated.precommitement_hex
1293
+ precommitementHex: generated.precommitementHex
1254
1294
  };
1255
1295
  }
1256
1296
 
1257
1297
  // src/transact/pool/service.ts
1258
1298
  var PrivacyPoolService = class {
1259
- constructor(assets, applicationId, auditPublicKey) {
1299
+ constructor(assets, applicationId, auditPublicKey, zkCircuits, zkConfigNonce, zkArtifactBaseUrl) {
1260
1300
  this.assets = assets;
1261
1301
  this.applicationId = applicationId;
1262
1302
  this.auditPublicKey = auditPublicKey;
1303
+ this.zkCircuits = zkCircuits;
1304
+ this.zkConfigNonce = zkConfigNonce;
1305
+ this.zkArtifactBaseUrl = zkArtifactBaseUrl;
1263
1306
  }
1264
1307
  assets;
1265
1308
  applicationId;
1266
1309
  auditPublicKey;
1310
+ zkCircuits;
1311
+ zkConfigNonce;
1312
+ zkArtifactBaseUrl;
1267
1313
  sdk = void 0;
1268
1314
  initPromise = void 0;
1269
1315
  async ensureInit() {
@@ -1279,10 +1325,16 @@ var PrivacyPoolService = class {
1279
1325
  "PrivacyPoolService requires browser ZK assets before initialization."
1280
1326
  );
1281
1327
  }
1282
- this.sdk = await PrivacyPoolSdkClass.init({
1328
+ const zkConfigNonce = this.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
1329
+ const zkCircuits = await materializeSelectedZkCircuit(
1330
+ this.zkCircuits,
1331
+ zkConfigNonce
1332
+ );
1333
+ this.sdk = await PrivacyPoolSDK2.init({
1283
1334
  wasmBinary: this.assets.sdkWasm,
1284
- circuitWasm: this.assets.circuitWasm,
1285
- zkey: this.assets.provingKey
1335
+ zkCircuits,
1336
+ zkConfigNonce,
1337
+ ...optionalZkArtifactBaseUrl(this.zkArtifactBaseUrl)
1286
1338
  });
1287
1339
  })();
1288
1340
  return this.initPromise;
@@ -1300,22 +1352,17 @@ var PrivacyPoolService = class {
1300
1352
  getApplicationId() {
1301
1353
  return resolvePoolApplicationId(this.applicationId);
1302
1354
  }
1303
- async generatePrivateAddressFromStellarSignature(signature) {
1304
- await this.ensureInit();
1305
- if (!this.sdk) {
1306
- throw new Error("SDK not initialized");
1307
- }
1308
- return privateAddressSdk(this.sdk).generatePrivateAddressFromStellarSignature(
1309
- signature
1355
+ async generatePrivateAddressFromStellarSignature(signature, domain) {
1356
+ const sdk = await this.getInitializedSdk();
1357
+ return privateAddressSdk(sdk).generatePrivateAddressFromStellarSignature(
1358
+ signature,
1359
+ domain
1310
1360
  );
1311
1361
  }
1312
1362
  async sharedSecretX(recipientScalarHex, ephemeralKeyEncoded) {
1313
- await this.ensureInit();
1314
- if (!this.sdk) {
1315
- throw new Error("SDK not initialized");
1316
- }
1363
+ const sdk = await this.getInitializedSdk();
1317
1364
  const ephemeralKey = decodeDecodedEphemeralKey(ephemeralKeyEncoded);
1318
- const shared = this.sdk.sharedSecretFromRecipientPreimage({
1365
+ const shared = sdk.sharedSecretFromRecipientPreimage({
1319
1366
  recipientScalar: recipientScalarHex,
1320
1367
  ephemeralKey
1321
1368
  });
@@ -1338,6 +1385,7 @@ var PrivacyPoolService = class {
1338
1385
  const applicationId = this.getApplicationId();
1339
1386
  const audit = buildPoolTransactionAuditParameters({
1340
1387
  applicationId,
1388
+ nAuditSlots: sdk.getLayout().nAuditSlots,
1341
1389
  ...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {}
1342
1390
  });
1343
1391
  const deposit = {
@@ -1351,38 +1399,35 @@ var PrivacyPoolService = class {
1351
1399
  const publicInput = withTokenAddressPublicInputs(
1352
1400
  {
1353
1401
  stateRoot,
1354
- withdrawAddressHi: "0",
1355
- withdrawAddressLo: "0",
1356
1402
  privKeyScalar: randomFrDecimal253()
1357
1403
  },
1358
1404
  parameters.tokenAddress
1359
1405
  );
1360
1406
  const proof = await sdk.proveTransaction(
1361
1407
  publicInput,
1362
- buildPublicDepositLegs(parameters.tokenAddress, parameters.coin.value),
1363
- ["dummy", "dummy"],
1364
- [deposit, "dummy"],
1408
+ padPublicLegsToLayout(
1409
+ sdk,
1410
+ buildPublicDepositLegs(parameters.tokenAddress, parameters.coin.value)
1411
+ ),
1412
+ padWithdrawSlotsToLayout(sdk, []),
1413
+ padDepositSlotsToLayout(sdk, [deposit]),
1365
1414
  audit
1366
1415
  );
1367
- const applicationIdsPlaintext = [
1368
- "0",
1369
- "0",
1370
- applicationId,
1371
- "0"
1372
- ];
1416
+ const applicationIdsPlaintext = buildApplicationIdHints({
1417
+ sdk,
1418
+ inputIds: [],
1419
+ outputIds: [applicationId]
1420
+ });
1373
1421
  return { ...proof, applicationIdsPlaintext };
1374
1422
  }
1375
- async calculateNullifierHash(nullifier) {
1423
+ async calculateNullifierHash(nullifier, privKeyScalar) {
1376
1424
  const sdk = await this.getInitializedSdk();
1377
- return sdk.calculateNullifierHash(nullifier);
1425
+ return sdk.calculateNullifierHash(nullifier, privKeyScalar);
1378
1426
  }
1379
1427
  async prepareWithdrawTransactProof(parameters) {
1380
- await this.ensureInit();
1381
- if (!this.sdk) {
1382
- throw new Error("SDK not initialized");
1383
- }
1428
+ const sdk = await this.getInitializedSdk();
1384
1429
  return proveWithdrawTransact({
1385
- sdk: this.sdk,
1430
+ sdk,
1386
1431
  applicationId: this.getApplicationId(),
1387
1432
  buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
1388
1433
  ...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
@@ -1390,12 +1435,9 @@ var PrivacyPoolService = class {
1390
1435
  });
1391
1436
  }
1392
1437
  async prepareWithdrawTransactProofDual(parameters) {
1393
- await this.ensureInit();
1394
- if (!this.sdk) {
1395
- throw new Error("SDK not initialized");
1396
- }
1438
+ const sdk = await this.getInitializedSdk();
1397
1439
  return proveWithdrawTransactDual({
1398
- sdk: this.sdk,
1440
+ sdk,
1399
1441
  applicationId: this.getApplicationId(),
1400
1442
  buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
1401
1443
  ...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
@@ -1418,7 +1460,10 @@ function createPrivacyPoolService(input) {
1418
1460
  return new PrivacyPoolService(
1419
1461
  input?.assets,
1420
1462
  input?.applicationId,
1421
- input?.auditPublicKey
1463
+ input?.auditPublicKey,
1464
+ input?.zkCircuits,
1465
+ input?.zkConfigNonce,
1466
+ input?.zkArtifactBaseUrl
1422
1467
  );
1423
1468
  }
1424
1469
  var configuredPrivacyPoolService;
@@ -1434,81 +1479,245 @@ function getPrivacyPoolService() {
1434
1479
  return configuredPrivacyPoolService;
1435
1480
  }
1436
1481
 
1437
- // src/transact/transfer-source/verify.ts
1438
- async function verifyPendingClaimBeforeExecute(input) {
1439
- try {
1440
- assertPendingClaimOwner({
1441
- claim: input.claim,
1442
- walletPublicKey: input.walletPublicKey
1482
+ // src/transact/merkle/fetch-contract.ts
1483
+ import { Buffer as Buffer11 } from "buffer";
1484
+
1485
+ // src/transact/merkle/encoding.ts
1486
+ import "buffer";
1487
+ var FR_ORDER = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n;
1488
+ function bufferToDecimal(buf) {
1489
+ const hex = buf.toString("hex");
1490
+ const bigintFromHex = BigInt(`0x${hex}`);
1491
+ const reduced = bigintFromHex % FR_ORDER;
1492
+ return reduced.toString();
1493
+ }
1494
+ function commitmentsBuffersToDecimal(buffers) {
1495
+ return buffers.map((bufferRow) => bufferToDecimal(bufferRow));
1496
+ }
1497
+
1498
+ // src/transact/merkle/state-port.ts
1499
+ function poolMerkleStateToCachedView(state) {
1500
+ return {
1501
+ commitments: state.commitments,
1502
+ updatedAt: state.updatedAt,
1503
+ merkleRootHex: state.merkleRootHex
1504
+ };
1505
+ }
1506
+
1507
+ // src/transact/merkle/fetch-contract.ts
1508
+ function normalizeCommitmentBuffers(rawBuffers) {
1509
+ return rawBuffers.map(
1510
+ (bufferRow) => Buffer11.isBuffer(bufferRow) ? bufferRow : Buffer11.from(bufferRow)
1511
+ );
1512
+ }
1513
+ function mergeContractMerkleWithCache(parameters) {
1514
+ const cachedCount = parameters.cachedState?.commitments.length ?? 0;
1515
+ const shouldPreferContract = parameters.contractCount > cachedCount || !parameters.cachedState || cachedCount === 0;
1516
+ if (shouldPreferContract) {
1517
+ const updatedAt = Date.now();
1518
+ void parameters.poolMerkleState?.set({
1519
+ poolContract: parameters.poolContractId,
1520
+ commitments: parameters.contractCommitments,
1521
+ commitmentCount: parameters.contractCount,
1522
+ merkleRootHex: parameters.merkleRootHex,
1523
+ updatedAt
1443
1524
  });
1444
- const coin = pendingClaimToCoin(input.claim);
1445
- const nullifierHashHex = await getPrivacyPoolService().calculateNullifierHash(
1446
- coin.nullifier
1447
- );
1448
- const contractContext = requireContractContext(input.environment);
1449
- const poolContractId = input.poolContractId?.trim() || contractContext.network.poolContract;
1450
- const spent = await readNullifierConsumedOnChain({
1451
- contractContext,
1452
- poolContractId,
1453
- walletPublicKey: input.walletPublicKey.trim(),
1454
- nullifierHashHex
1525
+ return {
1526
+ commitments: parameters.contractCommitments,
1527
+ updatedAt,
1528
+ merkleRootHex: parameters.merkleRootHex,
1529
+ commitmentCount: parameters.contractCount
1530
+ };
1531
+ }
1532
+ return {
1533
+ commitments: parameters.cachedState.commitments,
1534
+ updatedAt: parameters.cachedState.updatedAt,
1535
+ merkleRootHex: parameters.cachedState.merkleRootHex ?? parameters.merkleRootHex,
1536
+ commitmentCount: parameters.cachedState.commitments.length
1537
+ };
1538
+ }
1539
+ async function readCachedPoolMerkleView(poolMerkleState, poolContractId) {
1540
+ if (!poolMerkleState) {
1541
+ return void 0;
1542
+ }
1543
+ const cached = await poolMerkleState.get(poolContractId);
1544
+ return cached ? poolMerkleStateToCachedView(cached) : void 0;
1545
+ }
1546
+ async function fetchAndMergeMerkleState(parameters) {
1547
+ const client = readPoolClientFactory(parameters.transactEnvironment)({
1548
+ contractId: parameters.poolContractId,
1549
+ walletPublicKey: parameters.walletPublicKey,
1550
+ networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
1551
+ sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
1552
+ });
1553
+ const commitmentsRead = await client.get_commitments();
1554
+ const rawBuffers = commitmentsRead.result;
1555
+ const buffers = normalizeCommitmentBuffers(rawBuffers);
1556
+ const contractCommitments = commitmentsBuffersToDecimal(buffers);
1557
+ const contractCount = contractCommitments.length;
1558
+ const rootRead = await client.get_merkle_root();
1559
+ const merkleRootBuffer = rootRead.result;
1560
+ const merkleRootHex = Buffer11.from(merkleRootBuffer).toString("hex");
1561
+ const cachedState = await readCachedPoolMerkleView(
1562
+ parameters.poolMerkleState,
1563
+ parameters.poolContractId
1564
+ );
1565
+ return mergeContractMerkleWithCache({
1566
+ poolContractId: parameters.poolContractId,
1567
+ contractCommitments,
1568
+ contractCount,
1569
+ merkleRootHex,
1570
+ cachedState,
1571
+ ...parameters.poolMerkleState ? { poolMerkleState: parameters.poolMerkleState } : {}
1572
+ });
1573
+ }
1574
+ async function readLeafEphemeralHex(parameters) {
1575
+ const cached = await parameters.leafEphemeral?.get({
1576
+ poolContract: parameters.poolContractId,
1577
+ leafIndex: parameters.leafIndex
1578
+ });
1579
+ if (cached?.xHex && cached.yHex) {
1580
+ return { xHex: cached.xHex, yHex: cached.yHex };
1581
+ }
1582
+ const client = readPoolClientFactory(parameters.transactEnvironment)({
1583
+ contractId: parameters.poolContractId,
1584
+ walletPublicKey: parameters.walletPublicKey,
1585
+ networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
1586
+ sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
1587
+ });
1588
+ const read = await client.get_leaf_ephemeral({ leaf_index: parameters.leafIndex });
1589
+ const coords = read.result;
1590
+ if (!coords?.x || !coords?.y) {
1591
+ throw new Error("Missing leaf ephemeral key on contract");
1592
+ }
1593
+ const xHex = Buffer11.from(coords.x).toString("hex");
1594
+ const yHex = Buffer11.from(coords.y).toString("hex");
1595
+ await parameters.leafEphemeral?.set({
1596
+ poolContract: parameters.poolContractId,
1597
+ leafIndex: parameters.leafIndex,
1598
+ xHex,
1599
+ yHex,
1600
+ cachedAt: (/* @__PURE__ */ new Date()).toISOString()
1601
+ });
1602
+ return { xHex, yHex };
1603
+ }
1604
+
1605
+ // src/transact/engine/prepare/shared.ts
1606
+ async function resolveTokenContractId2(environment, assetId) {
1607
+ if (environment.resolveTokenContractId) {
1608
+ return environment.resolveTokenContractId(assetId);
1609
+ }
1610
+ throw new Error(`Token contract is not configured for asset ${assetId}.`);
1611
+ }
1612
+ async function resolveWalletPublicKey(environment, prepared) {
1613
+ if (environment.resolveWalletPublicKey) {
1614
+ return environment.resolveWalletPublicKey();
1615
+ }
1616
+ if (prepared.kind === "deposit") {
1617
+ const depositIntent = prepared.intent;
1618
+ return depositIntent.from;
1619
+ }
1620
+ throw new Error("Wallet public key resolver is not configured.");
1621
+ }
1622
+ async function resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
1623
+ const cached = await readSenderPrivKeyScalarHex(
1624
+ environment,
1625
+ privateAddressStpl1,
1626
+ owner
1627
+ );
1628
+ if (cached) {
1629
+ return cached;
1630
+ }
1631
+ if (environment.ensureSenderPrivKeyScalarHex) {
1632
+ return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
1633
+ }
1634
+ if (!environment.resolveSenderPrivKeyScalarHex) {
1635
+ throw new Error("Sender private key scalar resolver is not configured.");
1636
+ }
1637
+ return environment.resolveSenderPrivKeyScalarHex(privateAddressStpl1);
1638
+ }
1639
+ async function readSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
1640
+ if (owner && environment.resolveSenderPrivKeyScalarFromState) {
1641
+ const fromState = await environment.resolveSenderPrivKeyScalarFromState({
1642
+ owner,
1643
+ privateAddressStpl1
1455
1644
  });
1456
- if (spent) {
1457
- throw executionError3(
1458
- "Pending claim nullifier was already spent on-chain.",
1459
- "validation",
1460
- { reason: "pending_claim_nullifier_spent" }
1461
- );
1645
+ if (fromState?.trim()) {
1646
+ return fromState.trim();
1462
1647
  }
1463
- } catch (error) {
1464
- if (typeof error === "object" && error !== null && "code" in error && error.code === "insufficient_state") {
1465
- throw executionError3(
1466
- error instanceof Error ? error.message : "Pending claim owner mismatch.",
1467
- "validation",
1468
- { reason: "pending_claim_owner_mismatch" }
1469
- );
1648
+ }
1649
+ if (environment.readSenderPrivKeyScalarHex) {
1650
+ const cached = await environment.readSenderPrivKeyScalarHex(privateAddressStpl1);
1651
+ if (cached?.trim()) {
1652
+ return cached.trim();
1470
1653
  }
1471
- throw error;
1472
1654
  }
1655
+ return void 0;
1473
1656
  }
1474
-
1475
- // src/transact/transfer-source/verify-private-records.ts
1476
- import { executionError as executionError4, insufficientStateError as insufficientStateError2 } from "@arcanetech/privacy-sdk-core";
1477
-
1478
- // src/transact/private-address/record-coin.ts
1479
- function requireCoinNoteFromRecord(record) {
1480
- if (!record.coinNote) {
1481
- throw new Error(`Private record ${record.id} is missing coin note data.`);
1657
+ async function ensureSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
1658
+ const cached = await readSenderPrivKeyScalarHex(
1659
+ environment,
1660
+ privateAddressStpl1,
1661
+ owner
1662
+ );
1663
+ if (cached) {
1664
+ return cached;
1482
1665
  }
1483
- return record.coinNote;
1666
+ if (environment.ensureSenderPrivKeyScalarHex) {
1667
+ return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
1668
+ }
1669
+ return resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner);
1484
1670
  }
1485
- function findCommitmentLeafIndex(commitments, commitment) {
1486
- return commitments.indexOf(commitment);
1671
+ async function loadMerkleState(environment, walletPublicKey) {
1672
+ const merged = await fetchAndMergeMerkleState({
1673
+ poolContractId: environment.network.poolContract,
1674
+ walletPublicKey,
1675
+ transactEnvironment: environment,
1676
+ ...environment.poolMerkleState ? { poolMerkleState: environment.poolMerkleState } : {}
1677
+ });
1678
+ return { commitments: merged.commitments };
1487
1679
  }
1488
- function buildPrivateRecordFromDeposit(input) {
1680
+ function enrichPreparedOperation(prepared, outputRecords, artifacts) {
1489
1681
  return {
1490
- id: input.commitmentHex,
1491
- owner: input.owner,
1492
- asset: input.assetId,
1493
- amount: input.amount,
1494
- consumed: false,
1495
- status: input.status ?? "pending",
1496
- poolContract: input.poolContract,
1497
- commitmentHex: input.commitmentHex,
1498
- privateAddress: input.privateAddress,
1499
- amountDisplay: input.amountDisplay,
1500
- coinNote: input.coin,
1501
- depositScalarHex: input.depositScalarHex,
1502
- precommitementHex: input.precommitementHex,
1503
- ...input.txHash ? { txHash: input.txHash } : {}
1682
+ ...prepared,
1683
+ outputRecords,
1684
+ transactArtifacts: artifacts,
1685
+ submissionPayload: {
1686
+ operationId: crypto.randomUUID(),
1687
+ signed: false
1688
+ }
1504
1689
  };
1505
1690
  }
1506
1691
 
1507
1692
  // src/transact/transfer-source/verify-private-records.ts
1693
+ async function resolveNullifierSpendScalarHex(input) {
1694
+ const stamped = input.spendScalarHex?.trim();
1695
+ if (stamped) {
1696
+ return stamped;
1697
+ }
1698
+ const privateAddress = input.record.privateAddress?.trim();
1699
+ if (!privateAddress) {
1700
+ throw executionError3(
1701
+ "Private record is missing a private address; cannot derive the owner-bound spend scalar.",
1702
+ "validation",
1703
+ {
1704
+ reason: "private_record_missing_private_address",
1705
+ recordId: input.record.id
1706
+ }
1707
+ );
1708
+ }
1709
+ return ensureSenderPrivKeyScalarHex(
1710
+ input.environment,
1711
+ privateAddress,
1712
+ input.walletPublicKey
1713
+ );
1714
+ }
1508
1715
  async function readPrivateRecordNullifierSpendStatus(input) {
1509
1716
  const coin = requireCoinNoteFromRecord(input.record);
1717
+ const scalarHex = await resolveNullifierSpendScalarHex(input);
1510
1718
  const nullifierHashHex = await getPrivacyPoolService().calculateNullifierHash(
1511
- coin.nullifier
1719
+ coin.nullifier,
1720
+ privKeyScalarDecimalFromRecipientScalarHex(scalarHex)
1512
1721
  );
1513
1722
  const contractContext = requireContractContext(input.environment);
1514
1723
  const poolContractId = input.poolContractId?.trim() || contractContext.network.poolContract;
@@ -1526,10 +1735,11 @@ async function verifyPrivateRecordsNullifiersBeforeExecute(input) {
1526
1735
  record,
1527
1736
  environment: input.environment,
1528
1737
  walletPublicKey: input.walletPublicKey,
1529
- ...input.poolContractId ? { poolContractId: input.poolContractId } : {}
1738
+ ...input.poolContractId ? { poolContractId: input.poolContractId } : {},
1739
+ ...input.spendScalarHex ? { spendScalarHex: input.spendScalarHex } : {}
1530
1740
  });
1531
1741
  if (status.spent) {
1532
- throw executionError4(
1742
+ throw executionError3(
1533
1743
  "Private input note nullifier was already spent on-chain.",
1534
1744
  "validation",
1535
1745
  {
@@ -1549,10 +1759,11 @@ async function assertPrivateRecordsNullifiersAvailable(input) {
1549
1759
  const coin = requireCoinNoteFromRecord(record);
1550
1760
  const spent = await input.checkNullifierSpent({
1551
1761
  nullifier: coin.nullifier,
1552
- walletPublicKey: input.walletPublicKey
1762
+ walletPublicKey: input.walletPublicKey,
1763
+ ...record.privateAddress ? { privateAddressStpl1: record.privateAddress } : {}
1553
1764
  });
1554
1765
  if (spent) {
1555
- throw insufficientStateError2(
1766
+ throw insufficientStateError(
1556
1767
  "private_record_nullifier_spent",
1557
1768
  "Private input note nullifier was already spent on-chain.",
1558
1769
  { recordId: record.id }
@@ -1564,15 +1775,6 @@ async function assertPrivateRecordsNullifiersAvailable(input) {
1564
1775
  // src/adapters/transfer-output-records.ts
1565
1776
  function buildTransferOutputRecords(intent, consumedTotal, walletPublicKey) {
1566
1777
  const recipientOwner = recipientOutputOwner(intent, walletPublicKey);
1567
- if (isPendingClaimSource(intent.from)) {
1568
- return [
1569
- createOutputRecord({
1570
- ...recipientOwner,
1571
- asset: intent.asset,
1572
- amount: intent.amount
1573
- })
1574
- ];
1575
- }
1576
1778
  const changeAmount = consumedTotal - intent.amount;
1577
1779
  const outputs = [
1578
1780
  createOutputRecord({
@@ -1679,7 +1881,8 @@ async function filterUnspentPrivateRecords(input) {
1679
1881
  const coin = requireCoinNoteFromRecord(record);
1680
1882
  const spent = await input.checkNullifierSpent({
1681
1883
  nullifier: coin.nullifier,
1682
- walletPublicKey: input.walletPublicKey
1884
+ walletPublicKey: input.walletPublicKey,
1885
+ ...record.privateAddress ? { privateAddressStpl1: record.privateAddress } : {}
1683
1886
  });
1684
1887
  if (!spent) {
1685
1888
  unspent.push(record);
@@ -1696,15 +1899,15 @@ function pickRecordsForSpendAmount(input) {
1696
1899
  if (selectedTotal >= input.amount) {
1697
1900
  return selected;
1698
1901
  }
1699
- if (input.kind === "transfer" && selected.length >= 2) {
1700
- throw insufficientStateError3(
1902
+ if ((input.kind === "transfer" || input.kind === "withdraw") && selected.length >= 2) {
1903
+ throw insufficientStateError2(
1701
1904
  "missing_private_records",
1702
1905
  "Storage does not contain enough private records for this operation.",
1703
1906
  { requestedAmount: input.amount, availableAmount: selectedTotal }
1704
1907
  );
1705
1908
  }
1706
1909
  }
1707
- throw insufficientStateError3(
1910
+ throw insufficientStateError2(
1708
1911
  "missing_private_records",
1709
1912
  "Storage does not contain enough private records for this operation.",
1710
1913
  { requestedAmount: input.amount, availableAmount: selectedTotal }
@@ -1713,7 +1916,7 @@ function pickRecordsForSpendAmount(input) {
1713
1916
  async function selectPrivateRecords(input) {
1714
1917
  const from = input.intent.from;
1715
1918
  if (!isPrivateAddressTransferFrom(from)) {
1716
- throw insufficientStateError3(
1919
+ throw insufficientStateError2(
1717
1920
  "invalid_transfer_source",
1718
1921
  "Private record selection requires a private address transfer source."
1719
1922
  );
@@ -1731,7 +1934,7 @@ async function selectPrivateRecords(input) {
1731
1934
  checkNullifierSpent: input.checkNullifierSpent
1732
1935
  }) : locallyAvailable;
1733
1936
  if (available.length === 0) {
1734
- throw insufficientStateError3(
1937
+ throw insufficientStateError2(
1735
1938
  "missing_private_records",
1736
1939
  "Storage does not contain enough private records for this operation.",
1737
1940
  { requestedAmount: input.intent.amount, availableAmount: 0n }
@@ -1759,11 +1962,10 @@ function buildSpendOutputRecords(input) {
1759
1962
  }
1760
1963
 
1761
1964
  // src/adapters/transfer-prepare.ts
1762
- import { insufficientStateError as insufficientStateError4 } from "@arcanetech/privacy-sdk-core";
1763
1965
  async function prepareTransferOperation(intent, deps) {
1966
+ const spend = await resolvePrivateAddressSpend(intent, deps);
1764
1967
  const walletAddress = await deps.wallet.getAddress();
1765
1968
  const walletPublicKey = walletAddress.trim();
1766
- const spend = isPendingClaimSource(intent.from) ? await resolvePendingClaimSpend(intent, deps, walletPublicKey) : await resolvePrivateAddressSpend(intent, deps);
1767
1969
  const consumedTotal = sumRecordAmounts(spend.consumedRecords);
1768
1970
  const prepared = {
1769
1971
  kind: "transfer",
@@ -1778,40 +1980,6 @@ async function prepareTransferOperation(intent, deps) {
1778
1980
  };
1779
1981
  return deps.engine.prepare(prepared);
1780
1982
  }
1781
- async function resolvePendingClaimSpend(intent, deps, walletPublicKey) {
1782
- if (!deps.getPendingClaims) {
1783
- throw insufficientStateError4(
1784
- "pending_claim_state_unavailable",
1785
- "Pending claim state is not available for this transfer."
1786
- );
1787
- }
1788
- const claim = await resolvePendingClaimSource({
1789
- from: intent.from,
1790
- walletPublicKey,
1791
- getPendingClaims: deps.getPendingClaims
1792
- });
1793
- assertPendingClaimOwner({ claim, walletPublicKey });
1794
- await assertPendingClaimNullifierAvailable({
1795
- claim,
1796
- walletPublicKey,
1797
- ...deps.checkNullifierSpent ? { checkNullifierSpent: deps.checkNullifierSpent } : {}
1798
- });
1799
- validatePendingClaimIntentMatches(claim, intent);
1800
- return {
1801
- consumedRecords: [
1802
- pendingClaimToConsumedRecord({
1803
- claim,
1804
- walletPublicKey,
1805
- poolContract: deps.poolContract
1806
- })
1807
- ],
1808
- transactArtifacts: {
1809
- pendingClaim: claim,
1810
- spendSource: "pendingClaim",
1811
- executeFinalizeRequired: true
1812
- }
1813
- };
1814
- }
1815
1983
  async function resolvePrivateAddressSpend(intent, deps) {
1816
1984
  const walletAddress = await deps.wallet.getAddress();
1817
1985
  const walletPublicKey = walletAddress.trim();
@@ -1834,37 +2002,6 @@ async function resolvePrivateAddressSpend(intent, deps) {
1834
2002
  }
1835
2003
  };
1836
2004
  }
1837
- function validatePendingClaimIntentMatches(claim, intent) {
1838
- if (claim.amount !== intent.amount) {
1839
- throw insufficientStateError4(
1840
- "pending_claim_amount_mismatch",
1841
- "Transfer amount must match the pending claim amount.",
1842
- { claimAmount: claim.amount, requestedAmount: intent.amount }
1843
- );
1844
- }
1845
- if (claim.asset !== intent.asset) {
1846
- throw insufficientStateError4(
1847
- "pending_claim_asset_mismatch",
1848
- "Transfer asset must match the pending claim asset."
1849
- );
1850
- }
1851
- }
1852
- async function assertPendingClaimNullifierAvailable(input) {
1853
- if (!input.checkNullifierSpent) {
1854
- return;
1855
- }
1856
- const nullifier = pendingClaimToCoin(input.claim).nullifier;
1857
- const spent = await input.checkNullifierSpent({
1858
- nullifier,
1859
- walletPublicKey: input.walletPublicKey
1860
- });
1861
- if (spent) {
1862
- throw insufficientStateError4(
1863
- "pending_claim_nullifier_spent",
1864
- "Pending claim nullifier was already spent on-chain."
1865
- );
1866
- }
1867
- }
1868
2005
 
1869
2006
  // src/adapters/network.ts
1870
2007
  function createStellarNetworkAdapter(deps) {
@@ -1948,9 +2085,6 @@ async function prepareOperation(input) {
1948
2085
  // src/state/foundation/paths.ts
1949
2086
  var STELLAR_STATE_PATHS = {
1950
2087
  privateRecords: "$.privateRecords",
1951
- pendingClaimsItems: "$.pendingClaims.items",
1952
- pendingClaimsPagination: "$.pendingClaims.pagination",
1953
- pendingClaimsCountByOwner: "$.pendingClaims.countByOwner",
1954
2088
  registryPrivateAddresses: "$.registry.privateAddresses",
1955
2089
  registryRegisteredAddresses: "$.registry.registeredAddresses",
1956
2090
  registryLookups: "$.registry.lookups",
@@ -1970,25 +2104,6 @@ var STELLAR_STATE_PATHS = {
1970
2104
 
1971
2105
  // src/state/schemas/shared.ts
1972
2106
  import { z } from "zod";
1973
- var pendingClaimSchema = z.object({
1974
- id: z.string().min(1),
1975
- owner: z.string().min(1),
1976
- asset: z.string().min(1),
1977
- amount: z.coerce.bigint(),
1978
- createdAt: z.string().min(1),
1979
- poolTxId: z.string().optional(),
1980
- commitmentHex: z.string().optional(),
1981
- nullifierHex: z.string().optional(),
1982
- futureNullifierHashHex: z.string().optional(),
1983
- assetHiHex: z.string().optional(),
1984
- assetLoHex: z.string().optional(),
1985
- nullifierFieldHex: z.string().optional(),
1986
- secretHex: z.string().optional(),
1987
- tempPublicKeyXHex: z.string().optional(),
1988
- tempPublicKeyYHex: z.string().optional(),
1989
- encryptedRecoveryBase64: z.string().optional(),
1990
- createdAtLedger: z.number().int().optional()
1991
- });
1992
2107
  var paginationSchema = z.object({
1993
2108
  total: z.number().int().nonnegative(),
1994
2109
  page: z.number().int().positive(),
@@ -2158,26 +2273,6 @@ function normalizePublicBalancesFromEntries(value, owner) {
2158
2273
  }).filter((balance) => balance !== void 0);
2159
2274
  }
2160
2275
 
2161
- // src/state/read/normalize/claims.ts
2162
- function normalizePendingClaimsState(value) {
2163
- if (typeof value !== "object" || value === null) {
2164
- return { items: [] };
2165
- }
2166
- const record = value;
2167
- const items = Array.isArray(record.items) ? record.items.flatMap((item) => {
2168
- const parsed = pendingClaimSchema.safeParse(item);
2169
- return parsed.success ? [withoutUndefinedFields(parsed.data)] : [];
2170
- }) : [];
2171
- const paginationResult = paginationSchema.safeParse(record.pagination);
2172
- if (paginationResult.success) {
2173
- return { items, pagination: paginationResult.data };
2174
- }
2175
- return { items };
2176
- }
2177
- function normalizePendingClaimsCount(value) {
2178
- return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
2179
- }
2180
-
2181
2276
  // src/state/read/normalize/deliveries.ts
2182
2277
  function normalizeIncomingDeliveries(value) {
2183
2278
  const entries = typeof value === "object" && value !== null && !Array.isArray(value) ? Object.values(value) : value;
@@ -2300,8 +2395,7 @@ import { registerArrayFilterItemSchema } from "@arcanetech/privacy-sdk-core/stat
2300
2395
 
2301
2396
  // src/state/filters/ops.ts
2302
2397
  var stellarArrayFilterSchemaKeys = {
2303
- privateRecord: "privateRecord",
2304
- pendingClaim: "pendingClaim"
2398
+ privateRecord: "privateRecord"
2305
2399
  };
2306
2400
  function rejectPrivateRecordsByIds(ids) {
2307
2401
  return {
@@ -2327,56 +2421,6 @@ function rejectConsumedPrivateRecords() {
2327
2421
  }
2328
2422
  };
2329
2423
  }
2330
- function rejectPendingClaimsByOwner(owner) {
2331
- return {
2332
- opType: "arrayFilter",
2333
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2334
- itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
2335
- rejectWhen: {
2336
- op: "fieldEquals",
2337
- field: "owner",
2338
- value: owner
2339
- }
2340
- };
2341
- }
2342
- function rejectPendingClaimsByIds(ids) {
2343
- return {
2344
- opType: "arrayFilter",
2345
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2346
- itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
2347
- rejectWhen: {
2348
- op: "fieldIn",
2349
- field: "id",
2350
- values: ids
2351
- }
2352
- };
2353
- }
2354
- function rejectPendingClaimsByOwnerAndAsset(input) {
2355
- const matches = [];
2356
- if (input.owner !== void 0) {
2357
- matches.push({
2358
- op: "fieldEquals",
2359
- field: "owner",
2360
- value: input.owner
2361
- });
2362
- }
2363
- if (input.asset !== void 0) {
2364
- matches.push({
2365
- op: "fieldEquals",
2366
- field: "asset",
2367
- value: input.asset
2368
- });
2369
- }
2370
- return {
2371
- opType: "arrayFilter",
2372
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2373
- itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
2374
- rejectWhen: {
2375
- op: "and",
2376
- matches
2377
- }
2378
- };
2379
- }
2380
2424
 
2381
2425
  // src/state/filters/register-schemas.ts
2382
2426
  var registered = false;
@@ -2388,24 +2432,12 @@ function registerStellarArrayFilterSchemas() {
2388
2432
  stellarArrayFilterSchemaKeys.privateRecord,
2389
2433
  privateRecordSchema
2390
2434
  );
2391
- registerArrayFilterItemSchema(
2392
- stellarArrayFilterSchemaKeys.pendingClaim,
2393
- pendingClaimSchema
2394
- );
2395
2435
  registered = true;
2396
2436
  }
2397
2437
 
2398
2438
  // src/state/bridge/call-types.ts
2399
2439
  import "@arcanetech/privacy-sdk-core/state";
2400
2440
  var stellarStateCallTypes = {
2401
- pendingClaims: "pendingClaims",
2402
- clearPendingClaims: "clearPendingClaims",
2403
- readPendingClaims: "readPendingClaims",
2404
- replacePendingClaimsPage: "replacePendingClaimsPage",
2405
- upsertPendingClaims: "upsertPendingClaims",
2406
- removePendingClaims: "removePendingClaims",
2407
- setPendingClaimsCount: "setPendingClaimsCount",
2408
- readPendingClaimsCount: "readPendingClaimsCount",
2409
2441
  readStellarAddressRegistered: "readStellarAddressRegistered",
2410
2442
  readCachedPrivateAddress: "readCachedPrivateAddress",
2411
2443
  readRegistryLookup: "readRegistryLookup",
@@ -2583,243 +2615,59 @@ var readPublicBalancesSchema = z4.object({
2583
2615
  var setPublicBalanceSchema = z4.object({
2584
2616
  type: z4.literal(stellarStateCallTypes.setPublicBalance),
2585
2617
  balance: publicBalanceSchema
2586
- }).transform(({ type, balance }) => ({
2587
- type,
2588
- operations: [
2589
- {
2590
- opType: "recordSet",
2591
- jsonPath: STELLAR_STATE_PATHS.publicBalances,
2592
- key: ownerAssetKey(balance.owner, balance.asset),
2593
- value: balance
2594
- }
2595
- ]
2596
- }));
2597
- var setPublicBalancesSchema = z4.object({
2598
- type: z4.literal(stellarStateCallTypes.setPublicBalances),
2599
- owner: z4.string().min(1),
2600
- balances: z4.array(publicBalanceSchema)
2601
- }).transform(({ type, owner, balances }) => ({
2602
- type,
2603
- operations: balances.map((balance) => ({
2604
- opType: "recordSet",
2605
- jsonPath: STELLAR_STATE_PATHS.publicBalances,
2606
- key: ownerAssetKey(owner, balance.asset),
2607
- value: { ...balance, owner }
2608
- }))
2609
- }));
2610
-
2611
- // src/state/definitions/balances.ts
2612
- var stellarBalancesStateDefinitions = [
2613
- {
2614
- type: stellarStateCallTypes.readPublicBalance,
2615
- mode: "read",
2616
- schema: readPublicBalanceSchema
2617
- },
2618
- {
2619
- type: stellarStateCallTypes.readPublicBalances,
2620
- mode: "read",
2621
- schema: readPublicBalancesSchema
2622
- },
2623
- {
2624
- type: stellarStateCallTypes.setPublicBalance,
2625
- mode: "write",
2626
- schema: setPublicBalanceSchema
2627
- },
2628
- {
2629
- type: stellarStateCallTypes.setPublicBalances,
2630
- mode: "write",
2631
- schema: setPublicBalancesSchema
2632
- }
2633
- ];
2634
-
2635
- // src/state/schemas/claims/write.ts
2636
- import { z as z5 } from "zod";
2637
- var pendingClaimsWriteSchema = z5.object({
2638
- type: z5.literal(stellarStateCallTypes.pendingClaims),
2639
- claims: z5.array(pendingClaimSchema),
2640
- paginationInfo: paginationSchema
2641
- }).transform(({ type, claims, paginationInfo }) => ({
2642
- type,
2643
- operations: [
2644
- {
2645
- opType: "arrayPush",
2646
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2647
- items: claims
2648
- },
2649
- {
2650
- opType: "primitiveSet",
2651
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsPagination,
2652
- value: paginationInfo
2653
- }
2654
- ]
2655
- }));
2656
- var clearPendingClaimsSchema = z5.object({
2657
- type: z5.literal(stellarStateCallTypes.clearPendingClaims),
2658
- owner: z5.string().optional(),
2659
- asset: z5.string().optional()
2660
- }).transform(({ type, owner, asset }) => {
2661
- if (owner === void 0 && asset === void 0) {
2662
- return {
2663
- type,
2664
- operations: [
2665
- {
2666
- opType: "arrayClean",
2667
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems
2668
- }
2669
- ]
2670
- };
2671
- }
2672
- return {
2673
- type,
2674
- operations: [rejectPendingClaimsByOwnerAndAsset({ owner, asset })]
2675
- };
2676
- });
2677
- var readPendingClaimsSchema = z5.object({
2678
- type: z5.literal(stellarStateCallTypes.readPendingClaims)
2679
- }).transform(({ type }) => ({
2680
- type,
2681
- operations: [
2682
- {
2683
- opType: "primitiveGet",
2684
- jsonPath: "$.pendingClaims"
2685
- }
2686
- ]
2687
- }));
2688
-
2689
- // src/state/schemas/claims/page.ts
2690
- import { z as z6 } from "zod";
2691
- var pendingClaimBridgeItemSchema = pendingClaimSchema;
2692
- var replacePendingClaimsPageSchema = z6.object({
2693
- type: z6.literal(stellarStateCallTypes.replacePendingClaimsPage),
2694
- owner: z6.string().min(1),
2695
- claims: z6.array(pendingClaimBridgeItemSchema),
2696
- paginationInfo: z6.object({
2697
- total: z6.number().int().nonnegative(),
2698
- page: z6.number().int().positive(),
2699
- pageSize: z6.number().int().positive(),
2700
- hasMore: z6.boolean()
2701
- }),
2702
- count: z6.number().int().nonnegative().optional()
2703
- }).transform(({ type, owner, claims, paginationInfo, count }) => ({
2704
- type,
2705
- operations: [
2706
- rejectPendingClaimsByOwner(owner),
2707
- {
2708
- opType: "arrayPush",
2709
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2710
- items: claims
2711
- },
2712
- {
2713
- opType: "primitiveSet",
2714
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsPagination,
2715
- value: paginationInfo
2716
- },
2717
- {
2718
- opType: "recordSet",
2719
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
2720
- key: owner,
2721
- value: count ?? paginationInfo.total
2722
- }
2723
- ]
2724
- }));
2725
- var upsertPendingClaimsSchema = z6.object({
2726
- type: z6.literal(stellarStateCallTypes.upsertPendingClaims),
2727
- claims: z6.array(pendingClaimBridgeItemSchema)
2728
- }).transform(({ type, claims }) => ({
2729
- type,
2730
- operations: [
2731
- rejectPendingClaimsByIds(claims.map((claim) => claim.id)),
2732
- {
2733
- opType: "arrayPush",
2734
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
2735
- items: claims
2736
- }
2737
- ]
2738
- }));
2739
- var removePendingClaimsSchema = z6.object({
2740
- type: z6.literal(stellarStateCallTypes.removePendingClaims),
2741
- ids: z6.array(z6.string().min(1))
2742
- }).transform(({ type, ids }) => ({
2743
- type,
2744
- operations: [rejectPendingClaimsByIds(ids)]
2745
- }));
2746
- var readPendingClaimsCountSchema = z6.object({
2747
- type: z6.literal(stellarStateCallTypes.readPendingClaimsCount),
2748
- owner: z6.string().min(1)
2749
- }).transform(({ type, owner }) => ({
2750
- type,
2751
- operations: [
2752
- {
2753
- opType: "recordGet",
2754
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
2755
- key: owner
2756
- }
2757
- ]
2758
- }));
2759
- var setPendingClaimsCountSchema = z6.object({
2760
- type: z6.literal(stellarStateCallTypes.setPendingClaimsCount),
2761
- owner: z6.string().min(1),
2762
- count: z6.number().int().nonnegative()
2763
- }).transform(({ type, owner, count }) => ({
2618
+ }).transform(({ type, balance }) => ({
2764
2619
  type,
2765
2620
  operations: [
2766
2621
  {
2767
2622
  opType: "recordSet",
2768
- jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
2769
- key: owner,
2770
- value: count
2623
+ jsonPath: STELLAR_STATE_PATHS.publicBalances,
2624
+ key: ownerAssetKey(balance.owner, balance.asset),
2625
+ value: balance
2771
2626
  }
2772
2627
  ]
2773
2628
  }));
2629
+ var setPublicBalancesSchema = z4.object({
2630
+ type: z4.literal(stellarStateCallTypes.setPublicBalances),
2631
+ owner: z4.string().min(1),
2632
+ balances: z4.array(publicBalanceSchema)
2633
+ }).transform(({ type, owner, balances }) => ({
2634
+ type,
2635
+ operations: balances.map((balance) => ({
2636
+ opType: "recordSet",
2637
+ jsonPath: STELLAR_STATE_PATHS.publicBalances,
2638
+ key: ownerAssetKey(owner, balance.asset),
2639
+ value: { ...balance, owner }
2640
+ }))
2641
+ }));
2774
2642
 
2775
- // src/state/definitions/claims.ts
2776
- var stellarClaimsStateDefinitions = [
2777
- {
2778
- type: stellarStateCallTypes.pendingClaims,
2779
- mode: "write",
2780
- schema: pendingClaimsWriteSchema
2781
- },
2782
- {
2783
- type: stellarStateCallTypes.clearPendingClaims,
2784
- mode: "write",
2785
- schema: clearPendingClaimsSchema
2786
- },
2643
+ // src/state/definitions/balances.ts
2644
+ var stellarBalancesStateDefinitions = [
2787
2645
  {
2788
- type: stellarStateCallTypes.readPendingClaims,
2646
+ type: stellarStateCallTypes.readPublicBalance,
2789
2647
  mode: "read",
2790
- schema: readPendingClaimsSchema
2791
- },
2792
- {
2793
- type: stellarStateCallTypes.replacePendingClaimsPage,
2794
- mode: "write",
2795
- schema: replacePendingClaimsPageSchema
2648
+ schema: readPublicBalanceSchema
2796
2649
  },
2797
2650
  {
2798
- type: stellarStateCallTypes.upsertPendingClaims,
2799
- mode: "write",
2800
- schema: upsertPendingClaimsSchema
2651
+ type: stellarStateCallTypes.readPublicBalances,
2652
+ mode: "read",
2653
+ schema: readPublicBalancesSchema
2801
2654
  },
2802
2655
  {
2803
- type: stellarStateCallTypes.removePendingClaims,
2656
+ type: stellarStateCallTypes.setPublicBalance,
2804
2657
  mode: "write",
2805
- schema: removePendingClaimsSchema
2806
- },
2807
- {
2808
- type: stellarStateCallTypes.readPendingClaimsCount,
2809
- mode: "read",
2810
- schema: readPendingClaimsCountSchema
2658
+ schema: setPublicBalanceSchema
2811
2659
  },
2812
2660
  {
2813
- type: stellarStateCallTypes.setPendingClaimsCount,
2661
+ type: stellarStateCallTypes.setPublicBalances,
2814
2662
  mode: "write",
2815
- schema: setPendingClaimsCountSchema
2663
+ schema: setPublicBalancesSchema
2816
2664
  }
2817
2665
  ];
2818
2666
 
2819
2667
  // src/state/schemas/claims/deliveries.ts
2820
- import { z as z7 } from "zod";
2821
- var readIncomingDeliveriesSchema = z7.object({
2822
- type: z7.literal(stellarStateCallTypes.readIncomingDeliveries)
2668
+ import { z as z5 } from "zod";
2669
+ var readIncomingDeliveriesSchema = z5.object({
2670
+ type: z5.literal(stellarStateCallTypes.readIncomingDeliveries)
2823
2671
  }).transform(({ type }) => ({
2824
2672
  type,
2825
2673
  operations: [
@@ -2829,9 +2677,9 @@ var readIncomingDeliveriesSchema = z7.object({
2829
2677
  }
2830
2678
  ]
2831
2679
  }));
2832
- var upsertIncomingDeliveriesSchema = z7.object({
2833
- type: z7.literal(stellarStateCallTypes.upsertIncomingDeliveries),
2834
- deliveries: z7.array(incomingDeliverySchema)
2680
+ var upsertIncomingDeliveriesSchema = z5.object({
2681
+ type: z5.literal(stellarStateCallTypes.upsertIncomingDeliveries),
2682
+ deliveries: z5.array(incomingDeliverySchema)
2835
2683
  }).transform(({ type, deliveries }) => ({
2836
2684
  type,
2837
2685
  operations: deliveries.map((delivery) => ({
@@ -2841,10 +2689,10 @@ var upsertIncomingDeliveriesSchema = z7.object({
2841
2689
  value: delivery
2842
2690
  }))
2843
2691
  }));
2844
- var readDeliverySyncStateSchema = z7.object({
2845
- type: z7.literal(stellarStateCallTypes.readDeliverySyncState),
2846
- privateAddress: z7.string().min(1),
2847
- asset: z7.string().min(1)
2692
+ var readDeliverySyncStateSchema = z5.object({
2693
+ type: z5.literal(stellarStateCallTypes.readDeliverySyncState),
2694
+ privateAddress: z5.string().min(1),
2695
+ asset: z5.string().min(1)
2848
2696
  }).transform(({ type, privateAddress, asset }) => ({
2849
2697
  type,
2850
2698
  operations: [
@@ -2855,8 +2703,8 @@ var readDeliverySyncStateSchema = z7.object({
2855
2703
  }
2856
2704
  ]
2857
2705
  }));
2858
- var setDeliverySyncStateSchema = z7.object({
2859
- type: z7.literal(stellarStateCallTypes.setDeliverySyncState),
2706
+ var setDeliverySyncStateSchema = z5.object({
2707
+ type: z5.literal(stellarStateCallTypes.setDeliverySyncState),
2860
2708
  syncState: deliverySyncStateSchema
2861
2709
  }).transform(({ type, syncState }) => ({
2862
2710
  type,
@@ -2895,10 +2743,10 @@ var stellarDeliveriesStateDefinitions = [
2895
2743
  ];
2896
2744
 
2897
2745
  // src/state/schemas/pool/merkle.ts
2898
- import { z as z8 } from "zod";
2899
- var readPoolMerkleStateSchema = z8.object({
2900
- type: z8.literal(stellarStateCallTypes.readPoolMerkleState),
2901
- poolContract: z8.string().min(1)
2746
+ import { z as z6 } from "zod";
2747
+ var readPoolMerkleStateSchema = z6.object({
2748
+ type: z6.literal(stellarStateCallTypes.readPoolMerkleState),
2749
+ poolContract: z6.string().min(1)
2902
2750
  }).transform(({ type, poolContract }) => ({
2903
2751
  type,
2904
2752
  operations: [
@@ -2909,8 +2757,8 @@ var readPoolMerkleStateSchema = z8.object({
2909
2757
  }
2910
2758
  ]
2911
2759
  }));
2912
- var setPoolMerkleStateSchema = z8.object({
2913
- type: z8.literal(stellarStateCallTypes.setPoolMerkleState),
2760
+ var setPoolMerkleStateSchema = z6.object({
2761
+ type: z6.literal(stellarStateCallTypes.setPoolMerkleState),
2914
2762
  state: poolMerkleStateSchema
2915
2763
  }).transform(({ type, state }) => ({
2916
2764
  type,
@@ -2923,10 +2771,10 @@ var setPoolMerkleStateSchema = z8.object({
2923
2771
  }
2924
2772
  ]
2925
2773
  }));
2926
- var readLeafEphemeralSchema = z8.object({
2927
- type: z8.literal(stellarStateCallTypes.readLeafEphemeral),
2928
- poolContract: z8.string().min(1),
2929
- leafIndex: z8.number().int().nonnegative()
2774
+ var readLeafEphemeralSchema = z6.object({
2775
+ type: z6.literal(stellarStateCallTypes.readLeafEphemeral),
2776
+ poolContract: z6.string().min(1),
2777
+ leafIndex: z6.number().int().nonnegative()
2930
2778
  }).transform(({ type, poolContract, leafIndex }) => ({
2931
2779
  type,
2932
2780
  operations: [
@@ -2937,8 +2785,8 @@ var readLeafEphemeralSchema = z8.object({
2937
2785
  }
2938
2786
  ]
2939
2787
  }));
2940
- var setLeafEphemeralSchema = z8.object({
2941
- type: z8.literal(stellarStateCallTypes.setLeafEphemeral),
2788
+ var setLeafEphemeralSchema = z6.object({
2789
+ type: z6.literal(stellarStateCallTypes.setLeafEphemeral),
2942
2790
  ephemeral: leafEphemeralSchema
2943
2791
  }).transform(({ type, ephemeral }) => ({
2944
2792
  type,
@@ -2977,9 +2825,9 @@ var stellarPoolStateDefinitions = [
2977
2825
  ];
2978
2826
 
2979
2827
  // src/state/schemas/records/private.ts
2980
- import { z as z9 } from "zod";
2981
- var listPrivateRecordsSchema = z9.object({
2982
- type: z9.literal(stellarStateCallTypes.listPrivateRecords)
2828
+ import { z as z7 } from "zod";
2829
+ var listPrivateRecordsSchema = z7.object({
2830
+ type: z7.literal(stellarStateCallTypes.listPrivateRecords)
2983
2831
  }).transform(({ type }) => ({
2984
2832
  type,
2985
2833
  operations: [
@@ -2989,9 +2837,9 @@ var listPrivateRecordsSchema = z9.object({
2989
2837
  }
2990
2838
  ]
2991
2839
  }));
2992
- var savePrivateRecordsSchema = z9.object({
2993
- type: z9.literal(stellarStateCallTypes.savePrivateRecords),
2994
- records: z9.array(privateRecordSchema)
2840
+ var savePrivateRecordsSchema = z7.object({
2841
+ type: z7.literal(stellarStateCallTypes.savePrivateRecords),
2842
+ records: z7.array(privateRecordSchema)
2995
2843
  }).transform(({ type, records }) => ({
2996
2844
  type,
2997
2845
  operations: [
@@ -3002,9 +2850,9 @@ var savePrivateRecordsSchema = z9.object({
3002
2850
  }
3003
2851
  ]
3004
2852
  }));
3005
- var replacePrivateRecordsSchema = z9.object({
3006
- type: z9.literal(stellarStateCallTypes.replacePrivateRecords),
3007
- records: z9.array(privateRecordSchema)
2853
+ var replacePrivateRecordsSchema = z7.object({
2854
+ type: z7.literal(stellarStateCallTypes.replacePrivateRecords),
2855
+ records: z7.array(privateRecordSchema)
3008
2856
  }).transform(({ type, records }) => ({
3009
2857
  type,
3010
2858
  operations: [
@@ -3019,18 +2867,18 @@ var replacePrivateRecordsSchema = z9.object({
3019
2867
  }
3020
2868
  ]
3021
2869
  }));
3022
- var pruneConsumedPrivateRecordsSchema = z9.object({
3023
- type: z9.literal(stellarStateCallTypes.pruneConsumedPrivateRecords)
2870
+ var pruneConsumedPrivateRecordsSchema = z7.object({
2871
+ type: z7.literal(stellarStateCallTypes.pruneConsumedPrivateRecords)
3024
2872
  }).transform(({ type }) => ({
3025
2873
  type,
3026
2874
  operations: [rejectConsumedPrivateRecords()]
3027
2875
  }));
3028
2876
 
3029
2877
  // src/state/schemas/records/transactions.ts
3030
- import { z as z10 } from "zod";
3031
- var upsertPrivateRecordsSchema = z10.object({
3032
- type: z10.literal(stellarStateCallTypes.upsertPrivateRecords),
3033
- records: z10.array(privateRecordSchema)
2878
+ import { z as z8 } from "zod";
2879
+ var upsertPrivateRecordsSchema = z8.object({
2880
+ type: z8.literal(stellarStateCallTypes.upsertPrivateRecords),
2881
+ records: z8.array(privateRecordSchema)
3034
2882
  }).transform(({ type, records }) => ({
3035
2883
  type,
3036
2884
  operations: [
@@ -3042,9 +2890,9 @@ var upsertPrivateRecordsSchema = z10.object({
3042
2890
  }
3043
2891
  ]
3044
2892
  }));
3045
- var readTransactionStatusSchema = z10.object({
3046
- type: z10.literal(stellarStateCallTypes.readTransactionStatus),
3047
- txHash: z10.string().min(1)
2893
+ var readTransactionStatusSchema = z8.object({
2894
+ type: z8.literal(stellarStateCallTypes.readTransactionStatus),
2895
+ txHash: z8.string().min(1)
3048
2896
  }).transform(({ type, txHash }) => ({
3049
2897
  type,
3050
2898
  operations: [
@@ -3055,8 +2903,8 @@ var readTransactionStatusSchema = z10.object({
3055
2903
  }
3056
2904
  ]
3057
2905
  }));
3058
- var setTransactionStatusSchema = z10.object({
3059
- type: z10.literal(stellarStateCallTypes.setTransactionStatus),
2906
+ var setTransactionStatusSchema = z8.object({
2907
+ type: z8.literal(stellarStateCallTypes.setTransactionStatus),
3060
2908
  status: transactionStatusSchema
3061
2909
  }).transform(({ type, status }) => ({
3062
2910
  type,
@@ -3069,9 +2917,9 @@ var setTransactionStatusSchema = z10.object({
3069
2917
  }
3070
2918
  ]
3071
2919
  }));
3072
- var clearTransactionStatusSchema = z10.object({
3073
- type: z10.literal(stellarStateCallTypes.clearTransactionStatus),
3074
- txHash: z10.string().min(1)
2920
+ var clearTransactionStatusSchema = z8.object({
2921
+ type: z8.literal(stellarStateCallTypes.clearTransactionStatus),
2922
+ txHash: z8.string().min(1)
3075
2923
  }).transform(({ type, txHash }) => ({
3076
2924
  type,
3077
2925
  operations: [
@@ -3113,10 +2961,10 @@ var stellarRecordsStateDefinitions = [
3113
2961
  ];
3114
2962
 
3115
2963
  // src/state/schemas/registry/lookup.ts
3116
- import { z as z11 } from "zod";
3117
- var readStellarAddressRegisteredSchema = z11.object({
3118
- type: z11.literal(stellarStateCallTypes.readStellarAddressRegistered),
3119
- address: z11.string().min(1)
2964
+ import { z as z9 } from "zod";
2965
+ var readStellarAddressRegisteredSchema = z9.object({
2966
+ type: z9.literal(stellarStateCallTypes.readStellarAddressRegistered),
2967
+ address: z9.string().min(1)
3120
2968
  }).transform(({ type, address }) => ({
3121
2969
  type,
3122
2970
  operations: [
@@ -3127,9 +2975,9 @@ var readStellarAddressRegisteredSchema = z11.object({
3127
2975
  }
3128
2976
  ]
3129
2977
  }));
3130
- var readCachedPrivateAddressSchema = z11.object({
3131
- type: z11.literal(stellarStateCallTypes.readCachedPrivateAddress),
3132
- address: z11.string().min(1)
2978
+ var readCachedPrivateAddressSchema = z9.object({
2979
+ type: z9.literal(stellarStateCallTypes.readCachedPrivateAddress),
2980
+ address: z9.string().min(1)
3133
2981
  }).transform(({ type, address }) => ({
3134
2982
  type,
3135
2983
  operations: [
@@ -3140,11 +2988,11 @@ var readCachedPrivateAddressSchema = z11.object({
3140
2988
  }
3141
2989
  ]
3142
2990
  }));
3143
- var saveRegisteredPrivateAddressSchema = z11.object({
3144
- type: z11.literal(stellarStateCallTypes.saveRegisteredPrivateAddress),
3145
- address: z11.string().min(1),
3146
- privateAddress: z11.string().min(1),
3147
- registered: z11.boolean()
2991
+ var saveRegisteredPrivateAddressSchema = z9.object({
2992
+ type: z9.literal(stellarStateCallTypes.saveRegisteredPrivateAddress),
2993
+ address: z9.string().min(1),
2994
+ privateAddress: z9.string().min(1),
2995
+ registered: z9.boolean()
3148
2996
  }).transform(({ type, address, privateAddress, registered: registered2 }) => {
3149
2997
  const lookup = registryLookupSchema.parse({
3150
2998
  owner: address,
@@ -3176,9 +3024,9 @@ var saveRegisteredPrivateAddressSchema = z11.object({
3176
3024
  ]
3177
3025
  };
3178
3026
  });
3179
- var invalidateRegisteredAddressSchema = z11.object({
3180
- type: z11.literal(stellarStateCallTypes.invalidateRegisteredAddress),
3181
- address: z11.string().min(1)
3027
+ var invalidateRegisteredAddressSchema = z9.object({
3028
+ type: z9.literal(stellarStateCallTypes.invalidateRegisteredAddress),
3029
+ address: z9.string().min(1)
3182
3030
  }).transform(({ type, address }) => ({
3183
3031
  type,
3184
3032
  operations: [
@@ -3199,9 +3047,9 @@ var invalidateRegisteredAddressSchema = z11.object({
3199
3047
  }
3200
3048
  ]
3201
3049
  }));
3202
- var readRegistryLookupSchema = z11.object({
3203
- type: z11.literal(stellarStateCallTypes.readRegistryLookup),
3204
- address: z11.string().min(1)
3050
+ var readRegistryLookupSchema = z9.object({
3051
+ type: z9.literal(stellarStateCallTypes.readRegistryLookup),
3052
+ address: z9.string().min(1)
3205
3053
  }).transform(({ type, address }) => ({
3206
3054
  type,
3207
3055
  operations: [
@@ -3212,8 +3060,8 @@ var readRegistryLookupSchema = z11.object({
3212
3060
  }
3213
3061
  ]
3214
3062
  }));
3215
- var saveRegistryLookupSchema = z11.object({
3216
- type: z11.literal(stellarStateCallTypes.saveRegistryLookup),
3063
+ var saveRegistryLookupSchema = z9.object({
3064
+ type: z9.literal(stellarStateCallTypes.saveRegistryLookup),
3217
3065
  lookup: registryLookupSchema
3218
3066
  }).transform(({ type, lookup }) => {
3219
3067
  const operations = [
@@ -3249,9 +3097,9 @@ var saveRegistryLookupSchema = z11.object({
3249
3097
  }
3250
3098
  return { type, operations };
3251
3099
  });
3252
- var invalidateRegistryLookupSchema = z11.object({
3253
- type: z11.literal(stellarStateCallTypes.invalidateRegistryLookup),
3254
- address: z11.string().min(1)
3100
+ var invalidateRegistryLookupSchema = z9.object({
3101
+ type: z9.literal(stellarStateCallTypes.invalidateRegistryLookup),
3102
+ address: z9.string().min(1)
3255
3103
  }).transform(({ type, address }) => ({
3256
3104
  type,
3257
3105
  operations: [
@@ -3332,9 +3180,9 @@ var stellarTransactionStateDefinitions = [
3332
3180
  ];
3333
3181
 
3334
3182
  // src/state/schemas/wallet/scalar.ts
3335
- import { z as z12 } from "zod";
3336
- var saveWalletPrivateAddressScalarSchema = z12.object({
3337
- type: z12.literal(stellarStateCallTypes.saveWalletPrivateAddressScalar),
3183
+ import { z as z10 } from "zod";
3184
+ var saveWalletPrivateAddressScalarSchema = z10.object({
3185
+ type: z10.literal(stellarStateCallTypes.saveWalletPrivateAddressScalar),
3338
3186
  scalar: walletPrivateAddressScalarSchema
3339
3187
  }).transform(({ type, scalar }) => ({
3340
3188
  type,
@@ -3347,10 +3195,10 @@ var saveWalletPrivateAddressScalarSchema = z12.object({
3347
3195
  }
3348
3196
  ]
3349
3197
  }));
3350
- var readWalletPrivateAddressScalarSchema = z12.object({
3351
- type: z12.literal(stellarStateCallTypes.readWalletPrivateAddressScalar),
3352
- owner: z12.string().min(1),
3353
- nonce: z12.string().min(1)
3198
+ var readWalletPrivateAddressScalarSchema = z10.object({
3199
+ type: z10.literal(stellarStateCallTypes.readWalletPrivateAddressScalar),
3200
+ owner: z10.string().min(1),
3201
+ nonce: z10.string().min(1)
3354
3202
  }).transform(({ type, owner, nonce }) => ({
3355
3203
  type,
3356
3204
  operations: [
@@ -3363,9 +3211,9 @@ var readWalletPrivateAddressScalarSchema = z12.object({
3363
3211
  }));
3364
3212
 
3365
3213
  // src/state/schemas/wallet/private-address.ts
3366
- import { z as z13 } from "zod";
3367
- var saveWalletPrivateAddressRecordSchema = z13.object({
3368
- type: z13.literal(stellarStateCallTypes.saveWalletPrivateAddressRecord),
3214
+ import { z as z11 } from "zod";
3215
+ var saveWalletPrivateAddressRecordSchema = z11.object({
3216
+ type: z11.literal(stellarStateCallTypes.saveWalletPrivateAddressRecord),
3369
3217
  record: walletPrivateAddressRecordSchema
3370
3218
  }).transform(({ type, record }) => ({
3371
3219
  type,
@@ -3378,10 +3226,10 @@ var saveWalletPrivateAddressRecordSchema = z13.object({
3378
3226
  }
3379
3227
  ]
3380
3228
  }));
3381
- var readWalletPrivateAddressRecordSchema = z13.object({
3382
- type: z13.literal(stellarStateCallTypes.readWalletPrivateAddressRecord),
3383
- owner: z13.string().min(1),
3384
- nonce: z13.string().min(1)
3229
+ var readWalletPrivateAddressRecordSchema = z11.object({
3230
+ type: z11.literal(stellarStateCallTypes.readWalletPrivateAddressRecord),
3231
+ owner: z11.string().min(1),
3232
+ nonce: z11.string().min(1)
3385
3233
  }).transform(({ type, owner, nonce }) => ({
3386
3234
  type,
3387
3235
  operations: [
@@ -3392,10 +3240,10 @@ var readWalletPrivateAddressRecordSchema = z13.object({
3392
3240
  }
3393
3241
  ]
3394
3242
  }));
3395
- var setWalletDefaultPrivateAddressNonceSchema = z13.object({
3396
- type: z13.literal(stellarStateCallTypes.setWalletDefaultPrivateAddressNonce),
3397
- owner: z13.string().min(1),
3398
- nonce: z13.string().min(1)
3243
+ var setWalletDefaultPrivateAddressNonceSchema = z11.object({
3244
+ type: z11.literal(stellarStateCallTypes.setWalletDefaultPrivateAddressNonce),
3245
+ owner: z11.string().min(1),
3246
+ nonce: z11.string().min(1)
3399
3247
  }).transform(({ type, owner, nonce }) => ({
3400
3248
  type,
3401
3249
  operations: [
@@ -3407,9 +3255,9 @@ var setWalletDefaultPrivateAddressNonceSchema = z13.object({
3407
3255
  }
3408
3256
  ]
3409
3257
  }));
3410
- var readWalletDefaultPrivateAddressNonceSchema = z13.object({
3411
- type: z13.literal(stellarStateCallTypes.readWalletDefaultPrivateAddressNonce),
3412
- owner: z13.string().min(1)
3258
+ var readWalletDefaultPrivateAddressNonceSchema = z11.object({
3259
+ type: z11.literal(stellarStateCallTypes.readWalletDefaultPrivateAddressNonce),
3260
+ owner: z11.string().min(1)
3413
3261
  }).transform(({ type, owner }) => ({
3414
3262
  type,
3415
3263
  operations: [
@@ -3420,10 +3268,10 @@ var readWalletDefaultPrivateAddressNonceSchema = z13.object({
3420
3268
  }
3421
3269
  ]
3422
3270
  }));
3423
- var deleteWalletPrivateAddressScalarSchema = z13.object({
3424
- type: z13.literal(stellarStateCallTypes.deleteWalletPrivateAddressScalar),
3425
- owner: z13.string().min(1),
3426
- nonce: z13.string().min(1)
3271
+ var deleteWalletPrivateAddressScalarSchema = z11.object({
3272
+ type: z11.literal(stellarStateCallTypes.deleteWalletPrivateAddressScalar),
3273
+ owner: z11.string().min(1),
3274
+ nonce: z11.string().min(1)
3427
3275
  }).transform(({ type, owner, nonce }) => ({
3428
3276
  type,
3429
3277
  operations: [
@@ -3477,7 +3325,6 @@ var stellarWalletStateDefinitions = [
3477
3325
  // src/state/definitions/index.ts
3478
3326
  registerStellarArrayFilterSchemas();
3479
3327
  var stellarStateDefinitions = [
3480
- ...stellarClaimsStateDefinitions,
3481
3328
  ...stellarRegistryStateDefinitions,
3482
3329
  ...stellarAssetsStateDefinitions,
3483
3330
  ...stellarBalancesStateDefinitions,
@@ -3608,108 +3455,6 @@ function createAssetsService(context) {
3608
3455
  };
3609
3456
  }
3610
3457
 
3611
- // src/state/service/claims/read-methods.ts
3612
- function createClaimsReadMethods(context) {
3613
- const { bridge } = context;
3614
- async function getPendingClaims(filter = {}) {
3615
- const value = await bridge.read({
3616
- type: stellarStateCallTypes.readPendingClaims
3617
- });
3618
- const state = normalizePendingClaimsState(value);
3619
- const items = state.items.filter((claim) => {
3620
- if (filter.owner !== void 0 && claim.owner !== filter.owner) {
3621
- return false;
3622
- }
3623
- if (filter.asset !== void 0 && claim.asset !== filter.asset) {
3624
- return false;
3625
- }
3626
- return true;
3627
- });
3628
- if (state.pagination !== void 0) {
3629
- return { items, pagination: state.pagination };
3630
- }
3631
- return { items };
3632
- }
3633
- return {
3634
- getPendingClaims,
3635
- async getPendingClaimsCount(owner) {
3636
- const value = await bridge.read({
3637
- type: stellarStateCallTypes.readPendingClaimsCount,
3638
- owner
3639
- });
3640
- const count = normalizePendingClaimsCount(value);
3641
- if (count !== void 0) {
3642
- return count;
3643
- }
3644
- const claims = await getPendingClaims({ owner });
3645
- return claims.items.length;
3646
- }
3647
- };
3648
- }
3649
-
3650
- // src/state/service/claims/write-methods.ts
3651
- function appendPendingClaims(bridge, claims, paginationInfo) {
3652
- return bridge.write({
3653
- type: stellarStateCallTypes.pendingClaims,
3654
- claims,
3655
- paginationInfo
3656
- });
3657
- }
3658
- function replacePendingClaimsPage(bridge, input) {
3659
- return bridge.write({
3660
- type: stellarStateCallTypes.replacePendingClaimsPage,
3661
- owner: input.owner,
3662
- claims: input.claims,
3663
- paginationInfo: input.paginationInfo,
3664
- ...input.count === void 0 ? {} : { count: input.count }
3665
- });
3666
- }
3667
- function upsertPendingClaims(bridge, claims) {
3668
- return bridge.write({
3669
- type: stellarStateCallTypes.upsertPendingClaims,
3670
- claims
3671
- });
3672
- }
3673
- function removePendingClaims(bridge, ids) {
3674
- return bridge.write({
3675
- type: stellarStateCallTypes.removePendingClaims,
3676
- ids
3677
- });
3678
- }
3679
- function clearPendingClaims(bridge, input = {}) {
3680
- return bridge.write({
3681
- type: stellarStateCallTypes.clearPendingClaims,
3682
- ...input.owner === void 0 ? {} : { owner: input.owner },
3683
- ...input.asset === void 0 ? {} : { asset: input.asset }
3684
- });
3685
- }
3686
- function setPendingClaimsCount(bridge, owner, count) {
3687
- return bridge.write({
3688
- type: stellarStateCallTypes.setPendingClaimsCount,
3689
- owner,
3690
- count
3691
- });
3692
- }
3693
- function createClaimsWriteMethods(context) {
3694
- const { bridge } = context;
3695
- return {
3696
- appendPendingClaims: (claims, paginationInfo) => appendPendingClaims(bridge, claims, paginationInfo),
3697
- replacePendingClaimsPage: (input) => replacePendingClaimsPage(bridge, input),
3698
- upsertPendingClaims: (claims) => upsertPendingClaims(bridge, claims),
3699
- removePendingClaims: (ids) => removePendingClaims(bridge, ids),
3700
- clearPendingClaims: (input = {}) => clearPendingClaims(bridge, input),
3701
- setPendingClaimsCount: (owner, count) => setPendingClaimsCount(bridge, owner, count)
3702
- };
3703
- }
3704
-
3705
- // src/state/service/claims/index.ts
3706
- function createClaimsService(context) {
3707
- return {
3708
- ...createClaimsWriteMethods(context),
3709
- ...createClaimsReadMethods(context)
3710
- };
3711
- }
3712
-
3713
3458
  // src/state/service/deliveries/incoming-methods.ts
3714
3459
  function createIncomingDeliveryMethods(context) {
3715
3460
  const { bridge } = context;
@@ -4235,7 +3980,6 @@ function composeStellarStateService(adapter) {
4235
3980
  ...createWalletAddressService(base),
4236
3981
  ...createPoolMerkleService(base),
4237
3982
  ...createPoolEphemeralService(base),
4238
- ...createClaimsService(base),
4239
3983
  ...createDeliveriesService(base),
4240
3984
  ...createRecordsService(base)
4241
3985
  };
@@ -4402,22 +4146,63 @@ async function registerPrivateAddressOnChain(input) {
4402
4146
  return transactionHash;
4403
4147
  }
4404
4148
 
4405
- // src/transact/onboarding/recipient.ts
4406
- import { PrivacyPoolSDK as PrivacyPoolSDK3 } from "@auditable/privacy-pool-zk-sdk";
4149
+ // src/contracts/registry/resolve-transfer-recipient.ts
4150
+ import { StrKey as StrKey5 } from "@stellar/stellar-sdk";
4151
+
4152
+ // src/transact/escrow/derived-escrow-recipient.ts
4153
+ import { Buffer as Buffer13 } from "buffer";
4154
+ import { StrKey as StrKey4 } from "@stellar/stellar-sdk";
4155
+ import {
4156
+ derivedEscrowKey,
4157
+ ed25519PubkeyPayloadHexToWithdrawFrDecimals as ed25519PubkeyPayloadHexToWithdrawFrDecimals2,
4158
+ sampleDerivedEscrowKey
4159
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
4407
4160
  var COORDINATE_HEX_LENGTH2 = 64;
4408
- async function generateTemporaryRecipientPrivateAddress() {
4409
- await getPrivacyPoolService().getInitializedSdk();
4410
- const temporaryScalarHex = PrivacyPoolSDK3.generateRandomScalarHex32();
4411
- const sdk = await getPrivacyPoolService().getInitializedSdk();
4412
- const point = sdk.ecdhEphemeralPublicKeyFromScalarHex(temporaryScalarHex);
4413
- const publicKeyXHex = point.x.padStart(COORDINATE_HEX_LENGTH2, "0");
4414
- const publicKeyYHex = point.y.padStart(COORDINATE_HEX_LENGTH2, "0");
4161
+ function stellarAccountToFieldLimbs(stellarAddress) {
4162
+ const pkRaw = StrKey4.decodeEd25519PublicKey(stellarAddress.trim());
4163
+ const pkHex = Buffer13.from(pkRaw).toString("hex");
4164
+ const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals2(pkHex);
4165
+ return { recipientHi: hi, recipientLo: lo };
4166
+ }
4167
+ function padCoordinateHex(value) {
4168
+ return value.replace(/^0x/iu, "").padStart(COORDINATE_HEX_LENGTH2, "0");
4169
+ }
4170
+ async function deriveEscrowRecipientFromStellarAddress(input) {
4171
+ const recipientStellarAddress = input.recipientStellarAddress.trim();
4172
+ if (!StrKey4.isValidEd25519PublicKey(recipientStellarAddress)) {
4173
+ throw new Error("Escrow recipient must be a Stellar G-address.");
4174
+ }
4175
+ const { recipientHi, recipientLo } = stellarAccountToFieldLimbs(
4176
+ recipientStellarAddress
4177
+ );
4178
+ const deriveKey = input.deriveKey ?? derivedEscrowKey;
4179
+ let nonceDecimal;
4180
+ let key;
4181
+ if (input.nonceDecimal) {
4182
+ nonceDecimal = input.nonceDecimal;
4183
+ key = await deriveKey(
4184
+ BigInt(nonceDecimal),
4185
+ BigInt(recipientHi),
4186
+ BigInt(recipientLo)
4187
+ );
4188
+ } else {
4189
+ const sampled = await sampleDerivedEscrowKey(
4190
+ BigInt(recipientHi),
4191
+ BigInt(recipientLo)
4192
+ );
4193
+ nonceDecimal = sampled.nonce.toString();
4194
+ key = sampled.key;
4195
+ }
4415
4196
  return {
4416
- temporaryScalarHex,
4417
- temporaryPrivateAddressStpl1: encodePrivateAddressFromHexCoordinates(
4418
- publicKeyXHex,
4419
- publicKeyYHex
4420
- )
4197
+ nonceDecimal,
4198
+ recipientHi,
4199
+ recipientLo,
4200
+ recipientStellarAddress,
4201
+ privateAddressStpl1: encodePrivateAddressFromHexCoordinates(
4202
+ padCoordinateHex(key.pointXHex),
4203
+ padCoordinateHex(key.pointYHex)
4204
+ ),
4205
+ scalarHex: padCoordinateHex(key.scalarHex)
4421
4206
  };
4422
4207
  }
4423
4208
 
@@ -4436,11 +4221,23 @@ async function resolveTransferRecipientFromChain(input) {
4436
4221
  recipientStellarAddress
4437
4222
  };
4438
4223
  }
4439
- const temporaryKey = await generateTemporaryRecipientPrivateAddress();
4224
+ if (!StrKey5.isValidEd25519PublicKey(recipientStellarAddress)) {
4225
+ throw new Error(
4226
+ "Transfers to unregistered recipients require a Stellar G-address."
4227
+ );
4228
+ }
4229
+ const escrow = await deriveEscrowRecipientFromStellarAddress({
4230
+ recipientStellarAddress
4231
+ });
4440
4232
  return {
4441
- recipientPrivateAddressStpl1: temporaryKey.temporaryPrivateAddressStpl1,
4233
+ recipientPrivateAddressStpl1: escrow.privateAddressStpl1,
4442
4234
  recipientStellarAddress,
4443
- temporaryRecipientKey: temporaryKey
4235
+ escrowSend: {
4236
+ nonceDecimal: escrow.nonceDecimal,
4237
+ recipientHi: escrow.recipientHi,
4238
+ recipientLo: escrow.recipientLo,
4239
+ recipientStellarAddress
4240
+ }
4444
4241
  };
4445
4242
  }
4446
4243
 
@@ -4448,7 +4245,7 @@ async function resolveTransferRecipientFromChain(input) {
4448
4245
  import { Api } from "@stellar/stellar-sdk/rpc";
4449
4246
 
4450
4247
  // src/rpc/soroban-transaction-meta.ts
4451
- import { Address, StrKey as StrKey5 } from "@stellar/stellar-sdk";
4248
+ import { Address, StrKey as StrKey6 } from "@stellar/stellar-sdk";
4452
4249
  var BIGINT_SHIFT_64 = 64n;
4453
4250
  var TRANSACTION_META_SWITCH_SOROBAN_V3 = 3;
4454
4251
  var TRANSACTION_META_SWITCH_SOROBAN_V4 = 4;
@@ -4492,7 +4289,7 @@ function extractAmountFromScValue(value) {
4492
4289
  return void 0;
4493
4290
  }
4494
4291
  function contractIdToString(contractId) {
4495
- return StrKey5.encodeContract(Buffer.from(contractId));
4292
+ return StrKey6.encodeContract(Buffer.from(contractId));
4496
4293
  }
4497
4294
  function scAddressToContractString(address) {
4498
4295
  if (address.switch().name !== "scAddressTypeContract") {
@@ -4816,7 +4613,8 @@ async function checkPrivateRecordSpendStatusWithEnvironment(input) {
4816
4613
  const environment = requireNetworkEnvironment(input.transactEnvironment);
4817
4614
  const contractContext = requireContractContext(environment);
4818
4615
  const nullifierHashHex = await getPrivacyPoolService().calculateNullifierHash(
4819
- input.nullifier
4616
+ input.nullifier,
4617
+ privKeyScalarDecimalFromRecipientScalarHex(input.privKeyScalarHex)
4820
4618
  );
4821
4619
  const poolContractId = input.poolContractId?.trim() || contractContext.network.poolContract;
4822
4620
  const spent = await readNullifierConsumedOnChain({
@@ -4865,148 +4663,38 @@ async function getTransactionDetailsWithEnvironment(input) {
4865
4663
  if ("kind" in details) {
4866
4664
  throw new Error(details.message);
4867
4665
  }
4868
- return details;
4869
- }
4870
-
4871
- // src/client/nullifier-checker.ts
4872
- function createNullifierSpentChecker(transactEnvironment) {
4873
- if (!transactEnvironment) {
4874
- return;
4875
- }
4876
- return async ({
4877
- nullifier,
4878
- walletPublicKey
4879
- }) => {
4880
- const status = await checkPrivateRecordSpendStatusWithEnvironment({
4881
- transactEnvironment,
4882
- nullifier,
4883
- walletPublicKey
4884
- });
4885
- return status.spent;
4886
- };
4887
- }
4888
-
4889
- // src/transact/merkle/fetch-contract.ts
4890
- import { Buffer as Buffer14 } from "buffer";
4891
-
4892
- // src/transact/merkle/encoding.ts
4893
- import "buffer";
4894
- var FR_ORDER = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n;
4895
- function bufferToDecimal(buf) {
4896
- const hex = buf.toString("hex");
4897
- const bigintFromHex = BigInt(`0x${hex}`);
4898
- const reduced = bigintFromHex % FR_ORDER;
4899
- return reduced.toString();
4900
- }
4901
- function commitmentsBuffersToDecimal(buffers) {
4902
- return buffers.map((bufferRow) => bufferToDecimal(bufferRow));
4903
- }
4904
-
4905
- // src/transact/merkle/state-port.ts
4906
- function poolMerkleStateToCachedView(state) {
4907
- return {
4908
- commitments: state.commitments,
4909
- updatedAt: state.updatedAt,
4910
- merkleRootHex: state.merkleRootHex
4911
- };
4912
- }
4913
-
4914
- // src/transact/merkle/fetch-contract.ts
4915
- function normalizeCommitmentBuffers(rawBuffers) {
4916
- return rawBuffers.map(
4917
- (bufferRow) => Buffer14.isBuffer(bufferRow) ? bufferRow : Buffer14.from(bufferRow)
4918
- );
4919
- }
4920
- function mergeContractMerkleWithCache(parameters) {
4921
- const cachedCount = parameters.cachedState?.commitments.length ?? 0;
4922
- const shouldPreferContract = parameters.contractCount > cachedCount || !parameters.cachedState || cachedCount === 0;
4923
- if (shouldPreferContract) {
4924
- const updatedAt = Date.now();
4925
- void parameters.poolMerkleState?.set({
4926
- poolContract: parameters.poolContractId,
4927
- commitments: parameters.contractCommitments,
4928
- commitmentCount: parameters.contractCount,
4929
- merkleRootHex: parameters.merkleRootHex,
4930
- updatedAt
4931
- });
4932
- return {
4933
- commitments: parameters.contractCommitments,
4934
- updatedAt,
4935
- merkleRootHex: parameters.merkleRootHex,
4936
- commitmentCount: parameters.contractCount
4937
- };
4938
- }
4939
- return {
4940
- commitments: parameters.cachedState.commitments,
4941
- updatedAt: parameters.cachedState.updatedAt,
4942
- merkleRootHex: parameters.cachedState.merkleRootHex ?? parameters.merkleRootHex,
4943
- commitmentCount: parameters.cachedState.commitments.length
4944
- };
4945
- }
4946
- async function readCachedPoolMerkleView(poolMerkleState, poolContractId) {
4947
- if (!poolMerkleState) {
4948
- return void 0;
4949
- }
4950
- const cached = await poolMerkleState.get(poolContractId);
4951
- return cached ? poolMerkleStateToCachedView(cached) : void 0;
4952
- }
4953
- async function fetchAndMergeMerkleState(parameters) {
4954
- const client = readPoolClientFactory(parameters.transactEnvironment)({
4955
- contractId: parameters.poolContractId,
4956
- walletPublicKey: parameters.walletPublicKey,
4957
- networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
4958
- sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
4959
- });
4960
- const commitmentsRead = await client.get_commitments();
4961
- const rawBuffers = commitmentsRead.result;
4962
- const buffers = normalizeCommitmentBuffers(rawBuffers);
4963
- const contractCommitments = commitmentsBuffersToDecimal(buffers);
4964
- const contractCount = contractCommitments.length;
4965
- const rootRead = await client.get_merkle_root();
4966
- const merkleRootBuffer = rootRead.result;
4967
- const merkleRootHex = Buffer14.from(merkleRootBuffer).toString("hex");
4968
- const cachedState = await readCachedPoolMerkleView(
4969
- parameters.poolMerkleState,
4970
- parameters.poolContractId
4971
- );
4972
- return mergeContractMerkleWithCache({
4973
- poolContractId: parameters.poolContractId,
4974
- contractCommitments,
4975
- contractCount,
4976
- merkleRootHex,
4977
- cachedState,
4978
- ...parameters.poolMerkleState ? { poolMerkleState: parameters.poolMerkleState } : {}
4979
- });
4980
- }
4981
- async function readLeafEphemeralHex(parameters) {
4982
- const cached = await parameters.leafEphemeral?.get({
4983
- poolContract: parameters.poolContractId,
4984
- leafIndex: parameters.leafIndex
4985
- });
4986
- if (cached?.xHex && cached.yHex) {
4987
- return { xHex: cached.xHex, yHex: cached.yHex };
4988
- }
4989
- const client = readPoolClientFactory(parameters.transactEnvironment)({
4990
- contractId: parameters.poolContractId,
4991
- walletPublicKey: parameters.walletPublicKey,
4992
- networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
4993
- sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
4994
- });
4995
- const read = await client.get_leaf_ephemeral({ leaf_index: parameters.leafIndex });
4996
- const coords = read.result;
4997
- if (!coords?.x || !coords?.y) {
4998
- throw new Error("Missing leaf ephemeral key on contract");
4666
+ return details;
4667
+ }
4668
+
4669
+ // src/client/nullifier-checker.ts
4670
+ function createNullifierSpentChecker(transactEnvironment) {
4671
+ if (!transactEnvironment) {
4672
+ return;
4999
4673
  }
5000
- const xHex = Buffer14.from(coords.x).toString("hex");
5001
- const yHex = Buffer14.from(coords.y).toString("hex");
5002
- await parameters.leafEphemeral?.set({
5003
- poolContract: parameters.poolContractId,
5004
- leafIndex: parameters.leafIndex,
5005
- xHex,
5006
- yHex,
5007
- cachedAt: (/* @__PURE__ */ new Date()).toISOString()
5008
- });
5009
- return { xHex, yHex };
4674
+ return async ({
4675
+ nullifier,
4676
+ walletPublicKey,
4677
+ privKeyScalarHex,
4678
+ privateAddressStpl1
4679
+ }) => {
4680
+ const addressHint = privateAddressStpl1?.trim() ?? "";
4681
+ const resolvedFromEnsure = transactEnvironment.ensureSenderPrivKeyScalarHex ? await transactEnvironment.ensureSenderPrivKeyScalarHex(addressHint) : void 0;
4682
+ const resolvedFromState = addressHint && transactEnvironment.resolveSenderPrivKeyScalarFromState ? await transactEnvironment.resolveSenderPrivKeyScalarFromState({
4683
+ owner: walletPublicKey,
4684
+ privateAddressStpl1: addressHint
4685
+ }) : void 0;
4686
+ const resolvedScalarHex = privKeyScalarHex?.trim() || resolvedFromEnsure?.trim() || resolvedFromState?.trim();
4687
+ if (!resolvedScalarHex) {
4688
+ throw new Error("Spend scalar is required to check owner-bound nullifiers.");
4689
+ }
4690
+ const status = await checkPrivateRecordSpendStatusWithEnvironment({
4691
+ transactEnvironment,
4692
+ nullifier,
4693
+ walletPublicKey,
4694
+ privKeyScalarHex: resolvedScalarHex
4695
+ });
4696
+ return status.spent;
4697
+ };
5010
4698
  }
5011
4699
 
5012
4700
  // src/client/pool-sync.ts
@@ -5131,7 +4819,6 @@ function createOperationsFacet(config, state) {
5131
4819
  wallet: config.wallet,
5132
4820
  engine: config.transactEngine,
5133
4821
  poolContract: config.network.poolContract,
5134
- getPendingClaims: () => state.getPendingClaims(),
5135
4822
  ...checkNullifierSpent ? { checkNullifierSpent } : {}
5136
4823
  }),
5137
4824
  policy: createStellarPolicyAdapter(config.policy)
@@ -5175,103 +4862,6 @@ function createAssetsStateDelegates(state) {
5175
4862
  };
5176
4863
  }
5177
4864
 
5178
- // src/state/claims/backend.ts
5179
- var DEFAULT_PENDING_CLAIMS_PAGE_SIZE = 20;
5180
- async function fetchPendingClaimsBackendPage(input) {
5181
- const page = input.page ?? 1;
5182
- const limit = input.pageSize ?? DEFAULT_PENDING_CLAIMS_PAGE_SIZE;
5183
- const params = new URLSearchParams({
5184
- ownerAddress: input.ownerAddress,
5185
- page: String(page),
5186
- limit: String(limit)
5187
- });
5188
- const baseUrl = input.backendBaseUrl.replace(/\/$/, "");
5189
- const response = await fetch(`${baseUrl}/pending-claims?${params.toString()}`);
5190
- if (!response.ok) {
5191
- throw new Error(`Pending claims request failed: ${response.status}`);
5192
- }
5193
- return response.json();
5194
- }
5195
- async function fetchPendingClaimsBackendCount(input) {
5196
- const params = new URLSearchParams({
5197
- ownerAddress: input.ownerAddress
5198
- });
5199
- const baseUrl = input.backendBaseUrl.replace(/\/$/, "");
5200
- const response = await fetch(`${baseUrl}/pending-claims/count?${params.toString()}`);
5201
- if (!response.ok) {
5202
- throw new Error(`Pending claims count request failed: ${response.status}`);
5203
- }
5204
- const payload = await response.json();
5205
- return payload.count;
5206
- }
5207
- function mapBackendPendingClaimItem(item, asset = "") {
5208
- return {
5209
- id: String(item.id),
5210
- owner: item.ownerAddress,
5211
- asset,
5212
- amount: BigInt(item.noteValue),
5213
- createdAt: item.createdAt,
5214
- poolTxId: item.poolTxId,
5215
- commitmentHex: item.commitmentHex,
5216
- nullifierHex: item.nullifierHex,
5217
- futureNullifierHashHex: item.futureNullifierHashHex,
5218
- assetHiHex: item.assetHiHex,
5219
- assetLoHex: item.assetLoHex,
5220
- nullifierFieldHex: item.nullifierFieldHex,
5221
- secretHex: item.secretHex,
5222
- tempPublicKeyXHex: item.tempPublicKeyXHex,
5223
- tempPublicKeyYHex: item.tempPublicKeyYHex,
5224
- encryptedRecoveryBase64: item.encryptedRecoveryBase64,
5225
- createdAtLedger: item.createdAtLedger
5226
- };
5227
- }
5228
- function mapBackendPendingClaimsPage(response, asset = "") {
5229
- return {
5230
- claims: response.data.map((item) => mapBackendPendingClaimItem(item, asset)),
5231
- paginationInfo: {
5232
- total: response.meta.total,
5233
- page: response.meta.page,
5234
- pageSize: response.meta.limit,
5235
- hasMore: response.meta.page < response.meta.totalPages
5236
- }
5237
- };
5238
- }
5239
-
5240
- // src/state/claims/sync-from-backend.ts
5241
- async function syncPendingClaimsFromBackend(stateService, input) {
5242
- const response = await fetchPendingClaimsBackendPage(input);
5243
- const { claims, paginationInfo } = mapBackendPendingClaimsPage(
5244
- response,
5245
- input.asset ?? ""
5246
- );
5247
- await stateService.replacePendingClaimsPage({
5248
- owner: input.ownerAddress,
5249
- claims,
5250
- paginationInfo,
5251
- count: paginationInfo.total
5252
- });
5253
- }
5254
- async function syncPendingClaimsCountFromBackend(stateService, ownerAddress, input) {
5255
- const count = await fetchPendingClaimsBackendCount(input);
5256
- await stateService.setPendingClaimsCount(ownerAddress, count);
5257
- }
5258
-
5259
- // src/client/state-delegates/claims.ts
5260
- function createClaimsStateDelegates(state) {
5261
- return {
5262
- appendPendingClaims: (claims, paginationInfo) => state.appendPendingClaims(claims, paginationInfo),
5263
- loadPendingClaimsFromBackend: (input) => syncPendingClaimsFromBackend(state, input),
5264
- loadPendingClaimsCountFromBackend: (input) => syncPendingClaimsCountFromBackend(state, input.ownerAddress, input),
5265
- replacePendingClaimsPage: (input) => state.replacePendingClaimsPage(input),
5266
- upsertPendingClaims: (claims) => state.upsertPendingClaims(claims),
5267
- removePendingClaims: (ids) => state.removePendingClaims(ids),
5268
- clearPendingClaims: (input = {}) => state.clearPendingClaims(input),
5269
- getPendingClaims: (filter = {}) => state.getPendingClaims(filter),
5270
- getPendingClaimsCount: (owner) => state.getPendingClaimsCount(owner),
5271
- setPendingClaimsCount: (owner, count) => state.setPendingClaimsCount(owner, count)
5272
- };
5273
- }
5274
-
5275
4865
  // src/client/state-delegates/deliveries.ts
5276
4866
  function createDeliveriesStateDelegates(state) {
5277
4867
  return {
@@ -5336,7 +4926,6 @@ function createStateDelegates(state) {
5336
4926
  ...createAssetsStateDelegates(state),
5337
4927
  ...createRegistryStateDelegates(state),
5338
4928
  ...createPoolStateDelegates(state),
5339
- ...createClaimsStateDelegates(state),
5340
4929
  ...createDeliveriesStateDelegates(state),
5341
4930
  ...createRecordsStateDelegates(state)
5342
4931
  };
@@ -5463,91 +5052,14 @@ function createStellarPrivacyClientFromResolvedConfig(config) {
5463
5052
  }
5464
5053
 
5465
5054
  // src/transact/engine/default-factory.ts
5466
- import { PrivacyPoolSDK as PrivacyPoolSDK4 } from "@auditable/privacy-pool-zk-sdk";
5055
+ import { PrivacyPoolSDK as PrivacyPoolSDK3 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
5467
5056
 
5468
- // src/transact/engine/prepare/shared.ts
5469
- async function resolveTokenContractId2(environment, assetId) {
5470
- if (environment.resolveTokenContractId) {
5471
- return environment.resolveTokenContractId(assetId);
5472
- }
5473
- throw new Error(`Token contract is not configured for asset ${assetId}.`);
5474
- }
5475
- async function resolveWalletPublicKey(environment, prepared) {
5476
- if (environment.resolveWalletPublicKey) {
5477
- return environment.resolveWalletPublicKey();
5478
- }
5479
- if (prepared.kind === "deposit") {
5480
- const depositIntent = prepared.intent;
5481
- return depositIntent.from;
5482
- }
5483
- throw new Error("Wallet public key resolver is not configured.");
5484
- }
5485
- async function resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
5486
- const cached = await readSenderPrivKeyScalarHex(
5487
- environment,
5488
- privateAddressStpl1,
5489
- owner
5490
- );
5491
- if (cached) {
5492
- return cached;
5493
- }
5494
- if (environment.ensureSenderPrivKeyScalarHex) {
5495
- return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
5496
- }
5497
- if (!environment.resolveSenderPrivKeyScalarHex) {
5498
- throw new Error("Sender private key scalar resolver is not configured.");
5499
- }
5500
- return environment.resolveSenderPrivKeyScalarHex(privateAddressStpl1);
5501
- }
5502
- async function readSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
5503
- if (owner && environment.resolveSenderPrivKeyScalarFromState) {
5504
- const fromState = await environment.resolveSenderPrivKeyScalarFromState({
5505
- owner,
5506
- privateAddressStpl1
5507
- });
5508
- if (fromState?.trim()) {
5509
- return fromState.trim();
5510
- }
5511
- }
5512
- if (environment.readSenderPrivKeyScalarHex) {
5513
- const cached = await environment.readSenderPrivKeyScalarHex(privateAddressStpl1);
5514
- if (cached?.trim()) {
5515
- return cached.trim();
5516
- }
5517
- }
5518
- return void 0;
5519
- }
5520
- async function ensureSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
5521
- const cached = await readSenderPrivKeyScalarHex(
5522
- environment,
5523
- privateAddressStpl1,
5524
- owner
5525
- );
5526
- if (cached) {
5527
- return cached;
5528
- }
5529
- if (environment.ensureSenderPrivKeyScalarHex) {
5530
- return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
5531
- }
5532
- return resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner);
5533
- }
5534
- async function loadMerkleState(environment, walletPublicKey) {
5535
- const merged = await fetchAndMergeMerkleState({
5536
- poolContractId: environment.network.poolContract,
5537
- walletPublicKey,
5538
- transactEnvironment: environment,
5539
- ...environment.poolMerkleState ? { poolMerkleState: environment.poolMerkleState } : {}
5540
- });
5541
- return { commitments: merged.commitments };
5542
- }
5543
- function enrichPreparedOperation(prepared, outputRecords, artifacts) {
5057
+ // src/transact/pool/proof-types.ts
5058
+ function ciphertextArtifactsFromProof(proof) {
5544
5059
  return {
5545
- ...prepared,
5546
- outputRecords,
5547
- transactArtifacts: artifacts,
5548
- submissionPayload: {
5549
- operationId: crypto.randomUUID(),
5550
- signed: false
5060
+ ...proof.ciphertext_hex === void 0 ? {} : { ciphertextHex: proof.ciphertext_hex },
5061
+ ...proof.output_note_ephemeral_scalars === void 0 ? {} : {
5062
+ outputNoteEphemeralScalars: [...proof.output_note_ephemeral_scalars]
5551
5063
  }
5552
5064
  };
5553
5065
  }
@@ -5602,6 +5114,7 @@ async function prepareDepositOperation(prepared, environment, poolService) {
5602
5114
  return enrichPreparedOperation(prepared, [outputRecord], {
5603
5115
  proofHex: depositProof.proof.proof_hex,
5604
5116
  publicHex: depositProof.proof.public_hex,
5117
+ ...ciphertextArtifactsFromProof(depositProof.proof),
5605
5118
  applicationIdsPlaintext: depositProof.proof.applicationIdsPlaintext,
5606
5119
  tokenAddress,
5607
5120
  depositScalarHex: depositProof.depositScalarHex,
@@ -5611,6 +5124,42 @@ async function prepareDepositOperation(prepared, environment, poolService) {
5611
5124
  });
5612
5125
  }
5613
5126
 
5127
+ // src/transact/engine/prepare/transfer-helpers.ts
5128
+ import { StrKey as StrKey7 } from "@stellar/stellar-sdk";
5129
+ function isStellarAccountRecipient(prepared) {
5130
+ return prepared.kind === "transfer" && StrKey7.isValidEd25519PublicKey(prepared.intent.to.trim());
5131
+ }
5132
+ async function stampEscrowSendArtifacts(prepared, environment, walletPublicKey) {
5133
+ if (!isStellarAccountRecipient(prepared)) {
5134
+ return {};
5135
+ }
5136
+ if (!environment.resolveTransferRecipientAtExecute) {
5137
+ return {};
5138
+ }
5139
+ const recipient = await environment.resolveTransferRecipientAtExecute({
5140
+ recipientStellarAddress: prepared.intent.to.trim(),
5141
+ walletPublicKey
5142
+ });
5143
+ if (!recipient.escrowSend) {
5144
+ return {};
5145
+ }
5146
+ return { escrowSend: true, spendSource: "escrow" };
5147
+ }
5148
+ async function resolveTransferRecipientForExecute(prepared, environment, walletPublicKey) {
5149
+ if (!isStellarAccountRecipient(prepared)) {
5150
+ return {
5151
+ recipientPrivateAddressStpl1: prepared.intent.to.trim()
5152
+ };
5153
+ }
5154
+ if (!environment.resolveTransferRecipientAtExecute) {
5155
+ throw new Error("Transfer recipient resolver is not configured.");
5156
+ }
5157
+ return environment.resolveTransferRecipientAtExecute({
5158
+ recipientStellarAddress: prepared.intent.to.trim(),
5159
+ walletPublicKey
5160
+ });
5161
+ }
5162
+
5614
5163
  // src/transact/engine/prepare/spend.ts
5615
5164
  async function prepareSpendOperation(prepared, environment) {
5616
5165
  const walletPublicKey = await resolveWalletPublicKey(environment, prepared);
@@ -5621,18 +5170,52 @@ async function prepareSpendOperation(prepared, environment) {
5621
5170
  ...prepared.transactArtifacts,
5622
5171
  tokenAddress,
5623
5172
  walletPublicKey,
5624
- executeFinalizeRequired: true
5173
+ executeFinalizeRequired: true,
5174
+ ...await stampEscrowSendArtifacts(prepared, environment, walletPublicKey)
5625
5175
  }
5626
5176
  };
5627
5177
  }
5628
5178
  var prepareTransferOperation2 = prepareSpendOperation;
5629
5179
  var prepareWithdrawOperation = prepareSpendOperation;
5630
5180
 
5181
+ // src/transact/encoding/ephemeral-key.ts
5182
+ var HEX_64_RE = /^[\da-f]{64}$/iu;
5183
+ function normalizeCoordinate(value) {
5184
+ const hex = value.trim().replace(/^0x/iu, "").toLowerCase();
5185
+ if (!HEX_64_RE.test(hex)) {
5186
+ throw new Error("Ephemeral key coordinate must be a 32-byte hex string.");
5187
+ }
5188
+ return hex;
5189
+ }
5190
+ function serializeEphemeralKeyString(point) {
5191
+ return `${normalizeCoordinate(point.xHex)}:${normalizeCoordinate(point.yHex)}`;
5192
+ }
5193
+
5194
+ // src/transact/escrow/require-escrow-spend-scalar.ts
5195
+ function isEscrowSweepSpend(artifacts) {
5196
+ return artifacts?.spendSource === "escrow" && artifacts.escrowSend !== true;
5197
+ }
5198
+ function requireEscrowSpendScalarHex(artifacts) {
5199
+ if (!isEscrowSweepSpend(artifacts)) {
5200
+ throw new Error("Escrow sweep requires spendSource escrow.");
5201
+ }
5202
+ const hex = artifacts?.escrowSpendScalarHex?.trim();
5203
+ if (!hex) {
5204
+ throw new Error("Escrow sweep requires the reconstructed note owner scalar.");
5205
+ }
5206
+ return hex;
5207
+ }
5208
+ function nullifierCheckSpendScalarHex(artifacts) {
5209
+ if (!isEscrowSweepSpend(artifacts)) {
5210
+ return void 0;
5211
+ }
5212
+ return requireEscrowSpendScalarHex(artifacts);
5213
+ }
5214
+
5631
5215
  // src/transact/engine/spend-proof-context.ts
5632
5216
  async function resolveSenderPrivKeyScalarHex2(input) {
5633
- const pendingClaim = input.prepared.transactArtifacts?.pendingClaim;
5634
- if (pendingClaim) {
5635
- return recoveryScalarHexFromClaim(pendingClaim);
5217
+ if (isEscrowSweepSpend(input.prepared.transactArtifacts)) {
5218
+ return requireEscrowSpendScalarHex(input.prepared.transactArtifacts);
5636
5219
  }
5637
5220
  if (input.prepared.kind !== "transfer" && input.prepared.kind !== "withdraw") {
5638
5221
  throw new Error("Spend execution requires a transfer or withdraw intent.");
@@ -5681,8 +5264,7 @@ async function buildSpendProofContextAtExecute(input) {
5681
5264
  commitments,
5682
5265
  ephemeral,
5683
5266
  senderPrivKeyScalarHex,
5684
- recipientPrivateAddressStpl1: input.recipientPrivateAddressStpl1,
5685
- pendingClaim: input.prepared.transactArtifacts?.pendingClaim
5267
+ recipientPrivateAddressStpl1: input.recipientPrivateAddressStpl1
5686
5268
  };
5687
5269
  }
5688
5270
  async function readCoinEphemeralForRecord(input) {
@@ -5701,14 +5283,19 @@ async function readCoinEphemeralForRecord(input) {
5701
5283
  return { coin, ephemeral };
5702
5284
  }
5703
5285
 
5704
- // src/transact/onboarding/recipient-change-deposits.ts
5705
- async function buildPaddingDepositPair(recipientPrivateAddressStpl1, tokenAddress, recipientDeposit) {
5706
- const paddingSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
5707
- privateAddressStpl1: recipientPrivateAddressStpl1,
5708
- amountStroops: ZERO_STROOPS,
5709
- tokenAddress
5710
- });
5711
- return [recipientDeposit, paddingSlot.deposit];
5286
+ // src/transact/proofs/confidential/recipient-change-deposits.ts
5287
+ function escrowOutputFields(input) {
5288
+ if (!input.escrowSend) {
5289
+ return {};
5290
+ }
5291
+ return {
5292
+ escrowNonce: input.escrowSend.nonceDecimal,
5293
+ recipientHi: input.escrowSend.recipientHi,
5294
+ recipientLo: input.escrowSend.recipientLo
5295
+ };
5296
+ }
5297
+ function paddingDepositPair(recipientDeposit) {
5298
+ return [recipientDeposit, "dummy"];
5712
5299
  }
5713
5300
  async function buildChangeDepositPair(parameters) {
5714
5301
  const changeSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
@@ -5727,24 +5314,24 @@ async function buildChangeDepositPair(parameters) {
5727
5314
  };
5728
5315
  }
5729
5316
  async function buildRecipientAndOptionalChangeDeposits(parameters) {
5317
+ const escrow = {
5318
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
5319
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
5320
+ };
5730
5321
  const recipientPrivateAddress = parameters.recipientPrivateAddressStpl1.trim();
5731
5322
  const recipientSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
5732
5323
  privateAddressStpl1: recipientPrivateAddress,
5733
5324
  amountStroops: parameters.transferStroops,
5734
- tokenAddress: parameters.tokenAddress
5325
+ tokenAddress: parameters.tokenAddress,
5326
+ ...escrowOutputFields(escrow)
5735
5327
  });
5736
5328
  if (parameters.changeStroops <= ZERO_STROOPS) {
5737
5329
  return {
5738
5330
  recipientSlot,
5739
- deposits: await buildPaddingDepositPair(
5740
- recipientPrivateAddress,
5741
- parameters.tokenAddress,
5742
- recipientSlot.deposit
5743
- )
5331
+ deposits: paddingDepositPair(recipientSlot.deposit)
5744
5332
  };
5745
5333
  }
5746
5334
  const changeResult = await buildChangeDepositPair({
5747
- recipientPrivateAddressStpl1: recipientPrivateAddress,
5748
5335
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
5749
5336
  changeStroops: parameters.changeStroops,
5750
5337
  tokenAddress: parameters.tokenAddress,
@@ -5766,20 +5353,61 @@ function generatedOutputCoinFromSlot(slot) {
5766
5353
  precommitementHex: slot.precommitementHex
5767
5354
  };
5768
5355
  }
5356
+ function publicEscrowRecipientLimbs(parameters) {
5357
+ const limbs = parameters.escrowClaimantLimbs;
5358
+ if (!limbs) {
5359
+ return void 0;
5360
+ }
5361
+ return {
5362
+ escrowRecipientHi: limbs.recipientHi,
5363
+ escrowRecipientLo: limbs.recipientLo
5364
+ };
5365
+ }
5366
+ function sweepWithdrawStamp(parameters) {
5367
+ const publicLimbs = publicEscrowRecipientLimbs(parameters);
5368
+ if (!publicLimbs) {
5369
+ return void 0;
5370
+ }
5371
+ return {
5372
+ ...publicLimbs,
5373
+ ...parameters.escrowClaimantLimbs?.nonceDecimal ? { escrowNonce: parameters.escrowClaimantLimbs.nonceDecimal } : {}
5374
+ };
5375
+ }
5376
+ function stampWithdrawEscrowLimbs(withdrawObject, limbs) {
5377
+ if (!limbs) {
5378
+ return withdrawObject;
5379
+ }
5380
+ return {
5381
+ ...withdrawObject,
5382
+ recipientStellar: [limbs.escrowRecipientHi, limbs.escrowRecipientLo],
5383
+ ...limbs.escrowNonce ? { escrowNonce: limbs.escrowNonce } : {}
5384
+ };
5385
+ }
5386
+ function sweepOutputOwnerFields(parameters) {
5387
+ if (!parameters.escrowClaimantLimbs) {
5388
+ return void 0;
5389
+ }
5390
+ const [sweepOutputOwnerPubX, sweepOutputOwnerPubY] = recipientPublicKeysDecimalFromPrivateAddress(
5391
+ parameters.recipientPrivateAddressStpl1
5392
+ );
5393
+ return { sweepOutputOwnerPubX, sweepOutputOwnerPubY };
5394
+ }
5769
5395
  async function buildTransferDepositsAndPublicInput(parameters) {
5770
5396
  const { recipientSlot, deposits, changeCoin } = await buildRecipientAndOptionalChangeDeposits({
5771
5397
  recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
5772
5398
  transferStroops: parameters.transferStroops,
5773
5399
  changeStroops: parameters.changeStroops,
5774
5400
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
5775
- tokenAddress: parameters.tokenAddress
5401
+ tokenAddress: parameters.tokenAddress,
5402
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
5403
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
5776
5404
  });
5777
5405
  const publicInput = withTokenAddressPublicInputs(
5778
5406
  {
5779
5407
  stateRoot: parameters.stateRoot,
5780
- withdrawAddressHi: parameters.withdrawAddressHi,
5781
- withdrawAddressLo: parameters.withdrawAddressLo,
5782
- privKeyScalar: parameters.privKeyScalar
5408
+ privKeyScalar: parameters.privKeyScalar,
5409
+ ...publicEscrowRecipientLimbs(parameters),
5410
+ ...sweepOutputOwnerFields(parameters)
5783
5411
  },
5784
5412
  parameters.tokenAddress
5785
5413
  );
@@ -5791,10 +5419,6 @@ async function buildTransferDepositsAndPublicInput(parameters) {
5791
5419
  };
5792
5420
  }
5793
5421
  async function buildSenderTransferDepositsAndPublicInput(parameters) {
5794
- const { hi, lo, privKeyScalar } = senderWithdrawFrAndScalar({
5795
- senderGAddress: parameters.senderGAddress,
5796
- senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex
5797
- });
5798
5422
  return buildTransferDepositsAndPublicInput({
5799
5423
  recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
5800
5424
  transferStroops: parameters.transferStroops,
@@ -5802,31 +5426,55 @@ async function buildSenderTransferDepositsAndPublicInput(parameters) {
5802
5426
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
5803
5427
  tokenAddress: parameters.tokenAddress,
5804
5428
  stateRoot: parameters.stateRoot,
5805
- withdrawAddressHi: hi,
5806
- withdrawAddressLo: lo,
5807
- privKeyScalar
5429
+ privKeyScalar: privKeyScalarDecimalFromRecipientScalarHex(
5430
+ parameters.senderPrivKeyScalarHex
5431
+ ),
5432
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
5433
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
5808
5434
  });
5809
5435
  }
5810
5436
 
5811
5437
  // src/transact/proofs/confidential/dual.ts
5812
- function buildDualTransferApplicationIds(applicationId, changeCoin) {
5813
- return [
5814
- applicationId,
5815
- applicationId,
5816
- applicationId,
5817
- changeCoin ? applicationId : "0"
5818
- ];
5438
+ function confidentialEscrowFields(parameters) {
5439
+ return {
5440
+ ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
5441
+ ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
5442
+ };
5443
+ }
5444
+ function stampDualWithdrawLegs(legs, parameters) {
5445
+ const escrowLimbs = sweepWithdrawStamp(confidentialEscrowFields(parameters));
5446
+ return {
5447
+ legA: {
5448
+ ...legs.legA,
5449
+ withdrawObject: stampWithdrawEscrowLimbs(legs.legA.withdrawObject, escrowLimbs)
5450
+ },
5451
+ legB: {
5452
+ ...legs.legB,
5453
+ withdrawObject: stampWithdrawEscrowLimbs(legs.legB.withdrawObject, escrowLimbs)
5454
+ }
5455
+ };
5456
+ }
5457
+ function buildDualTransferApplicationIds(sdk, applicationId, changeCoin) {
5458
+ return buildApplicationIdHints({
5459
+ sdk,
5460
+ inputIds: [applicationId, applicationId],
5461
+ outputIds: [applicationId, changeCoin ? applicationId : "0"]
5462
+ });
5819
5463
  }
5820
5464
  async function proveDualConfidentialTransfer(parameters) {
5821
5465
  const audit = buildPoolTransactionAuditParameters({
5822
5466
  applicationId: parameters.applicationId,
5467
+ nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
5823
5468
  ...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
5824
5469
  });
5825
5470
  return parameters.sdk.proveTransaction(
5826
5471
  parameters.publicInput,
5827
- buildZeroPublicLegs(),
5828
- [parameters.legA.withdrawObject, parameters.legB.withdrawObject],
5829
- parameters.deposits,
5472
+ padPublicLegsToLayout(parameters.sdk, buildZeroPublicLegs()),
5473
+ padWithdrawSlotsToLayout(parameters.sdk, [
5474
+ parameters.legA.withdrawObject,
5475
+ parameters.legB.withdrawObject
5476
+ ]),
5477
+ padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
5830
5478
  audit
5831
5479
  );
5832
5480
  }
@@ -5840,24 +5488,33 @@ async function buildDualTransferProofContext(parameters, applicationId, sdk) {
5840
5488
  changeStroops,
5841
5489
  parameters.selfPrivateAddressStpl1ForChange
5842
5490
  );
5843
- const { legA, legB } = dualWithdrawLegsWithSharedRoot({
5844
- sdk,
5845
- coinA: parameters.coinA,
5846
- coinB: parameters.coinB,
5847
- state: parameters.state,
5848
- ephemeralA: parseEphemeralKeyString(parameters.ephemeralAKey),
5849
- ephemeralB: parseEphemeralKeyString(parameters.ephemeralBKey),
5850
- applicationId
5851
- });
5491
+ const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
5492
+ parameters.senderPrivKeyScalarHex
5493
+ );
5494
+ const ownerPubHex = sdk.ecdhEphemeralPublicKeyFromScalarHex(
5495
+ parameters.senderPrivKeyScalarHex
5496
+ );
5497
+ const { legA, legB } = stampDualWithdrawLegs(
5498
+ dualWithdrawLegsWithSharedRoot({
5499
+ sdk,
5500
+ coinA: parameters.coinA,
5501
+ coinB: parameters.coinB,
5502
+ state: parameters.state,
5503
+ ownerPubHex,
5504
+ privKeyScalar,
5505
+ applicationId
5506
+ }),
5507
+ parameters
5508
+ );
5852
5509
  const transferInputs = await buildSenderTransferDepositsAndPublicInput({
5853
- senderGAddress: parameters.senderGAddress,
5854
5510
  senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex,
5855
5511
  recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
5856
5512
  transferStroops: parameters.transferStroops,
5857
5513
  changeStroops,
5858
5514
  selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
5859
5515
  tokenAddress: parameters.tokenAddress,
5860
- stateRoot: legA.witness.stateRoot
5516
+ stateRoot: legA.witness.stateRoot,
5517
+ ...confidentialEscrowFields(parameters)
5861
5518
  });
5862
5519
  return { legA, legB, applicationId, ...transferInputs };
5863
5520
  }
@@ -5885,7 +5542,11 @@ async function prepareConfidentialTransferProofDual(parameters) {
5885
5542
  }));
5886
5543
  return {
5887
5544
  ...proof,
5888
- applicationIdsPlaintext: buildDualTransferApplicationIds(applicationId, changeCoin),
5545
+ applicationIdsPlaintext: buildDualTransferApplicationIds(
5546
+ sdk,
5547
+ applicationId,
5548
+ changeCoin
5549
+ ),
5889
5550
  recipientCoin: generatedOutputCoinFromSlot(recipientSlot),
5890
5551
  ...changeCoin ? { changeCoin } : {}
5891
5552
  };
@@ -5903,51 +5564,72 @@ function validateSingleCoinTransferAmounts(transferStroops, noteStroops, selfPri
5903
5564
  requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange);
5904
5565
  return changeStroops;
5905
5566
  }
5906
- function buildSingleTransferApplicationIds(applicationId, changeCoin) {
5907
- return [applicationId, "0", applicationId, changeCoin ? applicationId : "0"];
5567
+ function buildSingleTransferApplicationIds(sdk, applicationId, changeCoin) {
5568
+ return buildApplicationIdHints({
5569
+ sdk,
5570
+ inputIds: [applicationId],
5571
+ outputIds: [applicationId, changeCoin ? applicationId : "0"]
5572
+ });
5908
5573
  }
5909
5574
  function buildTransferAuditParameters(parameters) {
5910
5575
  const auditPublicKey = parameters.poolService.getAuditPublicKey();
5911
5576
  return buildPoolTransactionAuditParameters({
5912
5577
  applicationId: parameters.applicationId,
5578
+ nAuditSlots: parameters.nAuditSlots,
5913
5579
  ...auditPublicKey ? { auditPublicKey } : {}
5914
5580
  });
5915
5581
  }
5916
5582
  async function proveTransaction(parameters) {
5917
5583
  return parameters.sdk.proveTransaction(
5918
5584
  parameters.publicInput,
5919
- buildZeroPublicLegs(),
5920
- [parameters.withdrawObject, "dummy"],
5921
- parameters.deposits,
5585
+ padPublicLegsToLayout(parameters.sdk, buildZeroPublicLegs()),
5586
+ padWithdrawSlotsToLayout(parameters.sdk, [parameters.withdrawObject]),
5587
+ padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
5922
5588
  parameters.audit
5923
5589
  );
5924
5590
  }
5591
+ function confidentialEscrowFields2(input) {
5592
+ return {
5593
+ ...input.escrowSend ? { escrowSend: input.escrowSend } : {},
5594
+ ...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
5595
+ };
5596
+ }
5925
5597
  async function buildTransferProofInputs(parameters) {
5926
5598
  const changeStroops = validateSingleCoinTransferAmounts(
5927
5599
  parameters.input.transferStroops,
5928
5600
  parameters.noteStroops,
5929
5601
  parameters.input.selfPrivateAddressStpl1ForChange
5930
5602
  );
5603
+ const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
5604
+ parameters.input.senderPrivKeyScalarHex
5605
+ );
5931
5606
  const { witness, withdrawObject } = withdrawWitnessForCoin({
5932
5607
  sdk: parameters.sdk,
5933
5608
  coin: parameters.input.coin,
5934
5609
  state: parameters.input.state,
5935
- ...parseEphemeralKeyString(parameters.input.depositorEphemeralKey),
5610
+ ownerPubHex: parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
5611
+ parameters.input.senderPrivKeyScalarHex
5612
+ ),
5613
+ privKeyScalar,
5936
5614
  applicationId: parameters.applicationId
5937
5615
  });
5616
+ const stampedWithdraw = stampWithdrawEscrowLimbs(
5617
+ withdrawObject,
5618
+ sweepWithdrawStamp(confidentialEscrowFields2(parameters.input))
5619
+ );
5938
5620
  const { recipientSlot, deposits, changeCoin, publicInput } = await buildSenderTransferDepositsAndPublicInput({
5939
- senderGAddress: parameters.input.senderGAddress,
5940
5621
  senderPrivKeyScalarHex: parameters.input.senderPrivKeyScalarHex,
5941
5622
  recipientPrivateAddressStpl1: parameters.input.recipientPrivateAddressStpl1,
5942
5623
  transferStroops: parameters.input.transferStroops,
5943
5624
  changeStroops,
5944
5625
  selfPrivateAddressStpl1ForChange: parameters.input.selfPrivateAddressStpl1ForChange,
5945
5626
  tokenAddress: parameters.input.tokenAddress,
5946
- stateRoot: witness.stateRoot
5627
+ stateRoot: witness.stateRoot,
5628
+ ...confidentialEscrowFields2(parameters.input)
5947
5629
  });
5948
5630
  return {
5949
5631
  witness,
5950
- withdrawObject,
5632
+ withdrawObject: stampedWithdraw,
5951
5633
  recipientSlot,
5952
5634
  deposits,
5953
5635
  changeCoin,
@@ -5965,7 +5647,11 @@ async function prepareConfidentialTransferProof(parameters) {
5965
5647
  input: parameters,
5966
5648
  noteStroops
5967
5649
  });
5968
- const audit = buildTransferAuditParameters({ poolService, applicationId });
5650
+ const audit = buildTransferAuditParameters({
5651
+ poolService,
5652
+ applicationId,
5653
+ nAuditSlots: sdk.getLayout().nAuditSlots
5654
+ });
5969
5655
  const proof = await proveTransaction({
5970
5656
  sdk,
5971
5657
  publicInput,
@@ -5976,6 +5662,7 @@ async function prepareConfidentialTransferProof(parameters) {
5976
5662
  return {
5977
5663
  ...proof,
5978
5664
  applicationIdsPlaintext: buildSingleTransferApplicationIds(
5665
+ sdk,
5979
5666
  applicationId,
5980
5667
  changeCoin
5981
5668
  ),
@@ -5984,95 +5671,26 @@ async function prepareConfidentialTransferProof(parameters) {
5984
5671
  };
5985
5672
  }
5986
5673
 
5987
- // src/transact/engine/prepare/transfer-helpers.ts
5988
- function isPublicRecipientTransfer(prepared) {
5989
- return prepared.kind === "transfer" && prepared.intent.disclosure.recipientAddress === "public";
5990
- }
5991
- async function resolveTransferRecipientForExecute(prepared, environment, walletPublicKey) {
5992
- if (!isPublicRecipientTransfer(prepared)) {
5993
- return {
5994
- recipientPrivateAddressStpl1: prepared.intent.to.trim()
5995
- };
5996
- }
5997
- if (!environment.resolveTransferRecipientAtExecute) {
5998
- throw new Error("Transfer recipient resolver is not configured.");
5999
- }
6000
- return environment.resolveTransferRecipientAtExecute({
6001
- recipientStellarAddress: prepared.intent.to.trim(),
6002
- walletPublicKey
6003
- });
6004
- }
6005
- async function resolveTransferOnboardingAtExecute(input) {
6006
- if (input.prepared.transactArtifacts?.onboarding) {
6007
- return input.prepared.transactArtifacts.onboarding;
6008
- }
6009
- if (!input.recipient.temporaryRecipientKey || !input.environment.buildTransferOnboardingAtExecute) {
6010
- return;
6011
- }
6012
- return input.environment.buildTransferOnboardingAtExecute({
6013
- ownerStellarAddress: input.recipient.recipientStellarAddress ?? input.prepared.intent.to.trim(),
6014
- temporaryRecipientKey: input.recipient.temporaryRecipientKey,
6015
- recipientNote: {
6016
- tokenAddress: input.tokenAddress,
6017
- nullifier: input.recipientCoin.nullifier,
6018
- secret: input.recipientCoin.secret,
6019
- value: input.recipientCoin.value
6020
- }
6021
- });
6022
- }
6023
-
6024
- // src/transact/onboarding/build-pending-claim-payload.ts
6025
- import { Buffer as Buffer15 } from "buffer";
6026
- var FIELD_HEX_LENGTH2 = 64;
6027
- function hexToBuffer2(hex) {
6028
- const clean = hex.trim().replace(/^0x/u, "");
6029
- return Buffer15.from(clean.padStart(FIELD_HEX_LENGTH2, "0"), "hex");
6030
- }
6031
- function buildPendingClaimOnboardingPayload(input) {
6032
- const ownerAddress = input.claim.owner.trim();
6033
- const permanentPrivateAddress = input.permanentPrivateAddressStpl1.trim();
6034
- const decoded = decodePrivateAddress(permanentPrivateAddress);
6035
- const encryptedRecovery = input.claim.encryptedRecoveryBase64?.trim();
6036
- if (!encryptedRecovery) {
6037
- throw new Error("Pending claim is missing encrypted recovery data.");
6038
- }
6039
- return {
6040
- owner: ownerAddress,
6041
- temp_public_key_x: hexToBuffer2(input.claim.tempPublicKeyXHex ?? ""),
6042
- temp_public_key_y: hexToBuffer2(input.claim.tempPublicKeyYHex ?? ""),
6043
- encrypted_private_key: Buffer15.from(encryptedRecovery, "base64"),
6044
- notes: { notes: [] },
6045
- private_address_registration: {
6046
- tag: "Some",
6047
- values: [
6048
- {
6049
- owner: ownerAddress,
6050
- public_key_x: hexToBuffer2(decoded.x),
6051
- public_key_y: hexToBuffer2(decoded.y)
6052
- }
6053
- ]
6054
- }
6055
- };
6056
- }
6057
-
6058
5674
  // src/transact/engine/transfer-proof-at-execute.ts
6059
5675
  function readChangeRecipient(input, changeStroops) {
6060
5676
  if (changeStroops <= 0n || input.prepared.kind !== "transfer") {
6061
5677
  return void 0;
6062
5678
  }
6063
5679
  const from = input.prepared.intent.from;
6064
- if (isPendingClaimSource(from)) {
6065
- return void 0;
6066
- }
6067
5680
  return readTransferFromPrivateAddress(from);
6068
5681
  }
5682
+ function proofEscrowFields(input) {
5683
+ return {
5684
+ ...input.escrowSend ? { escrowSend: input.escrowSend } : {},
5685
+ ...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
5686
+ };
5687
+ }
6069
5688
  async function buildSingleTransferProofAtExecute(input) {
6070
5689
  const context = await buildSpendProofContextAtExecute(input);
6071
- const changeStroops = context.pendingClaim ? 0n : BigInt(context.coin.value) - input.prepared.intent.amount;
5690
+ const changeStroops = BigInt(context.coin.value) - input.prepared.intent.amount;
6072
5691
  const proof = await prepareConfidentialTransferProof({
6073
5692
  coin: context.coin,
6074
5693
  state: { commitments: context.commitments },
6075
- senderGAddress: context.walletPublicKey,
6076
5694
  senderPrivKeyScalarHex: context.senderPrivKeyScalarHex,
6077
5695
  depositorEphemeralKey: serializeEphemeralKeyString({
6078
5696
  xHex: context.ephemeral.xHex,
@@ -6081,7 +5699,8 @@ async function buildSingleTransferProofAtExecute(input) {
6081
5699
  transferStroops: input.prepared.intent.amount,
6082
5700
  recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
6083
5701
  selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
6084
- tokenAddress: context.tokenAddress
5702
+ tokenAddress: context.tokenAddress,
5703
+ ...proofEscrowFields(input)
6085
5704
  });
6086
5705
  return { context, proof };
6087
5706
  }
@@ -6103,7 +5722,6 @@ async function buildDualTransferProofAtExecute(input) {
6103
5722
  coinA: context.coin,
6104
5723
  coinB: secondary.coin,
6105
5724
  state: { commitments: context.commitments },
6106
- senderGAddress: context.walletPublicKey,
6107
5725
  senderPrivKeyScalarHex: context.senderPrivKeyScalarHex,
6108
5726
  ephemeralAKey: serializeEphemeralKeyString({
6109
5727
  xHex: context.ephemeral.xHex,
@@ -6116,7 +5734,8 @@ async function buildDualTransferProofAtExecute(input) {
6116
5734
  transferStroops: input.prepared.intent.amount,
6117
5735
  recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
6118
5736
  selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
6119
- tokenAddress: context.tokenAddress
5737
+ tokenAddress: context.tokenAddress,
5738
+ ...proofEscrowFields(input)
6120
5739
  });
6121
5740
  return { context, proof };
6122
5741
  }
@@ -6132,6 +5751,41 @@ async function buildTransferProofAtExecute(input) {
6132
5751
  }
6133
5752
 
6134
5753
  // src/transact/engine/transfer-finalize.ts
5754
+ function stampEscrowOutputRecords(input) {
5755
+ if (input.escrowSendPrivateAddress) {
5756
+ const [recipientRecord, ...rest] = input.prepared.outputRecords;
5757
+ if (recipientRecord) {
5758
+ input.prepared.outputRecords = [
5759
+ {
5760
+ ...recipientRecord,
5761
+ privateAddress: input.escrowSendPrivateAddress
5762
+ },
5763
+ ...rest
5764
+ ];
5765
+ }
5766
+ }
5767
+ seedEscrowSweepOutputsFromProof({
5768
+ prepared: input.prepared,
5769
+ proof: input.proof,
5770
+ walletPublicKey: input.walletPublicKey
5771
+ });
5772
+ enrichTransferOutputRecords(input.prepared, input.proof);
5773
+ }
5774
+ function seedEscrowSweepOutputsFromProof(input) {
5775
+ if (input.prepared.transactArtifacts?.spendSource !== "escrow" || input.prepared.outputRecords.length > 0) {
5776
+ return;
5777
+ }
5778
+ input.prepared.outputRecords = [
5779
+ {
5780
+ id: input.proof.recipientCoin.commitment_hex,
5781
+ owner: input.walletPublicKey,
5782
+ privateAddress: input.prepared.intent.to,
5783
+ asset: input.prepared.intent.asset,
5784
+ amount: input.prepared.intent.amount,
5785
+ consumed: false
5786
+ }
5787
+ ];
5788
+ }
6135
5789
  function enrichTransferOutputRecords(prepared, proof) {
6136
5790
  if (prepared.outputRecords.length === 0) {
6137
5791
  return;
@@ -6155,65 +5809,34 @@ function enrichTransferOutputRecords(prepared, proof) {
6155
5809
  };
6156
5810
  });
6157
5811
  }
6158
- async function resolvePendingClaimOnboardingAtExecute(input) {
6159
- const claim = input.prepared.transactArtifacts?.pendingClaim;
6160
- if (!claim || input.prepared.kind !== "transfer") {
6161
- return;
6162
- }
6163
- const contractContext = requireContractContext(input.environment);
6164
- const lookup = await readRegistryLookupFromChain({
6165
- contractContext,
6166
- owner: input.walletPublicKey.trim(),
6167
- walletPublicKey: input.walletPublicKey.trim()
6168
- });
6169
- if (lookup.status === "registered") {
6170
- return;
6171
- }
6172
- return buildPendingClaimOnboardingPayload({
6173
- claim,
6174
- permanentPrivateAddressStpl1: input.prepared.intent.to.trim()
6175
- });
6176
- }
6177
- async function ensurePendingClaimReadyForExecute(input) {
6178
- const pendingClaim = input.prepared.transactArtifacts?.pendingClaim;
6179
- if (!pendingClaim) {
6180
- return;
5812
+ function escrowSpendArtifacts(input) {
5813
+ if (input.escrowSend) {
5814
+ return {
5815
+ escrowSend: true,
5816
+ spendSource: "escrow",
5817
+ ...input.escrowRecipient ? { escrowRecipient: input.escrowRecipient } : {}
5818
+ };
6181
5819
  }
6182
- await verifyPendingClaimBeforeExecute({
6183
- claim: pendingClaim,
6184
- environment: input.environment,
6185
- walletPublicKey: input.walletPublicKey
6186
- });
6187
- }
6188
- async function resolveTransferOnboardingBundle(input) {
6189
- const pendingClaim = input.prepared.transactArtifacts?.pendingClaim;
6190
- if (pendingClaim) {
6191
- const pendingOnboarding = await resolvePendingClaimOnboardingAtExecute({
6192
- prepared: input.prepared,
6193
- environment: input.environment,
6194
- walletPublicKey: input.walletPublicKey
6195
- });
6196
- if (pendingOnboarding) {
6197
- return pendingOnboarding;
6198
- }
5820
+ if (input.preparedSpendSource === "escrow") {
5821
+ return {
5822
+ spendSource: "escrow",
5823
+ ...input.escrowRecipient ? { escrowRecipient: input.escrowRecipient } : {},
5824
+ ...input.escrowSpendScalarHex ? { escrowSpendScalarHex: input.escrowSpendScalarHex } : {},
5825
+ ...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
5826
+ };
6199
5827
  }
6200
- return resolveTransferOnboardingAtExecute({
6201
- prepared: input.prepared,
6202
- environment: input.environment,
6203
- recipient: input.recipient,
6204
- recipientCoin: input.recipientCoin,
6205
- tokenAddress: input.tokenAddress
6206
- });
5828
+ return {};
6207
5829
  }
6208
5830
  function buildTransferFinalizeArtifacts(input) {
6209
5831
  return {
6210
5832
  proofHex: input.proof.proof_hex,
6211
5833
  publicHex: input.proof.public_hex,
5834
+ ...ciphertextArtifactsFromProof(input.proof),
6212
5835
  applicationIdsPlaintext: input.proof.applicationIdsPlaintext,
6213
5836
  tokenAddress: input.context.tokenAddress,
6214
5837
  walletPublicKey: input.context.walletPublicKey,
6215
- onboarding: input.onboarding,
6216
- executeFinalizeRequired: false
5838
+ executeFinalizeRequired: false,
5839
+ ...escrowSpendArtifacts(input)
6217
5840
  };
6218
5841
  }
6219
5842
  async function runTransferFinalizeSteps(input) {
@@ -6222,26 +5845,50 @@ async function runTransferFinalizeSteps(input) {
6222
5845
  input.environment,
6223
5846
  input.walletPublicKey
6224
5847
  );
5848
+ const spendScalarHex = nullifierCheckSpendScalarHex(input.prepared.transactArtifacts);
6225
5849
  await verifyPrivateRecordsNullifiersBeforeExecute({
6226
5850
  records: input.prepared.consumedRecords,
6227
5851
  environment: input.environment,
6228
- walletPublicKey: input.walletPublicKey
5852
+ walletPublicKey: input.walletPublicKey,
5853
+ ...spendScalarHex ? { spendScalarHex } : {}
6229
5854
  });
6230
5855
  const { context, proof } = await buildTransferProofAtExecute({
6231
5856
  prepared: input.prepared,
6232
5857
  environment: input.environment,
6233
- recipientPrivateAddressStpl1: recipient.recipientPrivateAddressStpl1
5858
+ recipientPrivateAddressStpl1: recipient.recipientPrivateAddressStpl1,
5859
+ ...recipient.escrowSend ? { escrowSend: recipient.escrowSend } : {},
5860
+ ...input.prepared.transactArtifacts?.escrowClaimantLimbs ? {
5861
+ escrowClaimantLimbs: input.prepared.transactArtifacts.escrowClaimantLimbs
5862
+ } : {}
6234
5863
  });
6235
- const onboarding = await resolveTransferOnboardingBundle({
5864
+ stampEscrowOutputRecords({
6236
5865
  prepared: input.prepared,
6237
- environment: input.environment,
5866
+ proof,
6238
5867
  walletPublicKey: input.walletPublicKey,
6239
- recipient,
6240
- recipientCoin: proof.recipientCoin.coin,
6241
- tokenAddress: context.tokenAddress
5868
+ ...recipient.escrowSend ? { escrowSendPrivateAddress: recipient.recipientPrivateAddressStpl1 } : {}
5869
+ });
5870
+ return buildTransferFinalizeArtifacts({
5871
+ proof,
5872
+ context,
5873
+ ...sweepFinalizeStamp(input.prepared, recipient)
6242
5874
  });
6243
- enrichTransferOutputRecords(input.prepared, proof);
6244
- return buildTransferFinalizeArtifacts({ proof, context, onboarding });
5875
+ }
5876
+ function sweepArtifactStamp(artifacts) {
5877
+ return {
5878
+ ...artifacts?.escrowSpendScalarHex ? { escrowSpendScalarHex: artifacts.escrowSpendScalarHex } : {},
5879
+ ...artifacts?.spendSource ? { preparedSpendSource: artifacts.spendSource } : {},
5880
+ ...artifacts?.escrowClaimantLimbs ? { escrowClaimantLimbs: artifacts.escrowClaimantLimbs } : {}
5881
+ };
5882
+ }
5883
+ function sweepFinalizeStamp(prepared, recipient) {
5884
+ const artifacts = prepared.transactArtifacts;
5885
+ const fromSend = recipient.escrowSend?.recipientStellarAddress?.trim();
5886
+ const escrowRecipient = fromSend || artifacts?.escrowRecipient?.trim();
5887
+ return {
5888
+ ...recipient.escrowSend ? { escrowSend: true } : {},
5889
+ ...escrowRecipient ? { escrowRecipient } : {},
5890
+ ...sweepArtifactStamp(artifacts)
5891
+ };
6245
5892
  }
6246
5893
  async function finalizeTransferAtExecute(prepared, environment) {
6247
5894
  const [primaryRecord] = prepared.consumedRecords;
@@ -6249,11 +5896,6 @@ async function finalizeTransferAtExecute(prepared, environment) {
6249
5896
  throw new Error("Transfer execution record owner is missing.");
6250
5897
  }
6251
5898
  const walletPublicKey = primaryRecord.owner.trim();
6252
- await ensurePendingClaimReadyForExecute({
6253
- prepared,
6254
- environment,
6255
- walletPublicKey
6256
- });
6257
5899
  return runTransferFinalizeSteps({ prepared, environment, walletPublicKey });
6258
5900
  }
6259
5901
 
@@ -6272,12 +5914,18 @@ function enrichWithdrawOutputRecords(prepared, proof) {
6272
5914
  precommitementHex: changeCoin.precommitementHex
6273
5915
  }));
6274
5916
  }
6275
- async function finalizeWithdrawAtExecute(prepared, environment, poolService) {
6276
- if (prepared.kind !== "withdraw") {
6277
- throw new Error("Withdraw finalize requires a withdraw operation.");
6278
- }
6279
- const withdrawIntent = prepared.intent;
6280
- const withdrawFrom = withdrawIntent.from;
5917
+ function buildWithdrawFinalizeArtifacts(proof, context) {
5918
+ return {
5919
+ proofHex: proof.proof_hex,
5920
+ publicHex: proof.public_hex,
5921
+ ...ciphertextArtifactsFromProof(proof),
5922
+ applicationIdsPlaintext: proof.applicationIdsPlaintext,
5923
+ tokenAddress: context.tokenAddress,
5924
+ walletPublicKey: context.walletPublicKey,
5925
+ executeFinalizeRequired: false
5926
+ };
5927
+ }
5928
+ async function finalizeSingleWithdrawAtExecute(prepared, environment, poolService, withdrawFrom) {
6281
5929
  const context = await buildSpendProofContextAtExecute({
6282
5930
  prepared,
6283
5931
  environment,
@@ -6298,14 +5946,71 @@ async function finalizeWithdrawAtExecute(prepared, environment, poolService) {
6298
5946
  tokenAddress: context.tokenAddress
6299
5947
  });
6300
5948
  enrichWithdrawOutputRecords(prepared, proof);
6301
- return {
6302
- proofHex: proof.proof_hex,
6303
- publicHex: proof.public_hex,
6304
- applicationIdsPlaintext: proof.applicationIdsPlaintext,
6305
- tokenAddress: context.tokenAddress,
5949
+ return buildWithdrawFinalizeArtifacts(proof, context);
5950
+ }
5951
+ async function finalizeDualWithdrawAtExecute(prepared, environment, poolService, withdrawFrom) {
5952
+ const [, secondaryRecord] = prepared.consumedRecords;
5953
+ if (!secondaryRecord) {
5954
+ throw new Error("Dual withdraw execution requires two private input records.");
5955
+ }
5956
+ const context = await buildSpendProofContextAtExecute({
5957
+ prepared,
5958
+ environment,
5959
+ recipientPrivateAddressStpl1: withdrawFrom
5960
+ });
5961
+ const secondary = await readCoinEphemeralForRecord({
5962
+ record: secondaryRecord,
5963
+ environment,
6306
5964
  walletPublicKey: context.walletPublicKey,
6307
- executeFinalizeRequired: false
6308
- };
5965
+ commitments: context.commitments
5966
+ });
5967
+ const totalNotes = BigInt(context.coin.value) + BigInt(secondary.coin.value);
5968
+ const changeStroops = totalNotes - prepared.intent.amount;
5969
+ const proof = await poolService.prepareWithdrawTransactProofDual({
5970
+ coinA: context.coin,
5971
+ coinB: secondary.coin,
5972
+ state: { commitments: context.commitments },
5973
+ destinationStellarAddress: prepared.intent.to,
5974
+ privKeyScalarHex: context.senderPrivKeyScalarHex,
5975
+ depositorEphemeralAKey: serializeEphemeralKeyString({
5976
+ xHex: context.ephemeral.xHex,
5977
+ yHex: context.ephemeral.yHex
5978
+ }),
5979
+ depositorEphemeralBKey: serializeEphemeralKeyString({
5980
+ xHex: secondary.ephemeral.xHex,
5981
+ yHex: secondary.ephemeral.yHex
5982
+ }),
5983
+ withdrawAmountStroops: prepared.intent.amount,
5984
+ changePrivateAddressStpl1: changeStroops > 0n ? withdrawFrom : void 0,
5985
+ tokenAddress: context.tokenAddress
5986
+ });
5987
+ enrichWithdrawOutputRecords(prepared, proof);
5988
+ return buildWithdrawFinalizeArtifacts(proof, context);
5989
+ }
5990
+ async function finalizeWithdrawAtExecute(prepared, environment, poolService) {
5991
+ if (prepared.kind !== "withdraw") {
5992
+ throw new Error("Withdraw finalize requires a withdraw operation.");
5993
+ }
5994
+ const withdrawIntent = prepared.intent;
5995
+ const withdrawFrom = withdrawIntent.from;
5996
+ const recordCount = prepared.consumedRecords.length;
5997
+ if (recordCount === 1) {
5998
+ return finalizeSingleWithdrawAtExecute(
5999
+ prepared,
6000
+ environment,
6001
+ poolService,
6002
+ withdrawFrom
6003
+ );
6004
+ }
6005
+ if (recordCount === 2) {
6006
+ return finalizeDualWithdrawAtExecute(
6007
+ prepared,
6008
+ environment,
6009
+ poolService,
6010
+ withdrawFrom
6011
+ );
6012
+ }
6013
+ throw new Error("Confidential withdraw execution supports at most two input notes.");
6309
6014
  }
6310
6015
  async function finalizeSpendOperationAtExecute(prepared, environment, poolService) {
6311
6016
  if (prepared.kind !== "transfer" && prepared.kind !== "withdraw") {
@@ -6324,6 +6029,12 @@ async function finalizeSpendOperationAtExecute(prepared, environment, poolServic
6324
6029
  };
6325
6030
  }
6326
6031
 
6032
+ // src/transact/kyt/passage/inspect.ts
6033
+ import {
6034
+ layoutForKnownNonce,
6035
+ zeroBindingTagsInPublicSignals
6036
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
6037
+
6327
6038
  // src/transact/kyt/inspect-error.ts
6328
6039
  var KytInspectError = class extends Error {
6329
6040
  reasonCode;
@@ -6406,16 +6117,16 @@ async function waitForKytRegistration(parameters) {
6406
6117
  }
6407
6118
 
6408
6119
  // src/transact/kyt/passage/submit.ts
6409
- import { Buffer as Buffer16 } from "buffer";
6120
+ import { Buffer as Buffer14 } from "buffer";
6410
6121
  import { Operation, TransactionBuilder, rpc as rpc3, xdr as xdr2 } from "@stellar/stellar-sdk";
6411
6122
  var KYT_REGISTER_FEE_STROOPS = "1000000";
6412
6123
  var KYT_REGISTER_TIMEOUT_SECONDS = 300;
6413
6124
  function passageIdToScValue(passageId) {
6414
- return xdr2.ScVal.scvBytes(Buffer16.from(passageId.replace(/^0x/, ""), "hex"));
6125
+ return xdr2.ScVal.scvBytes(Buffer14.from(passageId.replace(/^0x/, ""), "hex"));
6415
6126
  }
6416
6127
  function approvalSignatureToBytes(signature) {
6417
6128
  const clean = signature.trim();
6418
- return /^(0x)?[0-9a-fA-F]{128}$/.test(clean) ? Buffer16.from(clean.replace(/^0x/i, ""), "hex") : Buffer16.from(clean, "base64");
6129
+ return /^(0x)?[0-9a-fA-F]{128}$/.test(clean) ? Buffer14.from(clean.replace(/^0x/i, ""), "hex") : Buffer14.from(clean, "base64");
6419
6130
  }
6420
6131
  function signatureToScValue(signature) {
6421
6132
  const bytes = approvalSignatureToBytes(signature);
@@ -6464,8 +6175,8 @@ async function registerKytPassage(parameters) {
6464
6175
  }
6465
6176
 
6466
6177
  // src/transact/kyt/passage/inspect.ts
6467
- function buildApplicationIdHints(applicationId) {
6468
- return [applicationId, applicationId, applicationId, applicationId];
6178
+ function buildApplicationIdHints2(applicationId, nAuditSlots) {
6179
+ return uniformApplicationIdHints(applicationId, nAuditSlots);
6469
6180
  }
6470
6181
  function buildNonce() {
6471
6182
  return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}`;
@@ -6493,36 +6204,61 @@ function throwKytInspectRejected(body) {
6493
6204
  ...parsed.address ? { detailAddress: parsed.address } : {}
6494
6205
  });
6495
6206
  }
6496
- async function requestKytPassageForPoolInteraction(input) {
6497
- const applicationId = resolvePoolApplicationId(
6498
- input.transactEnvironment.network.applicationId
6499
- );
6500
- const applicationIdsPlaintext = input.applicationIdsPlaintext ?? buildApplicationIdHints(applicationId);
6501
- const kytRegistry = input.transactEnvironment.kyt.kytPassageRegistryContract;
6502
- const currentLedger = await fetchCurrentLedger(input.sorobanRpcUrl);
6207
+ function inspectRequestHeaders(inspectAuthorization) {
6208
+ const token = inspectAuthorization?.trim();
6209
+ return {
6210
+ "content-type": "application/json",
6211
+ ...token ? { authorization: `Bearer ${token}` } : {}
6212
+ };
6213
+ }
6214
+ async function postKytInspect(input, applicationIdsPlaintext, zkConfigNonce, currentLedger) {
6503
6215
  const response = await fetch(
6504
6216
  `${input.transactEnvironment.kyt.apiBaseUrl}/kyt/passages/inspect`,
6505
6217
  {
6506
6218
  method: "POST",
6507
- headers: { "content-type": "application/json" },
6219
+ headers: inspectRequestHeaders(
6220
+ input.transactEnvironment.kyt.inspectAuthorization
6221
+ ),
6508
6222
  body: JSON.stringify(
6509
6223
  {
6510
6224
  owner: input.owner,
6511
6225
  poolContract: input.poolContract,
6512
- kytRegistry,
6226
+ kytRegistry: input.transactEnvironment.kyt.kytPassageRegistryContract,
6513
6227
  proofBytes: input.proofHex,
6514
- publicSignalsBytes: input.publicHex,
6228
+ publicSignalsBytes: zeroBindingTagsInPublicSignals(
6229
+ input.publicHex,
6230
+ zkConfigNonce
6231
+ ).toString("hex"),
6515
6232
  applicationIdsPlaintext,
6516
6233
  decryptedAuditSlots: input.decryptedAuditSlots,
6517
- onboarding: input.onboarding,
6518
6234
  nonce: buildNonce(),
6519
- currentLedger
6235
+ zkConfigNonce,
6236
+ currentLedger,
6237
+ ...input.ciphertextHex ? { ciphertextBytes: input.ciphertextHex } : {},
6238
+ ...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {}
6520
6239
  },
6521
6240
  kytJsonReplacer
6522
6241
  )
6523
6242
  }
6524
6243
  );
6525
- const body = await parseInspectResponse(response);
6244
+ return parseInspectResponse(response);
6245
+ }
6246
+ async function requestKytPassageForPoolInteraction(input) {
6247
+ const applicationId = resolvePoolApplicationId(
6248
+ input.transactEnvironment.network.applicationId
6249
+ );
6250
+ const zkConfigNonce = resolveZkConfigNonce(input.transactEnvironment);
6251
+ const applicationIdsPlaintext = input.applicationIdsPlaintext ?? buildApplicationIdHints2(
6252
+ applicationId,
6253
+ layoutForKnownNonce(zkConfigNonce).nAuditSlots
6254
+ );
6255
+ const currentLedger = await fetchCurrentLedger(input.sorobanRpcUrl);
6256
+ const body = await postKytInspect(
6257
+ input,
6258
+ applicationIdsPlaintext,
6259
+ zkConfigNonce,
6260
+ currentLedger
6261
+ );
6526
6262
  if (body.status !== "approved") {
6527
6263
  throwKytInspectRejected(body);
6528
6264
  }
@@ -6538,14 +6274,129 @@ async function requestKytPassageForPoolInteraction(input) {
6538
6274
  return body;
6539
6275
  }
6540
6276
 
6277
+ // src/transact/submit/zk-config-ttl.ts
6278
+ import {
6279
+ Address as Address2,
6280
+ Operation as Operation2,
6281
+ SorobanDataBuilder,
6282
+ TransactionBuilder as TransactionBuilder2,
6283
+ rpc as rpc4,
6284
+ xdr as xdr3
6285
+ } from "@stellar/stellar-sdk";
6286
+ var ZK_CONFIG_TTL_THRESHOLD_LEDGERS = 1e5;
6287
+ var ZK_CONFIG_TTL_EXTEND_TO_LEDGERS = 5e5;
6288
+ var EXTEND_TTL_FEE_STROOPS = "1000000";
6289
+ var EXTEND_TTL_TIMEOUT_SECONDS = 300;
6290
+ var EXTEND_TTL_MAX_POLLS = 60;
6291
+ var EXTEND_TTL_POLL_INTERVAL_MS = 1e3;
6292
+ async function waitForExtendFootprintTtlConfirmation(parameters) {
6293
+ for (let attempt = 0; attempt < EXTEND_TTL_MAX_POLLS; attempt += 1) {
6294
+ const response = await parameters.server.getTransaction(parameters.hash);
6295
+ if (response.status === "SUCCESS") {
6296
+ return;
6297
+ }
6298
+ if (response.status === "FAILED") {
6299
+ throw new Error("ZK config TTL extension failed on-chain");
6300
+ }
6301
+ await new Promise((resolve) => {
6302
+ setTimeout(resolve, EXTEND_TTL_POLL_INTERVAL_MS);
6303
+ });
6304
+ }
6305
+ throw new Error("ZK config TTL extension was not confirmed in time");
6306
+ }
6307
+ function zkConfigLedgerKey(contractId, nonce) {
6308
+ const configKeyScValue = xdr3.ScVal.scvVec([
6309
+ xdr3.ScVal.scvSymbol("Config"),
6310
+ xdr3.ScVal.scvU64(xdr3.Uint64.fromString(nonce.toString()))
6311
+ ]);
6312
+ return xdr3.LedgerKey.contractData(
6313
+ new xdr3.LedgerKeyContractData({
6314
+ contract: new Address2(contractId).toScAddress(),
6315
+ key: configKeyScValue,
6316
+ durability: xdr3.ContractDataDurability.persistent()
6317
+ })
6318
+ );
6319
+ }
6320
+ async function needsTtlExtension(parameters) {
6321
+ const [entriesResponse, latestLedger] = await Promise.all([
6322
+ parameters.server.getLedgerEntries(parameters.ledgerKey),
6323
+ parameters.server.getLatestLedger()
6324
+ ]);
6325
+ const entry = entriesResponse.entries.at(0);
6326
+ if (!entry || entry.liveUntilLedgerSeq === void 0) {
6327
+ return false;
6328
+ }
6329
+ const remainingLedgers = entry.liveUntilLedgerSeq - latestLedger.sequence;
6330
+ return remainingLedgers < ZK_CONFIG_TTL_THRESHOLD_LEDGERS;
6331
+ }
6332
+ async function submitExtendFootprintTtlTransaction(parameters) {
6333
+ const sourceAccount = await parameters.server.getAccount(parameters.sourcePublicKey);
6334
+ const transaction = new TransactionBuilder2(sourceAccount, {
6335
+ fee: EXTEND_TTL_FEE_STROOPS,
6336
+ networkPassphrase: parameters.networkPassphrase
6337
+ }).addOperation(
6338
+ Operation2.extendFootprintTtl({ extendTo: ZK_CONFIG_TTL_EXTEND_TO_LEDGERS })
6339
+ ).setSorobanData(
6340
+ new SorobanDataBuilder().setReadOnly([parameters.ledgerKey]).build()
6341
+ ).setTimeout(EXTEND_TTL_TIMEOUT_SECONDS).build();
6342
+ const preparedTransaction = await parameters.server.prepareTransaction(transaction);
6343
+ const { signedTxXdr } = await parameters.signTransaction({
6344
+ xdr: preparedTransaction.toXDR(),
6345
+ networkPassphrase: parameters.networkPassphrase,
6346
+ address: parameters.sourcePublicKey
6347
+ });
6348
+ const signedTransaction = TransactionBuilder2.fromXDR(
6349
+ signedTxXdr,
6350
+ parameters.networkPassphrase
6351
+ );
6352
+ const result = await parameters.server.sendTransaction(signedTransaction);
6353
+ const status = String(result.status);
6354
+ if (status !== "PENDING" && status !== "SUCCESS") {
6355
+ throw new Error(`ZK config TTL extension submit failed: ${status}`);
6356
+ }
6357
+ await waitForExtendFootprintTtlConfirmation({
6358
+ server: parameters.server,
6359
+ hash: result.hash
6360
+ });
6361
+ }
6362
+ async function extendZkConfigTtlIfNeeded(parameters) {
6363
+ if (!parameters.signTransaction) {
6364
+ return;
6365
+ }
6366
+ const server = new rpc4.Server(parameters.sorobanRpcUrl, { allowHttp: true });
6367
+ const ledgerKey = zkConfigLedgerKey(parameters.contractId, parameters.nonce);
6368
+ if (!await needsTtlExtension({ server, ledgerKey })) {
6369
+ return;
6370
+ }
6371
+ await submitExtendFootprintTtlTransaction({
6372
+ server,
6373
+ ledgerKey,
6374
+ networkPassphrase: parameters.networkPassphrase,
6375
+ sourcePublicKey: parameters.sourcePublicKey,
6376
+ signTransaction: parameters.signTransaction
6377
+ });
6378
+ }
6379
+
6541
6380
  // src/transact/submit/pool-transact.ts
6542
- import { Buffer as Buffer17 } from "buffer";
6381
+ import { Buffer as Buffer15 } from "buffer";
6543
6382
  async function submitPoolTransact(parameters) {
6383
+ await extendZkConfigTtlIfNeeded({
6384
+ sorobanRpcUrl: parameters.sorobanRpcUrl,
6385
+ networkPassphrase: parameters.networkPassphrase,
6386
+ contractId: parameters.contractId,
6387
+ nonce: parameters.nonce,
6388
+ sourcePublicKey: parameters.from,
6389
+ signTransaction: parameters.transactEnvironment.signTransaction
6390
+ });
6544
6391
  const assembledTransaction = await parameters.contractClient.transact({
6545
6392
  from: parameters.from,
6546
- proof_bytes: Buffer17.from(parameters.proofHex.replace(/^0x/iu, ""), "hex"),
6547
- pub_signals_bytes: Buffer17.from(parameters.publicHex.replace(/^0x/iu, ""), "hex"),
6548
- onboarding: parameters.onboarding,
6393
+ nonce: parameters.nonce,
6394
+ proof_bytes: Buffer15.from(parameters.proofHex.replace(/^0x/iu, ""), "hex"),
6395
+ pub_signals_bytes: Buffer15.from(parameters.publicHex.replace(/^0x/iu, ""), "hex"),
6396
+ ciphertext_bytes: Buffer15.from(
6397
+ (parameters.ciphertextHex ?? "").replace(/^0x/iu, ""),
6398
+ "hex"
6399
+ ),
6549
6400
  kyt_authorization: {
6550
6401
  expiration_ledger: parameters.approval.expiresAtLedger,
6551
6402
  signature: approvalSignatureToBytes(parameters.approval.signature)
@@ -6573,7 +6424,8 @@ async function submitSorobanConfidentialTransfer(input) {
6573
6424
  poolContract: input.contractId,
6574
6425
  proofHex: input.proofHex,
6575
6426
  publicHex: input.publicHex,
6576
- ...input.onboarding ? { onboarding: input.onboarding } : {},
6427
+ ...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
6428
+ ...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {},
6577
6429
  ...input.applicationIdsPlaintext ? { applicationIdsPlaintext: input.applicationIdsPlaintext } : {},
6578
6430
  networkPassphrase: input.networkPassphrase,
6579
6431
  sorobanRpcUrl: input.sorobanRpcUrl,
@@ -6581,15 +6433,27 @@ async function submitSorobanConfidentialTransfer(input) {
6581
6433
  });
6582
6434
  return submitPoolTransact({
6583
6435
  contractClient: poolClient,
6436
+ contractId: input.contractId,
6584
6437
  from: input.walletPublicKey,
6438
+ nonce: resolveZkConfigNonce(input.transactEnvironment),
6585
6439
  proofHex: input.proofHex,
6586
6440
  publicHex: input.publicHex,
6587
- ...input.onboarding ? { onboarding: input.onboarding } : {},
6588
- approval
6441
+ ...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
6442
+ approval,
6443
+ networkPassphrase: input.networkPassphrase,
6444
+ sorobanRpcUrl: input.sorobanRpcUrl,
6445
+ transactEnvironment: input.transactEnvironment
6589
6446
  });
6590
6447
  }
6591
6448
 
6592
6449
  // src/transact/engine/submit.ts
6450
+ function optionalInspectCiphertext(artifacts) {
6451
+ return {
6452
+ ...artifacts.ciphertextHex ? { ciphertextHex: artifacts.ciphertextHex } : {},
6453
+ ...artifacts.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: artifacts.outputNoteEphemeralScalars } : {},
6454
+ ...artifacts.applicationIdsPlaintext ? { applicationIdsPlaintext: artifacts.applicationIdsPlaintext } : {}
6455
+ };
6456
+ }
6593
6457
  async function submitPreparedDeposit(prepared, environment) {
6594
6458
  const artifacts = prepared.transactArtifacts;
6595
6459
  const outputRecord = prepared.outputRecords[0];
@@ -6607,17 +6471,23 @@ async function submitPreparedDeposit(prepared, environment) {
6607
6471
  poolContract: environment.network.poolContract,
6608
6472
  proofHex: artifacts.proofHex,
6609
6473
  publicHex: artifacts.publicHex,
6610
- ...artifacts.applicationIdsPlaintext ? { applicationIdsPlaintext: artifacts.applicationIdsPlaintext } : {},
6474
+ ...optionalInspectCiphertext(artifacts),
6611
6475
  networkPassphrase: environment.network.networkPassphrase,
6612
6476
  sorobanRpcUrl: environment.network.rpcUrl,
6613
6477
  transactEnvironment: environment
6614
6478
  });
6615
6479
  return submitPoolTransact({
6616
6480
  contractClient: poolClient,
6481
+ contractId: environment.network.poolContract,
6617
6482
  from: artifacts.walletPublicKey,
6483
+ nonce: resolveZkConfigNonce(environment),
6618
6484
  proofHex: artifacts.proofHex,
6619
6485
  publicHex: artifacts.publicHex,
6620
- approval
6486
+ ...artifacts.ciphertextHex ? { ciphertextHex: artifacts.ciphertextHex } : {},
6487
+ approval,
6488
+ networkPassphrase: environment.network.networkPassphrase,
6489
+ sorobanRpcUrl: environment.network.rpcUrl,
6490
+ transactEnvironment: environment
6621
6491
  });
6622
6492
  }
6623
6493
  async function submitPreparedPoolTransact(prepared, environment) {
@@ -6630,8 +6500,7 @@ async function submitPreparedPoolTransact(prepared, environment) {
6630
6500
  walletPublicKey: artifacts.walletPublicKey,
6631
6501
  proofHex: artifacts.proofHex,
6632
6502
  publicHex: artifacts.publicHex,
6633
- ...artifacts.onboarding ? { onboarding: artifacts.onboarding } : {},
6634
- ...artifacts.applicationIdsPlaintext ? { applicationIdsPlaintext: artifacts.applicationIdsPlaintext } : {},
6503
+ ...optionalInspectCiphertext(artifacts),
6635
6504
  networkPassphrase: environment.network.networkPassphrase,
6636
6505
  sorobanRpcUrl: environment.network.rpcUrl,
6637
6506
  transactEnvironment: environment
@@ -6669,18 +6538,33 @@ function createBrowserStellarTransactEngine(input) {
6669
6538
  }
6670
6539
 
6671
6540
  // src/transact/engine/default-factory.ts
6672
- async function createDefaultTransactEngine(assets, transactEnvironment) {
6673
- await PrivacyPoolSDK4.init({
6541
+ async function privacyPoolInitOptions(assets, transactEnvironment) {
6542
+ if (!transactEnvironment) {
6543
+ return { wasmBinary: assets.sdkWasm };
6544
+ }
6545
+ const zkConfigNonce = resolveZkConfigNonce(transactEnvironment);
6546
+ const zkCircuits = await materializeSelectedZkCircuit(
6547
+ transactEnvironment.zkCircuits,
6548
+ zkConfigNonce
6549
+ );
6550
+ return {
6674
6551
  wasmBinary: assets.sdkWasm,
6675
- circuitWasm: assets.circuitWasm,
6676
- zkey: assets.provingKey
6677
- });
6552
+ zkCircuits,
6553
+ zkConfigNonce,
6554
+ ...optionalZkArtifactBaseUrl(transactEnvironment.zkArtifactBaseUrl)
6555
+ };
6556
+ }
6557
+ async function createDefaultTransactEngine(assets, transactEnvironment) {
6558
+ await PrivacyPoolSDK3.init(await privacyPoolInitOptions(assets, transactEnvironment));
6678
6559
  if (transactEnvironment) {
6679
6560
  configurePrivacyPoolService(
6680
6561
  createPrivacyPoolService({
6681
6562
  assets,
6682
6563
  applicationId: transactEnvironment.network.applicationId,
6683
- ...transactEnvironment.auditPublicKey ? { auditPublicKey: transactEnvironment.auditPublicKey } : {}
6564
+ ...transactEnvironment.auditPublicKey ? { auditPublicKey: transactEnvironment.auditPublicKey } : {},
6565
+ ...transactEnvironment.zkCircuits ? { zkCircuits: transactEnvironment.zkCircuits } : {},
6566
+ ...transactEnvironment.zkConfigNonce === void 0 ? {} : { zkConfigNonce: transactEnvironment.zkConfigNonce },
6567
+ ...optionalZkArtifactBaseUrl(transactEnvironment.zkArtifactBaseUrl)
6684
6568
  })
6685
6569
  );
6686
6570
  return createBrowserStellarTransactEngine({
@@ -6723,7 +6607,7 @@ async function createStellarPrivacyClientFromNodeConfig(config) {
6723
6607
  return input.transactEngine;
6724
6608
  }
6725
6609
  const browserAssets = await loadNodeAssets(input.assets);
6726
- return createDefaultTransactEngine(browserAssets);
6610
+ return createDefaultTransactEngine(browserAssets, input.transactEnvironment);
6727
6611
  });
6728
6612
  if (!resolved.ok) {
6729
6613
  return resolved.result;