@arcanetech/privacy-sdk-stellar 0.5.2 → 0.6.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/README.md +1 -0
- package/dist/index.d.ts +85 -25
- package/dist/index.js +1081 -258
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +25 -1
- package/dist/node.js +1082 -267
- package/dist/node.js.map +1 -1
- package/dist/state/index.d.ts +31 -1
- package/dist/state/index.js +10 -2
- package/dist/state/index.js.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/transact/index.d.ts +50 -6
- package/dist/transact/index.js +975 -264
- package/dist/transact/index.js.map +1 -1
- package/package.json +7 -7
package/dist/node.js
CHANGED
|
@@ -466,13 +466,26 @@ function buildPrivateRecordFromDeposit(input) {
|
|
|
466
466
|
};
|
|
467
467
|
}
|
|
468
468
|
|
|
469
|
-
// src/transact/
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
469
|
+
// src/transact/merkle/lean-imt-api.ts
|
|
470
|
+
function asLeanImtSessionApi(sdk) {
|
|
471
|
+
const candidate = sdk;
|
|
472
|
+
if (typeof candidate.importLeanImtFromState !== "function") {
|
|
473
|
+
return void 0;
|
|
474
|
+
}
|
|
475
|
+
if (typeof candidate.insertTwoLeanImt !== "function") {
|
|
476
|
+
return void 0;
|
|
477
|
+
}
|
|
478
|
+
if (typeof candidate.exportLeanImt !== "function") {
|
|
479
|
+
return void 0;
|
|
480
|
+
}
|
|
481
|
+
if (typeof candidate.dropLeanImt !== "function") {
|
|
482
|
+
return void 0;
|
|
483
|
+
}
|
|
484
|
+
if (typeof candidate.buildWithdrawMerkleWitnessFromHandle !== "function") {
|
|
485
|
+
return void 0;
|
|
486
|
+
}
|
|
487
|
+
return candidate;
|
|
488
|
+
}
|
|
476
489
|
|
|
477
490
|
// src/transact/merkle/field-decimal.ts
|
|
478
491
|
import { Buffer as Buffer4 } from "buffer";
|
|
@@ -488,6 +501,230 @@ function merkleRootBufferToFrDecimal(root) {
|
|
|
488
501
|
const hex = Buffer4.from(root).toString("hex");
|
|
489
502
|
return (BigInt(`0x${hex}`) % BN254).toString(DECIMAL_STRING_RADIX);
|
|
490
503
|
}
|
|
504
|
+
var MERKLE_ROOT_HEX_PATTERN = /^[0-9a-fA-F]{64}$/;
|
|
505
|
+
function merkleRootHexToFrDecimal(merkleRootHex) {
|
|
506
|
+
const trimmed = merkleRootHex.trim();
|
|
507
|
+
if (!MERKLE_ROOT_HEX_PATTERN.test(trimmed)) {
|
|
508
|
+
return void 0;
|
|
509
|
+
}
|
|
510
|
+
return merkleRootBufferToFrDecimal(Buffer4.from(trimmed, "hex"));
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// src/transact/merkle/state-file.ts
|
|
514
|
+
function merkleSnapshotToStateFile(input) {
|
|
515
|
+
const root = merkleRootHexToFrDecimal(input.merkleRootHex);
|
|
516
|
+
const nodes = input.nodes;
|
|
517
|
+
if (!nodes || nodes.length === 0 || root === void 0) {
|
|
518
|
+
return { commitments: input.commitments };
|
|
519
|
+
}
|
|
520
|
+
return {
|
|
521
|
+
commitments: input.commitments,
|
|
522
|
+
nodes,
|
|
523
|
+
root
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// src/transact/merkle/extend-snapshot.ts
|
|
528
|
+
function isEvenLeafCount(count) {
|
|
529
|
+
return count % 2 === 0;
|
|
530
|
+
}
|
|
531
|
+
function importHandle(sdk, state) {
|
|
532
|
+
try {
|
|
533
|
+
return sdk.importLeanImtFromState(state);
|
|
534
|
+
} catch {
|
|
535
|
+
return void 0;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
function insertNewPairs(input) {
|
|
539
|
+
for (let index = input.prefixLength; index < input.commitments.length; index += 2) {
|
|
540
|
+
const leafA = input.commitments.at(index);
|
|
541
|
+
const leafB = input.commitments.at(index + 1);
|
|
542
|
+
if (leafA === void 0 || leafB === void 0) {
|
|
543
|
+
return false;
|
|
544
|
+
}
|
|
545
|
+
try {
|
|
546
|
+
input.sdk.insertTwoLeanImt(input.handle, leafA, leafB);
|
|
547
|
+
} catch {
|
|
548
|
+
return false;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return true;
|
|
552
|
+
}
|
|
553
|
+
function snapshotNodes(sdk, handle) {
|
|
554
|
+
try {
|
|
555
|
+
return sdk.exportLeanImt(handle).nodes;
|
|
556
|
+
} catch {
|
|
557
|
+
return void 0;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
function prefixSnapshotState(input) {
|
|
561
|
+
const prefixLength = input.cachedState?.nodes ? input.cachedState.commitments.length : 0;
|
|
562
|
+
return merkleSnapshotToStateFile({
|
|
563
|
+
commitments: input.commitments.slice(0, prefixLength),
|
|
564
|
+
merkleRootHex: input.cachedState?.merkleRootHex ?? input.merkleRootHex,
|
|
565
|
+
...input.cachedState?.nodes ? { nodes: input.cachedState.nodes } : {}
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
function importSnapshotState(input) {
|
|
569
|
+
if (input.prefixState.nodes && input.prefixState.commitments.length > 0) {
|
|
570
|
+
return input.prefixState;
|
|
571
|
+
}
|
|
572
|
+
return merkleSnapshotToStateFile({
|
|
573
|
+
commitments: input.commitments,
|
|
574
|
+
merkleRootHex: input.merkleRootHex
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
function exportExtendedNodes(input) {
|
|
578
|
+
const inserted = input.prefixState.nodes ? insertNewPairs({
|
|
579
|
+
sdk: input.sdk,
|
|
580
|
+
handle: input.handle,
|
|
581
|
+
prefixLength: input.prefixState.commitments.length,
|
|
582
|
+
commitments: input.commitments
|
|
583
|
+
}) : true;
|
|
584
|
+
if (!inserted) {
|
|
585
|
+
input.sdk.dropLeanImt(input.handle);
|
|
586
|
+
return void 0;
|
|
587
|
+
}
|
|
588
|
+
const nodes = snapshotNodes(input.sdk, input.handle);
|
|
589
|
+
if (!nodes) {
|
|
590
|
+
input.sdk.dropLeanImt(input.handle);
|
|
591
|
+
}
|
|
592
|
+
return nodes;
|
|
593
|
+
}
|
|
594
|
+
function extendMerkleSnapshotNodes(input) {
|
|
595
|
+
if (!isEvenLeafCount(input.commitments.length)) {
|
|
596
|
+
return {};
|
|
597
|
+
}
|
|
598
|
+
const prefixState = prefixSnapshotState(input);
|
|
599
|
+
const handle = importHandle(
|
|
600
|
+
input.sdk,
|
|
601
|
+
importSnapshotState({ ...input, prefixState })
|
|
602
|
+
);
|
|
603
|
+
if (handle === void 0) {
|
|
604
|
+
return {};
|
|
605
|
+
}
|
|
606
|
+
const nodes = exportExtendedNodes({
|
|
607
|
+
sdk: input.sdk,
|
|
608
|
+
handle,
|
|
609
|
+
prefixState,
|
|
610
|
+
commitments: input.commitments
|
|
611
|
+
});
|
|
612
|
+
if (!nodes) {
|
|
613
|
+
return {};
|
|
614
|
+
}
|
|
615
|
+
return { nodes, handle };
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// src/transact/merkle/tree-session.ts
|
|
619
|
+
var merkleSdkHost;
|
|
620
|
+
function registerMerkleSessionSdkHost(host) {
|
|
621
|
+
merkleSdkHost = host;
|
|
622
|
+
}
|
|
623
|
+
async function loadSessionSdk() {
|
|
624
|
+
const host = merkleSdkHost;
|
|
625
|
+
if (typeof host?.getInitializedSdk !== "function") {
|
|
626
|
+
return void 0;
|
|
627
|
+
}
|
|
628
|
+
try {
|
|
629
|
+
return asLeanImtSessionApi(await host.getInitializedSdk());
|
|
630
|
+
} catch {
|
|
631
|
+
return void 0;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
var sessionsByPool = /* @__PURE__ */ new Map();
|
|
635
|
+
var handlesByKey = /* @__PURE__ */ new Map();
|
|
636
|
+
function merkleSessionKey(state) {
|
|
637
|
+
const root = state.root?.trim();
|
|
638
|
+
if (root) {
|
|
639
|
+
return `${state.commitments.length}:${root}`;
|
|
640
|
+
}
|
|
641
|
+
const first = state.commitments[0] ?? "";
|
|
642
|
+
const last = state.commitments.at(-1) ?? "";
|
|
643
|
+
return `${state.commitments.length}:${first}:${last}`;
|
|
644
|
+
}
|
|
645
|
+
function rememberHandle(poolContract, key, handle) {
|
|
646
|
+
const existing = sessionsByPool.get(poolContract);
|
|
647
|
+
if (existing && existing.handle !== handle) {
|
|
648
|
+
handlesByKey.delete(existing.key);
|
|
649
|
+
}
|
|
650
|
+
sessionsByPool.set(poolContract, { handle, key });
|
|
651
|
+
handlesByKey.set(key, handle);
|
|
652
|
+
}
|
|
653
|
+
function importHandle2(sdk, state) {
|
|
654
|
+
try {
|
|
655
|
+
return sdk.importLeanImtFromState(state);
|
|
656
|
+
} catch {
|
|
657
|
+
return void 0;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
function merkleTreeHandleForState(state) {
|
|
661
|
+
return handlesByKey.get(merkleSessionKey(state));
|
|
662
|
+
}
|
|
663
|
+
function bindImportedMerkleTree(input) {
|
|
664
|
+
rememberHandle(input.poolContract, merkleSessionKey(input.state), input.handle);
|
|
665
|
+
}
|
|
666
|
+
async function bindPoolMerkleTree(state) {
|
|
667
|
+
const sdk = await loadSessionSdk();
|
|
668
|
+
if (!sdk) {
|
|
669
|
+
return void 0;
|
|
670
|
+
}
|
|
671
|
+
const snapshot = merkleSnapshotToStateFile(state);
|
|
672
|
+
const key = merkleSessionKey(snapshot);
|
|
673
|
+
const existing = sessionsByPool.get(state.poolContract);
|
|
674
|
+
if (existing?.key === key) {
|
|
675
|
+
return existing.handle;
|
|
676
|
+
}
|
|
677
|
+
const handle = importHandle2(sdk, snapshot);
|
|
678
|
+
if (handle === void 0) {
|
|
679
|
+
return void 0;
|
|
680
|
+
}
|
|
681
|
+
if (existing) {
|
|
682
|
+
sdk.dropLeanImt(existing.handle);
|
|
683
|
+
}
|
|
684
|
+
rememberHandle(state.poolContract, key, handle);
|
|
685
|
+
return handle;
|
|
686
|
+
}
|
|
687
|
+
async function resolveExtendedMerkleNodes(input) {
|
|
688
|
+
const cached = input.cachedState;
|
|
689
|
+
if (cached && cached.commitments.length === input.commitments.length && cached.merkleRootHex === input.merkleRootHex) {
|
|
690
|
+
return cached.nodes;
|
|
691
|
+
}
|
|
692
|
+
const sdk = await loadSessionSdk();
|
|
693
|
+
if (!sdk) {
|
|
694
|
+
return void 0;
|
|
695
|
+
}
|
|
696
|
+
const extended = extendMerkleSnapshotNodes({
|
|
697
|
+
sdk,
|
|
698
|
+
commitments: input.commitments,
|
|
699
|
+
merkleRootHex: input.merkleRootHex,
|
|
700
|
+
...cached ? { cachedState: cached } : {}
|
|
701
|
+
});
|
|
702
|
+
if (extended.handle !== void 0) {
|
|
703
|
+
bindImportedMerkleTree({
|
|
704
|
+
poolContract: input.poolContract,
|
|
705
|
+
handle: extended.handle,
|
|
706
|
+
state: merkleSnapshotToStateFile({
|
|
707
|
+
commitments: input.commitments,
|
|
708
|
+
merkleRootHex: input.merkleRootHex,
|
|
709
|
+
...extended.nodes ? { nodes: extended.nodes } : {}
|
|
710
|
+
})
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
return extended.nodes;
|
|
714
|
+
}
|
|
715
|
+
function withdrawMerkleWitnessFromTree(input) {
|
|
716
|
+
const session = asLeanImtSessionApi(input.sdk);
|
|
717
|
+
const handle = merkleTreeHandleForState(input.state);
|
|
718
|
+
if (session && handle !== void 0) {
|
|
719
|
+
return session.buildWithdrawMerkleWitnessFromHandle(input.coin, handle);
|
|
720
|
+
}
|
|
721
|
+
return input.sdk.buildWithdrawMerkleWitness(input.coin, input.state);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// src/transact/pool/service.ts
|
|
725
|
+
import {
|
|
726
|
+
decodeDecodedEphemeralKey
|
|
727
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
491
728
|
|
|
492
729
|
// src/transact/private-address/codec.ts
|
|
493
730
|
import {
|
|
@@ -700,7 +937,7 @@ var MIN_CONFIDENTIAL_TRANSFER_STROOPS = 1n;
|
|
|
700
937
|
var ZERO_STROOPS = 0n;
|
|
701
938
|
function withdrawWitnessForCoin(parameters) {
|
|
702
939
|
const { sdk, coin, state } = parameters;
|
|
703
|
-
const witness = sdk
|
|
940
|
+
const witness = withdrawMerkleWitnessFromTree({ sdk, coin, state });
|
|
704
941
|
const withdrawApplicationId = coin.application_id ?? parameters.applicationId;
|
|
705
942
|
const withdrawObject = withdrawObjectFromMerkleWitness(
|
|
706
943
|
witness,
|
|
@@ -742,14 +979,144 @@ function requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl
|
|
|
742
979
|
}
|
|
743
980
|
}
|
|
744
981
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
982
|
+
|
|
983
|
+
// src/transact/fees/quote-request-body.ts
|
|
984
|
+
function presentInstructedAmount(amount) {
|
|
985
|
+
const trimmed = amount?.trim() ?? "";
|
|
986
|
+
if (!trimmed || trimmed === "0") {
|
|
987
|
+
return void 0;
|
|
748
988
|
}
|
|
749
|
-
|
|
750
|
-
|
|
989
|
+
return trimmed;
|
|
990
|
+
}
|
|
991
|
+
function feeQuoteRequestBody(request) {
|
|
992
|
+
const publicDepositAmount = presentInstructedAmount(request.publicDepositAmount);
|
|
993
|
+
const transferInstructedAmount = presentInstructedAmount(
|
|
994
|
+
request.transferInstructedAmount
|
|
995
|
+
);
|
|
996
|
+
const publicWithdrawalAmount = presentInstructedAmount(
|
|
997
|
+
request.publicWithdrawalAmount
|
|
998
|
+
);
|
|
999
|
+
return {
|
|
1000
|
+
feeAsset: request.feeAsset,
|
|
1001
|
+
spendsNotes: request.spendsNotes,
|
|
1002
|
+
...publicDepositAmount === void 0 ? {} : { publicDepositAmount },
|
|
1003
|
+
...transferInstructedAmount === void 0 ? {} : { transferInstructedAmount },
|
|
1004
|
+
...publicWithdrawalAmount === void 0 ? {} : { publicWithdrawalAmount }
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
// src/transact/fees/quote-required-fee.ts
|
|
1009
|
+
function quoteHeaders(inspectAuthorization) {
|
|
1010
|
+
const token = inspectAuthorization?.trim();
|
|
1011
|
+
return {
|
|
1012
|
+
"content-type": "application/json",
|
|
1013
|
+
...token ? { authorization: `Bearer ${token}` } : {}
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
function parseRequiredFee(raw) {
|
|
1017
|
+
const text = `${raw ?? ""}`.trim();
|
|
1018
|
+
if (!/^\d+$/u.test(text)) {
|
|
1019
|
+
throw new Error("Fee Quote Required Fee must be an integer minor-unit string.");
|
|
751
1020
|
}
|
|
752
|
-
return
|
|
1021
|
+
return BigInt(text);
|
|
1022
|
+
}
|
|
1023
|
+
function requireQuoteString(raw, field) {
|
|
1024
|
+
const text = `${raw ?? ""}`.trim();
|
|
1025
|
+
if (!text) {
|
|
1026
|
+
throw new Error(`Fee Quote is missing ${field}.`);
|
|
1027
|
+
}
|
|
1028
|
+
return text;
|
|
1029
|
+
}
|
|
1030
|
+
function parseQuotePayload(payload) {
|
|
1031
|
+
return {
|
|
1032
|
+
requiredFee: parseRequiredFee(payload.requiredFee),
|
|
1033
|
+
feeAsset: requireQuoteString(payload.feeAsset, "Fee Asset"),
|
|
1034
|
+
feeCollectorPrivateAddress: requireQuoteString(
|
|
1035
|
+
payload.feeCollectorPrivateAddress,
|
|
1036
|
+
"Fee Collector Private Address"
|
|
1037
|
+
),
|
|
1038
|
+
feeRate: requireQuoteString(payload.feeRate, "Fee Rate")
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
async function quoteRequiredFee(input) {
|
|
1042
|
+
const response = await fetch(
|
|
1043
|
+
`${input.transactEnvironment.kyt.apiBaseUrl}/kyt/fees/quote`,
|
|
1044
|
+
{
|
|
1045
|
+
method: "POST",
|
|
1046
|
+
headers: quoteHeaders(input.transactEnvironment.kyt.inspectAuthorization),
|
|
1047
|
+
body: JSON.stringify(feeQuoteRequestBody(input.request))
|
|
1048
|
+
}
|
|
1049
|
+
);
|
|
1050
|
+
const payload = await response.json();
|
|
1051
|
+
if (!response.ok) {
|
|
1052
|
+
throw new Error(`Fee Quote failed: ${JSON.stringify(payload)}`);
|
|
1053
|
+
}
|
|
1054
|
+
return parseQuotePayload(payload);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
// src/transact/fees/should-attach-fee-output.ts
|
|
1058
|
+
function shouldAttachFeeOutput(input) {
|
|
1059
|
+
if (input.spendSource === "escrow" && input.escrowSend !== true) {
|
|
1060
|
+
return false;
|
|
1061
|
+
}
|
|
1062
|
+
return input.kind === "deposit" || input.kind === "transfer" || input.kind === "withdraw";
|
|
1063
|
+
}
|
|
1064
|
+
function feeOutputKindFromPrepared(prepared) {
|
|
1065
|
+
return {
|
|
1066
|
+
kind: prepared.kind,
|
|
1067
|
+
...prepared.transactArtifacts?.spendSource ? { spendSource: prepared.transactArtifacts.spendSource } : {},
|
|
1068
|
+
...prepared.transactArtifacts?.escrowSend ? { escrowSend: true } : {}
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// src/transact/fees/quote-fee-output-for-prepared.ts
|
|
1073
|
+
function instructedMinorUnits(prepared) {
|
|
1074
|
+
return prepared.intent.amount.toString();
|
|
1075
|
+
}
|
|
1076
|
+
function quoteRequestForPrepared(input) {
|
|
1077
|
+
const amount = instructedMinorUnits(input.prepared);
|
|
1078
|
+
if (input.prepared.kind === "deposit") {
|
|
1079
|
+
return {
|
|
1080
|
+
feeAsset: input.tokenAddress,
|
|
1081
|
+
publicDepositAmount: amount,
|
|
1082
|
+
spendsNotes: false
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
if (input.prepared.kind === "withdraw") {
|
|
1086
|
+
return {
|
|
1087
|
+
feeAsset: input.tokenAddress,
|
|
1088
|
+
publicWithdrawalAmount: amount,
|
|
1089
|
+
spendsNotes: true
|
|
1090
|
+
};
|
|
1091
|
+
}
|
|
1092
|
+
return {
|
|
1093
|
+
feeAsset: input.tokenAddress,
|
|
1094
|
+
transferInstructedAmount: amount,
|
|
1095
|
+
spendsNotes: true
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1098
|
+
async function quoteFeeOutputForPrepared(input) {
|
|
1099
|
+
if (!shouldAttachFeeOutput(feeOutputKindFromPrepared(input.prepared))) {
|
|
1100
|
+
return void 0;
|
|
1101
|
+
}
|
|
1102
|
+
const quote = await quoteRequiredFee({
|
|
1103
|
+
transactEnvironment: input.environment,
|
|
1104
|
+
request: quoteRequestForPrepared(input)
|
|
1105
|
+
});
|
|
1106
|
+
if (quote.requiredFee <= 0n) {
|
|
1107
|
+
return void 0;
|
|
1108
|
+
}
|
|
1109
|
+
return {
|
|
1110
|
+
requiredFee: quote.requiredFee,
|
|
1111
|
+
feeCollectorPrivateAddress: quote.feeCollectorPrivateAddress
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
function remainingAfterRequiredFee(input) {
|
|
1115
|
+
const remaining = input.available - input.instructed - input.requiredFee;
|
|
1116
|
+
if (remaining < 0n) {
|
|
1117
|
+
throw new Error("Instructed amount and Required Fee exceed available note value");
|
|
1118
|
+
}
|
|
1119
|
+
return remaining;
|
|
753
1120
|
}
|
|
754
1121
|
|
|
755
1122
|
// src/transact/audit/parameters.ts
|
|
@@ -890,6 +1257,32 @@ function privKeyScalarDecimalFromRecipientScalarHex(hexInput) {
|
|
|
890
1257
|
return canonicalBabyJubScalarFromInteger(value).toString(DECIMAL_RADIX2);
|
|
891
1258
|
}
|
|
892
1259
|
|
|
1260
|
+
// src/transact/fees/append-fee-output.ts
|
|
1261
|
+
function feeCoinFromSlot(slot) {
|
|
1262
|
+
return {
|
|
1263
|
+
commitment_hex: slot.commitment_hex,
|
|
1264
|
+
coin: slot.coin,
|
|
1265
|
+
depositScalarHex: slot.depositScalarHex,
|
|
1266
|
+
precommitementHex: slot.precommitementHex
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
async function appendFeeOutputSlot(input) {
|
|
1270
|
+
const requiredFee = input.feeOutput?.requiredFee ?? ZERO_STROOPS;
|
|
1271
|
+
const collector = input.feeOutput?.feeCollectorPrivateAddress.trim() ?? "";
|
|
1272
|
+
if (requiredFee <= ZERO_STROOPS || !collector) {
|
|
1273
|
+
return { deposits: input.deposits };
|
|
1274
|
+
}
|
|
1275
|
+
const slot = await input.buildAlignedDepositSlot({
|
|
1276
|
+
privateAddressStpl1: collector,
|
|
1277
|
+
amountStroops: requiredFee,
|
|
1278
|
+
tokenAddress: input.tokenAddress
|
|
1279
|
+
});
|
|
1280
|
+
return {
|
|
1281
|
+
deposits: [...input.deposits, slot.deposit],
|
|
1282
|
+
feeCoin: feeCoinFromSlot(slot)
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
|
|
893
1286
|
// src/transact/proofs/withdraw/helpers.ts
|
|
894
1287
|
function destinationWithdrawFrAndScalar(parameters) {
|
|
895
1288
|
const pkHex = ed25519PublicKeyHexFromStellarAccount(
|
|
@@ -944,14 +1337,15 @@ async function resolveWithdrawChangeDeposits(parameters) {
|
|
|
944
1337
|
}
|
|
945
1338
|
};
|
|
946
1339
|
}
|
|
947
|
-
function validateDualWithdrawAmounts(withdrawAmountStroops, totalNotes, changePrivateAddressStpl1) {
|
|
1340
|
+
function validateDualWithdrawAmounts(withdrawAmountStroops, totalNotes, changePrivateAddressStpl1, requiredFee) {
|
|
948
1341
|
if (withdrawAmountStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
949
1342
|
throw new Error("Withdraw amount must be positive");
|
|
950
1343
|
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1344
|
+
const changeStroops = remainingAfterRequiredFee({
|
|
1345
|
+
available: totalNotes,
|
|
1346
|
+
instructed: withdrawAmountStroops,
|
|
1347
|
+
requiredFee
|
|
1348
|
+
});
|
|
955
1349
|
requireChangeRecipientWhenPartial(changeStroops, changePrivateAddressStpl1);
|
|
956
1350
|
return changeStroops;
|
|
957
1351
|
}
|
|
@@ -964,11 +1358,31 @@ function buildDualWithdrawPublicInput(parameters) {
|
|
|
964
1358
|
publicWithdrawalAmount: parameters.publicWithdrawalAmount
|
|
965
1359
|
});
|
|
966
1360
|
}
|
|
1361
|
+
async function withdrawOutputsWithOptionalFee(parameters) {
|
|
1362
|
+
const { deposits: changeDeposits, changeCoin } = await resolveWithdrawChangeDeposits({
|
|
1363
|
+
changeStroops: parameters.changeStroops,
|
|
1364
|
+
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
1365
|
+
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
1366
|
+
tokenAddress: parameters.tokenAddress
|
|
1367
|
+
});
|
|
1368
|
+
const withFee = await appendFeeOutputSlot({
|
|
1369
|
+
deposits: changeDeposits,
|
|
1370
|
+
tokenAddress: parameters.tokenAddress,
|
|
1371
|
+
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
1372
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1373
|
+
});
|
|
1374
|
+
return {
|
|
1375
|
+
deposits: withFee.deposits,
|
|
1376
|
+
...changeCoin ? { changeCoin } : {},
|
|
1377
|
+
...withFee.feeCoin ? { feeCoin: withFee.feeCoin } : {}
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
967
1380
|
async function prepareDualWithdrawProofInputs(parameters) {
|
|
968
1381
|
const changeStroops = validateDualWithdrawAmounts(
|
|
969
1382
|
parameters.withdrawAmountStroops,
|
|
970
1383
|
BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value),
|
|
971
|
-
parameters.changePrivateAddressStpl1
|
|
1384
|
+
parameters.changePrivateAddressStpl1,
|
|
1385
|
+
parameters.feeOutput?.requiredFee ?? 0n
|
|
972
1386
|
);
|
|
973
1387
|
const { legA, legB } = dualWithdrawLegsWithSharedRoot({
|
|
974
1388
|
sdk: parameters.sdk,
|
|
@@ -983,11 +1397,12 @@ async function prepareDualWithdrawProofInputs(parameters) {
|
|
|
983
1397
|
),
|
|
984
1398
|
applicationId: parameters.applicationId
|
|
985
1399
|
});
|
|
986
|
-
const { deposits, changeCoin } = await
|
|
1400
|
+
const { deposits, changeCoin, feeCoin } = await withdrawOutputsWithOptionalFee({
|
|
987
1401
|
changeStroops,
|
|
988
1402
|
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
989
1403
|
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
990
|
-
tokenAddress: parameters.tokenAddress
|
|
1404
|
+
tokenAddress: parameters.tokenAddress,
|
|
1405
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
991
1406
|
});
|
|
992
1407
|
const publicInput = buildDualWithdrawPublicInput({
|
|
993
1408
|
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
@@ -1006,19 +1421,55 @@ async function prepareDualWithdrawProofInputs(parameters) {
|
|
|
1006
1421
|
audit,
|
|
1007
1422
|
deposits,
|
|
1008
1423
|
withdrawLegs: [legA.withdrawObject, legB.withdrawObject],
|
|
1009
|
-
...changeCoin ? { changeCoin } : {}
|
|
1424
|
+
...changeCoin ? { changeCoin } : {},
|
|
1425
|
+
...feeCoin ? { feeCoin } : {}
|
|
1426
|
+
};
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
// src/transact/proofs/withdraw/fee-deposits.ts
|
|
1430
|
+
async function withdrawDepositsWithFee(parameters) {
|
|
1431
|
+
const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
|
|
1432
|
+
changeStroops: parameters.changeStroops,
|
|
1433
|
+
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
1434
|
+
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
1435
|
+
tokenAddress: parameters.tokenAddress
|
|
1436
|
+
});
|
|
1437
|
+
const withFee = await appendFeeOutputSlot({
|
|
1438
|
+
deposits,
|
|
1439
|
+
tokenAddress: parameters.tokenAddress,
|
|
1440
|
+
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
1441
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1442
|
+
});
|
|
1443
|
+
return {
|
|
1444
|
+
deposits: withFee.deposits,
|
|
1445
|
+
...changeCoin ? { changeCoin } : {},
|
|
1446
|
+
...withFee.feeCoin ? { feeCoin: withFee.feeCoin } : {}
|
|
1010
1447
|
};
|
|
1011
1448
|
}
|
|
1449
|
+
function withdrawOutputApplicationIds(input) {
|
|
1450
|
+
const outputIds = [];
|
|
1451
|
+
if (input.hasChange) {
|
|
1452
|
+
outputIds.push(input.applicationId);
|
|
1453
|
+
}
|
|
1454
|
+
if (input.hasFeeOutput) {
|
|
1455
|
+
outputIds.push(input.applicationId);
|
|
1456
|
+
}
|
|
1457
|
+
if (outputIds.length === 0) {
|
|
1458
|
+
outputIds.push("0");
|
|
1459
|
+
}
|
|
1460
|
+
return outputIds;
|
|
1461
|
+
}
|
|
1012
1462
|
|
|
1013
1463
|
// src/transact/proofs/withdraw/transact-proof.ts
|
|
1014
|
-
function validateSingleWithdrawAmounts(withdrawAmountStroops, noteStroops) {
|
|
1464
|
+
function validateSingleWithdrawAmounts(withdrawAmountStroops, noteStroops, requiredFee) {
|
|
1015
1465
|
if (withdrawAmountStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
1016
1466
|
throw new Error("Withdraw amount must be positive");
|
|
1017
1467
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1468
|
+
return remainingAfterRequiredFee({
|
|
1469
|
+
available: noteStroops,
|
|
1470
|
+
instructed: withdrawAmountStroops,
|
|
1471
|
+
requiredFee
|
|
1472
|
+
});
|
|
1022
1473
|
}
|
|
1023
1474
|
async function proveSingleWithdrawTransaction(parameters) {
|
|
1024
1475
|
return parameters.sdk.proveTransaction(
|
|
@@ -1036,10 +1487,11 @@ async function proveSingleWithdrawTransaction(parameters) {
|
|
|
1036
1487
|
);
|
|
1037
1488
|
}
|
|
1038
1489
|
function buildPrimaryWithdrawForCoin(parameters) {
|
|
1039
|
-
const witness =
|
|
1040
|
-
parameters.
|
|
1041
|
-
parameters.
|
|
1042
|
-
|
|
1490
|
+
const witness = withdrawMerkleWitnessFromTree({
|
|
1491
|
+
sdk: parameters.sdk,
|
|
1492
|
+
coin: parameters.coin,
|
|
1493
|
+
state: parameters.state
|
|
1494
|
+
});
|
|
1043
1495
|
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
1044
1496
|
parameters.privKeyScalarHex
|
|
1045
1497
|
);
|
|
@@ -1057,7 +1509,8 @@ function buildPrimaryWithdrawForCoin(parameters) {
|
|
|
1057
1509
|
async function prepareSingleWithdrawProofInputs(parameters) {
|
|
1058
1510
|
const changeStroops = validateSingleWithdrawAmounts(
|
|
1059
1511
|
parameters.withdrawAmountStroops,
|
|
1060
|
-
BigInt(parameters.coin.value)
|
|
1512
|
+
BigInt(parameters.coin.value),
|
|
1513
|
+
parameters.feeOutput?.requiredFee ?? 0n
|
|
1061
1514
|
);
|
|
1062
1515
|
const { witness, primaryWithdraw } = buildPrimaryWithdrawForCoin({
|
|
1063
1516
|
sdk: parameters.sdk,
|
|
@@ -1066,11 +1519,12 @@ async function prepareSingleWithdrawProofInputs(parameters) {
|
|
|
1066
1519
|
state: parameters.state,
|
|
1067
1520
|
privKeyScalarHex: parameters.privKeyScalarHex
|
|
1068
1521
|
});
|
|
1069
|
-
const { deposits, changeCoin } = await
|
|
1522
|
+
const { deposits, changeCoin, feeCoin } = await withdrawDepositsWithFee({
|
|
1070
1523
|
changeStroops,
|
|
1071
1524
|
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
1072
1525
|
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
1073
|
-
tokenAddress: parameters.tokenAddress
|
|
1526
|
+
tokenAddress: parameters.tokenAddress,
|
|
1527
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1074
1528
|
});
|
|
1075
1529
|
const publicInput = buildWithdrawPublicInput({
|
|
1076
1530
|
stateRoot: witness.stateRoot,
|
|
@@ -1083,6 +1537,7 @@ async function prepareSingleWithdrawProofInputs(parameters) {
|
|
|
1083
1537
|
primaryWithdraw,
|
|
1084
1538
|
deposits,
|
|
1085
1539
|
changeCoin,
|
|
1540
|
+
feeCoin,
|
|
1086
1541
|
publicInput,
|
|
1087
1542
|
audit: buildPoolTransactionAuditParameters({
|
|
1088
1543
|
applicationId: parameters.applicationId,
|
|
@@ -1092,7 +1547,7 @@ async function prepareSingleWithdrawProofInputs(parameters) {
|
|
|
1092
1547
|
};
|
|
1093
1548
|
}
|
|
1094
1549
|
async function proveWithdrawTransact(parameters) {
|
|
1095
|
-
const { primaryWithdraw, deposits, changeCoin, publicInput, audit } = await prepareSingleWithdrawProofInputs(parameters);
|
|
1550
|
+
const { primaryWithdraw, deposits, changeCoin, feeCoin, publicInput, audit } = await prepareSingleWithdrawProofInputs(parameters);
|
|
1096
1551
|
const proof = await proveSingleWithdrawTransaction({
|
|
1097
1552
|
sdk: parameters.sdk,
|
|
1098
1553
|
publicInput,
|
|
@@ -1107,13 +1562,17 @@ async function proveWithdrawTransact(parameters) {
|
|
|
1107
1562
|
applicationIdsPlaintext: buildApplicationIdHints({
|
|
1108
1563
|
sdk: parameters.sdk,
|
|
1109
1564
|
inputIds: [parameters.applicationId],
|
|
1110
|
-
outputIds:
|
|
1565
|
+
outputIds: withdrawOutputApplicationIds({
|
|
1566
|
+
applicationId: parameters.applicationId,
|
|
1567
|
+
hasChange: Boolean(changeCoin),
|
|
1568
|
+
hasFeeOutput: Boolean(feeCoin)
|
|
1569
|
+
})
|
|
1111
1570
|
}),
|
|
1112
1571
|
...changeCoin ? { changeCoin } : {}
|
|
1113
1572
|
};
|
|
1114
1573
|
}
|
|
1115
1574
|
async function proveWithdrawTransactDual(parameters) {
|
|
1116
|
-
const { publicInput, audit, withdrawLegs, deposits, changeCoin } = await prepareDualWithdrawProofInputs(parameters);
|
|
1575
|
+
const { publicInput, audit, withdrawLegs, deposits, changeCoin, feeCoin } = await prepareDualWithdrawProofInputs(parameters);
|
|
1117
1576
|
const proof = await parameters.sdk.proveTransaction(
|
|
1118
1577
|
publicInput,
|
|
1119
1578
|
padPublicLegsToLayout(
|
|
@@ -1132,7 +1591,11 @@ async function proveWithdrawTransactDual(parameters) {
|
|
|
1132
1591
|
applicationIdsPlaintext: buildApplicationIdHints({
|
|
1133
1592
|
sdk: parameters.sdk,
|
|
1134
1593
|
inputIds: [audit.applicationId, audit.applicationId],
|
|
1135
|
-
outputIds:
|
|
1594
|
+
outputIds: withdrawOutputApplicationIds({
|
|
1595
|
+
applicationId: audit.applicationId,
|
|
1596
|
+
hasChange: Boolean(changeCoin),
|
|
1597
|
+
hasFeeOutput: Boolean(feeCoin)
|
|
1598
|
+
})
|
|
1136
1599
|
}),
|
|
1137
1600
|
...changeCoin ? { changeCoin } : {}
|
|
1138
1601
|
};
|
|
@@ -1153,6 +1616,9 @@ var DEFAULT_ZK_CONFIG_NONCE = BINDING_ZK_NONCE;
|
|
|
1153
1616
|
function resolveZkConfigNonce(transactEnvironment) {
|
|
1154
1617
|
return transactEnvironment.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
|
|
1155
1618
|
}
|
|
1619
|
+
function transactNonceFromArtifacts(artifacts, transactEnvironment) {
|
|
1620
|
+
return artifacts?.zkConfigNonce ?? resolveZkConfigNonce(transactEnvironment);
|
|
1621
|
+
}
|
|
1156
1622
|
|
|
1157
1623
|
// src/transact/zk/browser-artifact-cache.ts
|
|
1158
1624
|
import { ZK_ARTIFACT_VERSION } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
@@ -1387,21 +1853,120 @@ async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
|
|
|
1387
1853
|
const recipientPublicKeys = recipientPublicKeysDecimalFromPrivateAddress(
|
|
1388
1854
|
parameters.privateAddressStpl1
|
|
1389
1855
|
);
|
|
1390
|
-
const deposit = {
|
|
1391
|
-
value: generated.coin.value,
|
|
1392
|
-
nullifier: generated.coin.nullifier,
|
|
1393
|
-
ephemeralKeyScalar: scalarHexToFrDecimal(scalarHex),
|
|
1394
|
-
asset: [generated.coin.asset_hi, generated.coin.asset_lo],
|
|
1395
|
-
applicationId: resolvedApplicationId,
|
|
1396
|
-
recipientPublicKeys,
|
|
1397
|
-
...escrowDepositFields(parameters)
|
|
1398
|
-
};
|
|
1856
|
+
const deposit = {
|
|
1857
|
+
value: generated.coin.value,
|
|
1858
|
+
nullifier: generated.coin.nullifier,
|
|
1859
|
+
ephemeralKeyScalar: scalarHexToFrDecimal(scalarHex),
|
|
1860
|
+
asset: [generated.coin.asset_hi, generated.coin.asset_lo],
|
|
1861
|
+
applicationId: resolvedApplicationId,
|
|
1862
|
+
recipientPublicKeys,
|
|
1863
|
+
...escrowDepositFields(parameters)
|
|
1864
|
+
};
|
|
1865
|
+
return {
|
|
1866
|
+
deposit,
|
|
1867
|
+
commitment_hex: generated.commitment_hex,
|
|
1868
|
+
coin: generated.coin,
|
|
1869
|
+
depositScalarHex: scalarHex,
|
|
1870
|
+
precommitementHex: generated.precommitementHex
|
|
1871
|
+
};
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
// src/transact/pool/initialize-sdk.ts
|
|
1875
|
+
import { PrivacyPoolSDK as PrivacyPoolSDK2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
1876
|
+
async function initializePrivacyPoolSdk(input, nonce) {
|
|
1877
|
+
const zkConfigNonce = nonce ?? input.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
|
|
1878
|
+
const zkCircuits = await materializeSelectedZkCircuit(
|
|
1879
|
+
input.zkCircuits,
|
|
1880
|
+
zkConfigNonce,
|
|
1881
|
+
input.zkArtifactBaseUrl
|
|
1882
|
+
);
|
|
1883
|
+
return PrivacyPoolSDK2.init({
|
|
1884
|
+
wasmBinary: input.assets.sdkWasm,
|
|
1885
|
+
zkCircuits,
|
|
1886
|
+
zkConfigNonce,
|
|
1887
|
+
...optionalZkArtifactBaseUrl(input.zkArtifactBaseUrl)
|
|
1888
|
+
});
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
// src/transact/fees/zk-config-nonce-for-kind.ts
|
|
1892
|
+
function configuredNonceSpread(zkConfigNonce) {
|
|
1893
|
+
if (zkConfigNonce === void 0) {
|
|
1894
|
+
return {};
|
|
1895
|
+
}
|
|
1896
|
+
return { configuredNonce: zkConfigNonce };
|
|
1897
|
+
}
|
|
1898
|
+
function zkConfigNonceForFeeBearingKind(input) {
|
|
1899
|
+
if (input.configuredNonce === SIX_BY_SIX_BINDING_ZK_NONCE) {
|
|
1900
|
+
return SIX_BY_SIX_BINDING_ZK_NONCE;
|
|
1901
|
+
}
|
|
1902
|
+
if (input.kind === "transfer" && shouldAttachFeeOutput(input)) {
|
|
1903
|
+
return SIX_BY_SIX_BINDING_ZK_NONCE;
|
|
1904
|
+
}
|
|
1905
|
+
return input.configuredNonce ?? BINDING_ZK_NONCE;
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
// src/transact/pool/prepare-deposit-proof.ts
|
|
1909
|
+
import {
|
|
1910
|
+
randomFrDecimal253,
|
|
1911
|
+
scalarHexToFrDecimal as scalarHexToFrDecimal2
|
|
1912
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
1913
|
+
function userDepositSlot(input) {
|
|
1914
|
+
return {
|
|
1915
|
+
value: input.coin.value,
|
|
1916
|
+
nullifier: input.coin.nullifier,
|
|
1917
|
+
ephemeralKeyScalar: scalarHexToFrDecimal2(input.depositScalarHex),
|
|
1918
|
+
asset: [input.coin.asset_hi, input.coin.asset_lo],
|
|
1919
|
+
applicationId: input.applicationId,
|
|
1920
|
+
recipientPublicKeys: recipientPublicKeysDecimalFromPrivateAddress(
|
|
1921
|
+
input.privateAddressStpl1
|
|
1922
|
+
)
|
|
1923
|
+
};
|
|
1924
|
+
}
|
|
1925
|
+
function outputApplicationIds(input) {
|
|
1926
|
+
if (input.hasFeeOutput) {
|
|
1927
|
+
return [input.applicationId, input.applicationId];
|
|
1928
|
+
}
|
|
1929
|
+
return [input.applicationId];
|
|
1930
|
+
}
|
|
1931
|
+
async function proveDepositTransact(input) {
|
|
1932
|
+
const publicDeposit = (input.publicDepositStroops ?? BigInt(input.coin.value)).toString();
|
|
1933
|
+
const withFee = await appendFeeOutputSlot({
|
|
1934
|
+
deposits: [userDepositSlot(input)],
|
|
1935
|
+
tokenAddress: input.tokenAddress,
|
|
1936
|
+
buildAlignedDepositSlot: input.buildAlignedDepositSlot,
|
|
1937
|
+
...input.feeOutput ? { feeOutput: input.feeOutput } : {}
|
|
1938
|
+
});
|
|
1939
|
+
const audit = buildPoolTransactionAuditParameters({
|
|
1940
|
+
applicationId: input.applicationId,
|
|
1941
|
+
nAuditSlots: input.sdk.getLayout().nAuditSlots,
|
|
1942
|
+
...input.auditPublicKey ? { auditPublicKey: input.auditPublicKey } : {}
|
|
1943
|
+
});
|
|
1944
|
+
const proof = await input.sdk.proveTransaction(
|
|
1945
|
+
withTokenAddressPublicInputs(
|
|
1946
|
+
{
|
|
1947
|
+
stateRoot: merkleRootBufferToFrDecimal(input.merkleRootBytes),
|
|
1948
|
+
privKeyScalar: randomFrDecimal253()
|
|
1949
|
+
},
|
|
1950
|
+
input.tokenAddress
|
|
1951
|
+
),
|
|
1952
|
+
padPublicLegsToLayout(
|
|
1953
|
+
input.sdk,
|
|
1954
|
+
buildPublicDepositLegs(input.tokenAddress, publicDeposit)
|
|
1955
|
+
),
|
|
1956
|
+
padWithdrawSlotsToLayout(input.sdk, []),
|
|
1957
|
+
padDepositSlotsToLayout(input.sdk, withFee.deposits),
|
|
1958
|
+
audit
|
|
1959
|
+
);
|
|
1399
1960
|
return {
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1961
|
+
...proof,
|
|
1962
|
+
applicationIdsPlaintext: buildApplicationIdHints({
|
|
1963
|
+
sdk: input.sdk,
|
|
1964
|
+
inputIds: [],
|
|
1965
|
+
outputIds: outputApplicationIds({
|
|
1966
|
+
applicationId: input.applicationId,
|
|
1967
|
+
hasFeeOutput: Boolean(withFee.feeCoin)
|
|
1968
|
+
})
|
|
1969
|
+
})
|
|
1405
1970
|
};
|
|
1406
1971
|
}
|
|
1407
1972
|
|
|
@@ -1421,42 +1986,50 @@ var PrivacyPoolService = class {
|
|
|
1421
1986
|
zkCircuits;
|
|
1422
1987
|
zkConfigNonce;
|
|
1423
1988
|
zkArtifactBaseUrl;
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
async
|
|
1427
|
-
|
|
1428
|
-
|
|
1989
|
+
sdks = /* @__PURE__ */ new Map();
|
|
1990
|
+
initPromises = /* @__PURE__ */ new Map();
|
|
1991
|
+
async getInitializedSdk(nonce) {
|
|
1992
|
+
const zkConfigNonce = nonce ?? this.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
|
|
1993
|
+
const key = zkConfigNonce.toString();
|
|
1994
|
+
const existing = this.sdks.get(key);
|
|
1995
|
+
if (existing) {
|
|
1996
|
+
return existing;
|
|
1429
1997
|
}
|
|
1430
|
-
|
|
1431
|
-
|
|
1998
|
+
const pending = this.initPromises.get(key);
|
|
1999
|
+
if (pending) {
|
|
2000
|
+
return pending;
|
|
1432
2001
|
}
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
zkConfigNonce,
|
|
1449
|
-
...optionalZkArtifactBaseUrl(this.zkArtifactBaseUrl)
|
|
1450
|
-
});
|
|
1451
|
-
})();
|
|
1452
|
-
return this.initPromise;
|
|
2002
|
+
const started = this.initializeSdk(zkConfigNonce);
|
|
2003
|
+
this.initPromises.set(key, started);
|
|
2004
|
+
try {
|
|
2005
|
+
const sdk = await started;
|
|
2006
|
+
this.sdks.set(key, sdk);
|
|
2007
|
+
return sdk;
|
|
2008
|
+
} finally {
|
|
2009
|
+
this.initPromises.delete(key);
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
feeBearingZkConfigNonce(input) {
|
|
2013
|
+
return zkConfigNonceForFeeBearingKind({
|
|
2014
|
+
...input,
|
|
2015
|
+
...configuredNonceSpread(this.zkConfigNonce)
|
|
2016
|
+
});
|
|
1453
2017
|
}
|
|
1454
|
-
async
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
2018
|
+
async initializeSdk(nonce) {
|
|
2019
|
+
if (!this.assets) {
|
|
2020
|
+
throw new Error(
|
|
2021
|
+
"PrivacyPoolService requires browser ZK assets before initialization."
|
|
2022
|
+
);
|
|
1458
2023
|
}
|
|
1459
|
-
return
|
|
2024
|
+
return initializePrivacyPoolSdk(
|
|
2025
|
+
{
|
|
2026
|
+
assets: this.assets,
|
|
2027
|
+
...this.zkCircuits ? { zkCircuits: this.zkCircuits } : {},
|
|
2028
|
+
...this.zkConfigNonce === void 0 ? {} : { zkConfigNonce: this.zkConfigNonce },
|
|
2029
|
+
...optionalZkArtifactBaseUrl(this.zkArtifactBaseUrl)
|
|
2030
|
+
},
|
|
2031
|
+
nonce
|
|
2032
|
+
);
|
|
1460
2033
|
}
|
|
1461
2034
|
getAuditPublicKey() {
|
|
1462
2035
|
return this.auditPublicKey;
|
|
@@ -1489,65 +2062,51 @@ var PrivacyPoolService = class {
|
|
|
1489
2062
|
return { commitment_hex, coin, depositScalarHex, precommitementHex };
|
|
1490
2063
|
}
|
|
1491
2064
|
async prepareDepositTransactProof(parameters) {
|
|
1492
|
-
const sdk = await this.getInitializedSdk(
|
|
1493
|
-
|
|
1494
|
-
const recipientPublicKeys = recipientPublicKeysDecimalFromPrivateAddress(
|
|
1495
|
-
parameters.privateAddressStpl1
|
|
1496
|
-
);
|
|
1497
|
-
const applicationId = this.getApplicationId();
|
|
1498
|
-
const audit = buildPoolTransactionAuditParameters({
|
|
1499
|
-
applicationId,
|
|
1500
|
-
nAuditSlots: sdk.getLayout().nAuditSlots,
|
|
1501
|
-
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {}
|
|
1502
|
-
});
|
|
1503
|
-
const deposit = {
|
|
1504
|
-
value: parameters.coin.value,
|
|
1505
|
-
nullifier: parameters.coin.nullifier,
|
|
1506
|
-
ephemeralKeyScalar: scalarHexToFrDecimal2(parameters.depositScalarHex),
|
|
1507
|
-
asset: [parameters.coin.asset_hi, parameters.coin.asset_lo],
|
|
1508
|
-
applicationId,
|
|
1509
|
-
recipientPublicKeys
|
|
1510
|
-
};
|
|
1511
|
-
const publicInput = withTokenAddressPublicInputs(
|
|
1512
|
-
{
|
|
1513
|
-
stateRoot,
|
|
1514
|
-
privKeyScalar: randomFrDecimal253()
|
|
1515
|
-
},
|
|
1516
|
-
parameters.tokenAddress
|
|
2065
|
+
const sdk = await this.getInitializedSdk(
|
|
2066
|
+
this.feeBearingZkConfigNonce({ kind: "deposit" })
|
|
1517
2067
|
);
|
|
1518
|
-
|
|
1519
|
-
publicInput,
|
|
1520
|
-
padPublicLegsToLayout(
|
|
1521
|
-
sdk,
|
|
1522
|
-
buildPublicDepositLegs(parameters.tokenAddress, parameters.coin.value)
|
|
1523
|
-
),
|
|
1524
|
-
padWithdrawSlotsToLayout(sdk, []),
|
|
1525
|
-
padDepositSlotsToLayout(sdk, [deposit]),
|
|
1526
|
-
audit
|
|
1527
|
-
);
|
|
1528
|
-
const applicationIdsPlaintext = buildApplicationIdHints({
|
|
2068
|
+
return proveDepositTransact({
|
|
1529
2069
|
sdk,
|
|
1530
|
-
|
|
1531
|
-
|
|
2070
|
+
applicationId: this.getApplicationId(),
|
|
2071
|
+
privateAddressStpl1: parameters.privateAddressStpl1,
|
|
2072
|
+
coin: parameters.coin,
|
|
2073
|
+
depositScalarHex: parameters.depositScalarHex,
|
|
2074
|
+
merkleRootBytes: parameters.merkleRootBytes,
|
|
2075
|
+
tokenAddress: parameters.tokenAddress,
|
|
2076
|
+
buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
|
|
2077
|
+
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
|
|
2078
|
+
...parameters.publicDepositStroops === void 0 ? {} : { publicDepositStroops: parameters.publicDepositStroops },
|
|
2079
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1532
2080
|
});
|
|
1533
|
-
return { ...proof, applicationIdsPlaintext };
|
|
1534
2081
|
}
|
|
1535
2082
|
async calculateNullifierHash(nullifier, privKeyScalar) {
|
|
1536
2083
|
const sdk = await this.getInitializedSdk();
|
|
1537
2084
|
return sdk.calculateNullifierHash(nullifier, privKeyScalar);
|
|
1538
2085
|
}
|
|
1539
2086
|
async prepareWithdrawTransactProof(parameters) {
|
|
1540
|
-
const sdk = await this.getInitializedSdk(
|
|
2087
|
+
const sdk = await this.getInitializedSdk(
|
|
2088
|
+
this.feeBearingZkConfigNonce({ kind: "withdraw" })
|
|
2089
|
+
);
|
|
1541
2090
|
return proveWithdrawTransact({
|
|
1542
2091
|
sdk,
|
|
1543
2092
|
applicationId: this.getApplicationId(),
|
|
1544
2093
|
buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
|
|
1545
2094
|
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
|
|
1546
|
-
|
|
2095
|
+
coin: parameters.coin,
|
|
2096
|
+
state: parameters.state,
|
|
2097
|
+
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
2098
|
+
privKeyScalarHex: parameters.privKeyScalarHex,
|
|
2099
|
+
depositorEphemeralKey: parameters.depositorEphemeralKey,
|
|
2100
|
+
withdrawAmountStroops: parameters.withdrawAmountStroops,
|
|
2101
|
+
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
2102
|
+
tokenAddress: parameters.tokenAddress,
|
|
2103
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1547
2104
|
});
|
|
1548
2105
|
}
|
|
1549
2106
|
async prepareWithdrawTransactProofDual(parameters) {
|
|
1550
|
-
const sdk = await this.getInitializedSdk(
|
|
2107
|
+
const sdk = await this.getInitializedSdk(
|
|
2108
|
+
this.feeBearingZkConfigNonce({ kind: "withdraw" })
|
|
2109
|
+
);
|
|
1551
2110
|
return proveWithdrawTransactDual({
|
|
1552
2111
|
sdk,
|
|
1553
2112
|
applicationId: this.getApplicationId(),
|
|
@@ -1562,7 +2121,8 @@ var PrivacyPoolService = class {
|
|
|
1562
2121
|
ephemeralBKey: parameters.depositorEphemeralBKey,
|
|
1563
2122
|
withdrawAmountStroops: parameters.withdrawAmountStroops,
|
|
1564
2123
|
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
1565
|
-
tokenAddress: parameters.tokenAddress
|
|
2124
|
+
tokenAddress: parameters.tokenAddress,
|
|
2125
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1566
2126
|
});
|
|
1567
2127
|
}
|
|
1568
2128
|
};
|
|
@@ -1581,6 +2141,7 @@ function createPrivacyPoolService(input) {
|
|
|
1581
2141
|
var configuredPrivacyPoolService;
|
|
1582
2142
|
function configurePrivacyPoolService(service) {
|
|
1583
2143
|
configuredPrivacyPoolService = service;
|
|
2144
|
+
registerMerkleSessionSdkHost(service);
|
|
1584
2145
|
}
|
|
1585
2146
|
function getPrivacyPoolService() {
|
|
1586
2147
|
if (!configuredPrivacyPoolService) {
|
|
@@ -1599,7 +2160,8 @@ function poolMerkleStateToCachedView(state) {
|
|
|
1599
2160
|
return {
|
|
1600
2161
|
commitments: state.commitments,
|
|
1601
2162
|
updatedAt: state.updatedAt,
|
|
1602
|
-
merkleRootHex: state.merkleRootHex
|
|
2163
|
+
merkleRootHex: state.merkleRootHex,
|
|
2164
|
+
...state.nodes ? { nodes: state.nodes } : {}
|
|
1603
2165
|
};
|
|
1604
2166
|
}
|
|
1605
2167
|
|
|
@@ -1732,6 +2294,65 @@ function reuseCachedCommitments(input) {
|
|
|
1732
2294
|
return cachedCommitments;
|
|
1733
2295
|
}
|
|
1734
2296
|
|
|
2297
|
+
// src/transact/merkle/persist-fetched.ts
|
|
2298
|
+
function cachedMerkleUnchanged(cachedState, commitments, merkleRootHex) {
|
|
2299
|
+
if (!cachedState) {
|
|
2300
|
+
return false;
|
|
2301
|
+
}
|
|
2302
|
+
if (cachedState.commitments.length !== commitments.length) {
|
|
2303
|
+
return false;
|
|
2304
|
+
}
|
|
2305
|
+
return cachedState.merkleRootHex === merkleRootHex;
|
|
2306
|
+
}
|
|
2307
|
+
function viewFromCachedMerkle(cachedState, merkleRootHex) {
|
|
2308
|
+
return {
|
|
2309
|
+
commitments: cachedState.commitments,
|
|
2310
|
+
updatedAt: cachedState.updatedAt,
|
|
2311
|
+
merkleRootHex: cachedState.merkleRootHex ?? merkleRootHex,
|
|
2312
|
+
commitmentCount: cachedState.commitments.length,
|
|
2313
|
+
...cachedState.nodes ? { nodes: cachedState.nodes } : {}
|
|
2314
|
+
};
|
|
2315
|
+
}
|
|
2316
|
+
function merkleStateForPersist(input) {
|
|
2317
|
+
return {
|
|
2318
|
+
poolContract: input.poolContractId,
|
|
2319
|
+
commitments: input.commitments,
|
|
2320
|
+
commitmentCount: input.commitments.length,
|
|
2321
|
+
merkleRootHex: input.merkleRootHex,
|
|
2322
|
+
updatedAt: input.updatedAt,
|
|
2323
|
+
...input.nodes ? { nodes: input.nodes } : {}
|
|
2324
|
+
};
|
|
2325
|
+
}
|
|
2326
|
+
async function persistFetchedMerkleState(input) {
|
|
2327
|
+
const cachedState = input.cachedState;
|
|
2328
|
+
if (cachedMerkleUnchanged(cachedState, input.commitments, input.merkleRootHex) && cachedState) {
|
|
2329
|
+
return viewFromCachedMerkle(cachedState, input.merkleRootHex);
|
|
2330
|
+
}
|
|
2331
|
+
const nodes = await resolveExtendedMerkleNodes({
|
|
2332
|
+
poolContract: input.poolContractId,
|
|
2333
|
+
commitments: input.commitments,
|
|
2334
|
+
merkleRootHex: input.merkleRootHex,
|
|
2335
|
+
...cachedState ? { cachedState } : {}
|
|
2336
|
+
});
|
|
2337
|
+
const updatedAt = Date.now();
|
|
2338
|
+
await input.poolMerkleState?.set(
|
|
2339
|
+
merkleStateForPersist({
|
|
2340
|
+
poolContractId: input.poolContractId,
|
|
2341
|
+
commitments: input.commitments,
|
|
2342
|
+
merkleRootHex: input.merkleRootHex,
|
|
2343
|
+
updatedAt,
|
|
2344
|
+
...nodes ? { nodes } : {}
|
|
2345
|
+
})
|
|
2346
|
+
);
|
|
2347
|
+
return {
|
|
2348
|
+
commitments: input.commitments,
|
|
2349
|
+
updatedAt,
|
|
2350
|
+
merkleRootHex: input.merkleRootHex,
|
|
2351
|
+
commitmentCount: input.commitments.length,
|
|
2352
|
+
...nodes ? { nodes } : {}
|
|
2353
|
+
};
|
|
2354
|
+
}
|
|
2355
|
+
|
|
1735
2356
|
// src/transact/merkle/fetch-contract.ts
|
|
1736
2357
|
async function fetchAndMergeMerkleState(parameters) {
|
|
1737
2358
|
const client = createPoolClient(parameters);
|
|
@@ -1824,43 +2445,6 @@ async function loadCommitments(input) {
|
|
|
1824
2445
|
});
|
|
1825
2446
|
return [...reused, ...fetched];
|
|
1826
2447
|
}
|
|
1827
|
-
async function persistFetchedMerkleState(input) {
|
|
1828
|
-
const cachedState = input.cachedState;
|
|
1829
|
-
if (cachedState && cachedMerkleUnchanged(cachedState, input.commitments, input.merkleRootHex)) {
|
|
1830
|
-
return viewFromCachedMerkle(cachedState, input.merkleRootHex);
|
|
1831
|
-
}
|
|
1832
|
-
const updatedAt = Date.now();
|
|
1833
|
-
await input.poolMerkleState?.set({
|
|
1834
|
-
poolContract: input.poolContractId,
|
|
1835
|
-
commitments: input.commitments,
|
|
1836
|
-
commitmentCount: input.commitments.length,
|
|
1837
|
-
merkleRootHex: input.merkleRootHex,
|
|
1838
|
-
updatedAt
|
|
1839
|
-
});
|
|
1840
|
-
return {
|
|
1841
|
-
commitments: input.commitments,
|
|
1842
|
-
updatedAt,
|
|
1843
|
-
merkleRootHex: input.merkleRootHex,
|
|
1844
|
-
commitmentCount: input.commitments.length
|
|
1845
|
-
};
|
|
1846
|
-
}
|
|
1847
|
-
function viewFromCachedMerkle(cachedState, merkleRootHex) {
|
|
1848
|
-
return {
|
|
1849
|
-
commitments: cachedState.commitments,
|
|
1850
|
-
updatedAt: cachedState.updatedAt,
|
|
1851
|
-
merkleRootHex: cachedState.merkleRootHex ?? merkleRootHex,
|
|
1852
|
-
commitmentCount: cachedState.commitments.length
|
|
1853
|
-
};
|
|
1854
|
-
}
|
|
1855
|
-
function cachedMerkleUnchanged(cachedState, commitments, merkleRootHex) {
|
|
1856
|
-
if (!cachedState) {
|
|
1857
|
-
return false;
|
|
1858
|
-
}
|
|
1859
|
-
if ((cachedState.merkleRootHex ?? merkleRootHex) !== merkleRootHex) {
|
|
1860
|
-
return false;
|
|
1861
|
-
}
|
|
1862
|
-
return cachedState.commitments.join(",") === commitments.join(",");
|
|
1863
|
-
}
|
|
1864
2448
|
|
|
1865
2449
|
// src/transact/engine/prepare/shared.ts
|
|
1866
2450
|
async function resolveTokenContractId2(environment, assetId) {
|
|
@@ -1935,7 +2519,11 @@ async function loadMerkleState(environment, walletPublicKey) {
|
|
|
1935
2519
|
transactEnvironment: environment,
|
|
1936
2520
|
...environment.poolMerkleState ? { poolMerkleState: environment.poolMerkleState } : {}
|
|
1937
2521
|
});
|
|
1938
|
-
return {
|
|
2522
|
+
return merkleSnapshotToStateFile({
|
|
2523
|
+
commitments: merged.commitments,
|
|
2524
|
+
merkleRootHex: merged.merkleRootHex,
|
|
2525
|
+
...merged.nodes ? { nodes: merged.nodes } : {}
|
|
2526
|
+
});
|
|
1939
2527
|
}
|
|
1940
2528
|
function enrichPreparedOperation(prepared, outputRecords, artifacts) {
|
|
1941
2529
|
return {
|
|
@@ -2150,6 +2738,13 @@ async function filterUnspentPrivateRecords(input) {
|
|
|
2150
2738
|
}
|
|
2151
2739
|
return unspent;
|
|
2152
2740
|
}
|
|
2741
|
+
function spendAmountCoveringProtocolFee(amount) {
|
|
2742
|
+
if (amount <= 0n) {
|
|
2743
|
+
return amount;
|
|
2744
|
+
}
|
|
2745
|
+
const hundredths = (amount + 99n) / 100n;
|
|
2746
|
+
return amount + (hundredths === 0n ? 1n : hundredths);
|
|
2747
|
+
}
|
|
2153
2748
|
function pickRecordsForSpendAmount(input) {
|
|
2154
2749
|
let selectedTotal = 0n;
|
|
2155
2750
|
const selected = [];
|
|
@@ -2203,7 +2798,7 @@ async function selectPrivateRecords(input) {
|
|
|
2203
2798
|
return pickRecordsForSpendAmount({
|
|
2204
2799
|
available,
|
|
2205
2800
|
kind: input.kind,
|
|
2206
|
-
amount: input.intent.amount
|
|
2801
|
+
amount: spendAmountCoveringProtocolFee(input.intent.amount)
|
|
2207
2802
|
});
|
|
2208
2803
|
}
|
|
2209
2804
|
function sumRecordAmounts(records) {
|
|
@@ -2437,13 +3032,19 @@ var walletPrivateAddressRecordSchema = z.object({
|
|
|
2437
3032
|
privateAddress: z.string().min(1),
|
|
2438
3033
|
createdAt: z.number()
|
|
2439
3034
|
});
|
|
3035
|
+
var leanImtNodeSchema = z.object({
|
|
3036
|
+
level: z.number().int().nonnegative(),
|
|
3037
|
+
index: z.number().int().nonnegative(),
|
|
3038
|
+
value: z.string().min(1)
|
|
3039
|
+
});
|
|
2440
3040
|
var poolMerkleStateSchema = z.object({
|
|
2441
3041
|
poolContract: z.string().min(1),
|
|
2442
3042
|
commitments: z.array(z.string()),
|
|
2443
3043
|
commitmentCount: z.number().int().nonnegative(),
|
|
2444
3044
|
merkleRootHex: z.string().min(1),
|
|
2445
3045
|
updatedAt: z.number(),
|
|
2446
|
-
syncedLedger: z.number().int().optional()
|
|
3046
|
+
syncedLedger: z.number().int().optional(),
|
|
3047
|
+
nodes: z.array(leanImtNodeSchema).optional()
|
|
2447
3048
|
});
|
|
2448
3049
|
var leafEphemeralSchema = z.object({
|
|
2449
3050
|
poolContract: z.string().min(1),
|
|
@@ -3856,6 +4457,7 @@ function createPoolMerkleService(context) {
|
|
|
3856
4457
|
async appendPoolCommitments(input) {
|
|
3857
4458
|
const current = await this.getPoolMerkleState(input.poolContract);
|
|
3858
4459
|
const mergedCommitments = [...current?.commitments ?? [], ...input.commitments];
|
|
4460
|
+
const nodes = input.nodes ?? (input.commitments.length === 0 ? current?.nodes : void 0);
|
|
3859
4461
|
await this.setPoolMerkleState(
|
|
3860
4462
|
withoutUndefinedFields({
|
|
3861
4463
|
poolContract: input.poolContract,
|
|
@@ -3863,7 +4465,8 @@ function createPoolMerkleService(context) {
|
|
|
3863
4465
|
commitmentCount: mergedCommitments.length,
|
|
3864
4466
|
merkleRootHex: input.merkleRootHex,
|
|
3865
4467
|
updatedAt: Date.now(),
|
|
3866
|
-
syncedLedger: input.syncedLedger ?? current?.syncedLedger
|
|
4468
|
+
syncedLedger: input.syncedLedger ?? current?.syncedLedger,
|
|
4469
|
+
nodes
|
|
3867
4470
|
})
|
|
3868
4471
|
);
|
|
3869
4472
|
}
|
|
@@ -5133,12 +5736,46 @@ function createDeliveriesStateDelegates(state) {
|
|
|
5133
5736
|
};
|
|
5134
5737
|
}
|
|
5135
5738
|
|
|
5739
|
+
// src/transact/merkle/write-snapshot.ts
|
|
5740
|
+
async function writePoolMerkleState(input) {
|
|
5741
|
+
await input.setPoolMerkleState(input.state);
|
|
5742
|
+
await bindPoolMerkleTree(input.state);
|
|
5743
|
+
}
|
|
5744
|
+
async function appendPoolMerkleCommitments(input) {
|
|
5745
|
+
const current = await input.getPoolMerkleState(input.payload.poolContract);
|
|
5746
|
+
const merged = [...current?.commitments ?? [], ...input.payload.commitments];
|
|
5747
|
+
const nodes = input.payload.nodes ?? await resolveExtendedMerkleNodes({
|
|
5748
|
+
poolContract: input.payload.poolContract,
|
|
5749
|
+
commitments: merged,
|
|
5750
|
+
merkleRootHex: input.payload.merkleRootHex,
|
|
5751
|
+
...current ? { cachedState: poolMerkleStateToCachedView(current) } : {}
|
|
5752
|
+
});
|
|
5753
|
+
await input.appendPoolCommitments({
|
|
5754
|
+
poolContract: input.payload.poolContract,
|
|
5755
|
+
commitments: input.payload.commitments,
|
|
5756
|
+
merkleRootHex: input.payload.merkleRootHex,
|
|
5757
|
+
...input.payload.syncedLedger === void 0 ? {} : { syncedLedger: input.payload.syncedLedger },
|
|
5758
|
+
...nodes ? { nodes } : {}
|
|
5759
|
+
});
|
|
5760
|
+
const written = await input.getPoolMerkleState(input.payload.poolContract);
|
|
5761
|
+
if (written) {
|
|
5762
|
+
await bindPoolMerkleTree(written);
|
|
5763
|
+
}
|
|
5764
|
+
}
|
|
5765
|
+
|
|
5136
5766
|
// src/client/state-delegates/pool.ts
|
|
5137
5767
|
function createPoolStateDelegates(state) {
|
|
5138
5768
|
return {
|
|
5139
5769
|
getPoolMerkleState: (poolContract) => state.getPoolMerkleState(poolContract),
|
|
5140
|
-
setPoolMerkleState: (poolState) =>
|
|
5141
|
-
|
|
5770
|
+
setPoolMerkleState: (poolState) => writePoolMerkleState({
|
|
5771
|
+
setPoolMerkleState: (next) => state.setPoolMerkleState(next),
|
|
5772
|
+
state: poolState
|
|
5773
|
+
}),
|
|
5774
|
+
appendPoolCommitments: (input) => appendPoolMerkleCommitments({
|
|
5775
|
+
getPoolMerkleState: (poolContract) => state.getPoolMerkleState(poolContract),
|
|
5776
|
+
appendPoolCommitments: (payload) => state.appendPoolCommitments(payload),
|
|
5777
|
+
payload: input
|
|
5778
|
+
}),
|
|
5142
5779
|
getLeafEphemeral: (input) => state.getLeafEphemeral(input),
|
|
5143
5780
|
setLeafEphemeral: (ephemeral) => state.setLeafEphemeral(ephemeral)
|
|
5144
5781
|
};
|
|
@@ -5191,12 +5828,42 @@ function createStateDelegates(state) {
|
|
|
5191
5828
|
};
|
|
5192
5829
|
}
|
|
5193
5830
|
|
|
5831
|
+
// src/client/hydrate-state.ts
|
|
5832
|
+
async function hydratePoolMerkleStates(client, states) {
|
|
5833
|
+
for (const poolState of states ?? []) {
|
|
5834
|
+
await client.setPoolMerkleState(poolState);
|
|
5835
|
+
}
|
|
5836
|
+
}
|
|
5837
|
+
async function hydrateWalletAddresses(client, snapshot) {
|
|
5838
|
+
for (const record of snapshot.walletPrivateAddressRecords ?? []) {
|
|
5839
|
+
await client.saveWalletPrivateAddressRecord(record);
|
|
5840
|
+
}
|
|
5841
|
+
for (const scalar of snapshot.walletPrivateAddressScalars ?? []) {
|
|
5842
|
+
await client.saveWalletPrivateAddressScalar(scalar);
|
|
5843
|
+
}
|
|
5844
|
+
for (const entry of snapshot.walletDefaultPrivateAddressNonces ?? []) {
|
|
5845
|
+
await client.setWalletDefaultPrivateAddressNonce(entry);
|
|
5846
|
+
}
|
|
5847
|
+
}
|
|
5848
|
+
async function hydrateStellarPrivacyState(client, snapshot) {
|
|
5849
|
+
if (snapshot.assets && snapshot.assets.length > 0) {
|
|
5850
|
+
await client.replaceAssets(snapshot.assets);
|
|
5851
|
+
}
|
|
5852
|
+
await hydratePoolMerkleStates(client, snapshot.poolMerkleStates);
|
|
5853
|
+
if (snapshot.privateRecords && snapshot.privateRecords.length > 0) {
|
|
5854
|
+
await client.upsertPrivateRecords(snapshot.privateRecords);
|
|
5855
|
+
}
|
|
5856
|
+
await hydrateWalletAddresses(client, snapshot);
|
|
5857
|
+
}
|
|
5858
|
+
|
|
5194
5859
|
// src/client/client.ts
|
|
5195
5860
|
function createStellarPrivacyClientInstance(config) {
|
|
5196
5861
|
const composed = composeStellarPrivacyClient(config);
|
|
5862
|
+
const stateDelegates = createStateDelegates(composed.state);
|
|
5197
5863
|
return {
|
|
5198
5864
|
state: composed.state,
|
|
5199
|
-
...
|
|
5865
|
+
...stateDelegates,
|
|
5866
|
+
hydrateState: (snapshot) => hydrateStellarPrivacyState(stateDelegates, snapshot),
|
|
5200
5867
|
deposit: (intent) => composed.operations.deposit(intent),
|
|
5201
5868
|
transfer: (intent) => composed.operations.transfer(intent),
|
|
5202
5869
|
withdraw: (intent) => composed.operations.withdraw(intent),
|
|
@@ -5312,7 +5979,7 @@ function createStellarPrivacyClientFromResolvedConfig(config) {
|
|
|
5312
5979
|
}
|
|
5313
5980
|
|
|
5314
5981
|
// src/transact/engine/default-factory.ts
|
|
5315
|
-
import { PrivacyPoolSDK as
|
|
5982
|
+
import { PrivacyPoolSDK as PrivacyPoolSDK4 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
5316
5983
|
|
|
5317
5984
|
// src/transact/pool/proof-types.ts
|
|
5318
5985
|
function ciphertextArtifactsFromProof(proof) {
|
|
@@ -5327,9 +5994,15 @@ function ciphertextArtifactsFromProof(proof) {
|
|
|
5327
5994
|
// src/transact/engine/prepare/deposit.ts
|
|
5328
5995
|
var STROOPS_PER_UNIT = 10000000n;
|
|
5329
5996
|
async function createAlignedDepositWithProof(parameters) {
|
|
5997
|
+
const feeOutput = await quoteFeeOutputForPrepared(parameters);
|
|
5998
|
+
const instructed = parameters.prepared.intent.amount;
|
|
5999
|
+
const userAmount = instructed - (feeOutput?.requiredFee ?? 0n);
|
|
6000
|
+
if (userAmount <= 0n) {
|
|
6001
|
+
throw new Error("Required Fee leaves no spendable deposit note");
|
|
6002
|
+
}
|
|
5330
6003
|
const aligned = await parameters.poolService.createAlignedShieldCoinData({
|
|
5331
6004
|
privateAddressStpl1: parameters.prepared.intent.to,
|
|
5332
|
-
amountStroops:
|
|
6005
|
+
amountStroops: userAmount,
|
|
5333
6006
|
tokenAddress: parameters.tokenAddress
|
|
5334
6007
|
});
|
|
5335
6008
|
const poolClient = readPoolClientFactory(parameters.environment)({
|
|
@@ -5344,7 +6017,9 @@ async function createAlignedDepositWithProof(parameters) {
|
|
|
5344
6017
|
coin: aligned.coin,
|
|
5345
6018
|
depositScalarHex: aligned.depositScalarHex,
|
|
5346
6019
|
merkleRootBytes: merkleTx.result,
|
|
5347
|
-
tokenAddress: parameters.tokenAddress
|
|
6020
|
+
tokenAddress: parameters.tokenAddress,
|
|
6021
|
+
publicDepositStroops: instructed,
|
|
6022
|
+
...feeOutput ? { feeOutput } : {}
|
|
5348
6023
|
});
|
|
5349
6024
|
return { ...aligned, proof };
|
|
5350
6025
|
}
|
|
@@ -5363,8 +6038,8 @@ async function prepareDepositOperation(prepared, environment, poolService) {
|
|
|
5363
6038
|
privateAddress: prepared.intent.to,
|
|
5364
6039
|
assetId: prepared.intent.asset,
|
|
5365
6040
|
poolContract: environment.network.poolContract,
|
|
5366
|
-
amount:
|
|
5367
|
-
amountDisplay: Number(
|
|
6041
|
+
amount: BigInt(depositProof.coin.value),
|
|
6042
|
+
amountDisplay: Number(depositProof.coin.value) / Number(STROOPS_PER_UNIT),
|
|
5368
6043
|
commitmentHex: depositProof.commitment_hex,
|
|
5369
6044
|
coin: depositProof.coin,
|
|
5370
6045
|
depositScalarHex: depositProof.depositScalarHex,
|
|
@@ -5380,7 +6055,11 @@ async function prepareDepositOperation(prepared, environment, poolService) {
|
|
|
5380
6055
|
depositScalarHex: depositProof.depositScalarHex,
|
|
5381
6056
|
precommitementHex: depositProof.precommitementHex,
|
|
5382
6057
|
commitmentHex: depositProof.commitment_hex,
|
|
5383
|
-
walletPublicKey
|
|
6058
|
+
walletPublicKey,
|
|
6059
|
+
zkConfigNonce: zkConfigNonceForFeeBearingKind({
|
|
6060
|
+
kind: "deposit",
|
|
6061
|
+
...configuredNonceSpread(environment.zkConfigNonce)
|
|
6062
|
+
})
|
|
5384
6063
|
});
|
|
5385
6064
|
}
|
|
5386
6065
|
|
|
@@ -5505,7 +6184,8 @@ async function buildSpendProofContextAtExecute(input) {
|
|
|
5505
6184
|
input.prepared.intent.asset
|
|
5506
6185
|
);
|
|
5507
6186
|
const coin = requireCoinNoteFromRecord(primaryRecord);
|
|
5508
|
-
const
|
|
6187
|
+
const merkleState = await loadMerkleState(input.environment, walletPublicKey);
|
|
6188
|
+
const commitments = merkleState.commitments;
|
|
5509
6189
|
const leafIndex = findCommitmentLeafIndex(commitments, coin.commitment);
|
|
5510
6190
|
if (leafIndex < 0) {
|
|
5511
6191
|
throw new Error("Coin commitment not found in on-chain Merkle state.");
|
|
@@ -5522,6 +6202,7 @@ async function buildSpendProofContextAtExecute(input) {
|
|
|
5522
6202
|
tokenAddress,
|
|
5523
6203
|
coin,
|
|
5524
6204
|
commitments,
|
|
6205
|
+
merkleState,
|
|
5525
6206
|
ephemeral,
|
|
5526
6207
|
senderPrivKeyScalarHex,
|
|
5527
6208
|
recipientPrivateAddressStpl1: input.recipientPrivateAddressStpl1
|
|
@@ -5554,9 +6235,6 @@ function escrowOutputFields(input) {
|
|
|
5554
6235
|
recipientLo: input.escrowSend.recipientLo
|
|
5555
6236
|
};
|
|
5556
6237
|
}
|
|
5557
|
-
function paddingDepositPair(recipientDeposit) {
|
|
5558
|
-
return [recipientDeposit, "dummy"];
|
|
5559
|
-
}
|
|
5560
6238
|
async function buildChangeDepositPair(parameters) {
|
|
5561
6239
|
const changeSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
|
|
5562
6240
|
privateAddressStpl1: parameters.selfPrivateAddressStpl1ForChange.trim(),
|
|
@@ -5573,34 +6251,54 @@ async function buildChangeDepositPair(parameters) {
|
|
|
5573
6251
|
}
|
|
5574
6252
|
};
|
|
5575
6253
|
}
|
|
6254
|
+
function recipientOnlyDeposits(recipientDeposit, hasFeeOutput) {
|
|
6255
|
+
if (hasFeeOutput) {
|
|
6256
|
+
return [recipientDeposit];
|
|
6257
|
+
}
|
|
6258
|
+
return [recipientDeposit, "dummy"];
|
|
6259
|
+
}
|
|
6260
|
+
async function depositsWithoutFee(input) {
|
|
6261
|
+
if (input.changeStroops <= ZERO_STROOPS) {
|
|
6262
|
+
return {
|
|
6263
|
+
deposits: recipientOnlyDeposits(input.recipientDeposit, input.hasFeeOutput)
|
|
6264
|
+
};
|
|
6265
|
+
}
|
|
6266
|
+
return buildChangeDepositPair({
|
|
6267
|
+
selfPrivateAddressStpl1ForChange: input.selfPrivateAddressStpl1ForChange,
|
|
6268
|
+
changeStroops: input.changeStroops,
|
|
6269
|
+
tokenAddress: input.tokenAddress,
|
|
6270
|
+
recipientDeposit: input.recipientDeposit
|
|
6271
|
+
});
|
|
6272
|
+
}
|
|
5576
6273
|
async function buildRecipientAndOptionalChangeDeposits(parameters) {
|
|
5577
6274
|
const escrow = {
|
|
5578
6275
|
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
5579
6276
|
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
5580
6277
|
};
|
|
5581
|
-
const recipientPrivateAddress = parameters.recipientPrivateAddressStpl1.trim();
|
|
5582
6278
|
const recipientSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
|
|
5583
|
-
privateAddressStpl1:
|
|
6279
|
+
privateAddressStpl1: parameters.recipientPrivateAddressStpl1.trim(),
|
|
5584
6280
|
amountStroops: parameters.transferStroops,
|
|
5585
6281
|
tokenAddress: parameters.tokenAddress,
|
|
5586
6282
|
...escrowOutputFields(escrow)
|
|
5587
6283
|
});
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
recipientSlot,
|
|
5591
|
-
deposits: paddingDepositPair(recipientSlot.deposit)
|
|
5592
|
-
};
|
|
5593
|
-
}
|
|
5594
|
-
const changeResult = await buildChangeDepositPair({
|
|
5595
|
-
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
6284
|
+
const withoutFee = await depositsWithoutFee({
|
|
6285
|
+
recipientDeposit: recipientSlot.deposit,
|
|
5596
6286
|
changeStroops: parameters.changeStroops,
|
|
6287
|
+
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
6288
|
+
tokenAddress: parameters.tokenAddress,
|
|
6289
|
+
hasFeeOutput: (parameters.feeOutput?.requiredFee ?? ZERO_STROOPS) > ZERO_STROOPS
|
|
6290
|
+
});
|
|
6291
|
+
const withFee = await appendFeeOutputSlot({
|
|
6292
|
+
deposits: withoutFee.deposits,
|
|
5597
6293
|
tokenAddress: parameters.tokenAddress,
|
|
5598
|
-
|
|
6294
|
+
buildAlignedDepositSlot: (aligned) => getPrivacyPoolService().buildAlignedDepositSlot(aligned),
|
|
6295
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
5599
6296
|
});
|
|
5600
6297
|
return {
|
|
5601
6298
|
recipientSlot,
|
|
5602
|
-
deposits:
|
|
5603
|
-
changeCoin:
|
|
6299
|
+
deposits: withFee.deposits,
|
|
6300
|
+
..."changeCoin" in withoutFee ? { changeCoin: withoutFee.changeCoin } : {},
|
|
6301
|
+
...withFee.feeCoin ? { feeCoin: withFee.feeCoin } : {}
|
|
5604
6302
|
};
|
|
5605
6303
|
}
|
|
5606
6304
|
|
|
@@ -5653,14 +6351,15 @@ function sweepOutputOwnerFields(parameters) {
|
|
|
5653
6351
|
return { sweepOutputOwnerPubX, sweepOutputOwnerPubY };
|
|
5654
6352
|
}
|
|
5655
6353
|
async function buildTransferDepositsAndPublicInput(parameters) {
|
|
5656
|
-
const { recipientSlot, deposits, changeCoin } = await buildRecipientAndOptionalChangeDeposits({
|
|
6354
|
+
const { recipientSlot, deposits, changeCoin, feeCoin } = await buildRecipientAndOptionalChangeDeposits({
|
|
5657
6355
|
recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
|
|
5658
6356
|
transferStroops: parameters.transferStroops,
|
|
5659
6357
|
changeStroops: parameters.changeStroops,
|
|
5660
6358
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
5661
6359
|
tokenAddress: parameters.tokenAddress,
|
|
5662
6360
|
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
5663
|
-
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
6361
|
+
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {},
|
|
6362
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
5664
6363
|
});
|
|
5665
6364
|
const publicInput = withTokenAddressPublicInputs(
|
|
5666
6365
|
{
|
|
@@ -5675,6 +6374,7 @@ async function buildTransferDepositsAndPublicInput(parameters) {
|
|
|
5675
6374
|
recipientSlot,
|
|
5676
6375
|
deposits,
|
|
5677
6376
|
...changeCoin ? { changeCoin } : {},
|
|
6377
|
+
...feeCoin ? { feeCoin } : {},
|
|
5678
6378
|
publicInput
|
|
5679
6379
|
};
|
|
5680
6380
|
}
|
|
@@ -5690,7 +6390,8 @@ async function buildSenderTransferDepositsAndPublicInput(parameters) {
|
|
|
5690
6390
|
parameters.senderPrivKeyScalarHex
|
|
5691
6391
|
),
|
|
5692
6392
|
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
5693
|
-
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
6393
|
+
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {},
|
|
6394
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
5694
6395
|
});
|
|
5695
6396
|
}
|
|
5696
6397
|
|
|
@@ -5714,11 +6415,20 @@ function stampDualWithdrawLegs(legs, parameters) {
|
|
|
5714
6415
|
}
|
|
5715
6416
|
};
|
|
5716
6417
|
}
|
|
5717
|
-
function buildDualTransferApplicationIds(sdk, applicationId, changeCoin) {
|
|
6418
|
+
function buildDualTransferApplicationIds(sdk, applicationId, changeCoin, feeCoin) {
|
|
6419
|
+
const outputIds = [applicationId];
|
|
6420
|
+
if (changeCoin) {
|
|
6421
|
+
outputIds.push(applicationId);
|
|
6422
|
+
} else if (!feeCoin) {
|
|
6423
|
+
outputIds.push("0");
|
|
6424
|
+
}
|
|
6425
|
+
if (feeCoin) {
|
|
6426
|
+
outputIds.push(applicationId);
|
|
6427
|
+
}
|
|
5718
6428
|
return buildApplicationIdHints({
|
|
5719
6429
|
sdk,
|
|
5720
6430
|
inputIds: [applicationId, applicationId],
|
|
5721
|
-
outputIds
|
|
6431
|
+
outputIds
|
|
5722
6432
|
});
|
|
5723
6433
|
}
|
|
5724
6434
|
async function proveDualConfidentialTransfer(parameters) {
|
|
@@ -5738,16 +6448,24 @@ async function proveDualConfidentialTransfer(parameters) {
|
|
|
5738
6448
|
audit
|
|
5739
6449
|
);
|
|
5740
6450
|
}
|
|
5741
|
-
|
|
6451
|
+
function dualTransferChangeStroops(parameters) {
|
|
5742
6452
|
const totalNotes = BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value);
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
6453
|
+
if (parameters.transferStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
6454
|
+
throw new Error("Transfer amount must be positive");
|
|
6455
|
+
}
|
|
6456
|
+
const changeStroops = remainingAfterRequiredFee({
|
|
6457
|
+
available: totalNotes,
|
|
6458
|
+
instructed: parameters.transferStroops,
|
|
6459
|
+
requiredFee: parameters.feeOutput?.requiredFee ?? 0n
|
|
6460
|
+
});
|
|
5747
6461
|
requireChangeRecipientWhenPartial(
|
|
5748
6462
|
changeStroops,
|
|
5749
6463
|
parameters.selfPrivateAddressStpl1ForChange
|
|
5750
6464
|
);
|
|
6465
|
+
return changeStroops;
|
|
6466
|
+
}
|
|
6467
|
+
async function buildDualTransferProofContext(parameters, applicationId, sdk) {
|
|
6468
|
+
const changeStroops = dualTransferChangeStroops(parameters);
|
|
5751
6469
|
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
5752
6470
|
parameters.senderPrivKeyScalarHex
|
|
5753
6471
|
);
|
|
@@ -5774,15 +6492,21 @@ async function buildDualTransferProofContext(parameters, applicationId, sdk) {
|
|
|
5774
6492
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
5775
6493
|
tokenAddress: parameters.tokenAddress,
|
|
5776
6494
|
stateRoot: legA.witness.stateRoot,
|
|
5777
|
-
...confidentialEscrowFields(parameters)
|
|
6495
|
+
...confidentialEscrowFields(parameters),
|
|
6496
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
5778
6497
|
});
|
|
5779
6498
|
return { legA, legB, applicationId, ...transferInputs };
|
|
5780
6499
|
}
|
|
5781
6500
|
async function prepareConfidentialTransferProofDual(parameters) {
|
|
5782
6501
|
const poolService = getPrivacyPoolService();
|
|
5783
|
-
const sdk = await poolService.getInitializedSdk(
|
|
6502
|
+
const sdk = await poolService.getInitializedSdk(
|
|
6503
|
+
poolService.feeBearingZkConfigNonce({
|
|
6504
|
+
kind: "transfer",
|
|
6505
|
+
...parameters.escrowClaimantLimbs ? { spendSource: "escrow" } : {}
|
|
6506
|
+
})
|
|
6507
|
+
);
|
|
5784
6508
|
const applicationId = poolService.getApplicationId();
|
|
5785
|
-
const { legA, legB, recipientSlot, deposits, changeCoin, publicInput } = await buildDualTransferProofContext(parameters, applicationId, sdk);
|
|
6509
|
+
const { legA, legB, recipientSlot, deposits, changeCoin, feeCoin, publicInput } = await buildDualTransferProofContext(parameters, applicationId, sdk);
|
|
5786
6510
|
const auditPublicKey = poolService.getAuditPublicKey();
|
|
5787
6511
|
const proof = await (auditPublicKey ? proveDualConfidentialTransfer({
|
|
5788
6512
|
sdk,
|
|
@@ -5805,7 +6529,8 @@ async function prepareConfidentialTransferProofDual(parameters) {
|
|
|
5805
6529
|
applicationIdsPlaintext: buildDualTransferApplicationIds(
|
|
5806
6530
|
sdk,
|
|
5807
6531
|
applicationId,
|
|
5808
|
-
changeCoin
|
|
6532
|
+
changeCoin,
|
|
6533
|
+
feeCoin
|
|
5809
6534
|
),
|
|
5810
6535
|
recipientCoin: generatedOutputCoinFromSlot(recipientSlot),
|
|
5811
6536
|
...changeCoin ? { changeCoin } : {}
|
|
@@ -5813,22 +6538,32 @@ async function prepareConfidentialTransferProofDual(parameters) {
|
|
|
5813
6538
|
}
|
|
5814
6539
|
|
|
5815
6540
|
// src/transact/proofs/confidential/single.ts
|
|
5816
|
-
function validateSingleCoinTransferAmounts(transferStroops, noteStroops, selfPrivateAddressStpl1ForChange) {
|
|
6541
|
+
function validateSingleCoinTransferAmounts(transferStroops, noteStroops, selfPrivateAddressStpl1ForChange, requiredFee) {
|
|
5817
6542
|
if (transferStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
5818
6543
|
throw new Error("Transfer amount must be positive");
|
|
5819
6544
|
}
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
6545
|
+
const changeStroops = remainingAfterRequiredFee({
|
|
6546
|
+
available: noteStroops,
|
|
6547
|
+
instructed: transferStroops,
|
|
6548
|
+
requiredFee
|
|
6549
|
+
});
|
|
5824
6550
|
requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange);
|
|
5825
6551
|
return changeStroops;
|
|
5826
6552
|
}
|
|
5827
|
-
function buildSingleTransferApplicationIds(sdk, applicationId, changeCoin) {
|
|
6553
|
+
function buildSingleTransferApplicationIds(sdk, applicationId, changeCoin, feeCoin) {
|
|
6554
|
+
const outputIds = [applicationId];
|
|
6555
|
+
if (changeCoin) {
|
|
6556
|
+
outputIds.push(applicationId);
|
|
6557
|
+
} else if (!feeCoin) {
|
|
6558
|
+
outputIds.push("0");
|
|
6559
|
+
}
|
|
6560
|
+
if (feeCoin) {
|
|
6561
|
+
outputIds.push(applicationId);
|
|
6562
|
+
}
|
|
5828
6563
|
return buildApplicationIdHints({
|
|
5829
6564
|
sdk,
|
|
5830
6565
|
inputIds: [applicationId],
|
|
5831
|
-
outputIds
|
|
6566
|
+
outputIds
|
|
5832
6567
|
});
|
|
5833
6568
|
}
|
|
5834
6569
|
function buildTransferAuditParameters(parameters) {
|
|
@@ -5854,11 +6589,25 @@ function confidentialEscrowFields2(input) {
|
|
|
5854
6589
|
...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
|
|
5855
6590
|
};
|
|
5856
6591
|
}
|
|
6592
|
+
function transferDepositInputFromProof(input, changeStroops, stateRoot) {
|
|
6593
|
+
return {
|
|
6594
|
+
senderPrivKeyScalarHex: input.senderPrivKeyScalarHex,
|
|
6595
|
+
recipientPrivateAddressStpl1: input.recipientPrivateAddressStpl1,
|
|
6596
|
+
transferStroops: input.transferStroops,
|
|
6597
|
+
changeStroops,
|
|
6598
|
+
selfPrivateAddressStpl1ForChange: input.selfPrivateAddressStpl1ForChange,
|
|
6599
|
+
tokenAddress: input.tokenAddress,
|
|
6600
|
+
stateRoot,
|
|
6601
|
+
...confidentialEscrowFields2(input),
|
|
6602
|
+
...input.feeOutput ? { feeOutput: input.feeOutput } : {}
|
|
6603
|
+
};
|
|
6604
|
+
}
|
|
5857
6605
|
async function buildTransferProofInputs(parameters) {
|
|
5858
6606
|
const changeStroops = validateSingleCoinTransferAmounts(
|
|
5859
6607
|
parameters.input.transferStroops,
|
|
5860
6608
|
parameters.noteStroops,
|
|
5861
|
-
parameters.input.selfPrivateAddressStpl1ForChange
|
|
6609
|
+
parameters.input.selfPrivateAddressStpl1ForChange,
|
|
6610
|
+
parameters.input.feeOutput?.requiredFee ?? 0n
|
|
5862
6611
|
);
|
|
5863
6612
|
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
5864
6613
|
parameters.input.senderPrivKeyScalarHex
|
|
@@ -5877,31 +6626,30 @@ async function buildTransferProofInputs(parameters) {
|
|
|
5877
6626
|
withdrawObject,
|
|
5878
6627
|
sweepWithdrawStamp(confidentialEscrowFields2(parameters.input))
|
|
5879
6628
|
);
|
|
5880
|
-
const { recipientSlot, deposits, changeCoin, publicInput } = await buildSenderTransferDepositsAndPublicInput(
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
transferStroops: parameters.input.transferStroops,
|
|
5884
|
-
changeStroops,
|
|
5885
|
-
selfPrivateAddressStpl1ForChange: parameters.input.selfPrivateAddressStpl1ForChange,
|
|
5886
|
-
tokenAddress: parameters.input.tokenAddress,
|
|
5887
|
-
stateRoot: witness.stateRoot,
|
|
5888
|
-
...confidentialEscrowFields2(parameters.input)
|
|
5889
|
-
});
|
|
6629
|
+
const { recipientSlot, deposits, changeCoin, feeCoin, publicInput } = await buildSenderTransferDepositsAndPublicInput(
|
|
6630
|
+
transferDepositInputFromProof(parameters.input, changeStroops, witness.stateRoot)
|
|
6631
|
+
);
|
|
5890
6632
|
return {
|
|
5891
6633
|
witness,
|
|
5892
6634
|
withdrawObject: stampedWithdraw,
|
|
5893
6635
|
recipientSlot,
|
|
5894
6636
|
deposits,
|
|
5895
6637
|
changeCoin,
|
|
6638
|
+
feeCoin,
|
|
5896
6639
|
publicInput
|
|
5897
6640
|
};
|
|
5898
6641
|
}
|
|
5899
6642
|
async function prepareConfidentialTransferProof(parameters) {
|
|
5900
6643
|
const poolService = getPrivacyPoolService();
|
|
5901
|
-
const sdk = await poolService.getInitializedSdk(
|
|
6644
|
+
const sdk = await poolService.getInitializedSdk(
|
|
6645
|
+
poolService.feeBearingZkConfigNonce({
|
|
6646
|
+
kind: "transfer",
|
|
6647
|
+
...parameters.escrowClaimantLimbs ? { spendSource: "escrow" } : {}
|
|
6648
|
+
})
|
|
6649
|
+
);
|
|
5902
6650
|
const applicationId = poolService.getApplicationId();
|
|
5903
6651
|
const noteStroops = BigInt(parameters.coin.value);
|
|
5904
|
-
const { withdrawObject, recipientSlot, deposits, changeCoin, publicInput } = await buildTransferProofInputs({
|
|
6652
|
+
const { withdrawObject, recipientSlot, deposits, changeCoin, feeCoin, publicInput } = await buildTransferProofInputs({
|
|
5905
6653
|
sdk,
|
|
5906
6654
|
applicationId,
|
|
5907
6655
|
input: parameters,
|
|
@@ -5924,7 +6672,8 @@ async function prepareConfidentialTransferProof(parameters) {
|
|
|
5924
6672
|
applicationIdsPlaintext: buildSingleTransferApplicationIds(
|
|
5925
6673
|
sdk,
|
|
5926
6674
|
applicationId,
|
|
5927
|
-
changeCoin
|
|
6675
|
+
changeCoin,
|
|
6676
|
+
feeCoin
|
|
5928
6677
|
),
|
|
5929
6678
|
recipientCoin: generatedOutputCoinFromSlot(recipientSlot),
|
|
5930
6679
|
...changeCoin ? { changeCoin } : {}
|
|
@@ -5947,10 +6696,15 @@ function proofEscrowFields(input) {
|
|
|
5947
6696
|
}
|
|
5948
6697
|
async function buildSingleTransferProofAtExecute(input) {
|
|
5949
6698
|
const context = await buildSpendProofContextAtExecute(input);
|
|
5950
|
-
const
|
|
6699
|
+
const feeOutput = await quoteFeeOutputForPrepared({
|
|
6700
|
+
prepared: input.prepared,
|
|
6701
|
+
environment: input.environment,
|
|
6702
|
+
tokenAddress: context.tokenAddress
|
|
6703
|
+
});
|
|
6704
|
+
const changeStroops = BigInt(context.coin.value) - input.prepared.intent.amount - (feeOutput?.requiredFee ?? 0n);
|
|
5951
6705
|
const proof = await prepareConfidentialTransferProof({
|
|
5952
6706
|
coin: context.coin,
|
|
5953
|
-
state:
|
|
6707
|
+
state: context.merkleState,
|
|
5954
6708
|
senderPrivKeyScalarHex: context.senderPrivKeyScalarHex,
|
|
5955
6709
|
depositorEphemeralKey: serializeEphemeralKeyString({
|
|
5956
6710
|
xHex: context.ephemeral.xHex,
|
|
@@ -5960,7 +6714,8 @@ async function buildSingleTransferProofAtExecute(input) {
|
|
|
5960
6714
|
recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
|
|
5961
6715
|
selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
|
|
5962
6716
|
tokenAddress: context.tokenAddress,
|
|
5963
|
-
...proofEscrowFields(input)
|
|
6717
|
+
...proofEscrowFields(input),
|
|
6718
|
+
...feeOutput ? { feeOutput } : {}
|
|
5964
6719
|
});
|
|
5965
6720
|
return { context, proof };
|
|
5966
6721
|
}
|
|
@@ -5977,11 +6732,16 @@ async function buildDualTransferProofAtExecute(input) {
|
|
|
5977
6732
|
commitments: context.commitments
|
|
5978
6733
|
});
|
|
5979
6734
|
const totalNotes = BigInt(context.coin.value) + BigInt(secondary.coin.value);
|
|
5980
|
-
const
|
|
6735
|
+
const feeOutput = await quoteFeeOutputForPrepared({
|
|
6736
|
+
prepared: input.prepared,
|
|
6737
|
+
environment: input.environment,
|
|
6738
|
+
tokenAddress: context.tokenAddress
|
|
6739
|
+
});
|
|
6740
|
+
const changeStroops = totalNotes - input.prepared.intent.amount - (feeOutput?.requiredFee ?? 0n);
|
|
5981
6741
|
const proof = await prepareConfidentialTransferProofDual({
|
|
5982
6742
|
coinA: context.coin,
|
|
5983
6743
|
coinB: secondary.coin,
|
|
5984
|
-
state:
|
|
6744
|
+
state: context.merkleState,
|
|
5985
6745
|
senderPrivKeyScalarHex: context.senderPrivKeyScalarHex,
|
|
5986
6746
|
ephemeralAKey: serializeEphemeralKeyString({
|
|
5987
6747
|
xHex: context.ephemeral.xHex,
|
|
@@ -5995,7 +6755,8 @@ async function buildDualTransferProofAtExecute(input) {
|
|
|
5995
6755
|
recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
|
|
5996
6756
|
selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
|
|
5997
6757
|
tokenAddress: context.tokenAddress,
|
|
5998
|
-
...proofEscrowFields(input)
|
|
6758
|
+
...proofEscrowFields(input),
|
|
6759
|
+
...feeOutput ? { feeOutput } : {}
|
|
5999
6760
|
});
|
|
6000
6761
|
return { context, proof };
|
|
6001
6762
|
}
|
|
@@ -6127,11 +6888,17 @@ async function runTransferFinalizeSteps(input) {
|
|
|
6127
6888
|
walletPublicKey: input.walletPublicKey,
|
|
6128
6889
|
...recipient.escrowSend ? { escrowSendPrivateAddress: recipient.recipientPrivateAddressStpl1 } : {}
|
|
6129
6890
|
});
|
|
6130
|
-
return
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6891
|
+
return {
|
|
6892
|
+
...buildTransferFinalizeArtifacts({
|
|
6893
|
+
proof,
|
|
6894
|
+
context,
|
|
6895
|
+
...sweepFinalizeStamp(input.prepared, recipient)
|
|
6896
|
+
}),
|
|
6897
|
+
zkConfigNonce: zkConfigNonceForFeeBearingKind({
|
|
6898
|
+
...feeOutputKindFromPrepared(input.prepared),
|
|
6899
|
+
...configuredNonceSpread(input.environment.zkConfigNonce)
|
|
6900
|
+
})
|
|
6901
|
+
};
|
|
6135
6902
|
}
|
|
6136
6903
|
function sweepArtifactStamp(artifacts) {
|
|
6137
6904
|
return {
|
|
@@ -6159,6 +6926,24 @@ async function finalizeTransferAtExecute(prepared, environment) {
|
|
|
6159
6926
|
return runTransferFinalizeSteps({ prepared, environment, walletPublicKey });
|
|
6160
6927
|
}
|
|
6161
6928
|
|
|
6929
|
+
// src/transact/engine/withdraw-fee.ts
|
|
6930
|
+
async function withdrawFeeProofFields(input) {
|
|
6931
|
+
const feeOutput = await quoteFeeOutputForPrepared({
|
|
6932
|
+
prepared: input.prepared,
|
|
6933
|
+
environment: input.environment,
|
|
6934
|
+
tokenAddress: input.tokenAddress
|
|
6935
|
+
});
|
|
6936
|
+
const changeStroops = remainingAfterRequiredFee({
|
|
6937
|
+
available: input.available,
|
|
6938
|
+
instructed: input.prepared.intent.amount,
|
|
6939
|
+
requiredFee: feeOutput?.requiredFee ?? 0n
|
|
6940
|
+
});
|
|
6941
|
+
return {
|
|
6942
|
+
...feeOutput ? { feeOutput } : {},
|
|
6943
|
+
...changeStroops > 0n ? { changePrivateAddressStpl1: input.withdrawFrom } : {}
|
|
6944
|
+
};
|
|
6945
|
+
}
|
|
6946
|
+
|
|
6162
6947
|
// src/transact/engine/execute.ts
|
|
6163
6948
|
function enrichWithdrawOutputRecords(prepared, proof) {
|
|
6164
6949
|
if (!proof.changeCoin || prepared.outputRecords.length === 0) {
|
|
@@ -6174,7 +6959,7 @@ function enrichWithdrawOutputRecords(prepared, proof) {
|
|
|
6174
6959
|
precommitementHex: changeCoin.precommitementHex
|
|
6175
6960
|
}));
|
|
6176
6961
|
}
|
|
6177
|
-
function buildWithdrawFinalizeArtifacts(proof, context) {
|
|
6962
|
+
function buildWithdrawFinalizeArtifacts(proof, context, environment) {
|
|
6178
6963
|
return {
|
|
6179
6964
|
proofHex: proof.proof_hex,
|
|
6180
6965
|
publicHex: proof.public_hex,
|
|
@@ -6182,7 +6967,11 @@ function buildWithdrawFinalizeArtifacts(proof, context) {
|
|
|
6182
6967
|
applicationIdsPlaintext: proof.applicationIdsPlaintext,
|
|
6183
6968
|
tokenAddress: context.tokenAddress,
|
|
6184
6969
|
walletPublicKey: context.walletPublicKey,
|
|
6185
|
-
executeFinalizeRequired: false
|
|
6970
|
+
executeFinalizeRequired: false,
|
|
6971
|
+
zkConfigNonce: zkConfigNonceForFeeBearingKind({
|
|
6972
|
+
kind: "withdraw",
|
|
6973
|
+
...configuredNonceSpread(environment.zkConfigNonce)
|
|
6974
|
+
})
|
|
6186
6975
|
};
|
|
6187
6976
|
}
|
|
6188
6977
|
async function finalizeSingleWithdrawAtExecute(prepared, environment, poolService, withdrawFrom) {
|
|
@@ -6191,10 +6980,16 @@ async function finalizeSingleWithdrawAtExecute(prepared, environment, poolServic
|
|
|
6191
6980
|
environment,
|
|
6192
6981
|
recipientPrivateAddressStpl1: withdrawFrom
|
|
6193
6982
|
});
|
|
6194
|
-
const
|
|
6983
|
+
const feeFields = await withdrawFeeProofFields({
|
|
6984
|
+
prepared,
|
|
6985
|
+
environment,
|
|
6986
|
+
tokenAddress: context.tokenAddress,
|
|
6987
|
+
available: BigInt(context.coin.value),
|
|
6988
|
+
withdrawFrom
|
|
6989
|
+
});
|
|
6195
6990
|
const proof = await poolService.prepareWithdrawTransactProof({
|
|
6196
6991
|
coin: context.coin,
|
|
6197
|
-
state:
|
|
6992
|
+
state: context.merkleState,
|
|
6198
6993
|
destinationStellarAddress: prepared.intent.to,
|
|
6199
6994
|
privKeyScalarHex: context.senderPrivKeyScalarHex,
|
|
6200
6995
|
depositorEphemeralKey: serializeEphemeralKeyString({
|
|
@@ -6202,11 +6997,24 @@ async function finalizeSingleWithdrawAtExecute(prepared, environment, poolServic
|
|
|
6202
6997
|
yHex: context.ephemeral.yHex
|
|
6203
6998
|
}),
|
|
6204
6999
|
withdrawAmountStroops: prepared.intent.amount,
|
|
6205
|
-
changePrivateAddressStpl1:
|
|
6206
|
-
tokenAddress: context.tokenAddress
|
|
7000
|
+
changePrivateAddressStpl1: feeFields.changePrivateAddressStpl1,
|
|
7001
|
+
tokenAddress: context.tokenAddress,
|
|
7002
|
+
...feeFields.feeOutput ? { feeOutput: feeFields.feeOutput } : {}
|
|
6207
7003
|
});
|
|
6208
7004
|
enrichWithdrawOutputRecords(prepared, proof);
|
|
6209
|
-
return buildWithdrawFinalizeArtifacts(proof, context);
|
|
7005
|
+
return buildWithdrawFinalizeArtifacts(proof, context, environment);
|
|
7006
|
+
}
|
|
7007
|
+
function dualWithdrawEphemeralKeys(input) {
|
|
7008
|
+
return {
|
|
7009
|
+
depositorEphemeralAKey: serializeEphemeralKeyString({
|
|
7010
|
+
xHex: input.context.ephemeral.xHex,
|
|
7011
|
+
yHex: input.context.ephemeral.yHex
|
|
7012
|
+
}),
|
|
7013
|
+
depositorEphemeralBKey: serializeEphemeralKeyString({
|
|
7014
|
+
xHex: input.secondary.ephemeral.xHex,
|
|
7015
|
+
yHex: input.secondary.ephemeral.yHex
|
|
7016
|
+
})
|
|
7017
|
+
};
|
|
6210
7018
|
}
|
|
6211
7019
|
async function finalizeDualWithdrawAtExecute(prepared, environment, poolService, withdrawFrom) {
|
|
6212
7020
|
const [, secondaryRecord] = prepared.consumedRecords;
|
|
@@ -6224,28 +7032,27 @@ async function finalizeDualWithdrawAtExecute(prepared, environment, poolService,
|
|
|
6224
7032
|
walletPublicKey: context.walletPublicKey,
|
|
6225
7033
|
commitments: context.commitments
|
|
6226
7034
|
});
|
|
6227
|
-
const
|
|
6228
|
-
|
|
7035
|
+
const feeFields = await withdrawFeeProofFields({
|
|
7036
|
+
prepared,
|
|
7037
|
+
environment,
|
|
7038
|
+
tokenAddress: context.tokenAddress,
|
|
7039
|
+
available: BigInt(context.coin.value) + BigInt(secondary.coin.value),
|
|
7040
|
+
withdrawFrom
|
|
7041
|
+
});
|
|
6229
7042
|
const proof = await poolService.prepareWithdrawTransactProofDual({
|
|
6230
7043
|
coinA: context.coin,
|
|
6231
7044
|
coinB: secondary.coin,
|
|
6232
|
-
state:
|
|
7045
|
+
state: context.merkleState,
|
|
6233
7046
|
destinationStellarAddress: prepared.intent.to,
|
|
6234
7047
|
privKeyScalarHex: context.senderPrivKeyScalarHex,
|
|
6235
|
-
|
|
6236
|
-
xHex: context.ephemeral.xHex,
|
|
6237
|
-
yHex: context.ephemeral.yHex
|
|
6238
|
-
}),
|
|
6239
|
-
depositorEphemeralBKey: serializeEphemeralKeyString({
|
|
6240
|
-
xHex: secondary.ephemeral.xHex,
|
|
6241
|
-
yHex: secondary.ephemeral.yHex
|
|
6242
|
-
}),
|
|
7048
|
+
...dualWithdrawEphemeralKeys({ context, secondary }),
|
|
6243
7049
|
withdrawAmountStroops: prepared.intent.amount,
|
|
6244
|
-
changePrivateAddressStpl1:
|
|
6245
|
-
tokenAddress: context.tokenAddress
|
|
7050
|
+
changePrivateAddressStpl1: feeFields.changePrivateAddressStpl1,
|
|
7051
|
+
tokenAddress: context.tokenAddress,
|
|
7052
|
+
...feeFields.feeOutput ? { feeOutput: feeFields.feeOutput } : {}
|
|
6246
7053
|
});
|
|
6247
7054
|
enrichWithdrawOutputRecords(prepared, proof);
|
|
6248
|
-
return buildWithdrawFinalizeArtifacts(proof, context);
|
|
7055
|
+
return buildWithdrawFinalizeArtifacts(proof, context, environment);
|
|
6249
7056
|
}
|
|
6250
7057
|
async function finalizeWithdrawAtExecute(prepared, environment, poolService) {
|
|
6251
7058
|
if (prepared.kind !== "withdraw") {
|
|
@@ -6507,7 +7314,7 @@ async function requestKytPassageForPoolInteraction(input) {
|
|
|
6507
7314
|
const applicationId = resolvePoolApplicationId(
|
|
6508
7315
|
input.transactEnvironment.network.applicationId
|
|
6509
7316
|
);
|
|
6510
|
-
const zkConfigNonce = resolveZkConfigNonce(input.transactEnvironment);
|
|
7317
|
+
const zkConfigNonce = input.zkConfigNonce ?? resolveZkConfigNonce(input.transactEnvironment);
|
|
6511
7318
|
const applicationIdsPlaintext = input.applicationIdsPlaintext ?? buildApplicationIdHints2(
|
|
6512
7319
|
applicationId,
|
|
6513
7320
|
layoutForKnownNonce(zkConfigNonce).nAuditSlots
|
|
@@ -6679,6 +7486,10 @@ async function submitSorobanConfidentialTransfer(input) {
|
|
|
6679
7486
|
networkPassphrase: input.networkPassphrase,
|
|
6680
7487
|
sorobanRpcUrl: input.sorobanRpcUrl
|
|
6681
7488
|
});
|
|
7489
|
+
const nonce = transactNonceFromArtifacts(
|
|
7490
|
+
input.zkConfigNonce === void 0 ? void 0 : { zkConfigNonce: input.zkConfigNonce },
|
|
7491
|
+
input.transactEnvironment
|
|
7492
|
+
);
|
|
6682
7493
|
const approval = await requestKytPassageForPoolInteraction({
|
|
6683
7494
|
owner: input.walletPublicKey,
|
|
6684
7495
|
poolContract: input.contractId,
|
|
@@ -6687,6 +7498,7 @@ async function submitSorobanConfidentialTransfer(input) {
|
|
|
6687
7498
|
...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
|
|
6688
7499
|
...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {},
|
|
6689
7500
|
...input.applicationIdsPlaintext ? { applicationIdsPlaintext: input.applicationIdsPlaintext } : {},
|
|
7501
|
+
...input.zkConfigNonce === void 0 ? {} : { zkConfigNonce: input.zkConfigNonce },
|
|
6690
7502
|
networkPassphrase: input.networkPassphrase,
|
|
6691
7503
|
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
6692
7504
|
transactEnvironment: input.transactEnvironment
|
|
@@ -6695,7 +7507,7 @@ async function submitSorobanConfidentialTransfer(input) {
|
|
|
6695
7507
|
contractClient: poolClient,
|
|
6696
7508
|
contractId: input.contractId,
|
|
6697
7509
|
from: input.walletPublicKey,
|
|
6698
|
-
nonce
|
|
7510
|
+
nonce,
|
|
6699
7511
|
proofHex: input.proofHex,
|
|
6700
7512
|
publicHex: input.publicHex,
|
|
6701
7513
|
...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
|
|
@@ -6726,12 +7538,14 @@ async function submitPreparedDeposit(prepared, environment) {
|
|
|
6726
7538
|
networkPassphrase: environment.network.networkPassphrase,
|
|
6727
7539
|
sorobanRpcUrl: environment.network.rpcUrl
|
|
6728
7540
|
});
|
|
7541
|
+
const nonce = transactNonceFromArtifacts(artifacts, environment);
|
|
6729
7542
|
const approval = await requestKytPassageForPoolInteraction({
|
|
6730
7543
|
owner: artifacts.walletPublicKey,
|
|
6731
7544
|
poolContract: environment.network.poolContract,
|
|
6732
7545
|
proofHex: artifacts.proofHex,
|
|
6733
7546
|
publicHex: artifacts.publicHex,
|
|
6734
7547
|
...optionalInspectCiphertext(artifacts),
|
|
7548
|
+
...artifacts.zkConfigNonce === void 0 ? {} : { zkConfigNonce: artifacts.zkConfigNonce },
|
|
6735
7549
|
networkPassphrase: environment.network.networkPassphrase,
|
|
6736
7550
|
sorobanRpcUrl: environment.network.rpcUrl,
|
|
6737
7551
|
transactEnvironment: environment
|
|
@@ -6740,7 +7554,7 @@ async function submitPreparedDeposit(prepared, environment) {
|
|
|
6740
7554
|
contractClient: poolClient,
|
|
6741
7555
|
contractId: environment.network.poolContract,
|
|
6742
7556
|
from: artifacts.walletPublicKey,
|
|
6743
|
-
nonce
|
|
7557
|
+
nonce,
|
|
6744
7558
|
proofHex: artifacts.proofHex,
|
|
6745
7559
|
publicHex: artifacts.publicHex,
|
|
6746
7560
|
...artifacts.ciphertextHex ? { ciphertextHex: artifacts.ciphertextHex } : {},
|
|
@@ -6761,6 +7575,7 @@ async function submitPreparedPoolTransact(prepared, environment) {
|
|
|
6761
7575
|
proofHex: artifacts.proofHex,
|
|
6762
7576
|
publicHex: artifacts.publicHex,
|
|
6763
7577
|
...optionalInspectCiphertext(artifacts),
|
|
7578
|
+
...artifacts.zkConfigNonce === void 0 ? {} : { zkConfigNonce: artifacts.zkConfigNonce },
|
|
6764
7579
|
networkPassphrase: environment.network.networkPassphrase,
|
|
6765
7580
|
sorobanRpcUrl: environment.network.rpcUrl,
|
|
6766
7581
|
transactEnvironment: environment
|
|
@@ -6816,7 +7631,7 @@ async function privacyPoolInitOptions(assets, transactEnvironment) {
|
|
|
6816
7631
|
};
|
|
6817
7632
|
}
|
|
6818
7633
|
async function createDefaultTransactEngine(assets, transactEnvironment) {
|
|
6819
|
-
await
|
|
7634
|
+
await PrivacyPoolSDK4.init(await privacyPoolInitOptions(assets, transactEnvironment));
|
|
6820
7635
|
if (transactEnvironment) {
|
|
6821
7636
|
configurePrivacyPoolService(
|
|
6822
7637
|
createPrivacyPoolService({
|