@arcanetech/privacy-sdk-stellar 0.5.1 → 0.5.4
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 +40 -10
- package/dist/index.js +971 -335
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +7 -5
- package/dist/node.js +947 -319
- package/dist/node.js.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/transact/index.d.ts +40 -10
- package/dist/transact/index.js +905 -291
- package/dist/transact/index.js.map +1 -1
- package/package.json +6 -6
package/dist/node.js
CHANGED
|
@@ -468,27 +468,9 @@ function buildPrivateRecordFromDeposit(input) {
|
|
|
468
468
|
|
|
469
469
|
// src/transact/pool/service.ts
|
|
470
470
|
import {
|
|
471
|
-
|
|
472
|
-
decodeDecodedEphemeralKey,
|
|
473
|
-
randomFrDecimal253,
|
|
474
|
-
scalarHexToFrDecimal as scalarHexToFrDecimal2
|
|
471
|
+
decodeDecodedEphemeralKey
|
|
475
472
|
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
476
473
|
|
|
477
|
-
// src/transact/merkle/field-decimal.ts
|
|
478
|
-
import { Buffer as Buffer4 } from "buffer";
|
|
479
|
-
var BN254 = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
480
|
-
var MERKLE_ROOT_BYTE_LENGTH = 32;
|
|
481
|
-
var DECIMAL_STRING_RADIX = 10;
|
|
482
|
-
function merkleRootBufferToFrDecimal(root) {
|
|
483
|
-
if (root.length !== MERKLE_ROOT_BYTE_LENGTH) {
|
|
484
|
-
throw new Error(
|
|
485
|
-
`expected ${MERKLE_ROOT_BYTE_LENGTH}-byte merkle root, got ${root.length}`
|
|
486
|
-
);
|
|
487
|
-
}
|
|
488
|
-
const hex = Buffer4.from(root).toString("hex");
|
|
489
|
-
return (BigInt(`0x${hex}`) % BN254).toString(DECIMAL_STRING_RADIX);
|
|
490
|
-
}
|
|
491
|
-
|
|
492
474
|
// src/transact/private-address/codec.ts
|
|
493
475
|
import {
|
|
494
476
|
buildStealthAddressSignMessage,
|
|
@@ -537,18 +519,18 @@ function privateAddressSdk(sdk) {
|
|
|
537
519
|
import { withdrawObjectFromMerkleWitness as withdrawObjectFromMerkleWitness2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
538
520
|
|
|
539
521
|
// src/transact/proofs/transaction-input.ts
|
|
540
|
-
import { Buffer as
|
|
522
|
+
import { Buffer as Buffer5 } from "buffer";
|
|
541
523
|
import { StrKey as StrKey2 } from "@stellar/stellar-sdk";
|
|
542
524
|
|
|
543
525
|
// src/transact/stellar/token-contract.ts
|
|
544
|
-
import { Buffer as
|
|
526
|
+
import { Buffer as Buffer4 } from "buffer";
|
|
545
527
|
import { StrKey } from "@stellar/stellar-sdk";
|
|
546
528
|
var CONTRACT_ID_BYTE_LENGTH = 32;
|
|
547
529
|
var HEX_CHARS_PER_BYTE = 2;
|
|
548
530
|
var CONTRACT_ID_HEX_CHAR_LENGTH = CONTRACT_ID_BYTE_LENGTH * HEX_CHARS_PER_BYTE;
|
|
549
531
|
var CONTRACT_ID_HEX = /^(?:0x)?([0-9a-f]{64})$/i;
|
|
550
532
|
function encodeContractFromHex(hexPayload) {
|
|
551
|
-
return StrKey.encodeContract(
|
|
533
|
+
return StrKey.encodeContract(Buffer4.from(hexPayload, "hex"));
|
|
552
534
|
}
|
|
553
535
|
function normalizeSorobanContractId(raw) {
|
|
554
536
|
const trimmed = raw.trim();
|
|
@@ -581,7 +563,7 @@ var ZERO_PUBLIC_WITHDRAW_ADDRESS = {
|
|
|
581
563
|
var CONTRACT_ADDRESS_HALF_BYTES = 16;
|
|
582
564
|
var CONTRACT_ADDRESS_BYTES = 32;
|
|
583
565
|
function bytes16ToDecimal(bytes) {
|
|
584
|
-
return BigInt(`0x${
|
|
566
|
+
return BigInt(`0x${Buffer5.from(bytes).toString("hex")}`).toString();
|
|
585
567
|
}
|
|
586
568
|
function tokenAddressFrParts(tokenAddress) {
|
|
587
569
|
const normalized = resolveTokenContractId(tokenAddress);
|
|
@@ -742,14 +724,144 @@ function requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl
|
|
|
742
724
|
}
|
|
743
725
|
}
|
|
744
726
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
727
|
+
|
|
728
|
+
// src/transact/fees/quote-request-body.ts
|
|
729
|
+
function presentInstructedAmount(amount) {
|
|
730
|
+
const trimmed = amount?.trim() ?? "";
|
|
731
|
+
if (!trimmed || trimmed === "0") {
|
|
732
|
+
return void 0;
|
|
733
|
+
}
|
|
734
|
+
return trimmed;
|
|
735
|
+
}
|
|
736
|
+
function feeQuoteRequestBody(request) {
|
|
737
|
+
const publicDepositAmount = presentInstructedAmount(request.publicDepositAmount);
|
|
738
|
+
const transferInstructedAmount = presentInstructedAmount(
|
|
739
|
+
request.transferInstructedAmount
|
|
740
|
+
);
|
|
741
|
+
const publicWithdrawalAmount = presentInstructedAmount(
|
|
742
|
+
request.publicWithdrawalAmount
|
|
743
|
+
);
|
|
744
|
+
return {
|
|
745
|
+
feeAsset: request.feeAsset,
|
|
746
|
+
spendsNotes: request.spendsNotes,
|
|
747
|
+
...publicDepositAmount === void 0 ? {} : { publicDepositAmount },
|
|
748
|
+
...transferInstructedAmount === void 0 ? {} : { transferInstructedAmount },
|
|
749
|
+
...publicWithdrawalAmount === void 0 ? {} : { publicWithdrawalAmount }
|
|
750
|
+
};
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// src/transact/fees/quote-required-fee.ts
|
|
754
|
+
function quoteHeaders(inspectAuthorization) {
|
|
755
|
+
const token = inspectAuthorization?.trim();
|
|
756
|
+
return {
|
|
757
|
+
"content-type": "application/json",
|
|
758
|
+
...token ? { authorization: `Bearer ${token}` } : {}
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
function parseRequiredFee(raw) {
|
|
762
|
+
const text = `${raw ?? ""}`.trim();
|
|
763
|
+
if (!/^\d+$/u.test(text)) {
|
|
764
|
+
throw new Error("Fee Quote Required Fee must be an integer minor-unit string.");
|
|
765
|
+
}
|
|
766
|
+
return BigInt(text);
|
|
767
|
+
}
|
|
768
|
+
function requireQuoteString(raw, field) {
|
|
769
|
+
const text = `${raw ?? ""}`.trim();
|
|
770
|
+
if (!text) {
|
|
771
|
+
throw new Error(`Fee Quote is missing ${field}.`);
|
|
772
|
+
}
|
|
773
|
+
return text;
|
|
774
|
+
}
|
|
775
|
+
function parseQuotePayload(payload) {
|
|
776
|
+
return {
|
|
777
|
+
requiredFee: parseRequiredFee(payload.requiredFee),
|
|
778
|
+
feeAsset: requireQuoteString(payload.feeAsset, "Fee Asset"),
|
|
779
|
+
feeCollectorPrivateAddress: requireQuoteString(
|
|
780
|
+
payload.feeCollectorPrivateAddress,
|
|
781
|
+
"Fee Collector Private Address"
|
|
782
|
+
),
|
|
783
|
+
feeRate: requireQuoteString(payload.feeRate, "Fee Rate")
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
async function quoteRequiredFee(input) {
|
|
787
|
+
const response = await fetch(
|
|
788
|
+
`${input.transactEnvironment.kyt.apiBaseUrl}/kyt/fees/quote`,
|
|
789
|
+
{
|
|
790
|
+
method: "POST",
|
|
791
|
+
headers: quoteHeaders(input.transactEnvironment.kyt.inspectAuthorization),
|
|
792
|
+
body: JSON.stringify(feeQuoteRequestBody(input.request))
|
|
793
|
+
}
|
|
794
|
+
);
|
|
795
|
+
const payload = await response.json();
|
|
796
|
+
if (!response.ok) {
|
|
797
|
+
throw new Error(`Fee Quote failed: ${JSON.stringify(payload)}`);
|
|
798
|
+
}
|
|
799
|
+
return parseQuotePayload(payload);
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
// src/transact/fees/should-attach-fee-output.ts
|
|
803
|
+
function shouldAttachFeeOutput(input) {
|
|
804
|
+
if (input.spendSource === "escrow" && input.escrowSend !== true) {
|
|
805
|
+
return false;
|
|
806
|
+
}
|
|
807
|
+
return input.kind === "deposit" || input.kind === "transfer" || input.kind === "withdraw";
|
|
808
|
+
}
|
|
809
|
+
function feeOutputKindFromPrepared(prepared) {
|
|
810
|
+
return {
|
|
811
|
+
kind: prepared.kind,
|
|
812
|
+
...prepared.transactArtifacts?.spendSource ? { spendSource: prepared.transactArtifacts.spendSource } : {},
|
|
813
|
+
...prepared.transactArtifacts?.escrowSend ? { escrowSend: true } : {}
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// src/transact/fees/quote-fee-output-for-prepared.ts
|
|
818
|
+
function instructedMinorUnits(prepared) {
|
|
819
|
+
return prepared.intent.amount.toString();
|
|
820
|
+
}
|
|
821
|
+
function quoteRequestForPrepared(input) {
|
|
822
|
+
const amount = instructedMinorUnits(input.prepared);
|
|
823
|
+
if (input.prepared.kind === "deposit") {
|
|
824
|
+
return {
|
|
825
|
+
feeAsset: input.tokenAddress,
|
|
826
|
+
publicDepositAmount: amount,
|
|
827
|
+
spendsNotes: false
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
if (input.prepared.kind === "withdraw") {
|
|
831
|
+
return {
|
|
832
|
+
feeAsset: input.tokenAddress,
|
|
833
|
+
publicWithdrawalAmount: amount,
|
|
834
|
+
spendsNotes: true
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
return {
|
|
838
|
+
feeAsset: input.tokenAddress,
|
|
839
|
+
transferInstructedAmount: amount,
|
|
840
|
+
spendsNotes: true
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
async function quoteFeeOutputForPrepared(input) {
|
|
844
|
+
if (!shouldAttachFeeOutput(feeOutputKindFromPrepared(input.prepared))) {
|
|
845
|
+
return void 0;
|
|
846
|
+
}
|
|
847
|
+
const quote = await quoteRequiredFee({
|
|
848
|
+
transactEnvironment: input.environment,
|
|
849
|
+
request: quoteRequestForPrepared(input)
|
|
850
|
+
});
|
|
851
|
+
if (quote.requiredFee <= 0n) {
|
|
852
|
+
return void 0;
|
|
748
853
|
}
|
|
749
|
-
|
|
750
|
-
|
|
854
|
+
return {
|
|
855
|
+
requiredFee: quote.requiredFee,
|
|
856
|
+
feeCollectorPrivateAddress: quote.feeCollectorPrivateAddress
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
function remainingAfterRequiredFee(input) {
|
|
860
|
+
const remaining = input.available - input.instructed - input.requiredFee;
|
|
861
|
+
if (remaining < 0n) {
|
|
862
|
+
throw new Error("Instructed amount and Required Fee exceed available note value");
|
|
751
863
|
}
|
|
752
|
-
return
|
|
864
|
+
return remaining;
|
|
753
865
|
}
|
|
754
866
|
|
|
755
867
|
// src/transact/audit/parameters.ts
|
|
@@ -757,7 +869,7 @@ import {
|
|
|
757
869
|
DEMO_AUDIT_PUBLIC_KEY,
|
|
758
870
|
resolveTransactionAuditParams
|
|
759
871
|
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
760
|
-
import { Buffer as
|
|
872
|
+
import { Buffer as Buffer6 } from "buffer";
|
|
761
873
|
var UNCOMPRESSED_PREFIX = "04";
|
|
762
874
|
var UNCOMPRESSED_HEX_LENGTH = 130;
|
|
763
875
|
var XY_HEX_LENGTH = 128;
|
|
@@ -784,7 +896,7 @@ function parseAuditPublicKeyFromEnvHex(raw) {
|
|
|
784
896
|
"Audit public key must be uncompressed 65-byte hex (04 + X + Y) or 64-byte X+Y hex"
|
|
785
897
|
);
|
|
786
898
|
}
|
|
787
|
-
const bytes =
|
|
899
|
+
const bytes = Buffer6.from(payload, "hex");
|
|
788
900
|
const auditPublicKeyXDecimal = BigInt(
|
|
789
901
|
`0x${bytes.subarray(0, X_OFFSET_END).toString("hex")}`
|
|
790
902
|
).toString(DECIMAL_RADIX);
|
|
@@ -806,6 +918,7 @@ function buildPoolTransactionAuditParameters(input) {
|
|
|
806
918
|
input.nAuditSlots
|
|
807
919
|
);
|
|
808
920
|
}
|
|
921
|
+
var DECIMAL_APPLICATION_ID = /^\d+$/u;
|
|
809
922
|
function resolvePoolApplicationId(applicationId) {
|
|
810
923
|
const trimmed = applicationId?.trim();
|
|
811
924
|
if (!trimmed) {
|
|
@@ -813,6 +926,11 @@ function resolvePoolApplicationId(applicationId) {
|
|
|
813
926
|
"Privacy pool applicationId is required. Pass it in client factory config."
|
|
814
927
|
);
|
|
815
928
|
}
|
|
929
|
+
if (!DECIMAL_APPLICATION_ID.test(trimmed)) {
|
|
930
|
+
throw new Error(
|
|
931
|
+
"Privacy pool applicationId must be association.audit_id (decimal Fr), not a UUID or foreignId."
|
|
932
|
+
);
|
|
933
|
+
}
|
|
816
934
|
return trimmed;
|
|
817
935
|
}
|
|
818
936
|
|
|
@@ -821,13 +939,13 @@ import { ed25519PubkeyPayloadHexToWithdrawFrDecimals } from "@arcanetech/stellar
|
|
|
821
939
|
|
|
822
940
|
// src/transact/stellar/account.ts
|
|
823
941
|
import { StrKey as StrKey3 } from "@stellar/stellar-sdk";
|
|
824
|
-
import { Buffer as
|
|
942
|
+
import { Buffer as Buffer7 } from "buffer";
|
|
825
943
|
var MUXED_ACCOUNT_ID_BYTE_LENGTH = 8;
|
|
826
944
|
var ED25519_PUBLIC_KEY_BYTE_LENGTH = 32;
|
|
827
945
|
function ed25519HexFromGAddress(trimmed) {
|
|
828
946
|
try {
|
|
829
947
|
const raw = StrKey3.decodeEd25519PublicKey(trimmed);
|
|
830
|
-
return
|
|
948
|
+
return Buffer7.from(raw).toString("hex");
|
|
831
949
|
} catch {
|
|
832
950
|
return void 0;
|
|
833
951
|
}
|
|
@@ -884,6 +1002,32 @@ function privKeyScalarDecimalFromRecipientScalarHex(hexInput) {
|
|
|
884
1002
|
return canonicalBabyJubScalarFromInteger(value).toString(DECIMAL_RADIX2);
|
|
885
1003
|
}
|
|
886
1004
|
|
|
1005
|
+
// src/transact/fees/append-fee-output.ts
|
|
1006
|
+
function feeCoinFromSlot(slot) {
|
|
1007
|
+
return {
|
|
1008
|
+
commitment_hex: slot.commitment_hex,
|
|
1009
|
+
coin: slot.coin,
|
|
1010
|
+
depositScalarHex: slot.depositScalarHex,
|
|
1011
|
+
precommitementHex: slot.precommitementHex
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
async function appendFeeOutputSlot(input) {
|
|
1015
|
+
const requiredFee = input.feeOutput?.requiredFee ?? ZERO_STROOPS;
|
|
1016
|
+
const collector = input.feeOutput?.feeCollectorPrivateAddress.trim() ?? "";
|
|
1017
|
+
if (requiredFee <= ZERO_STROOPS || !collector) {
|
|
1018
|
+
return { deposits: input.deposits };
|
|
1019
|
+
}
|
|
1020
|
+
const slot = await input.buildAlignedDepositSlot({
|
|
1021
|
+
privateAddressStpl1: collector,
|
|
1022
|
+
amountStroops: requiredFee,
|
|
1023
|
+
tokenAddress: input.tokenAddress
|
|
1024
|
+
});
|
|
1025
|
+
return {
|
|
1026
|
+
deposits: [...input.deposits, slot.deposit],
|
|
1027
|
+
feeCoin: feeCoinFromSlot(slot)
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
|
|
887
1031
|
// src/transact/proofs/withdraw/helpers.ts
|
|
888
1032
|
function destinationWithdrawFrAndScalar(parameters) {
|
|
889
1033
|
const pkHex = ed25519PublicKeyHexFromStellarAccount(
|
|
@@ -938,14 +1082,15 @@ async function resolveWithdrawChangeDeposits(parameters) {
|
|
|
938
1082
|
}
|
|
939
1083
|
};
|
|
940
1084
|
}
|
|
941
|
-
function validateDualWithdrawAmounts(withdrawAmountStroops, totalNotes, changePrivateAddressStpl1) {
|
|
1085
|
+
function validateDualWithdrawAmounts(withdrawAmountStroops, totalNotes, changePrivateAddressStpl1, requiredFee) {
|
|
942
1086
|
if (withdrawAmountStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
943
1087
|
throw new Error("Withdraw amount must be positive");
|
|
944
1088
|
}
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
1089
|
+
const changeStroops = remainingAfterRequiredFee({
|
|
1090
|
+
available: totalNotes,
|
|
1091
|
+
instructed: withdrawAmountStroops,
|
|
1092
|
+
requiredFee
|
|
1093
|
+
});
|
|
949
1094
|
requireChangeRecipientWhenPartial(changeStroops, changePrivateAddressStpl1);
|
|
950
1095
|
return changeStroops;
|
|
951
1096
|
}
|
|
@@ -958,11 +1103,31 @@ function buildDualWithdrawPublicInput(parameters) {
|
|
|
958
1103
|
publicWithdrawalAmount: parameters.publicWithdrawalAmount
|
|
959
1104
|
});
|
|
960
1105
|
}
|
|
1106
|
+
async function withdrawOutputsWithOptionalFee(parameters) {
|
|
1107
|
+
const { deposits: changeDeposits, changeCoin } = await resolveWithdrawChangeDeposits({
|
|
1108
|
+
changeStroops: parameters.changeStroops,
|
|
1109
|
+
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
1110
|
+
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
1111
|
+
tokenAddress: parameters.tokenAddress
|
|
1112
|
+
});
|
|
1113
|
+
const withFee = await appendFeeOutputSlot({
|
|
1114
|
+
deposits: changeDeposits,
|
|
1115
|
+
tokenAddress: parameters.tokenAddress,
|
|
1116
|
+
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
1117
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1118
|
+
});
|
|
1119
|
+
return {
|
|
1120
|
+
deposits: withFee.deposits,
|
|
1121
|
+
...changeCoin ? { changeCoin } : {},
|
|
1122
|
+
...withFee.feeCoin ? { feeCoin: withFee.feeCoin } : {}
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
961
1125
|
async function prepareDualWithdrawProofInputs(parameters) {
|
|
962
1126
|
const changeStroops = validateDualWithdrawAmounts(
|
|
963
1127
|
parameters.withdrawAmountStroops,
|
|
964
1128
|
BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value),
|
|
965
|
-
parameters.changePrivateAddressStpl1
|
|
1129
|
+
parameters.changePrivateAddressStpl1,
|
|
1130
|
+
parameters.feeOutput?.requiredFee ?? 0n
|
|
966
1131
|
);
|
|
967
1132
|
const { legA, legB } = dualWithdrawLegsWithSharedRoot({
|
|
968
1133
|
sdk: parameters.sdk,
|
|
@@ -977,11 +1142,12 @@ async function prepareDualWithdrawProofInputs(parameters) {
|
|
|
977
1142
|
),
|
|
978
1143
|
applicationId: parameters.applicationId
|
|
979
1144
|
});
|
|
980
|
-
const { deposits, changeCoin } = await
|
|
1145
|
+
const { deposits, changeCoin, feeCoin } = await withdrawOutputsWithOptionalFee({
|
|
981
1146
|
changeStroops,
|
|
982
1147
|
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
983
1148
|
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
984
|
-
tokenAddress: parameters.tokenAddress
|
|
1149
|
+
tokenAddress: parameters.tokenAddress,
|
|
1150
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
985
1151
|
});
|
|
986
1152
|
const publicInput = buildDualWithdrawPublicInput({
|
|
987
1153
|
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
@@ -1000,19 +1166,55 @@ async function prepareDualWithdrawProofInputs(parameters) {
|
|
|
1000
1166
|
audit,
|
|
1001
1167
|
deposits,
|
|
1002
1168
|
withdrawLegs: [legA.withdrawObject, legB.withdrawObject],
|
|
1003
|
-
...changeCoin ? { changeCoin } : {}
|
|
1169
|
+
...changeCoin ? { changeCoin } : {},
|
|
1170
|
+
...feeCoin ? { feeCoin } : {}
|
|
1004
1171
|
};
|
|
1005
1172
|
}
|
|
1006
1173
|
|
|
1174
|
+
// src/transact/proofs/withdraw/fee-deposits.ts
|
|
1175
|
+
async function withdrawDepositsWithFee(parameters) {
|
|
1176
|
+
const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
|
|
1177
|
+
changeStroops: parameters.changeStroops,
|
|
1178
|
+
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
1179
|
+
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
1180
|
+
tokenAddress: parameters.tokenAddress
|
|
1181
|
+
});
|
|
1182
|
+
const withFee = await appendFeeOutputSlot({
|
|
1183
|
+
deposits,
|
|
1184
|
+
tokenAddress: parameters.tokenAddress,
|
|
1185
|
+
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
1186
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1187
|
+
});
|
|
1188
|
+
return {
|
|
1189
|
+
deposits: withFee.deposits,
|
|
1190
|
+
...changeCoin ? { changeCoin } : {},
|
|
1191
|
+
...withFee.feeCoin ? { feeCoin: withFee.feeCoin } : {}
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
function withdrawOutputApplicationIds(input) {
|
|
1195
|
+
const outputIds = [];
|
|
1196
|
+
if (input.hasChange) {
|
|
1197
|
+
outputIds.push(input.applicationId);
|
|
1198
|
+
}
|
|
1199
|
+
if (input.hasFeeOutput) {
|
|
1200
|
+
outputIds.push(input.applicationId);
|
|
1201
|
+
}
|
|
1202
|
+
if (outputIds.length === 0) {
|
|
1203
|
+
outputIds.push("0");
|
|
1204
|
+
}
|
|
1205
|
+
return outputIds;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1007
1208
|
// src/transact/proofs/withdraw/transact-proof.ts
|
|
1008
|
-
function validateSingleWithdrawAmounts(withdrawAmountStroops, noteStroops) {
|
|
1209
|
+
function validateSingleWithdrawAmounts(withdrawAmountStroops, noteStroops, requiredFee) {
|
|
1009
1210
|
if (withdrawAmountStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
1010
1211
|
throw new Error("Withdraw amount must be positive");
|
|
1011
1212
|
}
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1213
|
+
return remainingAfterRequiredFee({
|
|
1214
|
+
available: noteStroops,
|
|
1215
|
+
instructed: withdrawAmountStroops,
|
|
1216
|
+
requiredFee
|
|
1217
|
+
});
|
|
1016
1218
|
}
|
|
1017
1219
|
async function proveSingleWithdrawTransaction(parameters) {
|
|
1018
1220
|
return parameters.sdk.proveTransaction(
|
|
@@ -1051,7 +1253,8 @@ function buildPrimaryWithdrawForCoin(parameters) {
|
|
|
1051
1253
|
async function prepareSingleWithdrawProofInputs(parameters) {
|
|
1052
1254
|
const changeStroops = validateSingleWithdrawAmounts(
|
|
1053
1255
|
parameters.withdrawAmountStroops,
|
|
1054
|
-
BigInt(parameters.coin.value)
|
|
1256
|
+
BigInt(parameters.coin.value),
|
|
1257
|
+
parameters.feeOutput?.requiredFee ?? 0n
|
|
1055
1258
|
);
|
|
1056
1259
|
const { witness, primaryWithdraw } = buildPrimaryWithdrawForCoin({
|
|
1057
1260
|
sdk: parameters.sdk,
|
|
@@ -1060,11 +1263,12 @@ async function prepareSingleWithdrawProofInputs(parameters) {
|
|
|
1060
1263
|
state: parameters.state,
|
|
1061
1264
|
privKeyScalarHex: parameters.privKeyScalarHex
|
|
1062
1265
|
});
|
|
1063
|
-
const { deposits, changeCoin } = await
|
|
1266
|
+
const { deposits, changeCoin, feeCoin } = await withdrawDepositsWithFee({
|
|
1064
1267
|
changeStroops,
|
|
1065
1268
|
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
1066
1269
|
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
1067
|
-
tokenAddress: parameters.tokenAddress
|
|
1270
|
+
tokenAddress: parameters.tokenAddress,
|
|
1271
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1068
1272
|
});
|
|
1069
1273
|
const publicInput = buildWithdrawPublicInput({
|
|
1070
1274
|
stateRoot: witness.stateRoot,
|
|
@@ -1077,6 +1281,7 @@ async function prepareSingleWithdrawProofInputs(parameters) {
|
|
|
1077
1281
|
primaryWithdraw,
|
|
1078
1282
|
deposits,
|
|
1079
1283
|
changeCoin,
|
|
1284
|
+
feeCoin,
|
|
1080
1285
|
publicInput,
|
|
1081
1286
|
audit: buildPoolTransactionAuditParameters({
|
|
1082
1287
|
applicationId: parameters.applicationId,
|
|
@@ -1086,7 +1291,7 @@ async function prepareSingleWithdrawProofInputs(parameters) {
|
|
|
1086
1291
|
};
|
|
1087
1292
|
}
|
|
1088
1293
|
async function proveWithdrawTransact(parameters) {
|
|
1089
|
-
const { primaryWithdraw, deposits, changeCoin, publicInput, audit } = await prepareSingleWithdrawProofInputs(parameters);
|
|
1294
|
+
const { primaryWithdraw, deposits, changeCoin, feeCoin, publicInput, audit } = await prepareSingleWithdrawProofInputs(parameters);
|
|
1090
1295
|
const proof = await proveSingleWithdrawTransaction({
|
|
1091
1296
|
sdk: parameters.sdk,
|
|
1092
1297
|
publicInput,
|
|
@@ -1101,13 +1306,17 @@ async function proveWithdrawTransact(parameters) {
|
|
|
1101
1306
|
applicationIdsPlaintext: buildApplicationIdHints({
|
|
1102
1307
|
sdk: parameters.sdk,
|
|
1103
1308
|
inputIds: [parameters.applicationId],
|
|
1104
|
-
outputIds:
|
|
1309
|
+
outputIds: withdrawOutputApplicationIds({
|
|
1310
|
+
applicationId: parameters.applicationId,
|
|
1311
|
+
hasChange: Boolean(changeCoin),
|
|
1312
|
+
hasFeeOutput: Boolean(feeCoin)
|
|
1313
|
+
})
|
|
1105
1314
|
}),
|
|
1106
1315
|
...changeCoin ? { changeCoin } : {}
|
|
1107
1316
|
};
|
|
1108
1317
|
}
|
|
1109
1318
|
async function proveWithdrawTransactDual(parameters) {
|
|
1110
|
-
const { publicInput, audit, withdrawLegs, deposits, changeCoin } = await prepareDualWithdrawProofInputs(parameters);
|
|
1319
|
+
const { publicInput, audit, withdrawLegs, deposits, changeCoin, feeCoin } = await prepareDualWithdrawProofInputs(parameters);
|
|
1111
1320
|
const proof = await parameters.sdk.proveTransaction(
|
|
1112
1321
|
publicInput,
|
|
1113
1322
|
padPublicLegsToLayout(
|
|
@@ -1126,7 +1335,11 @@ async function proveWithdrawTransactDual(parameters) {
|
|
|
1126
1335
|
applicationIdsPlaintext: buildApplicationIdHints({
|
|
1127
1336
|
sdk: parameters.sdk,
|
|
1128
1337
|
inputIds: [audit.applicationId, audit.applicationId],
|
|
1129
|
-
outputIds:
|
|
1338
|
+
outputIds: withdrawOutputApplicationIds({
|
|
1339
|
+
applicationId: audit.applicationId,
|
|
1340
|
+
hasChange: Boolean(changeCoin),
|
|
1341
|
+
hasFeeOutput: Boolean(feeCoin)
|
|
1342
|
+
})
|
|
1130
1343
|
}),
|
|
1131
1344
|
...changeCoin ? { changeCoin } : {}
|
|
1132
1345
|
};
|
|
@@ -1147,6 +1360,9 @@ var DEFAULT_ZK_CONFIG_NONCE = BINDING_ZK_NONCE;
|
|
|
1147
1360
|
function resolveZkConfigNonce(transactEnvironment) {
|
|
1148
1361
|
return transactEnvironment.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
|
|
1149
1362
|
}
|
|
1363
|
+
function transactNonceFromArtifacts(artifacts, transactEnvironment) {
|
|
1364
|
+
return artifacts?.zkConfigNonce ?? resolveZkConfigNonce(transactEnvironment);
|
|
1365
|
+
}
|
|
1150
1366
|
|
|
1151
1367
|
// src/transact/zk/browser-artifact-cache.ts
|
|
1152
1368
|
import { ZK_ARTIFACT_VERSION } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
@@ -1399,6 +1615,122 @@ async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
|
|
|
1399
1615
|
};
|
|
1400
1616
|
}
|
|
1401
1617
|
|
|
1618
|
+
// src/transact/pool/initialize-sdk.ts
|
|
1619
|
+
import { PrivacyPoolSDK as PrivacyPoolSDK2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
1620
|
+
async function initializePrivacyPoolSdk(input, nonce) {
|
|
1621
|
+
const zkConfigNonce = nonce ?? input.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
|
|
1622
|
+
const zkCircuits = await materializeSelectedZkCircuit(
|
|
1623
|
+
input.zkCircuits,
|
|
1624
|
+
zkConfigNonce,
|
|
1625
|
+
input.zkArtifactBaseUrl
|
|
1626
|
+
);
|
|
1627
|
+
return PrivacyPoolSDK2.init({
|
|
1628
|
+
wasmBinary: input.assets.sdkWasm,
|
|
1629
|
+
zkCircuits,
|
|
1630
|
+
zkConfigNonce,
|
|
1631
|
+
...optionalZkArtifactBaseUrl(input.zkArtifactBaseUrl)
|
|
1632
|
+
});
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
// src/transact/fees/zk-config-nonce-for-kind.ts
|
|
1636
|
+
function configuredNonceSpread(zkConfigNonce) {
|
|
1637
|
+
if (zkConfigNonce === void 0) {
|
|
1638
|
+
return {};
|
|
1639
|
+
}
|
|
1640
|
+
return { configuredNonce: zkConfigNonce };
|
|
1641
|
+
}
|
|
1642
|
+
function zkConfigNonceForFeeBearingKind(input) {
|
|
1643
|
+
if (input.configuredNonce === SIX_BY_SIX_BINDING_ZK_NONCE) {
|
|
1644
|
+
return SIX_BY_SIX_BINDING_ZK_NONCE;
|
|
1645
|
+
}
|
|
1646
|
+
if (input.kind === "transfer" && shouldAttachFeeOutput(input)) {
|
|
1647
|
+
return SIX_BY_SIX_BINDING_ZK_NONCE;
|
|
1648
|
+
}
|
|
1649
|
+
return input.configuredNonce ?? BINDING_ZK_NONCE;
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
// src/transact/pool/prepare-deposit-proof.ts
|
|
1653
|
+
import {
|
|
1654
|
+
randomFrDecimal253,
|
|
1655
|
+
scalarHexToFrDecimal as scalarHexToFrDecimal2
|
|
1656
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
1657
|
+
|
|
1658
|
+
// src/transact/merkle/field-decimal.ts
|
|
1659
|
+
import { Buffer as Buffer8 } from "buffer";
|
|
1660
|
+
var BN254 = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
1661
|
+
var MERKLE_ROOT_BYTE_LENGTH = 32;
|
|
1662
|
+
var DECIMAL_STRING_RADIX = 10;
|
|
1663
|
+
function merkleRootBufferToFrDecimal(root) {
|
|
1664
|
+
if (root.length !== MERKLE_ROOT_BYTE_LENGTH) {
|
|
1665
|
+
throw new Error(
|
|
1666
|
+
`expected ${MERKLE_ROOT_BYTE_LENGTH}-byte merkle root, got ${root.length}`
|
|
1667
|
+
);
|
|
1668
|
+
}
|
|
1669
|
+
const hex = Buffer8.from(root).toString("hex");
|
|
1670
|
+
return (BigInt(`0x${hex}`) % BN254).toString(DECIMAL_STRING_RADIX);
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
// src/transact/pool/prepare-deposit-proof.ts
|
|
1674
|
+
function userDepositSlot(input) {
|
|
1675
|
+
return {
|
|
1676
|
+
value: input.coin.value,
|
|
1677
|
+
nullifier: input.coin.nullifier,
|
|
1678
|
+
ephemeralKeyScalar: scalarHexToFrDecimal2(input.depositScalarHex),
|
|
1679
|
+
asset: [input.coin.asset_hi, input.coin.asset_lo],
|
|
1680
|
+
applicationId: input.applicationId,
|
|
1681
|
+
recipientPublicKeys: recipientPublicKeysDecimalFromPrivateAddress(
|
|
1682
|
+
input.privateAddressStpl1
|
|
1683
|
+
)
|
|
1684
|
+
};
|
|
1685
|
+
}
|
|
1686
|
+
function outputApplicationIds(input) {
|
|
1687
|
+
if (input.hasFeeOutput) {
|
|
1688
|
+
return [input.applicationId, input.applicationId];
|
|
1689
|
+
}
|
|
1690
|
+
return [input.applicationId];
|
|
1691
|
+
}
|
|
1692
|
+
async function proveDepositTransact(input) {
|
|
1693
|
+
const publicDeposit = (input.publicDepositStroops ?? BigInt(input.coin.value)).toString();
|
|
1694
|
+
const withFee = await appendFeeOutputSlot({
|
|
1695
|
+
deposits: [userDepositSlot(input)],
|
|
1696
|
+
tokenAddress: input.tokenAddress,
|
|
1697
|
+
buildAlignedDepositSlot: input.buildAlignedDepositSlot,
|
|
1698
|
+
...input.feeOutput ? { feeOutput: input.feeOutput } : {}
|
|
1699
|
+
});
|
|
1700
|
+
const audit = buildPoolTransactionAuditParameters({
|
|
1701
|
+
applicationId: input.applicationId,
|
|
1702
|
+
nAuditSlots: input.sdk.getLayout().nAuditSlots,
|
|
1703
|
+
...input.auditPublicKey ? { auditPublicKey: input.auditPublicKey } : {}
|
|
1704
|
+
});
|
|
1705
|
+
const proof = await input.sdk.proveTransaction(
|
|
1706
|
+
withTokenAddressPublicInputs(
|
|
1707
|
+
{
|
|
1708
|
+
stateRoot: merkleRootBufferToFrDecimal(input.merkleRootBytes),
|
|
1709
|
+
privKeyScalar: randomFrDecimal253()
|
|
1710
|
+
},
|
|
1711
|
+
input.tokenAddress
|
|
1712
|
+
),
|
|
1713
|
+
padPublicLegsToLayout(
|
|
1714
|
+
input.sdk,
|
|
1715
|
+
buildPublicDepositLegs(input.tokenAddress, publicDeposit)
|
|
1716
|
+
),
|
|
1717
|
+
padWithdrawSlotsToLayout(input.sdk, []),
|
|
1718
|
+
padDepositSlotsToLayout(input.sdk, withFee.deposits),
|
|
1719
|
+
audit
|
|
1720
|
+
);
|
|
1721
|
+
return {
|
|
1722
|
+
...proof,
|
|
1723
|
+
applicationIdsPlaintext: buildApplicationIdHints({
|
|
1724
|
+
sdk: input.sdk,
|
|
1725
|
+
inputIds: [],
|
|
1726
|
+
outputIds: outputApplicationIds({
|
|
1727
|
+
applicationId: input.applicationId,
|
|
1728
|
+
hasFeeOutput: Boolean(withFee.feeCoin)
|
|
1729
|
+
})
|
|
1730
|
+
})
|
|
1731
|
+
};
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1402
1734
|
// src/transact/pool/service.ts
|
|
1403
1735
|
var PrivacyPoolService = class {
|
|
1404
1736
|
constructor(assets, applicationId, auditPublicKey, zkCircuits, zkConfigNonce, zkArtifactBaseUrl) {
|
|
@@ -1415,42 +1747,50 @@ var PrivacyPoolService = class {
|
|
|
1415
1747
|
zkCircuits;
|
|
1416
1748
|
zkConfigNonce;
|
|
1417
1749
|
zkArtifactBaseUrl;
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
async
|
|
1421
|
-
|
|
1422
|
-
|
|
1750
|
+
sdks = /* @__PURE__ */ new Map();
|
|
1751
|
+
initPromises = /* @__PURE__ */ new Map();
|
|
1752
|
+
async getInitializedSdk(nonce) {
|
|
1753
|
+
const zkConfigNonce = nonce ?? this.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
|
|
1754
|
+
const key = zkConfigNonce.toString();
|
|
1755
|
+
const existing = this.sdks.get(key);
|
|
1756
|
+
if (existing) {
|
|
1757
|
+
return existing;
|
|
1423
1758
|
}
|
|
1424
|
-
|
|
1425
|
-
|
|
1759
|
+
const pending = this.initPromises.get(key);
|
|
1760
|
+
if (pending) {
|
|
1761
|
+
return pending;
|
|
1426
1762
|
}
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
zkConfigNonce,
|
|
1443
|
-
...optionalZkArtifactBaseUrl(this.zkArtifactBaseUrl)
|
|
1444
|
-
});
|
|
1445
|
-
})();
|
|
1446
|
-
return this.initPromise;
|
|
1763
|
+
const started = this.initializeSdk(zkConfigNonce);
|
|
1764
|
+
this.initPromises.set(key, started);
|
|
1765
|
+
try {
|
|
1766
|
+
const sdk = await started;
|
|
1767
|
+
this.sdks.set(key, sdk);
|
|
1768
|
+
return sdk;
|
|
1769
|
+
} finally {
|
|
1770
|
+
this.initPromises.delete(key);
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
feeBearingZkConfigNonce(input) {
|
|
1774
|
+
return zkConfigNonceForFeeBearingKind({
|
|
1775
|
+
...input,
|
|
1776
|
+
...configuredNonceSpread(this.zkConfigNonce)
|
|
1777
|
+
});
|
|
1447
1778
|
}
|
|
1448
|
-
async
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1779
|
+
async initializeSdk(nonce) {
|
|
1780
|
+
if (!this.assets) {
|
|
1781
|
+
throw new Error(
|
|
1782
|
+
"PrivacyPoolService requires browser ZK assets before initialization."
|
|
1783
|
+
);
|
|
1452
1784
|
}
|
|
1453
|
-
return
|
|
1785
|
+
return initializePrivacyPoolSdk(
|
|
1786
|
+
{
|
|
1787
|
+
assets: this.assets,
|
|
1788
|
+
...this.zkCircuits ? { zkCircuits: this.zkCircuits } : {},
|
|
1789
|
+
...this.zkConfigNonce === void 0 ? {} : { zkConfigNonce: this.zkConfigNonce },
|
|
1790
|
+
...optionalZkArtifactBaseUrl(this.zkArtifactBaseUrl)
|
|
1791
|
+
},
|
|
1792
|
+
nonce
|
|
1793
|
+
);
|
|
1454
1794
|
}
|
|
1455
1795
|
getAuditPublicKey() {
|
|
1456
1796
|
return this.auditPublicKey;
|
|
@@ -1483,65 +1823,51 @@ var PrivacyPoolService = class {
|
|
|
1483
1823
|
return { commitment_hex, coin, depositScalarHex, precommitementHex };
|
|
1484
1824
|
}
|
|
1485
1825
|
async prepareDepositTransactProof(parameters) {
|
|
1486
|
-
const sdk = await this.getInitializedSdk(
|
|
1487
|
-
|
|
1488
|
-
const recipientPublicKeys = recipientPublicKeysDecimalFromPrivateAddress(
|
|
1489
|
-
parameters.privateAddressStpl1
|
|
1490
|
-
);
|
|
1491
|
-
const applicationId = this.getApplicationId();
|
|
1492
|
-
const audit = buildPoolTransactionAuditParameters({
|
|
1493
|
-
applicationId,
|
|
1494
|
-
nAuditSlots: sdk.getLayout().nAuditSlots,
|
|
1495
|
-
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {}
|
|
1496
|
-
});
|
|
1497
|
-
const deposit = {
|
|
1498
|
-
value: parameters.coin.value,
|
|
1499
|
-
nullifier: parameters.coin.nullifier,
|
|
1500
|
-
ephemeralKeyScalar: scalarHexToFrDecimal2(parameters.depositScalarHex),
|
|
1501
|
-
asset: [parameters.coin.asset_hi, parameters.coin.asset_lo],
|
|
1502
|
-
applicationId,
|
|
1503
|
-
recipientPublicKeys
|
|
1504
|
-
};
|
|
1505
|
-
const publicInput = withTokenAddressPublicInputs(
|
|
1506
|
-
{
|
|
1507
|
-
stateRoot,
|
|
1508
|
-
privKeyScalar: randomFrDecimal253()
|
|
1509
|
-
},
|
|
1510
|
-
parameters.tokenAddress
|
|
1826
|
+
const sdk = await this.getInitializedSdk(
|
|
1827
|
+
this.feeBearingZkConfigNonce({ kind: "deposit" })
|
|
1511
1828
|
);
|
|
1512
|
-
|
|
1513
|
-
publicInput,
|
|
1514
|
-
padPublicLegsToLayout(
|
|
1515
|
-
sdk,
|
|
1516
|
-
buildPublicDepositLegs(parameters.tokenAddress, parameters.coin.value)
|
|
1517
|
-
),
|
|
1518
|
-
padWithdrawSlotsToLayout(sdk, []),
|
|
1519
|
-
padDepositSlotsToLayout(sdk, [deposit]),
|
|
1520
|
-
audit
|
|
1521
|
-
);
|
|
1522
|
-
const applicationIdsPlaintext = buildApplicationIdHints({
|
|
1829
|
+
return proveDepositTransact({
|
|
1523
1830
|
sdk,
|
|
1524
|
-
|
|
1525
|
-
|
|
1831
|
+
applicationId: this.getApplicationId(),
|
|
1832
|
+
privateAddressStpl1: parameters.privateAddressStpl1,
|
|
1833
|
+
coin: parameters.coin,
|
|
1834
|
+
depositScalarHex: parameters.depositScalarHex,
|
|
1835
|
+
merkleRootBytes: parameters.merkleRootBytes,
|
|
1836
|
+
tokenAddress: parameters.tokenAddress,
|
|
1837
|
+
buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
|
|
1838
|
+
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
|
|
1839
|
+
...parameters.publicDepositStroops === void 0 ? {} : { publicDepositStroops: parameters.publicDepositStroops },
|
|
1840
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1526
1841
|
});
|
|
1527
|
-
return { ...proof, applicationIdsPlaintext };
|
|
1528
1842
|
}
|
|
1529
1843
|
async calculateNullifierHash(nullifier, privKeyScalar) {
|
|
1530
1844
|
const sdk = await this.getInitializedSdk();
|
|
1531
1845
|
return sdk.calculateNullifierHash(nullifier, privKeyScalar);
|
|
1532
1846
|
}
|
|
1533
1847
|
async prepareWithdrawTransactProof(parameters) {
|
|
1534
|
-
const sdk = await this.getInitializedSdk(
|
|
1848
|
+
const sdk = await this.getInitializedSdk(
|
|
1849
|
+
this.feeBearingZkConfigNonce({ kind: "withdraw" })
|
|
1850
|
+
);
|
|
1535
1851
|
return proveWithdrawTransact({
|
|
1536
1852
|
sdk,
|
|
1537
1853
|
applicationId: this.getApplicationId(),
|
|
1538
1854
|
buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
|
|
1539
1855
|
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
|
|
1540
|
-
|
|
1856
|
+
coin: parameters.coin,
|
|
1857
|
+
state: parameters.state,
|
|
1858
|
+
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
1859
|
+
privKeyScalarHex: parameters.privKeyScalarHex,
|
|
1860
|
+
depositorEphemeralKey: parameters.depositorEphemeralKey,
|
|
1861
|
+
withdrawAmountStroops: parameters.withdrawAmountStroops,
|
|
1862
|
+
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
1863
|
+
tokenAddress: parameters.tokenAddress,
|
|
1864
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1541
1865
|
});
|
|
1542
1866
|
}
|
|
1543
1867
|
async prepareWithdrawTransactProofDual(parameters) {
|
|
1544
|
-
const sdk = await this.getInitializedSdk(
|
|
1868
|
+
const sdk = await this.getInitializedSdk(
|
|
1869
|
+
this.feeBearingZkConfigNonce({ kind: "withdraw" })
|
|
1870
|
+
);
|
|
1545
1871
|
return proveWithdrawTransactDual({
|
|
1546
1872
|
sdk,
|
|
1547
1873
|
applicationId: this.getApplicationId(),
|
|
@@ -1556,7 +1882,8 @@ var PrivacyPoolService = class {
|
|
|
1556
1882
|
ephemeralBKey: parameters.depositorEphemeralBKey,
|
|
1557
1883
|
withdrawAmountStroops: parameters.withdrawAmountStroops,
|
|
1558
1884
|
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
1559
|
-
tokenAddress: parameters.tokenAddress
|
|
1885
|
+
tokenAddress: parameters.tokenAddress,
|
|
1886
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
1560
1887
|
});
|
|
1561
1888
|
}
|
|
1562
1889
|
};
|
|
@@ -1586,92 +1913,167 @@ function getPrivacyPoolService() {
|
|
|
1586
1913
|
}
|
|
1587
1914
|
|
|
1588
1915
|
// src/transact/merkle/fetch-contract.ts
|
|
1916
|
+
import { Buffer as Buffer12 } from "buffer";
|
|
1917
|
+
|
|
1918
|
+
// src/transact/merkle/state-port.ts
|
|
1919
|
+
function poolMerkleStateToCachedView(state) {
|
|
1920
|
+
return {
|
|
1921
|
+
commitments: state.commitments,
|
|
1922
|
+
updatedAt: state.updatedAt,
|
|
1923
|
+
merkleRootHex: state.merkleRootHex
|
|
1924
|
+
};
|
|
1925
|
+
}
|
|
1926
|
+
|
|
1927
|
+
// src/transact/merkle/read-tree-leaves.ts
|
|
1928
|
+
import { Address, xdr } from "@stellar/stellar-sdk";
|
|
1589
1929
|
import { Buffer as Buffer11 } from "buffer";
|
|
1590
1930
|
|
|
1591
1931
|
// src/transact/merkle/encoding.ts
|
|
1592
1932
|
import "buffer";
|
|
1593
1933
|
var FR_ORDER = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n;
|
|
1594
|
-
function
|
|
1934
|
+
function commitmentBufferToDecimal(buf) {
|
|
1595
1935
|
const hex = buf.toString("hex");
|
|
1596
1936
|
const bigintFromHex = BigInt(`0x${hex}`);
|
|
1597
1937
|
const reduced = bigintFromHex % FR_ORDER;
|
|
1598
1938
|
return reduced.toString();
|
|
1599
1939
|
}
|
|
1600
|
-
function commitmentsBuffersToDecimal(buffers) {
|
|
1601
|
-
return buffers.map((bufferRow) => bufferToDecimal(bufferRow));
|
|
1602
|
-
}
|
|
1603
1940
|
|
|
1604
|
-
// src/transact/merkle/
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
// src/transact/merkle/fetch-contract.ts
|
|
1614
|
-
function normalizeCommitmentBuffers(rawBuffers) {
|
|
1615
|
-
return rawBuffers.map(
|
|
1616
|
-
(bufferRow) => Buffer11.isBuffer(bufferRow) ? bufferRow : Buffer11.from(bufferRow)
|
|
1941
|
+
// src/transact/merkle/read-tree-leaves.ts
|
|
1942
|
+
var TREE_LEAF_LEDGER_BATCH_SIZE = 100;
|
|
1943
|
+
function treeLeafLedgerKey(contractId, leafIndex) {
|
|
1944
|
+
return xdr.LedgerKey.contractData(
|
|
1945
|
+
new xdr.LedgerKeyContractData({
|
|
1946
|
+
contract: new Address(contractId).toScAddress(),
|
|
1947
|
+
key: treeLeafKeyScValue(leafIndex),
|
|
1948
|
+
durability: xdr.ContractDataDurability.persistent()
|
|
1949
|
+
})
|
|
1617
1950
|
);
|
|
1618
1951
|
}
|
|
1619
|
-
function
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
void
|
|
1625
|
-
poolContract: parameters.poolContractId,
|
|
1626
|
-
commitments: parameters.contractCommitments,
|
|
1627
|
-
commitmentCount: parameters.contractCount,
|
|
1628
|
-
merkleRootHex: parameters.merkleRootHex,
|
|
1629
|
-
updatedAt
|
|
1630
|
-
});
|
|
1631
|
-
return {
|
|
1632
|
-
commitments: parameters.contractCommitments,
|
|
1633
|
-
updatedAt,
|
|
1634
|
-
merkleRootHex: parameters.merkleRootHex,
|
|
1635
|
-
commitmentCount: parameters.contractCount
|
|
1636
|
-
};
|
|
1952
|
+
function treeLeafKeyScValue(leafIndex) {
|
|
1953
|
+
return xdr.ScVal.scvVec([xdr.ScVal.scvSymbol("Leaf"), xdr.ScVal.scvU32(leafIndex)]);
|
|
1954
|
+
}
|
|
1955
|
+
function leafIndexFromContractDataKey(key) {
|
|
1956
|
+
if (key.switch() !== xdr.ScValType.scvVec()) {
|
|
1957
|
+
return void 0;
|
|
1637
1958
|
}
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1959
|
+
const fields = key.vec();
|
|
1960
|
+
if (!fields || fields.length !== 2) {
|
|
1961
|
+
return void 0;
|
|
1962
|
+
}
|
|
1963
|
+
const [tag, indexValue] = fields;
|
|
1964
|
+
if (!tag || tag.switch() !== xdr.ScValType.scvSymbol()) {
|
|
1965
|
+
return void 0;
|
|
1966
|
+
}
|
|
1967
|
+
if (tag.sym().toString() !== "Leaf") {
|
|
1968
|
+
return void 0;
|
|
1969
|
+
}
|
|
1970
|
+
if (!indexValue || indexValue.switch() !== xdr.ScValType.scvU32()) {
|
|
1971
|
+
return void 0;
|
|
1972
|
+
}
|
|
1973
|
+
return indexValue.u32();
|
|
1644
1974
|
}
|
|
1645
|
-
|
|
1646
|
-
if (
|
|
1975
|
+
function commitmentBytesFromContractDataValue(value) {
|
|
1976
|
+
if (value.switch() !== xdr.ScValType.scvBytes()) {
|
|
1647
1977
|
return void 0;
|
|
1648
1978
|
}
|
|
1649
|
-
|
|
1650
|
-
|
|
1979
|
+
return Buffer11.from(value.bytes());
|
|
1980
|
+
}
|
|
1981
|
+
async function readTreeLeafCommitments(input) {
|
|
1982
|
+
if (input.startIndex >= input.endIndex) {
|
|
1983
|
+
return [];
|
|
1984
|
+
}
|
|
1985
|
+
const byIndex = await readLeafBuffersByIndex(input);
|
|
1986
|
+
return decimalCommitmentsInRange(byIndex, input.startIndex, input.endIndex);
|
|
1987
|
+
}
|
|
1988
|
+
async function readLeafBuffersByIndex(input) {
|
|
1989
|
+
const keys = ledgerKeysForRange(input.contractId, input.startIndex, input.endIndex);
|
|
1990
|
+
const byIndex = /* @__PURE__ */ new Map();
|
|
1991
|
+
for (const batch of chunkLedgerKeys(keys, TREE_LEAF_LEDGER_BATCH_SIZE)) {
|
|
1992
|
+
const response = await input.reader.getLedgerEntries(...batch);
|
|
1993
|
+
collectLeafBuffers(response.entries, byIndex);
|
|
1994
|
+
}
|
|
1995
|
+
return byIndex;
|
|
1996
|
+
}
|
|
1997
|
+
function ledgerKeysForRange(contractId, startIndex, endIndex) {
|
|
1998
|
+
const keys = [];
|
|
1999
|
+
for (let leafIndex = startIndex; leafIndex < endIndex; leafIndex += 1) {
|
|
2000
|
+
keys.push(treeLeafLedgerKey(contractId, leafIndex));
|
|
2001
|
+
}
|
|
2002
|
+
return keys;
|
|
2003
|
+
}
|
|
2004
|
+
function chunkLedgerKeys(keys, batchSize) {
|
|
2005
|
+
const batches = [];
|
|
2006
|
+
for (let offset = 0; offset < keys.length; offset += batchSize) {
|
|
2007
|
+
batches.push(keys.slice(offset, offset + batchSize));
|
|
2008
|
+
}
|
|
2009
|
+
return batches;
|
|
2010
|
+
}
|
|
2011
|
+
function collectLeafBuffers(entries, byIndex) {
|
|
2012
|
+
for (const entry of entries) {
|
|
2013
|
+
const contractData = entry.val.contractData();
|
|
2014
|
+
const leafIndex = leafIndexFromContractDataKey(contractData.key());
|
|
2015
|
+
const bytes = commitmentBytesFromContractDataValue(contractData.val());
|
|
2016
|
+
if (leafIndex === void 0 || !bytes) {
|
|
2017
|
+
continue;
|
|
2018
|
+
}
|
|
2019
|
+
byIndex.set(leafIndex, bytes);
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
function decimalCommitmentsInRange(byIndex, startIndex, endIndex) {
|
|
2023
|
+
const commitments = [];
|
|
2024
|
+
for (let leafIndex = startIndex; leafIndex < endIndex; leafIndex += 1) {
|
|
2025
|
+
const bytes = byIndex.get(leafIndex);
|
|
2026
|
+
if (!bytes) {
|
|
2027
|
+
throw new Error(`Missing Merkle leaf ${String(leafIndex)} in pool storage.`);
|
|
2028
|
+
}
|
|
2029
|
+
commitments.push(commitmentBufferToDecimal(bytes));
|
|
2030
|
+
}
|
|
2031
|
+
return commitments;
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
// src/transact/merkle/reuse-cached-commitments.ts
|
|
2035
|
+
function completeCacheRootMatches(cachedState, merkleRootHex) {
|
|
2036
|
+
const cachedRoot = cachedState?.merkleRootHex;
|
|
2037
|
+
if (cachedRoot === void 0 || cachedRoot === "") {
|
|
2038
|
+
return true;
|
|
2039
|
+
}
|
|
2040
|
+
return cachedRoot === merkleRootHex;
|
|
2041
|
+
}
|
|
2042
|
+
function reuseCachedCommitments(input) {
|
|
2043
|
+
const cachedCommitments = input.cachedState?.commitments ?? [];
|
|
2044
|
+
if (cachedCommitments.length === 0) {
|
|
2045
|
+
return [];
|
|
2046
|
+
}
|
|
2047
|
+
if (cachedCommitments.length > input.onChainCount) {
|
|
2048
|
+
return [];
|
|
2049
|
+
}
|
|
2050
|
+
if (cachedCommitments.length === input.onChainCount) {
|
|
2051
|
+
return completeCacheRootMatches(input.cachedState, input.merkleRootHex) ? cachedCommitments : [];
|
|
2052
|
+
}
|
|
2053
|
+
return cachedCommitments;
|
|
1651
2054
|
}
|
|
2055
|
+
|
|
2056
|
+
// src/transact/merkle/fetch-contract.ts
|
|
1652
2057
|
async function fetchAndMergeMerkleState(parameters) {
|
|
1653
|
-
const client =
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
|
|
1657
|
-
sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
|
|
1658
|
-
});
|
|
1659
|
-
const commitmentsRead = await client.get_commitments();
|
|
1660
|
-
const rawBuffers = commitmentsRead.result;
|
|
1661
|
-
const buffers = normalizeCommitmentBuffers(rawBuffers);
|
|
1662
|
-
const contractCommitments = commitmentsBuffersToDecimal(buffers);
|
|
1663
|
-
const contractCount = contractCommitments.length;
|
|
2058
|
+
const client = createPoolClient(parameters);
|
|
2059
|
+
const countRead = await client.get_commitment_count();
|
|
2060
|
+
const onChainCount = requireCommitmentCount(countRead.result);
|
|
1664
2061
|
const rootRead = await client.get_merkle_root();
|
|
1665
|
-
const
|
|
1666
|
-
const merkleRootHex = Buffer11.from(merkleRootBuffer).toString("hex");
|
|
2062
|
+
const merkleRootHex = merkleRootToHex(rootRead.result);
|
|
1667
2063
|
const cachedState = await readCachedPoolMerkleView(
|
|
1668
2064
|
parameters.poolMerkleState,
|
|
1669
2065
|
parameters.poolContractId
|
|
1670
2066
|
);
|
|
1671
|
-
|
|
2067
|
+
const commitments = await loadCommitments({
|
|
2068
|
+
cachedState,
|
|
2069
|
+
onChainCount,
|
|
2070
|
+
merkleRootHex,
|
|
2071
|
+
rpcUrl: parameters.transactEnvironment.network.rpcUrl,
|
|
2072
|
+
contractId: parameters.poolContractId
|
|
2073
|
+
});
|
|
2074
|
+
return persistFetchedMerkleState({
|
|
1672
2075
|
poolContractId: parameters.poolContractId,
|
|
1673
|
-
|
|
1674
|
-
contractCount,
|
|
2076
|
+
commitments,
|
|
1675
2077
|
merkleRootHex,
|
|
1676
2078
|
cachedState,
|
|
1677
2079
|
...parameters.poolMerkleState ? { poolMerkleState: parameters.poolMerkleState } : {}
|
|
@@ -1685,19 +2087,14 @@ async function readLeafEphemeralHex(parameters) {
|
|
|
1685
2087
|
if (cached?.xHex && cached.yHex) {
|
|
1686
2088
|
return { xHex: cached.xHex, yHex: cached.yHex };
|
|
1687
2089
|
}
|
|
1688
|
-
const client =
|
|
1689
|
-
contractId: parameters.poolContractId,
|
|
1690
|
-
walletPublicKey: parameters.walletPublicKey,
|
|
1691
|
-
networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
|
|
1692
|
-
sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
|
|
1693
|
-
});
|
|
2090
|
+
const client = createPoolClient(parameters);
|
|
1694
2091
|
const read = await client.get_leaf_ephemeral({ leaf_index: parameters.leafIndex });
|
|
1695
2092
|
const coords = read.result;
|
|
1696
2093
|
if (!coords?.x || !coords?.y) {
|
|
1697
2094
|
throw new Error("Missing leaf ephemeral key on contract");
|
|
1698
2095
|
}
|
|
1699
|
-
const xHex =
|
|
1700
|
-
const yHex =
|
|
2096
|
+
const xHex = Buffer12.from(coords.x).toString("hex");
|
|
2097
|
+
const yHex = Buffer12.from(coords.y).toString("hex");
|
|
1701
2098
|
await parameters.leafEphemeral?.set({
|
|
1702
2099
|
poolContract: parameters.poolContractId,
|
|
1703
2100
|
leafIndex: parameters.leafIndex,
|
|
@@ -1707,6 +2104,84 @@ async function readLeafEphemeralHex(parameters) {
|
|
|
1707
2104
|
});
|
|
1708
2105
|
return { xHex, yHex };
|
|
1709
2106
|
}
|
|
2107
|
+
function createPoolClient(parameters) {
|
|
2108
|
+
return readPoolClientFactory(parameters.transactEnvironment)({
|
|
2109
|
+
contractId: parameters.poolContractId,
|
|
2110
|
+
walletPublicKey: parameters.walletPublicKey,
|
|
2111
|
+
networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
|
|
2112
|
+
sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
|
|
2113
|
+
});
|
|
2114
|
+
}
|
|
2115
|
+
function requireCommitmentCount(result) {
|
|
2116
|
+
if (typeof result === "number" && Number.isInteger(result) && result >= 0) {
|
|
2117
|
+
return result;
|
|
2118
|
+
}
|
|
2119
|
+
throw new Error("Pool commitment count is not a non-negative integer.");
|
|
2120
|
+
}
|
|
2121
|
+
function merkleRootToHex(root) {
|
|
2122
|
+
return Buffer12.from(root).toString("hex");
|
|
2123
|
+
}
|
|
2124
|
+
async function readCachedPoolMerkleView(poolMerkleState, poolContractId) {
|
|
2125
|
+
if (!poolMerkleState) {
|
|
2126
|
+
return void 0;
|
|
2127
|
+
}
|
|
2128
|
+
const cached = await poolMerkleState.get(poolContractId);
|
|
2129
|
+
return cached ? poolMerkleStateToCachedView(cached) : void 0;
|
|
2130
|
+
}
|
|
2131
|
+
async function loadCommitments(input) {
|
|
2132
|
+
const reused = reuseCachedCommitments({
|
|
2133
|
+
cachedState: input.cachedState,
|
|
2134
|
+
onChainCount: input.onChainCount,
|
|
2135
|
+
merkleRootHex: input.merkleRootHex
|
|
2136
|
+
});
|
|
2137
|
+
if (reused.length === input.onChainCount) {
|
|
2138
|
+
return reused;
|
|
2139
|
+
}
|
|
2140
|
+
const fetched = await readTreeLeafCommitments({
|
|
2141
|
+
reader: createStellarRpcServer(input.rpcUrl),
|
|
2142
|
+
contractId: input.contractId,
|
|
2143
|
+
startIndex: reused.length,
|
|
2144
|
+
endIndex: input.onChainCount
|
|
2145
|
+
});
|
|
2146
|
+
return [...reused, ...fetched];
|
|
2147
|
+
}
|
|
2148
|
+
async function persistFetchedMerkleState(input) {
|
|
2149
|
+
const cachedState = input.cachedState;
|
|
2150
|
+
if (cachedState && cachedMerkleUnchanged(cachedState, input.commitments, input.merkleRootHex)) {
|
|
2151
|
+
return viewFromCachedMerkle(cachedState, input.merkleRootHex);
|
|
2152
|
+
}
|
|
2153
|
+
const updatedAt = Date.now();
|
|
2154
|
+
await input.poolMerkleState?.set({
|
|
2155
|
+
poolContract: input.poolContractId,
|
|
2156
|
+
commitments: input.commitments,
|
|
2157
|
+
commitmentCount: input.commitments.length,
|
|
2158
|
+
merkleRootHex: input.merkleRootHex,
|
|
2159
|
+
updatedAt
|
|
2160
|
+
});
|
|
2161
|
+
return {
|
|
2162
|
+
commitments: input.commitments,
|
|
2163
|
+
updatedAt,
|
|
2164
|
+
merkleRootHex: input.merkleRootHex,
|
|
2165
|
+
commitmentCount: input.commitments.length
|
|
2166
|
+
};
|
|
2167
|
+
}
|
|
2168
|
+
function viewFromCachedMerkle(cachedState, merkleRootHex) {
|
|
2169
|
+
return {
|
|
2170
|
+
commitments: cachedState.commitments,
|
|
2171
|
+
updatedAt: cachedState.updatedAt,
|
|
2172
|
+
merkleRootHex: cachedState.merkleRootHex ?? merkleRootHex,
|
|
2173
|
+
commitmentCount: cachedState.commitments.length
|
|
2174
|
+
};
|
|
2175
|
+
}
|
|
2176
|
+
function cachedMerkleUnchanged(cachedState, commitments, merkleRootHex) {
|
|
2177
|
+
if (!cachedState) {
|
|
2178
|
+
return false;
|
|
2179
|
+
}
|
|
2180
|
+
if ((cachedState.merkleRootHex ?? merkleRootHex) !== merkleRootHex) {
|
|
2181
|
+
return false;
|
|
2182
|
+
}
|
|
2183
|
+
return cachedState.commitments.join(",") === commitments.join(",");
|
|
2184
|
+
}
|
|
1710
2185
|
|
|
1711
2186
|
// src/transact/engine/prepare/shared.ts
|
|
1712
2187
|
async function resolveTokenContractId2(environment, assetId) {
|
|
@@ -1996,6 +2471,13 @@ async function filterUnspentPrivateRecords(input) {
|
|
|
1996
2471
|
}
|
|
1997
2472
|
return unspent;
|
|
1998
2473
|
}
|
|
2474
|
+
function spendAmountCoveringProtocolFee(amount) {
|
|
2475
|
+
if (amount <= 0n) {
|
|
2476
|
+
return amount;
|
|
2477
|
+
}
|
|
2478
|
+
const hundredths = (amount + 99n) / 100n;
|
|
2479
|
+
return amount + (hundredths === 0n ? 1n : hundredths);
|
|
2480
|
+
}
|
|
1999
2481
|
function pickRecordsForSpendAmount(input) {
|
|
2000
2482
|
let selectedTotal = 0n;
|
|
2001
2483
|
const selected = [];
|
|
@@ -2049,7 +2531,7 @@ async function selectPrivateRecords(input) {
|
|
|
2049
2531
|
return pickRecordsForSpendAmount({
|
|
2050
2532
|
available,
|
|
2051
2533
|
kind: input.kind,
|
|
2052
|
-
amount: input.intent.amount
|
|
2534
|
+
amount: spendAmountCoveringProtocolFee(input.intent.amount)
|
|
2053
2535
|
});
|
|
2054
2536
|
}
|
|
2055
2537
|
function sumRecordAmounts(records) {
|
|
@@ -4104,7 +4586,7 @@ function createStellarStorageAdapterFromState(state) {
|
|
|
4104
4586
|
}
|
|
4105
4587
|
|
|
4106
4588
|
// src/contracts/registry/registry-domain-service.ts
|
|
4107
|
-
import { Buffer as
|
|
4589
|
+
import { Buffer as Buffer13 } from "buffer";
|
|
4108
4590
|
|
|
4109
4591
|
// src/transact/submit/ttl-preflight.ts
|
|
4110
4592
|
function getNested(source, path) {
|
|
@@ -4153,11 +4635,11 @@ async function runTtlPreflight(assembledTransaction) {
|
|
|
4153
4635
|
// src/contracts/registry/registry-domain-service.ts
|
|
4154
4636
|
var COORDINATE_HEX_LENGTH = 64;
|
|
4155
4637
|
function readCoordinateBytes(value) {
|
|
4156
|
-
if (value instanceof
|
|
4638
|
+
if (value instanceof Buffer13) {
|
|
4157
4639
|
return value;
|
|
4158
4640
|
}
|
|
4159
4641
|
if (value instanceof Uint8Array) {
|
|
4160
|
-
return
|
|
4642
|
+
return Buffer13.from(value);
|
|
4161
4643
|
}
|
|
4162
4644
|
return void 0;
|
|
4163
4645
|
}
|
|
@@ -4196,8 +4678,8 @@ function parseRegistryLookupRecord(result) {
|
|
|
4196
4678
|
return parseOptionSomeRecord(result);
|
|
4197
4679
|
}
|
|
4198
4680
|
function recordToLookupResult(record) {
|
|
4199
|
-
const publicKeyXHex =
|
|
4200
|
-
const publicKeyYHex =
|
|
4681
|
+
const publicKeyXHex = Buffer13.from(record.public_key_x).toString("hex");
|
|
4682
|
+
const publicKeyYHex = Buffer13.from(record.public_key_y).toString("hex");
|
|
4201
4683
|
return {
|
|
4202
4684
|
owner: record.owner,
|
|
4203
4685
|
status: "registered",
|
|
@@ -4240,8 +4722,8 @@ async function registerPrivateAddressOnChain(input) {
|
|
|
4240
4722
|
});
|
|
4241
4723
|
const assembled = await client.register_private_address({
|
|
4242
4724
|
owner: input.owner.trim(),
|
|
4243
|
-
public_key_x:
|
|
4244
|
-
public_key_y:
|
|
4725
|
+
public_key_x: Buffer13.from(decoded.x.padStart(COORDINATE_HEX_LENGTH, "0"), "hex"),
|
|
4726
|
+
public_key_y: Buffer13.from(decoded.y.padStart(COORDINATE_HEX_LENGTH, "0"), "hex")
|
|
4245
4727
|
});
|
|
4246
4728
|
await runTtlPreflight(assembled);
|
|
4247
4729
|
const sent = await assembled.signAndSend();
|
|
@@ -4256,7 +4738,7 @@ async function registerPrivateAddressOnChain(input) {
|
|
|
4256
4738
|
import { StrKey as StrKey5 } from "@stellar/stellar-sdk";
|
|
4257
4739
|
|
|
4258
4740
|
// src/transact/escrow/derived-escrow-recipient.ts
|
|
4259
|
-
import { Buffer as
|
|
4741
|
+
import { Buffer as Buffer14 } from "buffer";
|
|
4260
4742
|
import { StrKey as StrKey4 } from "@stellar/stellar-sdk";
|
|
4261
4743
|
import {
|
|
4262
4744
|
derivedEscrowKey,
|
|
@@ -4266,7 +4748,7 @@ import {
|
|
|
4266
4748
|
var COORDINATE_HEX_LENGTH2 = 64;
|
|
4267
4749
|
function stellarAccountToFieldLimbs(stellarAddress) {
|
|
4268
4750
|
const pkRaw = StrKey4.decodeEd25519PublicKey(stellarAddress.trim());
|
|
4269
|
-
const pkHex =
|
|
4751
|
+
const pkHex = Buffer14.from(pkRaw).toString("hex");
|
|
4270
4752
|
const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals2(pkHex);
|
|
4271
4753
|
return { recipientHi: hi, recipientLo: lo };
|
|
4272
4754
|
}
|
|
@@ -4351,7 +4833,7 @@ async function resolveTransferRecipientFromChain(input) {
|
|
|
4351
4833
|
import { Api } from "@stellar/stellar-sdk/rpc";
|
|
4352
4834
|
|
|
4353
4835
|
// src/rpc/soroban-transaction-meta.ts
|
|
4354
|
-
import { Address, StrKey as StrKey6 } from "@stellar/stellar-sdk";
|
|
4836
|
+
import { Address as Address2, StrKey as StrKey6 } from "@stellar/stellar-sdk";
|
|
4355
4837
|
var BIGINT_SHIFT_64 = 64n;
|
|
4356
4838
|
var TRANSACTION_META_SWITCH_SOROBAN_V3 = 3;
|
|
4357
4839
|
var TRANSACTION_META_SWITCH_SOROBAN_V4 = 4;
|
|
@@ -4451,8 +4933,8 @@ function transferPartyAddressesFromTopics(topics) {
|
|
|
4451
4933
|
return void 0;
|
|
4452
4934
|
}
|
|
4453
4935
|
return {
|
|
4454
|
-
from:
|
|
4455
|
-
to:
|
|
4936
|
+
from: Address2.fromScVal(fromTopic).toString(),
|
|
4937
|
+
to: Address2.fromScVal(toTopic).toString()
|
|
4456
4938
|
};
|
|
4457
4939
|
} catch {
|
|
4458
4940
|
return void 0;
|
|
@@ -5158,7 +5640,7 @@ function createStellarPrivacyClientFromResolvedConfig(config) {
|
|
|
5158
5640
|
}
|
|
5159
5641
|
|
|
5160
5642
|
// src/transact/engine/default-factory.ts
|
|
5161
|
-
import { PrivacyPoolSDK as
|
|
5643
|
+
import { PrivacyPoolSDK as PrivacyPoolSDK4 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
5162
5644
|
|
|
5163
5645
|
// src/transact/pool/proof-types.ts
|
|
5164
5646
|
function ciphertextArtifactsFromProof(proof) {
|
|
@@ -5173,9 +5655,15 @@ function ciphertextArtifactsFromProof(proof) {
|
|
|
5173
5655
|
// src/transact/engine/prepare/deposit.ts
|
|
5174
5656
|
var STROOPS_PER_UNIT = 10000000n;
|
|
5175
5657
|
async function createAlignedDepositWithProof(parameters) {
|
|
5658
|
+
const feeOutput = await quoteFeeOutputForPrepared(parameters);
|
|
5659
|
+
const instructed = parameters.prepared.intent.amount;
|
|
5660
|
+
const userAmount = instructed - (feeOutput?.requiredFee ?? 0n);
|
|
5661
|
+
if (userAmount <= 0n) {
|
|
5662
|
+
throw new Error("Required Fee leaves no spendable deposit note");
|
|
5663
|
+
}
|
|
5176
5664
|
const aligned = await parameters.poolService.createAlignedShieldCoinData({
|
|
5177
5665
|
privateAddressStpl1: parameters.prepared.intent.to,
|
|
5178
|
-
amountStroops:
|
|
5666
|
+
amountStroops: userAmount,
|
|
5179
5667
|
tokenAddress: parameters.tokenAddress
|
|
5180
5668
|
});
|
|
5181
5669
|
const poolClient = readPoolClientFactory(parameters.environment)({
|
|
@@ -5190,7 +5678,9 @@ async function createAlignedDepositWithProof(parameters) {
|
|
|
5190
5678
|
coin: aligned.coin,
|
|
5191
5679
|
depositScalarHex: aligned.depositScalarHex,
|
|
5192
5680
|
merkleRootBytes: merkleTx.result,
|
|
5193
|
-
tokenAddress: parameters.tokenAddress
|
|
5681
|
+
tokenAddress: parameters.tokenAddress,
|
|
5682
|
+
publicDepositStroops: instructed,
|
|
5683
|
+
...feeOutput ? { feeOutput } : {}
|
|
5194
5684
|
});
|
|
5195
5685
|
return { ...aligned, proof };
|
|
5196
5686
|
}
|
|
@@ -5209,8 +5699,8 @@ async function prepareDepositOperation(prepared, environment, poolService) {
|
|
|
5209
5699
|
privateAddress: prepared.intent.to,
|
|
5210
5700
|
assetId: prepared.intent.asset,
|
|
5211
5701
|
poolContract: environment.network.poolContract,
|
|
5212
|
-
amount:
|
|
5213
|
-
amountDisplay: Number(
|
|
5702
|
+
amount: BigInt(depositProof.coin.value),
|
|
5703
|
+
amountDisplay: Number(depositProof.coin.value) / Number(STROOPS_PER_UNIT),
|
|
5214
5704
|
commitmentHex: depositProof.commitment_hex,
|
|
5215
5705
|
coin: depositProof.coin,
|
|
5216
5706
|
depositScalarHex: depositProof.depositScalarHex,
|
|
@@ -5226,7 +5716,11 @@ async function prepareDepositOperation(prepared, environment, poolService) {
|
|
|
5226
5716
|
depositScalarHex: depositProof.depositScalarHex,
|
|
5227
5717
|
precommitementHex: depositProof.precommitementHex,
|
|
5228
5718
|
commitmentHex: depositProof.commitment_hex,
|
|
5229
|
-
walletPublicKey
|
|
5719
|
+
walletPublicKey,
|
|
5720
|
+
zkConfigNonce: zkConfigNonceForFeeBearingKind({
|
|
5721
|
+
kind: "deposit",
|
|
5722
|
+
...configuredNonceSpread(environment.zkConfigNonce)
|
|
5723
|
+
})
|
|
5230
5724
|
});
|
|
5231
5725
|
}
|
|
5232
5726
|
|
|
@@ -5400,9 +5894,6 @@ function escrowOutputFields(input) {
|
|
|
5400
5894
|
recipientLo: input.escrowSend.recipientLo
|
|
5401
5895
|
};
|
|
5402
5896
|
}
|
|
5403
|
-
function paddingDepositPair(recipientDeposit) {
|
|
5404
|
-
return [recipientDeposit, "dummy"];
|
|
5405
|
-
}
|
|
5406
5897
|
async function buildChangeDepositPair(parameters) {
|
|
5407
5898
|
const changeSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
|
|
5408
5899
|
privateAddressStpl1: parameters.selfPrivateAddressStpl1ForChange.trim(),
|
|
@@ -5419,34 +5910,54 @@ async function buildChangeDepositPair(parameters) {
|
|
|
5419
5910
|
}
|
|
5420
5911
|
};
|
|
5421
5912
|
}
|
|
5913
|
+
function recipientOnlyDeposits(recipientDeposit, hasFeeOutput) {
|
|
5914
|
+
if (hasFeeOutput) {
|
|
5915
|
+
return [recipientDeposit];
|
|
5916
|
+
}
|
|
5917
|
+
return [recipientDeposit, "dummy"];
|
|
5918
|
+
}
|
|
5919
|
+
async function depositsWithoutFee(input) {
|
|
5920
|
+
if (input.changeStroops <= ZERO_STROOPS) {
|
|
5921
|
+
return {
|
|
5922
|
+
deposits: recipientOnlyDeposits(input.recipientDeposit, input.hasFeeOutput)
|
|
5923
|
+
};
|
|
5924
|
+
}
|
|
5925
|
+
return buildChangeDepositPair({
|
|
5926
|
+
selfPrivateAddressStpl1ForChange: input.selfPrivateAddressStpl1ForChange,
|
|
5927
|
+
changeStroops: input.changeStroops,
|
|
5928
|
+
tokenAddress: input.tokenAddress,
|
|
5929
|
+
recipientDeposit: input.recipientDeposit
|
|
5930
|
+
});
|
|
5931
|
+
}
|
|
5422
5932
|
async function buildRecipientAndOptionalChangeDeposits(parameters) {
|
|
5423
5933
|
const escrow = {
|
|
5424
5934
|
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
5425
5935
|
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
5426
5936
|
};
|
|
5427
|
-
const recipientPrivateAddress = parameters.recipientPrivateAddressStpl1.trim();
|
|
5428
5937
|
const recipientSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
|
|
5429
|
-
privateAddressStpl1:
|
|
5938
|
+
privateAddressStpl1: parameters.recipientPrivateAddressStpl1.trim(),
|
|
5430
5939
|
amountStroops: parameters.transferStroops,
|
|
5431
5940
|
tokenAddress: parameters.tokenAddress,
|
|
5432
5941
|
...escrowOutputFields(escrow)
|
|
5433
5942
|
});
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
recipientSlot,
|
|
5437
|
-
deposits: paddingDepositPair(recipientSlot.deposit)
|
|
5438
|
-
};
|
|
5439
|
-
}
|
|
5440
|
-
const changeResult = await buildChangeDepositPair({
|
|
5441
|
-
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
5943
|
+
const withoutFee = await depositsWithoutFee({
|
|
5944
|
+
recipientDeposit: recipientSlot.deposit,
|
|
5442
5945
|
changeStroops: parameters.changeStroops,
|
|
5946
|
+
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
5947
|
+
tokenAddress: parameters.tokenAddress,
|
|
5948
|
+
hasFeeOutput: (parameters.feeOutput?.requiredFee ?? ZERO_STROOPS) > ZERO_STROOPS
|
|
5949
|
+
});
|
|
5950
|
+
const withFee = await appendFeeOutputSlot({
|
|
5951
|
+
deposits: withoutFee.deposits,
|
|
5443
5952
|
tokenAddress: parameters.tokenAddress,
|
|
5444
|
-
|
|
5953
|
+
buildAlignedDepositSlot: (aligned) => getPrivacyPoolService().buildAlignedDepositSlot(aligned),
|
|
5954
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
5445
5955
|
});
|
|
5446
5956
|
return {
|
|
5447
5957
|
recipientSlot,
|
|
5448
|
-
deposits:
|
|
5449
|
-
changeCoin:
|
|
5958
|
+
deposits: withFee.deposits,
|
|
5959
|
+
..."changeCoin" in withoutFee ? { changeCoin: withoutFee.changeCoin } : {},
|
|
5960
|
+
...withFee.feeCoin ? { feeCoin: withFee.feeCoin } : {}
|
|
5450
5961
|
};
|
|
5451
5962
|
}
|
|
5452
5963
|
|
|
@@ -5499,14 +6010,15 @@ function sweepOutputOwnerFields(parameters) {
|
|
|
5499
6010
|
return { sweepOutputOwnerPubX, sweepOutputOwnerPubY };
|
|
5500
6011
|
}
|
|
5501
6012
|
async function buildTransferDepositsAndPublicInput(parameters) {
|
|
5502
|
-
const { recipientSlot, deposits, changeCoin } = await buildRecipientAndOptionalChangeDeposits({
|
|
6013
|
+
const { recipientSlot, deposits, changeCoin, feeCoin } = await buildRecipientAndOptionalChangeDeposits({
|
|
5503
6014
|
recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
|
|
5504
6015
|
transferStroops: parameters.transferStroops,
|
|
5505
6016
|
changeStroops: parameters.changeStroops,
|
|
5506
6017
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
5507
6018
|
tokenAddress: parameters.tokenAddress,
|
|
5508
6019
|
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
5509
|
-
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
6020
|
+
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {},
|
|
6021
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
5510
6022
|
});
|
|
5511
6023
|
const publicInput = withTokenAddressPublicInputs(
|
|
5512
6024
|
{
|
|
@@ -5521,6 +6033,7 @@ async function buildTransferDepositsAndPublicInput(parameters) {
|
|
|
5521
6033
|
recipientSlot,
|
|
5522
6034
|
deposits,
|
|
5523
6035
|
...changeCoin ? { changeCoin } : {},
|
|
6036
|
+
...feeCoin ? { feeCoin } : {},
|
|
5524
6037
|
publicInput
|
|
5525
6038
|
};
|
|
5526
6039
|
}
|
|
@@ -5536,7 +6049,8 @@ async function buildSenderTransferDepositsAndPublicInput(parameters) {
|
|
|
5536
6049
|
parameters.senderPrivKeyScalarHex
|
|
5537
6050
|
),
|
|
5538
6051
|
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
5539
|
-
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
6052
|
+
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {},
|
|
6053
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
5540
6054
|
});
|
|
5541
6055
|
}
|
|
5542
6056
|
|
|
@@ -5560,11 +6074,20 @@ function stampDualWithdrawLegs(legs, parameters) {
|
|
|
5560
6074
|
}
|
|
5561
6075
|
};
|
|
5562
6076
|
}
|
|
5563
|
-
function buildDualTransferApplicationIds(sdk, applicationId, changeCoin) {
|
|
6077
|
+
function buildDualTransferApplicationIds(sdk, applicationId, changeCoin, feeCoin) {
|
|
6078
|
+
const outputIds = [applicationId];
|
|
6079
|
+
if (changeCoin) {
|
|
6080
|
+
outputIds.push(applicationId);
|
|
6081
|
+
} else if (!feeCoin) {
|
|
6082
|
+
outputIds.push("0");
|
|
6083
|
+
}
|
|
6084
|
+
if (feeCoin) {
|
|
6085
|
+
outputIds.push(applicationId);
|
|
6086
|
+
}
|
|
5564
6087
|
return buildApplicationIdHints({
|
|
5565
6088
|
sdk,
|
|
5566
6089
|
inputIds: [applicationId, applicationId],
|
|
5567
|
-
outputIds
|
|
6090
|
+
outputIds
|
|
5568
6091
|
});
|
|
5569
6092
|
}
|
|
5570
6093
|
async function proveDualConfidentialTransfer(parameters) {
|
|
@@ -5584,16 +6107,24 @@ async function proveDualConfidentialTransfer(parameters) {
|
|
|
5584
6107
|
audit
|
|
5585
6108
|
);
|
|
5586
6109
|
}
|
|
5587
|
-
|
|
6110
|
+
function dualTransferChangeStroops(parameters) {
|
|
5588
6111
|
const totalNotes = BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value);
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
6112
|
+
if (parameters.transferStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
6113
|
+
throw new Error("Transfer amount must be positive");
|
|
6114
|
+
}
|
|
6115
|
+
const changeStroops = remainingAfterRequiredFee({
|
|
6116
|
+
available: totalNotes,
|
|
6117
|
+
instructed: parameters.transferStroops,
|
|
6118
|
+
requiredFee: parameters.feeOutput?.requiredFee ?? 0n
|
|
6119
|
+
});
|
|
5593
6120
|
requireChangeRecipientWhenPartial(
|
|
5594
6121
|
changeStroops,
|
|
5595
6122
|
parameters.selfPrivateAddressStpl1ForChange
|
|
5596
6123
|
);
|
|
6124
|
+
return changeStroops;
|
|
6125
|
+
}
|
|
6126
|
+
async function buildDualTransferProofContext(parameters, applicationId, sdk) {
|
|
6127
|
+
const changeStroops = dualTransferChangeStroops(parameters);
|
|
5597
6128
|
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
5598
6129
|
parameters.senderPrivKeyScalarHex
|
|
5599
6130
|
);
|
|
@@ -5620,15 +6151,21 @@ async function buildDualTransferProofContext(parameters, applicationId, sdk) {
|
|
|
5620
6151
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
5621
6152
|
tokenAddress: parameters.tokenAddress,
|
|
5622
6153
|
stateRoot: legA.witness.stateRoot,
|
|
5623
|
-
...confidentialEscrowFields(parameters)
|
|
6154
|
+
...confidentialEscrowFields(parameters),
|
|
6155
|
+
...parameters.feeOutput ? { feeOutput: parameters.feeOutput } : {}
|
|
5624
6156
|
});
|
|
5625
6157
|
return { legA, legB, applicationId, ...transferInputs };
|
|
5626
6158
|
}
|
|
5627
6159
|
async function prepareConfidentialTransferProofDual(parameters) {
|
|
5628
6160
|
const poolService = getPrivacyPoolService();
|
|
5629
|
-
const sdk = await poolService.getInitializedSdk(
|
|
6161
|
+
const sdk = await poolService.getInitializedSdk(
|
|
6162
|
+
poolService.feeBearingZkConfigNonce({
|
|
6163
|
+
kind: "transfer",
|
|
6164
|
+
...parameters.escrowClaimantLimbs ? { spendSource: "escrow" } : {}
|
|
6165
|
+
})
|
|
6166
|
+
);
|
|
5630
6167
|
const applicationId = poolService.getApplicationId();
|
|
5631
|
-
const { legA, legB, recipientSlot, deposits, changeCoin, publicInput } = await buildDualTransferProofContext(parameters, applicationId, sdk);
|
|
6168
|
+
const { legA, legB, recipientSlot, deposits, changeCoin, feeCoin, publicInput } = await buildDualTransferProofContext(parameters, applicationId, sdk);
|
|
5632
6169
|
const auditPublicKey = poolService.getAuditPublicKey();
|
|
5633
6170
|
const proof = await (auditPublicKey ? proveDualConfidentialTransfer({
|
|
5634
6171
|
sdk,
|
|
@@ -5651,7 +6188,8 @@ async function prepareConfidentialTransferProofDual(parameters) {
|
|
|
5651
6188
|
applicationIdsPlaintext: buildDualTransferApplicationIds(
|
|
5652
6189
|
sdk,
|
|
5653
6190
|
applicationId,
|
|
5654
|
-
changeCoin
|
|
6191
|
+
changeCoin,
|
|
6192
|
+
feeCoin
|
|
5655
6193
|
),
|
|
5656
6194
|
recipientCoin: generatedOutputCoinFromSlot(recipientSlot),
|
|
5657
6195
|
...changeCoin ? { changeCoin } : {}
|
|
@@ -5659,22 +6197,32 @@ async function prepareConfidentialTransferProofDual(parameters) {
|
|
|
5659
6197
|
}
|
|
5660
6198
|
|
|
5661
6199
|
// src/transact/proofs/confidential/single.ts
|
|
5662
|
-
function validateSingleCoinTransferAmounts(transferStroops, noteStroops, selfPrivateAddressStpl1ForChange) {
|
|
6200
|
+
function validateSingleCoinTransferAmounts(transferStroops, noteStroops, selfPrivateAddressStpl1ForChange, requiredFee) {
|
|
5663
6201
|
if (transferStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
5664
6202
|
throw new Error("Transfer amount must be positive");
|
|
5665
6203
|
}
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
6204
|
+
const changeStroops = remainingAfterRequiredFee({
|
|
6205
|
+
available: noteStroops,
|
|
6206
|
+
instructed: transferStroops,
|
|
6207
|
+
requiredFee
|
|
6208
|
+
});
|
|
5670
6209
|
requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange);
|
|
5671
6210
|
return changeStroops;
|
|
5672
6211
|
}
|
|
5673
|
-
function buildSingleTransferApplicationIds(sdk, applicationId, changeCoin) {
|
|
6212
|
+
function buildSingleTransferApplicationIds(sdk, applicationId, changeCoin, feeCoin) {
|
|
6213
|
+
const outputIds = [applicationId];
|
|
6214
|
+
if (changeCoin) {
|
|
6215
|
+
outputIds.push(applicationId);
|
|
6216
|
+
} else if (!feeCoin) {
|
|
6217
|
+
outputIds.push("0");
|
|
6218
|
+
}
|
|
6219
|
+
if (feeCoin) {
|
|
6220
|
+
outputIds.push(applicationId);
|
|
6221
|
+
}
|
|
5674
6222
|
return buildApplicationIdHints({
|
|
5675
6223
|
sdk,
|
|
5676
6224
|
inputIds: [applicationId],
|
|
5677
|
-
outputIds
|
|
6225
|
+
outputIds
|
|
5678
6226
|
});
|
|
5679
6227
|
}
|
|
5680
6228
|
function buildTransferAuditParameters(parameters) {
|
|
@@ -5700,11 +6248,25 @@ function confidentialEscrowFields2(input) {
|
|
|
5700
6248
|
...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
|
|
5701
6249
|
};
|
|
5702
6250
|
}
|
|
6251
|
+
function transferDepositInputFromProof(input, changeStroops, stateRoot) {
|
|
6252
|
+
return {
|
|
6253
|
+
senderPrivKeyScalarHex: input.senderPrivKeyScalarHex,
|
|
6254
|
+
recipientPrivateAddressStpl1: input.recipientPrivateAddressStpl1,
|
|
6255
|
+
transferStroops: input.transferStroops,
|
|
6256
|
+
changeStroops,
|
|
6257
|
+
selfPrivateAddressStpl1ForChange: input.selfPrivateAddressStpl1ForChange,
|
|
6258
|
+
tokenAddress: input.tokenAddress,
|
|
6259
|
+
stateRoot,
|
|
6260
|
+
...confidentialEscrowFields2(input),
|
|
6261
|
+
...input.feeOutput ? { feeOutput: input.feeOutput } : {}
|
|
6262
|
+
};
|
|
6263
|
+
}
|
|
5703
6264
|
async function buildTransferProofInputs(parameters) {
|
|
5704
6265
|
const changeStroops = validateSingleCoinTransferAmounts(
|
|
5705
6266
|
parameters.input.transferStroops,
|
|
5706
6267
|
parameters.noteStroops,
|
|
5707
|
-
parameters.input.selfPrivateAddressStpl1ForChange
|
|
6268
|
+
parameters.input.selfPrivateAddressStpl1ForChange,
|
|
6269
|
+
parameters.input.feeOutput?.requiredFee ?? 0n
|
|
5708
6270
|
);
|
|
5709
6271
|
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
5710
6272
|
parameters.input.senderPrivKeyScalarHex
|
|
@@ -5723,31 +6285,30 @@ async function buildTransferProofInputs(parameters) {
|
|
|
5723
6285
|
withdrawObject,
|
|
5724
6286
|
sweepWithdrawStamp(confidentialEscrowFields2(parameters.input))
|
|
5725
6287
|
);
|
|
5726
|
-
const { recipientSlot, deposits, changeCoin, publicInput } = await buildSenderTransferDepositsAndPublicInput(
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
transferStroops: parameters.input.transferStroops,
|
|
5730
|
-
changeStroops,
|
|
5731
|
-
selfPrivateAddressStpl1ForChange: parameters.input.selfPrivateAddressStpl1ForChange,
|
|
5732
|
-
tokenAddress: parameters.input.tokenAddress,
|
|
5733
|
-
stateRoot: witness.stateRoot,
|
|
5734
|
-
...confidentialEscrowFields2(parameters.input)
|
|
5735
|
-
});
|
|
6288
|
+
const { recipientSlot, deposits, changeCoin, feeCoin, publicInput } = await buildSenderTransferDepositsAndPublicInput(
|
|
6289
|
+
transferDepositInputFromProof(parameters.input, changeStroops, witness.stateRoot)
|
|
6290
|
+
);
|
|
5736
6291
|
return {
|
|
5737
6292
|
witness,
|
|
5738
6293
|
withdrawObject: stampedWithdraw,
|
|
5739
6294
|
recipientSlot,
|
|
5740
6295
|
deposits,
|
|
5741
6296
|
changeCoin,
|
|
6297
|
+
feeCoin,
|
|
5742
6298
|
publicInput
|
|
5743
6299
|
};
|
|
5744
6300
|
}
|
|
5745
6301
|
async function prepareConfidentialTransferProof(parameters) {
|
|
5746
6302
|
const poolService = getPrivacyPoolService();
|
|
5747
|
-
const sdk = await poolService.getInitializedSdk(
|
|
6303
|
+
const sdk = await poolService.getInitializedSdk(
|
|
6304
|
+
poolService.feeBearingZkConfigNonce({
|
|
6305
|
+
kind: "transfer",
|
|
6306
|
+
...parameters.escrowClaimantLimbs ? { spendSource: "escrow" } : {}
|
|
6307
|
+
})
|
|
6308
|
+
);
|
|
5748
6309
|
const applicationId = poolService.getApplicationId();
|
|
5749
6310
|
const noteStroops = BigInt(parameters.coin.value);
|
|
5750
|
-
const { withdrawObject, recipientSlot, deposits, changeCoin, publicInput } = await buildTransferProofInputs({
|
|
6311
|
+
const { withdrawObject, recipientSlot, deposits, changeCoin, feeCoin, publicInput } = await buildTransferProofInputs({
|
|
5751
6312
|
sdk,
|
|
5752
6313
|
applicationId,
|
|
5753
6314
|
input: parameters,
|
|
@@ -5770,7 +6331,8 @@ async function prepareConfidentialTransferProof(parameters) {
|
|
|
5770
6331
|
applicationIdsPlaintext: buildSingleTransferApplicationIds(
|
|
5771
6332
|
sdk,
|
|
5772
6333
|
applicationId,
|
|
5773
|
-
changeCoin
|
|
6334
|
+
changeCoin,
|
|
6335
|
+
feeCoin
|
|
5774
6336
|
),
|
|
5775
6337
|
recipientCoin: generatedOutputCoinFromSlot(recipientSlot),
|
|
5776
6338
|
...changeCoin ? { changeCoin } : {}
|
|
@@ -5793,7 +6355,12 @@ function proofEscrowFields(input) {
|
|
|
5793
6355
|
}
|
|
5794
6356
|
async function buildSingleTransferProofAtExecute(input) {
|
|
5795
6357
|
const context = await buildSpendProofContextAtExecute(input);
|
|
5796
|
-
const
|
|
6358
|
+
const feeOutput = await quoteFeeOutputForPrepared({
|
|
6359
|
+
prepared: input.prepared,
|
|
6360
|
+
environment: input.environment,
|
|
6361
|
+
tokenAddress: context.tokenAddress
|
|
6362
|
+
});
|
|
6363
|
+
const changeStroops = BigInt(context.coin.value) - input.prepared.intent.amount - (feeOutput?.requiredFee ?? 0n);
|
|
5797
6364
|
const proof = await prepareConfidentialTransferProof({
|
|
5798
6365
|
coin: context.coin,
|
|
5799
6366
|
state: { commitments: context.commitments },
|
|
@@ -5806,7 +6373,8 @@ async function buildSingleTransferProofAtExecute(input) {
|
|
|
5806
6373
|
recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
|
|
5807
6374
|
selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
|
|
5808
6375
|
tokenAddress: context.tokenAddress,
|
|
5809
|
-
...proofEscrowFields(input)
|
|
6376
|
+
...proofEscrowFields(input),
|
|
6377
|
+
...feeOutput ? { feeOutput } : {}
|
|
5810
6378
|
});
|
|
5811
6379
|
return { context, proof };
|
|
5812
6380
|
}
|
|
@@ -5823,7 +6391,12 @@ async function buildDualTransferProofAtExecute(input) {
|
|
|
5823
6391
|
commitments: context.commitments
|
|
5824
6392
|
});
|
|
5825
6393
|
const totalNotes = BigInt(context.coin.value) + BigInt(secondary.coin.value);
|
|
5826
|
-
const
|
|
6394
|
+
const feeOutput = await quoteFeeOutputForPrepared({
|
|
6395
|
+
prepared: input.prepared,
|
|
6396
|
+
environment: input.environment,
|
|
6397
|
+
tokenAddress: context.tokenAddress
|
|
6398
|
+
});
|
|
6399
|
+
const changeStroops = totalNotes - input.prepared.intent.amount - (feeOutput?.requiredFee ?? 0n);
|
|
5827
6400
|
const proof = await prepareConfidentialTransferProofDual({
|
|
5828
6401
|
coinA: context.coin,
|
|
5829
6402
|
coinB: secondary.coin,
|
|
@@ -5841,7 +6414,8 @@ async function buildDualTransferProofAtExecute(input) {
|
|
|
5841
6414
|
recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
|
|
5842
6415
|
selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
|
|
5843
6416
|
tokenAddress: context.tokenAddress,
|
|
5844
|
-
...proofEscrowFields(input)
|
|
6417
|
+
...proofEscrowFields(input),
|
|
6418
|
+
...feeOutput ? { feeOutput } : {}
|
|
5845
6419
|
});
|
|
5846
6420
|
return { context, proof };
|
|
5847
6421
|
}
|
|
@@ -5973,11 +6547,17 @@ async function runTransferFinalizeSteps(input) {
|
|
|
5973
6547
|
walletPublicKey: input.walletPublicKey,
|
|
5974
6548
|
...recipient.escrowSend ? { escrowSendPrivateAddress: recipient.recipientPrivateAddressStpl1 } : {}
|
|
5975
6549
|
});
|
|
5976
|
-
return
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
6550
|
+
return {
|
|
6551
|
+
...buildTransferFinalizeArtifacts({
|
|
6552
|
+
proof,
|
|
6553
|
+
context,
|
|
6554
|
+
...sweepFinalizeStamp(input.prepared, recipient)
|
|
6555
|
+
}),
|
|
6556
|
+
zkConfigNonce: zkConfigNonceForFeeBearingKind({
|
|
6557
|
+
...feeOutputKindFromPrepared(input.prepared),
|
|
6558
|
+
...configuredNonceSpread(input.environment.zkConfigNonce)
|
|
6559
|
+
})
|
|
6560
|
+
};
|
|
5981
6561
|
}
|
|
5982
6562
|
function sweepArtifactStamp(artifacts) {
|
|
5983
6563
|
return {
|
|
@@ -6005,6 +6585,24 @@ async function finalizeTransferAtExecute(prepared, environment) {
|
|
|
6005
6585
|
return runTransferFinalizeSteps({ prepared, environment, walletPublicKey });
|
|
6006
6586
|
}
|
|
6007
6587
|
|
|
6588
|
+
// src/transact/engine/withdraw-fee.ts
|
|
6589
|
+
async function withdrawFeeProofFields(input) {
|
|
6590
|
+
const feeOutput = await quoteFeeOutputForPrepared({
|
|
6591
|
+
prepared: input.prepared,
|
|
6592
|
+
environment: input.environment,
|
|
6593
|
+
tokenAddress: input.tokenAddress
|
|
6594
|
+
});
|
|
6595
|
+
const changeStroops = remainingAfterRequiredFee({
|
|
6596
|
+
available: input.available,
|
|
6597
|
+
instructed: input.prepared.intent.amount,
|
|
6598
|
+
requiredFee: feeOutput?.requiredFee ?? 0n
|
|
6599
|
+
});
|
|
6600
|
+
return {
|
|
6601
|
+
...feeOutput ? { feeOutput } : {},
|
|
6602
|
+
...changeStroops > 0n ? { changePrivateAddressStpl1: input.withdrawFrom } : {}
|
|
6603
|
+
};
|
|
6604
|
+
}
|
|
6605
|
+
|
|
6008
6606
|
// src/transact/engine/execute.ts
|
|
6009
6607
|
function enrichWithdrawOutputRecords(prepared, proof) {
|
|
6010
6608
|
if (!proof.changeCoin || prepared.outputRecords.length === 0) {
|
|
@@ -6020,7 +6618,7 @@ function enrichWithdrawOutputRecords(prepared, proof) {
|
|
|
6020
6618
|
precommitementHex: changeCoin.precommitementHex
|
|
6021
6619
|
}));
|
|
6022
6620
|
}
|
|
6023
|
-
function buildWithdrawFinalizeArtifacts(proof, context) {
|
|
6621
|
+
function buildWithdrawFinalizeArtifacts(proof, context, environment) {
|
|
6024
6622
|
return {
|
|
6025
6623
|
proofHex: proof.proof_hex,
|
|
6026
6624
|
publicHex: proof.public_hex,
|
|
@@ -6028,7 +6626,11 @@ function buildWithdrawFinalizeArtifacts(proof, context) {
|
|
|
6028
6626
|
applicationIdsPlaintext: proof.applicationIdsPlaintext,
|
|
6029
6627
|
tokenAddress: context.tokenAddress,
|
|
6030
6628
|
walletPublicKey: context.walletPublicKey,
|
|
6031
|
-
executeFinalizeRequired: false
|
|
6629
|
+
executeFinalizeRequired: false,
|
|
6630
|
+
zkConfigNonce: zkConfigNonceForFeeBearingKind({
|
|
6631
|
+
kind: "withdraw",
|
|
6632
|
+
...configuredNonceSpread(environment.zkConfigNonce)
|
|
6633
|
+
})
|
|
6032
6634
|
};
|
|
6033
6635
|
}
|
|
6034
6636
|
async function finalizeSingleWithdrawAtExecute(prepared, environment, poolService, withdrawFrom) {
|
|
@@ -6037,7 +6639,13 @@ async function finalizeSingleWithdrawAtExecute(prepared, environment, poolServic
|
|
|
6037
6639
|
environment,
|
|
6038
6640
|
recipientPrivateAddressStpl1: withdrawFrom
|
|
6039
6641
|
});
|
|
6040
|
-
const
|
|
6642
|
+
const feeFields = await withdrawFeeProofFields({
|
|
6643
|
+
prepared,
|
|
6644
|
+
environment,
|
|
6645
|
+
tokenAddress: context.tokenAddress,
|
|
6646
|
+
available: BigInt(context.coin.value),
|
|
6647
|
+
withdrawFrom
|
|
6648
|
+
});
|
|
6041
6649
|
const proof = await poolService.prepareWithdrawTransactProof({
|
|
6042
6650
|
coin: context.coin,
|
|
6043
6651
|
state: { commitments: context.commitments },
|
|
@@ -6048,11 +6656,24 @@ async function finalizeSingleWithdrawAtExecute(prepared, environment, poolServic
|
|
|
6048
6656
|
yHex: context.ephemeral.yHex
|
|
6049
6657
|
}),
|
|
6050
6658
|
withdrawAmountStroops: prepared.intent.amount,
|
|
6051
|
-
changePrivateAddressStpl1:
|
|
6052
|
-
tokenAddress: context.tokenAddress
|
|
6659
|
+
changePrivateAddressStpl1: feeFields.changePrivateAddressStpl1,
|
|
6660
|
+
tokenAddress: context.tokenAddress,
|
|
6661
|
+
...feeFields.feeOutput ? { feeOutput: feeFields.feeOutput } : {}
|
|
6053
6662
|
});
|
|
6054
6663
|
enrichWithdrawOutputRecords(prepared, proof);
|
|
6055
|
-
return buildWithdrawFinalizeArtifacts(proof, context);
|
|
6664
|
+
return buildWithdrawFinalizeArtifacts(proof, context, environment);
|
|
6665
|
+
}
|
|
6666
|
+
function dualWithdrawEphemeralKeys(input) {
|
|
6667
|
+
return {
|
|
6668
|
+
depositorEphemeralAKey: serializeEphemeralKeyString({
|
|
6669
|
+
xHex: input.context.ephemeral.xHex,
|
|
6670
|
+
yHex: input.context.ephemeral.yHex
|
|
6671
|
+
}),
|
|
6672
|
+
depositorEphemeralBKey: serializeEphemeralKeyString({
|
|
6673
|
+
xHex: input.secondary.ephemeral.xHex,
|
|
6674
|
+
yHex: input.secondary.ephemeral.yHex
|
|
6675
|
+
})
|
|
6676
|
+
};
|
|
6056
6677
|
}
|
|
6057
6678
|
async function finalizeDualWithdrawAtExecute(prepared, environment, poolService, withdrawFrom) {
|
|
6058
6679
|
const [, secondaryRecord] = prepared.consumedRecords;
|
|
@@ -6070,28 +6691,27 @@ async function finalizeDualWithdrawAtExecute(prepared, environment, poolService,
|
|
|
6070
6691
|
walletPublicKey: context.walletPublicKey,
|
|
6071
6692
|
commitments: context.commitments
|
|
6072
6693
|
});
|
|
6073
|
-
const
|
|
6074
|
-
|
|
6694
|
+
const feeFields = await withdrawFeeProofFields({
|
|
6695
|
+
prepared,
|
|
6696
|
+
environment,
|
|
6697
|
+
tokenAddress: context.tokenAddress,
|
|
6698
|
+
available: BigInt(context.coin.value) + BigInt(secondary.coin.value),
|
|
6699
|
+
withdrawFrom
|
|
6700
|
+
});
|
|
6075
6701
|
const proof = await poolService.prepareWithdrawTransactProofDual({
|
|
6076
6702
|
coinA: context.coin,
|
|
6077
6703
|
coinB: secondary.coin,
|
|
6078
6704
|
state: { commitments: context.commitments },
|
|
6079
6705
|
destinationStellarAddress: prepared.intent.to,
|
|
6080
6706
|
privKeyScalarHex: context.senderPrivKeyScalarHex,
|
|
6081
|
-
|
|
6082
|
-
xHex: context.ephemeral.xHex,
|
|
6083
|
-
yHex: context.ephemeral.yHex
|
|
6084
|
-
}),
|
|
6085
|
-
depositorEphemeralBKey: serializeEphemeralKeyString({
|
|
6086
|
-
xHex: secondary.ephemeral.xHex,
|
|
6087
|
-
yHex: secondary.ephemeral.yHex
|
|
6088
|
-
}),
|
|
6707
|
+
...dualWithdrawEphemeralKeys({ context, secondary }),
|
|
6089
6708
|
withdrawAmountStroops: prepared.intent.amount,
|
|
6090
|
-
changePrivateAddressStpl1:
|
|
6091
|
-
tokenAddress: context.tokenAddress
|
|
6709
|
+
changePrivateAddressStpl1: feeFields.changePrivateAddressStpl1,
|
|
6710
|
+
tokenAddress: context.tokenAddress,
|
|
6711
|
+
...feeFields.feeOutput ? { feeOutput: feeFields.feeOutput } : {}
|
|
6092
6712
|
});
|
|
6093
6713
|
enrichWithdrawOutputRecords(prepared, proof);
|
|
6094
|
-
return buildWithdrawFinalizeArtifacts(proof, context);
|
|
6714
|
+
return buildWithdrawFinalizeArtifacts(proof, context, environment);
|
|
6095
6715
|
}
|
|
6096
6716
|
async function finalizeWithdrawAtExecute(prepared, environment, poolService) {
|
|
6097
6717
|
if (prepared.kind !== "withdraw") {
|
|
@@ -6223,20 +6843,20 @@ async function waitForKytRegistration(parameters) {
|
|
|
6223
6843
|
}
|
|
6224
6844
|
|
|
6225
6845
|
// src/transact/kyt/passage/submit.ts
|
|
6226
|
-
import { Buffer as
|
|
6227
|
-
import { Operation, TransactionBuilder, rpc as rpc3, xdr as
|
|
6846
|
+
import { Buffer as Buffer15 } from "buffer";
|
|
6847
|
+
import { Operation, TransactionBuilder, rpc as rpc3, xdr as xdr3 } from "@stellar/stellar-sdk";
|
|
6228
6848
|
var KYT_REGISTER_FEE_STROOPS = "1000000";
|
|
6229
6849
|
var KYT_REGISTER_TIMEOUT_SECONDS = 300;
|
|
6230
6850
|
function passageIdToScValue(passageId) {
|
|
6231
|
-
return
|
|
6851
|
+
return xdr3.ScVal.scvBytes(Buffer15.from(passageId.replace(/^0x/, ""), "hex"));
|
|
6232
6852
|
}
|
|
6233
6853
|
function approvalSignatureToBytes(signature) {
|
|
6234
6854
|
const clean = signature.trim();
|
|
6235
|
-
return /^(0x)?[0-9a-fA-F]{128}$/.test(clean) ?
|
|
6855
|
+
return /^(0x)?[0-9a-fA-F]{128}$/.test(clean) ? Buffer15.from(clean.replace(/^0x/i, ""), "hex") : Buffer15.from(clean, "base64");
|
|
6236
6856
|
}
|
|
6237
6857
|
function signatureToScValue(signature) {
|
|
6238
6858
|
const bytes = approvalSignatureToBytes(signature);
|
|
6239
|
-
return
|
|
6859
|
+
return xdr3.ScVal.scvBytes(bytes);
|
|
6240
6860
|
}
|
|
6241
6861
|
async function registerKytPassage(parameters) {
|
|
6242
6862
|
const signTransaction = parameters.transactEnvironment.signTransaction;
|
|
@@ -6257,7 +6877,7 @@ async function registerKytPassage(parameters) {
|
|
|
6257
6877
|
function: "register_passage",
|
|
6258
6878
|
args: [
|
|
6259
6879
|
passageIdToScValue(parameters.approval.passageId),
|
|
6260
|
-
|
|
6880
|
+
xdr3.ScVal.scvU32(parameters.approval.expiresAtLedger),
|
|
6261
6881
|
signatureToScValue(parameters.approval.signature)
|
|
6262
6882
|
]
|
|
6263
6883
|
})
|
|
@@ -6353,7 +6973,7 @@ async function requestKytPassageForPoolInteraction(input) {
|
|
|
6353
6973
|
const applicationId = resolvePoolApplicationId(
|
|
6354
6974
|
input.transactEnvironment.network.applicationId
|
|
6355
6975
|
);
|
|
6356
|
-
const zkConfigNonce = resolveZkConfigNonce(input.transactEnvironment);
|
|
6976
|
+
const zkConfigNonce = input.zkConfigNonce ?? resolveZkConfigNonce(input.transactEnvironment);
|
|
6357
6977
|
const applicationIdsPlaintext = input.applicationIdsPlaintext ?? buildApplicationIdHints2(
|
|
6358
6978
|
applicationId,
|
|
6359
6979
|
layoutForKnownNonce(zkConfigNonce).nAuditSlots
|
|
@@ -6382,12 +7002,12 @@ async function requestKytPassageForPoolInteraction(input) {
|
|
|
6382
7002
|
|
|
6383
7003
|
// src/transact/submit/zk-config-ttl.ts
|
|
6384
7004
|
import {
|
|
6385
|
-
Address as
|
|
7005
|
+
Address as Address3,
|
|
6386
7006
|
Operation as Operation2,
|
|
6387
7007
|
SorobanDataBuilder,
|
|
6388
7008
|
TransactionBuilder as TransactionBuilder2,
|
|
6389
7009
|
rpc as rpc4,
|
|
6390
|
-
xdr as
|
|
7010
|
+
xdr as xdr4
|
|
6391
7011
|
} from "@stellar/stellar-sdk";
|
|
6392
7012
|
var ZK_CONFIG_TTL_THRESHOLD_LEDGERS = 1e5;
|
|
6393
7013
|
var ZK_CONFIG_TTL_EXTEND_TO_LEDGERS = 5e5;
|
|
@@ -6411,15 +7031,15 @@ async function waitForExtendFootprintTtlConfirmation(parameters) {
|
|
|
6411
7031
|
throw new Error("ZK config TTL extension was not confirmed in time");
|
|
6412
7032
|
}
|
|
6413
7033
|
function zkConfigLedgerKey(contractId, nonce) {
|
|
6414
|
-
const configKeyScValue =
|
|
6415
|
-
|
|
6416
|
-
|
|
7034
|
+
const configKeyScValue = xdr4.ScVal.scvVec([
|
|
7035
|
+
xdr4.ScVal.scvSymbol("Config"),
|
|
7036
|
+
xdr4.ScVal.scvU64(xdr4.Uint64.fromString(nonce.toString()))
|
|
6417
7037
|
]);
|
|
6418
|
-
return
|
|
6419
|
-
new
|
|
6420
|
-
contract: new
|
|
7038
|
+
return xdr4.LedgerKey.contractData(
|
|
7039
|
+
new xdr4.LedgerKeyContractData({
|
|
7040
|
+
contract: new Address3(contractId).toScAddress(),
|
|
6421
7041
|
key: configKeyScValue,
|
|
6422
|
-
durability:
|
|
7042
|
+
durability: xdr4.ContractDataDurability.persistent()
|
|
6423
7043
|
})
|
|
6424
7044
|
);
|
|
6425
7045
|
}
|
|
@@ -6484,7 +7104,7 @@ async function extendZkConfigTtlIfNeeded(parameters) {
|
|
|
6484
7104
|
}
|
|
6485
7105
|
|
|
6486
7106
|
// src/transact/submit/pool-transact.ts
|
|
6487
|
-
import { Buffer as
|
|
7107
|
+
import { Buffer as Buffer16 } from "buffer";
|
|
6488
7108
|
async function submitPoolTransact(parameters) {
|
|
6489
7109
|
await extendZkConfigTtlIfNeeded({
|
|
6490
7110
|
sorobanRpcUrl: parameters.sorobanRpcUrl,
|
|
@@ -6497,9 +7117,9 @@ async function submitPoolTransact(parameters) {
|
|
|
6497
7117
|
const assembledTransaction = await parameters.contractClient.transact({
|
|
6498
7118
|
from: parameters.from,
|
|
6499
7119
|
nonce: parameters.nonce,
|
|
6500
|
-
proof_bytes:
|
|
6501
|
-
pub_signals_bytes:
|
|
6502
|
-
ciphertext_bytes:
|
|
7120
|
+
proof_bytes: Buffer16.from(parameters.proofHex.replace(/^0x/iu, ""), "hex"),
|
|
7121
|
+
pub_signals_bytes: Buffer16.from(parameters.publicHex.replace(/^0x/iu, ""), "hex"),
|
|
7122
|
+
ciphertext_bytes: Buffer16.from(
|
|
6503
7123
|
(parameters.ciphertextHex ?? "").replace(/^0x/iu, ""),
|
|
6504
7124
|
"hex"
|
|
6505
7125
|
),
|
|
@@ -6525,6 +7145,10 @@ async function submitSorobanConfidentialTransfer(input) {
|
|
|
6525
7145
|
networkPassphrase: input.networkPassphrase,
|
|
6526
7146
|
sorobanRpcUrl: input.sorobanRpcUrl
|
|
6527
7147
|
});
|
|
7148
|
+
const nonce = transactNonceFromArtifacts(
|
|
7149
|
+
input.zkConfigNonce === void 0 ? void 0 : { zkConfigNonce: input.zkConfigNonce },
|
|
7150
|
+
input.transactEnvironment
|
|
7151
|
+
);
|
|
6528
7152
|
const approval = await requestKytPassageForPoolInteraction({
|
|
6529
7153
|
owner: input.walletPublicKey,
|
|
6530
7154
|
poolContract: input.contractId,
|
|
@@ -6533,6 +7157,7 @@ async function submitSorobanConfidentialTransfer(input) {
|
|
|
6533
7157
|
...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
|
|
6534
7158
|
...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {},
|
|
6535
7159
|
...input.applicationIdsPlaintext ? { applicationIdsPlaintext: input.applicationIdsPlaintext } : {},
|
|
7160
|
+
...input.zkConfigNonce === void 0 ? {} : { zkConfigNonce: input.zkConfigNonce },
|
|
6536
7161
|
networkPassphrase: input.networkPassphrase,
|
|
6537
7162
|
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
6538
7163
|
transactEnvironment: input.transactEnvironment
|
|
@@ -6541,7 +7166,7 @@ async function submitSorobanConfidentialTransfer(input) {
|
|
|
6541
7166
|
contractClient: poolClient,
|
|
6542
7167
|
contractId: input.contractId,
|
|
6543
7168
|
from: input.walletPublicKey,
|
|
6544
|
-
nonce
|
|
7169
|
+
nonce,
|
|
6545
7170
|
proofHex: input.proofHex,
|
|
6546
7171
|
publicHex: input.publicHex,
|
|
6547
7172
|
...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
|
|
@@ -6572,12 +7197,14 @@ async function submitPreparedDeposit(prepared, environment) {
|
|
|
6572
7197
|
networkPassphrase: environment.network.networkPassphrase,
|
|
6573
7198
|
sorobanRpcUrl: environment.network.rpcUrl
|
|
6574
7199
|
});
|
|
7200
|
+
const nonce = transactNonceFromArtifacts(artifacts, environment);
|
|
6575
7201
|
const approval = await requestKytPassageForPoolInteraction({
|
|
6576
7202
|
owner: artifacts.walletPublicKey,
|
|
6577
7203
|
poolContract: environment.network.poolContract,
|
|
6578
7204
|
proofHex: artifacts.proofHex,
|
|
6579
7205
|
publicHex: artifacts.publicHex,
|
|
6580
7206
|
...optionalInspectCiphertext(artifacts),
|
|
7207
|
+
...artifacts.zkConfigNonce === void 0 ? {} : { zkConfigNonce: artifacts.zkConfigNonce },
|
|
6581
7208
|
networkPassphrase: environment.network.networkPassphrase,
|
|
6582
7209
|
sorobanRpcUrl: environment.network.rpcUrl,
|
|
6583
7210
|
transactEnvironment: environment
|
|
@@ -6586,7 +7213,7 @@ async function submitPreparedDeposit(prepared, environment) {
|
|
|
6586
7213
|
contractClient: poolClient,
|
|
6587
7214
|
contractId: environment.network.poolContract,
|
|
6588
7215
|
from: artifacts.walletPublicKey,
|
|
6589
|
-
nonce
|
|
7216
|
+
nonce,
|
|
6590
7217
|
proofHex: artifacts.proofHex,
|
|
6591
7218
|
publicHex: artifacts.publicHex,
|
|
6592
7219
|
...artifacts.ciphertextHex ? { ciphertextHex: artifacts.ciphertextHex } : {},
|
|
@@ -6607,6 +7234,7 @@ async function submitPreparedPoolTransact(prepared, environment) {
|
|
|
6607
7234
|
proofHex: artifacts.proofHex,
|
|
6608
7235
|
publicHex: artifacts.publicHex,
|
|
6609
7236
|
...optionalInspectCiphertext(artifacts),
|
|
7237
|
+
...artifacts.zkConfigNonce === void 0 ? {} : { zkConfigNonce: artifacts.zkConfigNonce },
|
|
6610
7238
|
networkPassphrase: environment.network.networkPassphrase,
|
|
6611
7239
|
sorobanRpcUrl: environment.network.rpcUrl,
|
|
6612
7240
|
transactEnvironment: environment
|
|
@@ -6662,7 +7290,7 @@ async function privacyPoolInitOptions(assets, transactEnvironment) {
|
|
|
6662
7290
|
};
|
|
6663
7291
|
}
|
|
6664
7292
|
async function createDefaultTransactEngine(assets, transactEnvironment) {
|
|
6665
|
-
await
|
|
7293
|
+
await PrivacyPoolSDK4.init(await privacyPoolInitOptions(assets, transactEnvironment));
|
|
6666
7294
|
if (transactEnvironment) {
|
|
6667
7295
|
configurePrivacyPoolService(
|
|
6668
7296
|
createPrivacyPoolService({
|