@arcanetech/privacy-sdk-stellar 0.6.1 → 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -227,7 +227,10 @@ function uniformApplicationIdHints(applicationId, nAuditSlots) {
227
227
  }
228
228
 
229
229
  // src/transact/proofs/confidential/helpers.ts
230
- import { withdrawObjectFromMerkleWitness } from "@arcanetech/stellar-privacy-pool-zk-sdk";
230
+ import {
231
+ withdrawObjectFromEscrowMerkleWitness,
232
+ withdrawObjectFromMerkleWitness
233
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
231
234
 
232
235
  // src/transact/merkle/lean-imt-api.ts
233
236
  function asLeanImtSessionApi(sdk) {
@@ -459,11 +462,33 @@ function withdrawMerkleWitnessFromTree(input) {
459
462
  // src/transact/proofs/confidential/helpers.ts
460
463
  var MIN_CONFIDENTIAL_TRANSFER_STROOPS = 1n;
461
464
  var ZERO_STROOPS = 0n;
465
+ function escrowSpendWitnessFromLimbs(limbs, derivedScalarHex) {
466
+ const nonce = limbs.nonceDecimal?.trim() ?? "";
467
+ if (!nonce) {
468
+ throw new Error("Escrow claimant limbs require nonceDecimal");
469
+ }
470
+ return {
471
+ nonce,
472
+ recipientHi: limbs.recipientHi,
473
+ recipientLo: limbs.recipientLo,
474
+ derivedScalarHex
475
+ };
476
+ }
462
477
  function withdrawWitnessForCoin(parameters) {
463
478
  const { sdk, coin, state } = parameters;
464
479
  const witness = withdrawMerkleWitnessFromTree({ sdk, coin, state });
465
480
  const withdrawApplicationId = coin.application_id ?? parameters.applicationId;
466
- const withdrawObject = withdrawObjectFromMerkleWitness(
481
+ const withdrawObject = parameters.escrow ? withdrawObjectFromEscrowMerkleWitness(
482
+ witness,
483
+ parameters.ownerPubHex,
484
+ withdrawApplicationId,
485
+ parameters.escrow.derivedScalarHex,
486
+ {
487
+ nonce: parameters.escrow.nonce,
488
+ recipientHi: parameters.escrow.recipientHi,
489
+ recipientLo: parameters.escrow.recipientLo
490
+ }
491
+ ) : withdrawObjectFromMerkleWitness(
467
492
  witness,
468
493
  parameters.ownerPubHex,
469
494
  withdrawApplicationId,
@@ -472,21 +497,21 @@ function withdrawWitnessForCoin(parameters) {
472
497
  return { witness, withdrawObject };
473
498
  }
474
499
  function dualWithdrawLegsWithSharedRoot(parameters) {
475
- const legA = withdrawWitnessForCoin({
500
+ const shared = {
476
501
  sdk: parameters.sdk,
477
- coin: parameters.coinA,
478
502
  state: parameters.state,
479
503
  ownerPubHex: parameters.ownerPubHex,
480
504
  privKeyScalar: parameters.privKeyScalar,
481
- applicationId: parameters.applicationId
505
+ applicationId: parameters.applicationId,
506
+ ...parameters.escrow ? { escrow: parameters.escrow } : {}
507
+ };
508
+ const legA = withdrawWitnessForCoin({
509
+ ...shared,
510
+ coin: parameters.coinA
482
511
  });
483
512
  const legB = withdrawWitnessForCoin({
484
- sdk: parameters.sdk,
485
- coin: parameters.coinB,
486
- state: parameters.state,
487
- ownerPubHex: parameters.ownerPubHex,
488
- privKeyScalar: parameters.privKeyScalar,
489
- applicationId: parameters.applicationId
513
+ ...shared,
514
+ coin: parameters.coinB
490
515
  });
491
516
  if (legA.witness.stateRoot !== legB.witness.stateRoot) {
492
517
  throw new Error("Merkle state root mismatch between input coins");
@@ -757,7 +782,10 @@ function ed25519PublicKeyHexFromStellarAccount(address) {
757
782
  }
758
783
 
759
784
  // src/transact/encoding/priv-key-scalar-from-recipient-hex.ts
760
- import { canonicalBabyJubScalarFromInteger } from "@arcanetech/stellar-privacy-pool-zk-sdk";
785
+ import {
786
+ canonicalBabyJubScalarFromInteger,
787
+ reduceDerivedEscrowSpendScalar
788
+ } from "@arcanetech/stellar-privacy-pool-zk-sdk";
761
789
  var SCALAR_HEX_CHAR_LENGTH = 64;
762
790
  var DECIMAL_RADIX2 = 10;
763
791
  function normalizeRecipientScalarHex(hexInput) {
@@ -780,6 +808,25 @@ function privKeyScalarDecimalFromRecipientScalarHex(hexInput) {
780
808
  const value = BigInt(`0x${hex}`);
781
809
  return canonicalBabyJubScalarFromInteger(value).toString(DECIMAL_RADIX2);
782
810
  }
811
+ function privKeyScalarDecimalFromDerivedEscrowHex(hexInput) {
812
+ const hex = normalizeRecipientScalarHex(hexInput);
813
+ const value = BigInt(`0x${hex}`);
814
+ return reduceDerivedEscrowSpendScalar(value).toString(DECIMAL_RADIX2);
815
+ }
816
+ function resolveTransferSpendScalars(input) {
817
+ const senderHex = input.senderPrivKeyScalarHex;
818
+ if (!input.escrowSweep) {
819
+ return {
820
+ privKeyScalar: privKeyScalarDecimalFromRecipientScalarHex(senderHex),
821
+ ownerScalarHex: senderHex
822
+ };
823
+ }
824
+ const privKeyScalar = privKeyScalarDecimalFromDerivedEscrowHex(senderHex);
825
+ return {
826
+ privKeyScalar,
827
+ ownerScalarHex: BigInt(privKeyScalar).toString(16).padStart(SCALAR_HEX_CHAR_LENGTH, "0")
828
+ };
829
+ }
783
830
 
784
831
  // src/transact/fees/append-fee-output.ts
785
832
  function feeCoinFromSlot(slot) {
@@ -3033,14 +3080,63 @@ async function buildSenderTransferDepositsAndPublicInput(parameters) {
3033
3080
  });
3034
3081
  }
3035
3082
 
3036
- // src/transact/proofs/confidential/dual.ts
3037
- function confidentialEscrowFields(parameters) {
3083
+ // src/transact/proofs/confidential/transfer-spend.ts
3084
+ function confidentialEscrowFields(input) {
3038
3085
  return {
3039
- ...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
3040
- ...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
3086
+ ...input.escrowSend ? { escrowSend: input.escrowSend } : {},
3087
+ ...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
3088
+ };
3089
+ }
3090
+ function transferDepositInputFromProof(input, changeStroops, stateRoot) {
3091
+ return {
3092
+ senderPrivKeyScalarHex: input.senderPrivKeyScalarHex,
3093
+ recipientPrivateAddressStpl1: input.recipientPrivateAddressStpl1,
3094
+ transferStroops: input.transferStroops,
3095
+ changeStroops,
3096
+ selfPrivateAddressStpl1ForChange: input.selfPrivateAddressStpl1ForChange,
3097
+ tokenAddress: input.tokenAddress,
3098
+ stateRoot,
3099
+ ...confidentialEscrowFields(input),
3100
+ ...input.feeOutput ? { feeOutput: input.feeOutput } : {}
3101
+ };
3102
+ }
3103
+ function spendWithdrawForTransfer(parameters) {
3104
+ const limbs = parameters.input.escrowClaimantLimbs;
3105
+ const { privKeyScalar, ownerScalarHex } = resolveTransferSpendScalars({
3106
+ senderPrivKeyScalarHex: parameters.input.senderPrivKeyScalarHex,
3107
+ escrowSweep: Boolean(limbs)
3108
+ });
3109
+ const spent = withdrawWitnessForCoin({
3110
+ sdk: parameters.sdk,
3111
+ coin: parameters.input.coin,
3112
+ state: parameters.input.state,
3113
+ ownerPubHex: parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(ownerScalarHex),
3114
+ privKeyScalar,
3115
+ applicationId: parameters.applicationId,
3116
+ ...limbs ? {
3117
+ escrow: escrowSpendWitnessFromLimbs(
3118
+ limbs,
3119
+ parameters.input.senderPrivKeyScalarHex
3120
+ )
3121
+ } : {}
3122
+ });
3123
+ if (limbs) {
3124
+ return spent;
3125
+ }
3126
+ return {
3127
+ witness: spent.witness,
3128
+ withdrawObject: stampWithdrawEscrowLimbs(
3129
+ spent.withdrawObject,
3130
+ sweepWithdrawStamp(confidentialEscrowFields(parameters.input))
3131
+ )
3041
3132
  };
3042
3133
  }
3134
+
3135
+ // src/transact/proofs/confidential/dual.ts
3043
3136
  function stampDualWithdrawLegs(legs, parameters) {
3137
+ if (parameters.escrowClaimantLimbs) {
3138
+ return legs;
3139
+ }
3044
3140
  const escrowLimbs = sweepWithdrawStamp(confidentialEscrowFields(parameters));
3045
3141
  return {
3046
3142
  legA: {
@@ -3104,12 +3200,12 @@ function dualTransferChangeStroops(parameters) {
3104
3200
  }
3105
3201
  async function buildDualTransferProofContext(parameters, applicationId, sdk) {
3106
3202
  const changeStroops = dualTransferChangeStroops(parameters);
3107
- const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
3108
- parameters.senderPrivKeyScalarHex
3109
- );
3110
- const ownerPubHex = sdk.ecdhEphemeralPublicKeyFromScalarHex(
3111
- parameters.senderPrivKeyScalarHex
3112
- );
3203
+ const limbs = parameters.escrowClaimantLimbs;
3204
+ const { privKeyScalar, ownerScalarHex } = resolveTransferSpendScalars({
3205
+ senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex,
3206
+ escrowSweep: Boolean(limbs)
3207
+ });
3208
+ const ownerPubHex = sdk.ecdhEphemeralPublicKeyFromScalarHex(ownerScalarHex);
3113
3209
  const { legA, legB } = stampDualWithdrawLegs(
3114
3210
  dualWithdrawLegsWithSharedRoot({
3115
3211
  sdk,
@@ -3118,7 +3214,13 @@ async function buildDualTransferProofContext(parameters, applicationId, sdk) {
3118
3214
  state: parameters.state,
3119
3215
  ownerPubHex,
3120
3216
  privKeyScalar,
3121
- applicationId
3217
+ applicationId,
3218
+ ...limbs ? {
3219
+ escrow: escrowSpendWitnessFromLimbs(
3220
+ limbs,
3221
+ parameters.senderPrivKeyScalarHex
3222
+ )
3223
+ } : {}
3122
3224
  }),
3123
3225
  parameters
3124
3226
  );
@@ -3221,25 +3323,6 @@ async function proveTransaction(parameters) {
3221
3323
  parameters.audit
3222
3324
  );
3223
3325
  }
3224
- function confidentialEscrowFields2(input) {
3225
- return {
3226
- ...input.escrowSend ? { escrowSend: input.escrowSend } : {},
3227
- ...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
3228
- };
3229
- }
3230
- function transferDepositInputFromProof(input, changeStroops, stateRoot) {
3231
- return {
3232
- senderPrivKeyScalarHex: input.senderPrivKeyScalarHex,
3233
- recipientPrivateAddressStpl1: input.recipientPrivateAddressStpl1,
3234
- transferStroops: input.transferStroops,
3235
- changeStroops,
3236
- selfPrivateAddressStpl1ForChange: input.selfPrivateAddressStpl1ForChange,
3237
- tokenAddress: input.tokenAddress,
3238
- stateRoot,
3239
- ...confidentialEscrowFields2(input),
3240
- ...input.feeOutput ? { feeOutput: input.feeOutput } : {}
3241
- };
3242
- }
3243
3326
  async function buildTransferProofInputs(parameters) {
3244
3327
  const changeStroops = validateSingleCoinTransferAmounts(
3245
3328
  parameters.input.transferStroops,
@@ -3247,35 +3330,11 @@ async function buildTransferProofInputs(parameters) {
3247
3330
  parameters.input.selfPrivateAddressStpl1ForChange,
3248
3331
  parameters.input.feeOutput?.requiredFee ?? 0n
3249
3332
  );
3250
- const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
3251
- parameters.input.senderPrivKeyScalarHex
3252
- );
3253
- const { witness, withdrawObject } = withdrawWitnessForCoin({
3254
- sdk: parameters.sdk,
3255
- coin: parameters.input.coin,
3256
- state: parameters.input.state,
3257
- ownerPubHex: parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
3258
- parameters.input.senderPrivKeyScalarHex
3259
- ),
3260
- privKeyScalar,
3261
- applicationId: parameters.applicationId
3262
- });
3263
- const stampedWithdraw = stampWithdrawEscrowLimbs(
3264
- withdrawObject,
3265
- sweepWithdrawStamp(confidentialEscrowFields2(parameters.input))
3266
- );
3267
- const { recipientSlot, deposits, changeCoin, feeCoin, publicInput } = await buildSenderTransferDepositsAndPublicInput(
3333
+ const { witness, withdrawObject } = spendWithdrawForTransfer(parameters);
3334
+ const depositsBuild = await buildSenderTransferDepositsAndPublicInput(
3268
3335
  transferDepositInputFromProof(parameters.input, changeStroops, witness.stateRoot)
3269
3336
  );
3270
- return {
3271
- witness,
3272
- withdrawObject: stampedWithdraw,
3273
- recipientSlot,
3274
- deposits,
3275
- changeCoin,
3276
- feeCoin,
3277
- publicInput
3278
- };
3337
+ return { witness, withdrawObject, ...depositsBuild };
3279
3338
  }
3280
3339
  async function prepareConfidentialTransferProof(parameters) {
3281
3340
  const poolService = getPrivacyPoolService();