@arcanetech/privacy-sdk-stellar 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -0
- package/dist/index.js +7057 -0
- package/dist/index.js.map +1 -0
- package/dist/node.js +6726 -0
- package/dist/node.js.map +1 -0
- package/dist/state/index.js +2478 -0
- package/dist/state/index.js.map +1 -0
- package/dist/transact/index.js +4163 -0
- package/dist/transact/index.js.map +1 -0
- package/generated/contract/README.md +54 -0
- package/generated/contract/dist/index.d.ts +369 -0
- package/generated/contract/dist/index.js +125 -0
- package/generated/contract/package.json +17 -0
- package/generated/contract/src/index.ts +399 -0
- package/generated/contract/tsconfig.json +98 -0
- package/generated/registry/README.md +54 -0
- package/generated/registry/dist/index.d.ts +198 -0
- package/generated/registry/dist/index.js +70 -0
- package/generated/registry/package.json +17 -0
- package/generated/registry/src/index.ts +238 -0
- package/generated/registry/tsconfig.json +98 -0
- package/package.json +69 -0
|
@@ -0,0 +1,4163 @@
|
|
|
1
|
+
// src/transact/pool/service.ts
|
|
2
|
+
import {
|
|
3
|
+
decodeDecodedEphemeralKey,
|
|
4
|
+
randomFrDecimal253,
|
|
5
|
+
scalarHexToFrDecimal as scalarHexToFrDecimal2
|
|
6
|
+
} from "@auditable/privacy-pool-zk-sdk";
|
|
7
|
+
|
|
8
|
+
// src/transact/merkle/field-decimal.ts
|
|
9
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
10
|
+
var BN254 = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
11
|
+
var MERKLE_ROOT_BYTE_LENGTH = 32;
|
|
12
|
+
var DECIMAL_STRING_RADIX = 10;
|
|
13
|
+
function merkleRootBufferToFrDecimal(root) {
|
|
14
|
+
if (root.length !== MERKLE_ROOT_BYTE_LENGTH) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
`expected ${MERKLE_ROOT_BYTE_LENGTH}-byte merkle root, got ${root.length}`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
const hex = Buffer2.from(root).toString("hex");
|
|
20
|
+
return (BigInt(`0x${hex}`) % BN254).toString(DECIMAL_STRING_RADIX);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/transact/private-address/codec.ts
|
|
24
|
+
import {
|
|
25
|
+
buildStealthAddressSignMessage,
|
|
26
|
+
decodeStealthAddress,
|
|
27
|
+
encodeStealthAddress,
|
|
28
|
+
recipientPublicKeysDecimalFromStealthAddress
|
|
29
|
+
} from "@auditable/privacy-pool-zk-sdk";
|
|
30
|
+
import { DEFAULT_STEALTH_SIGN_NONCE } from "@auditable/privacy-pool-zk-sdk";
|
|
31
|
+
function buildPrivateAddressSignMessage(publicKey, nonce) {
|
|
32
|
+
const buildMessage = buildStealthAddressSignMessage;
|
|
33
|
+
return buildMessage(publicKey, nonce);
|
|
34
|
+
}
|
|
35
|
+
function decodePrivateAddress(value) {
|
|
36
|
+
const decodeAddress = decodeStealthAddress;
|
|
37
|
+
return decodeAddress(value);
|
|
38
|
+
}
|
|
39
|
+
function encodePrivateAddress(decoded) {
|
|
40
|
+
const encodeAddress = encodeStealthAddress;
|
|
41
|
+
return encodeAddress(decoded);
|
|
42
|
+
}
|
|
43
|
+
function encodePrivateAddressFromHexCoordinates(publicKeyXHex, publicKeyYHex) {
|
|
44
|
+
return encodePrivateAddress(
|
|
45
|
+
Object.fromEntries([
|
|
46
|
+
["x", publicKeyXHex],
|
|
47
|
+
["y", publicKeyYHex]
|
|
48
|
+
])
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
function recipientPublicKeysDecimalFromPrivateAddress(value) {
|
|
52
|
+
const readPublicKeys = recipientPublicKeysDecimalFromStealthAddress;
|
|
53
|
+
return readPublicKeys(value);
|
|
54
|
+
}
|
|
55
|
+
function privateAddressSdk(sdk) {
|
|
56
|
+
const generator = sdk.generateStealthAddressFromStellarSignature;
|
|
57
|
+
if (typeof generator !== "function") {
|
|
58
|
+
throw new TypeError(
|
|
59
|
+
"Missing privacy pool SDK method: generateStealthAddressFromStellarSignature"
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
generatePrivateAddressFromStellarSignature: (signature) => generator.call(sdk, signature)
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// src/transact/proofs/withdraw/transact-proof.ts
|
|
68
|
+
import { withdrawObjectFromMerkleWitness as withdrawObjectFromMerkleWitness2 } from "@auditable/privacy-pool-zk-sdk";
|
|
69
|
+
|
|
70
|
+
// src/transact/proofs/transaction-input.ts
|
|
71
|
+
import { Buffer as Buffer4 } from "buffer";
|
|
72
|
+
import { StrKey as StrKey2 } from "@stellar/stellar-sdk";
|
|
73
|
+
|
|
74
|
+
// src/transact/stellar/token-contract.ts
|
|
75
|
+
import { Buffer as Buffer3 } from "buffer";
|
|
76
|
+
import { StrKey } from "@stellar/stellar-sdk";
|
|
77
|
+
var CONTRACT_ID_BYTE_LENGTH = 32;
|
|
78
|
+
var HEX_CHARS_PER_BYTE = 2;
|
|
79
|
+
var CONTRACT_ID_HEX_CHAR_LENGTH = CONTRACT_ID_BYTE_LENGTH * HEX_CHARS_PER_BYTE;
|
|
80
|
+
var CONTRACT_ID_HEX = /^(?:0x)?([0-9a-f]{64})$/i;
|
|
81
|
+
function encodeContractFromHex(hexPayload) {
|
|
82
|
+
return StrKey.encodeContract(Buffer3.from(hexPayload, "hex"));
|
|
83
|
+
}
|
|
84
|
+
function normalizeSorobanContractId(raw) {
|
|
85
|
+
const trimmed = raw.trim();
|
|
86
|
+
if (trimmed.length === 0) {
|
|
87
|
+
throw new Error("Contract ID is empty");
|
|
88
|
+
}
|
|
89
|
+
if (StrKey.isValidContract(trimmed)) {
|
|
90
|
+
return trimmed;
|
|
91
|
+
}
|
|
92
|
+
const hexMatch = CONTRACT_ID_HEX.exec(trimmed);
|
|
93
|
+
const hexPayload = hexMatch?.[1];
|
|
94
|
+
if (hexPayload !== void 0 && hexPayload.length === CONTRACT_ID_HEX_CHAR_LENGTH) {
|
|
95
|
+
return encodeContractFromHex(hexPayload);
|
|
96
|
+
}
|
|
97
|
+
throw new Error(`Invalid Soroban contract address: ${trimmed}`);
|
|
98
|
+
}
|
|
99
|
+
function resolveTokenContractId(tokenContractRaw) {
|
|
100
|
+
const raw = tokenContractRaw?.trim();
|
|
101
|
+
if (!raw) {
|
|
102
|
+
throw new Error("Selected asset has no client contract");
|
|
103
|
+
}
|
|
104
|
+
return normalizeSorobanContractId(raw);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/transact/proofs/transaction-input.ts
|
|
108
|
+
var CONTRACT_ADDRESS_HALF_BYTES = 16;
|
|
109
|
+
var CONTRACT_ADDRESS_BYTES = 32;
|
|
110
|
+
function bytes16ToDecimal(bytes) {
|
|
111
|
+
return BigInt(`0x${Buffer4.from(bytes).toString("hex")}`).toString();
|
|
112
|
+
}
|
|
113
|
+
function decimalToBytes16(value) {
|
|
114
|
+
const hex = BigInt(value).toString(16).padStart(CONTRACT_ADDRESS_HALF_BYTES * 2, "0");
|
|
115
|
+
if (hex.length > CONTRACT_ADDRESS_HALF_BYTES * 2) {
|
|
116
|
+
throw new Error("Asset leg does not fit into 16 bytes.");
|
|
117
|
+
}
|
|
118
|
+
return Buffer4.from(hex, "hex");
|
|
119
|
+
}
|
|
120
|
+
function tokenAddressFrParts(tokenAddress) {
|
|
121
|
+
const normalized = resolveTokenContractId(tokenAddress);
|
|
122
|
+
const payload = StrKey2.decodeContract(normalized);
|
|
123
|
+
const hi = bytes16ToDecimal(payload.subarray(0, CONTRACT_ADDRESS_HALF_BYTES));
|
|
124
|
+
const lo = bytes16ToDecimal(
|
|
125
|
+
payload.subarray(CONTRACT_ADDRESS_HALF_BYTES, CONTRACT_ADDRESS_BYTES)
|
|
126
|
+
);
|
|
127
|
+
return { hi, lo };
|
|
128
|
+
}
|
|
129
|
+
function withTokenAddressPublicInputs(base, tokenAddress) {
|
|
130
|
+
const { hi, lo } = tokenAddressFrParts(tokenAddress);
|
|
131
|
+
return {
|
|
132
|
+
...base,
|
|
133
|
+
tokenAddressHi: hi,
|
|
134
|
+
tokenAddressLo: lo
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function tokenAddressToAssetLeg(tokenAddress) {
|
|
138
|
+
const { hi, lo } = tokenAddressFrParts(tokenAddress);
|
|
139
|
+
return [hi, lo];
|
|
140
|
+
}
|
|
141
|
+
function assetLegToTokenAddress(assetHi, assetLo) {
|
|
142
|
+
const payload = Buffer4.concat([decimalToBytes16(assetHi), decimalToBytes16(assetLo)]);
|
|
143
|
+
return StrKey2.encodeContract(payload);
|
|
144
|
+
}
|
|
145
|
+
function buildZeroPublicLegs() {
|
|
146
|
+
return {
|
|
147
|
+
publicWithdrawnAssets: [["0", "0"]],
|
|
148
|
+
publicDepositedAssets: [["0", "0"]],
|
|
149
|
+
publicDeposits: ["0"],
|
|
150
|
+
publicWithdrawals: ["0"]
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function buildPublicDepositLegs(tokenAddress, amount) {
|
|
154
|
+
const legs = buildZeroPublicLegs();
|
|
155
|
+
return {
|
|
156
|
+
...legs,
|
|
157
|
+
publicDepositedAssets: [tokenAddressToAssetLeg(tokenAddress)],
|
|
158
|
+
publicDeposits: [amount]
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function buildPublicWithdrawLegs(tokenAddress, amount) {
|
|
162
|
+
const legs = buildZeroPublicLegs();
|
|
163
|
+
return {
|
|
164
|
+
...legs,
|
|
165
|
+
publicWithdrawnAssets: [tokenAddressToAssetLeg(tokenAddress)],
|
|
166
|
+
publicWithdrawals: [amount]
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/transact/proofs/confidential/helpers.ts
|
|
171
|
+
import {
|
|
172
|
+
ed25519PubkeyPayloadHexToWithdrawFrDecimals,
|
|
173
|
+
withdrawObjectFromMerkleWitness
|
|
174
|
+
} from "@auditable/privacy-pool-zk-sdk";
|
|
175
|
+
import { StrKey as StrKey3 } from "@stellar/stellar-sdk";
|
|
176
|
+
import { Buffer as Buffer5 } from "buffer";
|
|
177
|
+
|
|
178
|
+
// src/transact/encoding/priv-key-scalar-from-recipient-hex.ts
|
|
179
|
+
import { BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE } from "@auditable/privacy-pool-zk-sdk";
|
|
180
|
+
var SCALAR_HEX_CHAR_LENGTH = 64;
|
|
181
|
+
var DECIMAL_RADIX = 10;
|
|
182
|
+
var BIGINT_ONE = 1n;
|
|
183
|
+
function normalizeRecipientScalarHex(hexInput) {
|
|
184
|
+
const trimmed = hexInput.trim().replace(/^0x/iu, "");
|
|
185
|
+
if (!/^[0-9a-f]*$/iu.test(trimmed)) {
|
|
186
|
+
throw new Error("recipient scalar hex must be hexadecimal");
|
|
187
|
+
}
|
|
188
|
+
const withLeadingNibble = trimmed.length % 2 === 0 ? trimmed : `0${trimmed}`;
|
|
189
|
+
const lower = withLeadingNibble.toLowerCase();
|
|
190
|
+
const padded = lower.padStart(SCALAR_HEX_CHAR_LENGTH, "0").slice(-SCALAR_HEX_CHAR_LENGTH);
|
|
191
|
+
if (padded.length !== SCALAR_HEX_CHAR_LENGTH) {
|
|
192
|
+
throw new Error(
|
|
193
|
+
`recipient scalar hex must fit 32 bytes (${SCALAR_HEX_CHAR_LENGTH} hex chars)`
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
return padded;
|
|
197
|
+
}
|
|
198
|
+
function privKeyScalarDecimalFromRecipientScalarHex(hexInput) {
|
|
199
|
+
const hex = normalizeRecipientScalarHex(hexInput);
|
|
200
|
+
const value = BigInt(`0x${hex}`);
|
|
201
|
+
const mask = BN254_BABYJUB_SCALAR_MAX_EXCLUSIVE - BIGINT_ONE;
|
|
202
|
+
return (value & mask).toString(DECIMAL_RADIX);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// src/transact/proofs/confidential/helpers.ts
|
|
206
|
+
var MIN_CONFIDENTIAL_TRANSFER_STROOPS = 1n;
|
|
207
|
+
var ZERO_STROOPS = 0n;
|
|
208
|
+
function leafEphemeralCoords(xHex, yHex) {
|
|
209
|
+
const coords = {};
|
|
210
|
+
Object.defineProperty(coords, "x", {
|
|
211
|
+
value: xHex,
|
|
212
|
+
enumerable: true,
|
|
213
|
+
writable: true
|
|
214
|
+
});
|
|
215
|
+
Object.defineProperty(coords, "y", {
|
|
216
|
+
value: yHex,
|
|
217
|
+
enumerable: true,
|
|
218
|
+
writable: true
|
|
219
|
+
});
|
|
220
|
+
return coords;
|
|
221
|
+
}
|
|
222
|
+
function withdrawWitnessForCoin(parameters) {
|
|
223
|
+
const { sdk, coin, state, xHex, yHex } = parameters;
|
|
224
|
+
const witness = sdk.buildWithdrawMerkleWitness(coin, state);
|
|
225
|
+
const withdrawApplicationId = coin.application_id ?? parameters.applicationId;
|
|
226
|
+
const withdrawObject = withdrawObjectFromMerkleWitness(
|
|
227
|
+
witness,
|
|
228
|
+
leafEphemeralCoords(xHex, yHex),
|
|
229
|
+
withdrawApplicationId
|
|
230
|
+
);
|
|
231
|
+
return { witness, withdrawObject };
|
|
232
|
+
}
|
|
233
|
+
function dualWithdrawLegsWithSharedRoot(parameters) {
|
|
234
|
+
const legA = withdrawWitnessForCoin({
|
|
235
|
+
sdk: parameters.sdk,
|
|
236
|
+
coin: parameters.coinA,
|
|
237
|
+
state: parameters.state,
|
|
238
|
+
xHex: parameters.ephemeralA.xHex,
|
|
239
|
+
yHex: parameters.ephemeralA.yHex,
|
|
240
|
+
applicationId: parameters.applicationId
|
|
241
|
+
});
|
|
242
|
+
const legB = withdrawWitnessForCoin({
|
|
243
|
+
sdk: parameters.sdk,
|
|
244
|
+
coin: parameters.coinB,
|
|
245
|
+
state: parameters.state,
|
|
246
|
+
xHex: parameters.ephemeralB.xHex,
|
|
247
|
+
yHex: parameters.ephemeralB.yHex,
|
|
248
|
+
applicationId: parameters.applicationId
|
|
249
|
+
});
|
|
250
|
+
if (legA.witness.stateRoot !== legB.witness.stateRoot) {
|
|
251
|
+
throw new Error("Merkle state root mismatch between input coins");
|
|
252
|
+
}
|
|
253
|
+
return { legA, legB };
|
|
254
|
+
}
|
|
255
|
+
function senderWithdrawFrAndScalar(parameters) {
|
|
256
|
+
const pkRaw = StrKey3.decodeEd25519PublicKey(parameters.senderGAddress);
|
|
257
|
+
const pkHex = Buffer5.from(pkRaw).toString("hex");
|
|
258
|
+
const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals(pkHex);
|
|
259
|
+
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
260
|
+
parameters.senderPrivKeyScalarHex
|
|
261
|
+
);
|
|
262
|
+
return { hi, lo, privKeyScalar };
|
|
263
|
+
}
|
|
264
|
+
function requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange) {
|
|
265
|
+
if (changeStroops > ZERO_STROOPS) {
|
|
266
|
+
const stpl1 = selfPrivateAddressStpl1ForChange?.trim() ?? "";
|
|
267
|
+
if (!stpl1) {
|
|
268
|
+
throw new Error(
|
|
269
|
+
"Private address is required to receive the remaining balance after a partial transfer"
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function changeStroopsAfterDualTransfer(transferStroops, totalNotes) {
|
|
275
|
+
if (transferStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
276
|
+
throw new Error("Transfer amount must be positive");
|
|
277
|
+
}
|
|
278
|
+
if (transferStroops > totalNotes) {
|
|
279
|
+
throw new Error("Transfer amount exceeds combined note value");
|
|
280
|
+
}
|
|
281
|
+
return totalNotes - transferStroops;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// src/transact/audit/parameters.ts
|
|
285
|
+
import {
|
|
286
|
+
DEMO_AUDIT_PUBLIC_KEY,
|
|
287
|
+
resolveTransactionAuditParams
|
|
288
|
+
} from "@auditable/privacy-pool-zk-sdk";
|
|
289
|
+
import { Buffer as Buffer6 } from "buffer";
|
|
290
|
+
var UNCOMPRESSED_PREFIX = "04";
|
|
291
|
+
var UNCOMPRESSED_HEX_LENGTH = 130;
|
|
292
|
+
var XY_HEX_LENGTH = 128;
|
|
293
|
+
var X_OFFSET_END = 32;
|
|
294
|
+
var Y_OFFSET_START = 32;
|
|
295
|
+
var Y_OFFSET_END = 64;
|
|
296
|
+
var DECIMAL_RADIX2 = 10;
|
|
297
|
+
var BN254_FR_MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
298
|
+
var BABYJUBJUB_A = 168700n;
|
|
299
|
+
var BABYJUBJUB_D = 168696n;
|
|
300
|
+
var BABYJUB_CURVE_ONE = 1n;
|
|
301
|
+
function passesBabyJubCurveCheck(coordinateX, coordinateY) {
|
|
302
|
+
const xSquared = coordinateX * coordinateX % BN254_FR_MODULUS;
|
|
303
|
+
const ySquared = coordinateY * coordinateY % BN254_FR_MODULUS;
|
|
304
|
+
const lhs = (BABYJUBJUB_A * xSquared + ySquared) % BN254_FR_MODULUS;
|
|
305
|
+
const rhs = (BABYJUB_CURVE_ONE + BABYJUBJUB_D * xSquared * ySquared) % BN254_FR_MODULUS;
|
|
306
|
+
return lhs === rhs;
|
|
307
|
+
}
|
|
308
|
+
function parseAuditPublicKeyFromEnvHex(raw) {
|
|
309
|
+
const normalized = raw.replace(/^0x/i, "");
|
|
310
|
+
const payload = normalized.length === UNCOMPRESSED_HEX_LENGTH && normalized.startsWith(UNCOMPRESSED_PREFIX) ? normalized.slice(UNCOMPRESSED_PREFIX.length) : normalized;
|
|
311
|
+
if (payload.length !== XY_HEX_LENGTH || !/^[\da-fA-F]+$/.test(payload)) {
|
|
312
|
+
throw new Error(
|
|
313
|
+
"Audit public key must be uncompressed 65-byte hex (04 + X + Y) or 64-byte X+Y hex"
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
const bytes = Buffer6.from(payload, "hex");
|
|
317
|
+
const auditPublicKeyXDecimal = BigInt(
|
|
318
|
+
`0x${bytes.subarray(0, X_OFFSET_END).toString("hex")}`
|
|
319
|
+
).toString(DECIMAL_RADIX2);
|
|
320
|
+
const auditPublicKeyYDecimal = BigInt(
|
|
321
|
+
`0x${bytes.subarray(Y_OFFSET_START, Y_OFFSET_END).toString("hex")}`
|
|
322
|
+
).toString(DECIMAL_RADIX2);
|
|
323
|
+
if (!passesBabyJubCurveCheck(
|
|
324
|
+
BigInt(auditPublicKeyXDecimal),
|
|
325
|
+
BigInt(auditPublicKeyYDecimal)
|
|
326
|
+
)) {
|
|
327
|
+
throw new Error("Audit public key is not a valid BabyJubJub point.");
|
|
328
|
+
}
|
|
329
|
+
return [auditPublicKeyXDecimal, auditPublicKeyYDecimal];
|
|
330
|
+
}
|
|
331
|
+
function buildPoolTransactionAuditParameters(input) {
|
|
332
|
+
return resolveTransactionAuditParams(
|
|
333
|
+
input.applicationId,
|
|
334
|
+
input.auditPublicKey ?? DEMO_AUDIT_PUBLIC_KEY
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
function resolvePoolApplicationId(applicationId) {
|
|
338
|
+
const trimmed = applicationId?.trim();
|
|
339
|
+
if (!trimmed) {
|
|
340
|
+
throw new Error(
|
|
341
|
+
"Privacy pool applicationId is required. Pass it in client factory config."
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
return trimmed;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// src/transact/proofs/withdraw/helpers.ts
|
|
348
|
+
import { ed25519PubkeyPayloadHexToWithdrawFrDecimals as ed25519PubkeyPayloadHexToWithdrawFrDecimals2 } from "@auditable/privacy-pool-zk-sdk";
|
|
349
|
+
|
|
350
|
+
// src/transact/stellar/account.ts
|
|
351
|
+
import { StrKey as StrKey4 } from "@stellar/stellar-sdk";
|
|
352
|
+
import { Buffer as Buffer7 } from "buffer";
|
|
353
|
+
var MUXED_ACCOUNT_ID_BYTE_LENGTH = 8;
|
|
354
|
+
var ED25519_PUBLIC_KEY_BYTE_LENGTH = 32;
|
|
355
|
+
function ed25519HexFromGAddress(trimmed) {
|
|
356
|
+
try {
|
|
357
|
+
const raw = StrKey4.decodeEd25519PublicKey(trimmed);
|
|
358
|
+
return Buffer7.from(raw).toString("hex");
|
|
359
|
+
} catch {
|
|
360
|
+
return void 0;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function ed25519HexFromMuxedAddress(trimmed) {
|
|
364
|
+
try {
|
|
365
|
+
const raw = StrKey4.decodeMed25519PublicKey(trimmed);
|
|
366
|
+
if (raw.length === MUXED_ACCOUNT_ID_BYTE_LENGTH + ED25519_PUBLIC_KEY_BYTE_LENGTH) {
|
|
367
|
+
return raw.subarray(MUXED_ACCOUNT_ID_BYTE_LENGTH).toString("hex");
|
|
368
|
+
}
|
|
369
|
+
if (raw.length === ED25519_PUBLIC_KEY_BYTE_LENGTH) {
|
|
370
|
+
return raw.toString("hex");
|
|
371
|
+
}
|
|
372
|
+
return void 0;
|
|
373
|
+
} catch {
|
|
374
|
+
return void 0;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
function ed25519PublicKeyHexFromStellarAccount(address) {
|
|
378
|
+
const trimmed = address.trim();
|
|
379
|
+
const fromG = ed25519HexFromGAddress(trimmed);
|
|
380
|
+
if (fromG !== void 0) {
|
|
381
|
+
return fromG;
|
|
382
|
+
}
|
|
383
|
+
const fromMuxed = ed25519HexFromMuxedAddress(trimmed);
|
|
384
|
+
if (fromMuxed !== void 0) {
|
|
385
|
+
return fromMuxed;
|
|
386
|
+
}
|
|
387
|
+
throw new Error("Invalid destination Stellar address");
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// src/transact/encoding/ephemeral-key.ts
|
|
391
|
+
var HEX_64_RE = /^[\da-f]{64}$/iu;
|
|
392
|
+
function normalizeCoordinate(value) {
|
|
393
|
+
const hex = value.trim().replace(/^0x/iu, "").toLowerCase();
|
|
394
|
+
if (!HEX_64_RE.test(hex)) {
|
|
395
|
+
throw new Error("Ephemeral key coordinate must be a 32-byte hex string.");
|
|
396
|
+
}
|
|
397
|
+
return hex;
|
|
398
|
+
}
|
|
399
|
+
function parseEphemeralKeyString(input) {
|
|
400
|
+
const [xRaw, yRaw, extra] = input.split(":");
|
|
401
|
+
if (!xRaw || !yRaw || extra !== void 0) {
|
|
402
|
+
throw new Error(
|
|
403
|
+
'Ephemeral key must be a string in "xHex:yHex" format (32-byte hex each).'
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
return {
|
|
407
|
+
xHex: normalizeCoordinate(xRaw),
|
|
408
|
+
yHex: normalizeCoordinate(yRaw)
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// src/transact/proofs/withdraw/helpers.ts
|
|
413
|
+
function destinationWithdrawFrAndScalar(parameters) {
|
|
414
|
+
const pkHex = ed25519PublicKeyHexFromStellarAccount(
|
|
415
|
+
parameters.destinationStellarAddress
|
|
416
|
+
);
|
|
417
|
+
const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals2(pkHex);
|
|
418
|
+
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
419
|
+
parameters.privKeyScalarHex
|
|
420
|
+
);
|
|
421
|
+
return { hi, lo, privKeyScalar };
|
|
422
|
+
}
|
|
423
|
+
function buildWithdrawPublicInput(parameters) {
|
|
424
|
+
const { hi, lo, privKeyScalar } = destinationWithdrawFrAndScalar({
|
|
425
|
+
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
426
|
+
privKeyScalarHex: parameters.privKeyScalarHex
|
|
427
|
+
});
|
|
428
|
+
return withTokenAddressPublicInputs(
|
|
429
|
+
{
|
|
430
|
+
stateRoot: parameters.stateRoot,
|
|
431
|
+
withdrawAddressHi: hi,
|
|
432
|
+
withdrawAddressLo: lo,
|
|
433
|
+
privKeyScalar
|
|
434
|
+
},
|
|
435
|
+
parameters.tokenAddress
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
async function resolveWithdrawChangeDeposits(parameters) {
|
|
439
|
+
if (parameters.changeStroops <= ZERO_STROOPS) {
|
|
440
|
+
return { deposits: ["dummy", "dummy"] };
|
|
441
|
+
}
|
|
442
|
+
const stpl1 = parameters.changePrivateAddressStpl1?.trim() ?? "";
|
|
443
|
+
if (!stpl1) {
|
|
444
|
+
throw new Error(
|
|
445
|
+
"Private address is required to return the unused balance to the pool (partial withdraw)"
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
const slot = await parameters.buildAlignedDepositSlot({
|
|
449
|
+
privateAddressStpl1: stpl1,
|
|
450
|
+
amountStroops: parameters.changeStroops,
|
|
451
|
+
tokenAddress: parameters.tokenAddress
|
|
452
|
+
});
|
|
453
|
+
return {
|
|
454
|
+
deposits: [slot.deposit, "dummy"],
|
|
455
|
+
changeCoin: {
|
|
456
|
+
commitment_hex: slot.commitment_hex,
|
|
457
|
+
coin: slot.coin,
|
|
458
|
+
depositScalarHex: slot.depositScalarHex,
|
|
459
|
+
precommitementHex: slot.precommitementHex
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
function validateDualWithdrawAmounts(withdrawAmountStroops, totalNotes, changePrivateAddressStpl1) {
|
|
464
|
+
if (withdrawAmountStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
465
|
+
throw new Error("Withdraw amount must be positive");
|
|
466
|
+
}
|
|
467
|
+
if (withdrawAmountStroops > totalNotes) {
|
|
468
|
+
throw new Error("Withdraw amount exceeds combined note value");
|
|
469
|
+
}
|
|
470
|
+
const changeStroops = totalNotes - withdrawAmountStroops;
|
|
471
|
+
requireChangeRecipientWhenPartial(changeStroops, changePrivateAddressStpl1);
|
|
472
|
+
return changeStroops;
|
|
473
|
+
}
|
|
474
|
+
function buildDualWithdrawPublicInput(parameters) {
|
|
475
|
+
return buildWithdrawPublicInput({
|
|
476
|
+
stateRoot: parameters.stateRoot,
|
|
477
|
+
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
478
|
+
privKeyScalarHex: parameters.privKeyScalarHex,
|
|
479
|
+
tokenAddress: parameters.tokenAddress
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
async function prepareDualWithdrawProofInputs(parameters) {
|
|
483
|
+
const totalNotes = BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value);
|
|
484
|
+
const changeStroops = validateDualWithdrawAmounts(
|
|
485
|
+
parameters.withdrawAmountStroops,
|
|
486
|
+
totalNotes,
|
|
487
|
+
parameters.changePrivateAddressStpl1
|
|
488
|
+
);
|
|
489
|
+
const { legA, legB } = dualWithdrawLegsWithSharedRoot({
|
|
490
|
+
sdk: parameters.sdk,
|
|
491
|
+
coinA: parameters.coinA,
|
|
492
|
+
coinB: parameters.coinB,
|
|
493
|
+
state: parameters.state,
|
|
494
|
+
ephemeralA: parseEphemeralKeyString(parameters.ephemeralAKey),
|
|
495
|
+
ephemeralB: parseEphemeralKeyString(parameters.ephemeralBKey),
|
|
496
|
+
applicationId: parameters.applicationId
|
|
497
|
+
});
|
|
498
|
+
const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
|
|
499
|
+
changeStroops,
|
|
500
|
+
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
501
|
+
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
502
|
+
tokenAddress: parameters.tokenAddress
|
|
503
|
+
});
|
|
504
|
+
const publicInput = buildDualWithdrawPublicInput({
|
|
505
|
+
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
506
|
+
privKeyScalarHex: parameters.privKeyScalarHex,
|
|
507
|
+
tokenAddress: parameters.tokenAddress,
|
|
508
|
+
stateRoot: legA.witness.stateRoot
|
|
509
|
+
});
|
|
510
|
+
const audit = buildPoolTransactionAuditParameters({
|
|
511
|
+
applicationId: parameters.applicationId,
|
|
512
|
+
...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
|
|
513
|
+
});
|
|
514
|
+
return {
|
|
515
|
+
publicInput,
|
|
516
|
+
audit,
|
|
517
|
+
withdrawLegs: [legA.withdrawObject, legB.withdrawObject],
|
|
518
|
+
deposits,
|
|
519
|
+
...changeCoin ? { changeCoin } : {}
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// src/transact/proofs/withdraw/transact-proof.ts
|
|
524
|
+
function validateSingleWithdrawAmounts(withdrawAmountStroops, noteStroops) {
|
|
525
|
+
if (withdrawAmountStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
526
|
+
throw new Error("Withdraw amount must be positive");
|
|
527
|
+
}
|
|
528
|
+
if (withdrawAmountStroops > noteStroops) {
|
|
529
|
+
throw new Error("Withdraw amount exceeds note value");
|
|
530
|
+
}
|
|
531
|
+
return noteStroops - withdrawAmountStroops;
|
|
532
|
+
}
|
|
533
|
+
async function proveSingleWithdrawTransaction(parameters) {
|
|
534
|
+
return parameters.sdk.proveTransaction(
|
|
535
|
+
parameters.publicInput,
|
|
536
|
+
buildPublicWithdrawLegs(
|
|
537
|
+
parameters.tokenAddress,
|
|
538
|
+
parameters.withdrawAmountStroops.toString()
|
|
539
|
+
),
|
|
540
|
+
[parameters.primaryWithdraw, "dummy"],
|
|
541
|
+
parameters.deposits,
|
|
542
|
+
parameters.audit
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
function buildPrimaryWithdrawForCoin(parameters) {
|
|
546
|
+
const ephemeralPoint = parseEphemeralKeyString(parameters.depositorEphemeralKey);
|
|
547
|
+
const witness = parameters.sdk.buildWithdrawMerkleWitness(
|
|
548
|
+
parameters.coin,
|
|
549
|
+
parameters.state
|
|
550
|
+
);
|
|
551
|
+
const primaryWithdraw = withdrawObjectFromMerkleWitness2(
|
|
552
|
+
witness,
|
|
553
|
+
leafEphemeralCoords(ephemeralPoint.xHex, ephemeralPoint.yHex),
|
|
554
|
+
parameters.applicationId
|
|
555
|
+
);
|
|
556
|
+
return { witness, primaryWithdraw };
|
|
557
|
+
}
|
|
558
|
+
async function prepareSingleWithdrawProofInputs(parameters) {
|
|
559
|
+
const noteStroops = BigInt(parameters.coin.value);
|
|
560
|
+
const changeStroops = validateSingleWithdrawAmounts(
|
|
561
|
+
parameters.withdrawAmountStroops,
|
|
562
|
+
noteStroops
|
|
563
|
+
);
|
|
564
|
+
const { witness, primaryWithdraw } = buildPrimaryWithdrawForCoin(parameters);
|
|
565
|
+
const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
|
|
566
|
+
changeStroops,
|
|
567
|
+
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
568
|
+
buildAlignedDepositSlot: parameters.buildAlignedDepositSlot,
|
|
569
|
+
tokenAddress: parameters.tokenAddress
|
|
570
|
+
});
|
|
571
|
+
const publicInput = buildWithdrawPublicInput({
|
|
572
|
+
stateRoot: witness.stateRoot,
|
|
573
|
+
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
574
|
+
privKeyScalarHex: parameters.privKeyScalarHex,
|
|
575
|
+
tokenAddress: parameters.tokenAddress
|
|
576
|
+
});
|
|
577
|
+
const audit = buildPoolTransactionAuditParameters({
|
|
578
|
+
applicationId: parameters.applicationId,
|
|
579
|
+
...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
|
|
580
|
+
});
|
|
581
|
+
return {
|
|
582
|
+
primaryWithdraw,
|
|
583
|
+
deposits,
|
|
584
|
+
changeCoin,
|
|
585
|
+
publicInput,
|
|
586
|
+
audit
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
async function proveWithdrawTransact(parameters) {
|
|
590
|
+
const { primaryWithdraw, deposits, changeCoin, publicInput, audit } = await prepareSingleWithdrawProofInputs(parameters);
|
|
591
|
+
const proof = await proveSingleWithdrawTransaction({
|
|
592
|
+
sdk: parameters.sdk,
|
|
593
|
+
publicInput,
|
|
594
|
+
audit,
|
|
595
|
+
primaryWithdraw,
|
|
596
|
+
deposits,
|
|
597
|
+
tokenAddress: parameters.tokenAddress,
|
|
598
|
+
withdrawAmountStroops: parameters.withdrawAmountStroops
|
|
599
|
+
});
|
|
600
|
+
return {
|
|
601
|
+
...proof,
|
|
602
|
+
applicationIdsPlaintext: [
|
|
603
|
+
parameters.applicationId,
|
|
604
|
+
"0",
|
|
605
|
+
changeCoin ? parameters.applicationId : "0",
|
|
606
|
+
"0"
|
|
607
|
+
],
|
|
608
|
+
...changeCoin ? { changeCoin } : {}
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
async function proveWithdrawTransactDual(parameters) {
|
|
612
|
+
const { publicInput, audit, withdrawLegs, deposits, changeCoin } = await prepareDualWithdrawProofInputs(parameters);
|
|
613
|
+
const proof = await parameters.sdk.proveTransaction(
|
|
614
|
+
publicInput,
|
|
615
|
+
buildPublicWithdrawLegs(
|
|
616
|
+
parameters.tokenAddress,
|
|
617
|
+
parameters.withdrawAmountStroops.toString()
|
|
618
|
+
),
|
|
619
|
+
withdrawLegs,
|
|
620
|
+
deposits,
|
|
621
|
+
audit
|
|
622
|
+
);
|
|
623
|
+
return {
|
|
624
|
+
...proof,
|
|
625
|
+
applicationIdsPlaintext: [
|
|
626
|
+
audit.applicationId,
|
|
627
|
+
audit.applicationId,
|
|
628
|
+
changeCoin ? audit.applicationId : "0",
|
|
629
|
+
"0"
|
|
630
|
+
],
|
|
631
|
+
...changeCoin ? { changeCoin } : {}
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// src/transact/pool/service.ts
|
|
636
|
+
import "buffer";
|
|
637
|
+
import { PrivacyPoolSDK as PrivacyPoolSdkClass } from "@auditable/privacy-pool-zk-sdk";
|
|
638
|
+
|
|
639
|
+
// src/transact/pool/aligned-deposit.ts
|
|
640
|
+
import { PrivacyPoolSDK, scalarHexToFrDecimal } from "@auditable/privacy-pool-zk-sdk";
|
|
641
|
+
var SAMPLE_SCALAR_ATTEMPTS = 10;
|
|
642
|
+
function sampleValidDepositScalarHex() {
|
|
643
|
+
for (let index = 0; index < SAMPLE_SCALAR_ATTEMPTS; index++) {
|
|
644
|
+
const candidate = PrivacyPoolSDK.generateRandomScalarHex32();
|
|
645
|
+
try {
|
|
646
|
+
scalarHexToFrDecimal(candidate);
|
|
647
|
+
return candidate;
|
|
648
|
+
} catch {
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
throw new Error("could not sample valid depositor ephemeral scalar");
|
|
653
|
+
}
|
|
654
|
+
async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
|
|
655
|
+
const privateAddressPoint = decodePrivateAddress(parameters.privateAddressStpl1);
|
|
656
|
+
const scalarHex = sampleValidDepositScalarHex();
|
|
657
|
+
const shared = sdk.ecdhSharedKey(
|
|
658
|
+
scalarHex,
|
|
659
|
+
privateAddressPoint.x,
|
|
660
|
+
privateAddressPoint.y
|
|
661
|
+
);
|
|
662
|
+
const [assetHi, assetLo] = tokenAddressToAssetLeg(parameters.tokenAddress);
|
|
663
|
+
const resolvedApplicationId = resolvePoolApplicationId(applicationId);
|
|
664
|
+
const generated = sdk.generateCoinForDepositWithSharedHex(
|
|
665
|
+
scalarHex,
|
|
666
|
+
shared.x,
|
|
667
|
+
shared.y,
|
|
668
|
+
parameters.amountStroops,
|
|
669
|
+
assetHi,
|
|
670
|
+
assetLo,
|
|
671
|
+
resolvedApplicationId
|
|
672
|
+
);
|
|
673
|
+
const recipientPublicKeys = recipientPublicKeysDecimalFromPrivateAddress(
|
|
674
|
+
parameters.privateAddressStpl1
|
|
675
|
+
);
|
|
676
|
+
const deposit = {
|
|
677
|
+
value: generated.coin.value,
|
|
678
|
+
nullifier: generated.coin.nullifier,
|
|
679
|
+
ephemeralKeyScalar: scalarHexToFrDecimal(scalarHex),
|
|
680
|
+
asset: [generated.coin.asset_hi, generated.coin.asset_lo],
|
|
681
|
+
applicationId: resolvedApplicationId,
|
|
682
|
+
recipientPublicKeys
|
|
683
|
+
};
|
|
684
|
+
return {
|
|
685
|
+
deposit,
|
|
686
|
+
commitment_hex: generated.commitment_hex,
|
|
687
|
+
coin: generated.coin,
|
|
688
|
+
depositScalarHex: scalarHex,
|
|
689
|
+
precommitementHex: generated.precommitement_hex
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// src/transact/pool/service.ts
|
|
694
|
+
var PrivacyPoolService = class {
|
|
695
|
+
constructor(assets, applicationId, auditPublicKey) {
|
|
696
|
+
this.assets = assets;
|
|
697
|
+
this.applicationId = applicationId;
|
|
698
|
+
this.auditPublicKey = auditPublicKey;
|
|
699
|
+
}
|
|
700
|
+
assets;
|
|
701
|
+
applicationId;
|
|
702
|
+
auditPublicKey;
|
|
703
|
+
sdk = void 0;
|
|
704
|
+
initPromise = void 0;
|
|
705
|
+
async ensureInit() {
|
|
706
|
+
if (this.sdk) {
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
if (this.initPromise) {
|
|
710
|
+
return this.initPromise;
|
|
711
|
+
}
|
|
712
|
+
this.initPromise = (async () => {
|
|
713
|
+
if (!this.assets) {
|
|
714
|
+
throw new Error(
|
|
715
|
+
"PrivacyPoolService requires browser ZK assets before initialization."
|
|
716
|
+
);
|
|
717
|
+
}
|
|
718
|
+
this.sdk = await PrivacyPoolSdkClass.init({
|
|
719
|
+
wasmBinary: this.assets.sdkWasm,
|
|
720
|
+
circuitWasm: this.assets.circuitWasm,
|
|
721
|
+
zkey: this.assets.provingKey
|
|
722
|
+
});
|
|
723
|
+
})();
|
|
724
|
+
return this.initPromise;
|
|
725
|
+
}
|
|
726
|
+
async getInitializedSdk() {
|
|
727
|
+
await this.ensureInit();
|
|
728
|
+
if (!this.sdk) {
|
|
729
|
+
throw new Error("SDK not initialized");
|
|
730
|
+
}
|
|
731
|
+
return this.sdk;
|
|
732
|
+
}
|
|
733
|
+
getAuditPublicKey() {
|
|
734
|
+
return this.auditPublicKey;
|
|
735
|
+
}
|
|
736
|
+
getApplicationId() {
|
|
737
|
+
return resolvePoolApplicationId(this.applicationId);
|
|
738
|
+
}
|
|
739
|
+
async generatePrivateAddressFromStellarSignature(signature) {
|
|
740
|
+
await this.ensureInit();
|
|
741
|
+
if (!this.sdk) {
|
|
742
|
+
throw new Error("SDK not initialized");
|
|
743
|
+
}
|
|
744
|
+
return privateAddressSdk(this.sdk).generatePrivateAddressFromStellarSignature(
|
|
745
|
+
signature
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
async sharedSecretX(recipientScalarHex, ephemeralKeyEncoded) {
|
|
749
|
+
await this.ensureInit();
|
|
750
|
+
if (!this.sdk) {
|
|
751
|
+
throw new Error("SDK not initialized");
|
|
752
|
+
}
|
|
753
|
+
const ephemeralKey = decodeDecodedEphemeralKey(ephemeralKeyEncoded);
|
|
754
|
+
const shared = this.sdk.sharedSecretFromRecipientPreimage({
|
|
755
|
+
recipientScalar: recipientScalarHex,
|
|
756
|
+
ephemeralKey
|
|
757
|
+
});
|
|
758
|
+
return shared.x;
|
|
759
|
+
}
|
|
760
|
+
async buildAlignedDepositSlot(parameters) {
|
|
761
|
+
const sdk = await this.getInitializedSdk();
|
|
762
|
+
return buildAlignedDepositSlotForSdk(sdk, this.getApplicationId(), parameters);
|
|
763
|
+
}
|
|
764
|
+
async createAlignedShieldCoinData(parameters) {
|
|
765
|
+
const { commitment_hex, coin, depositScalarHex, precommitementHex } = await this.buildAlignedDepositSlot(parameters);
|
|
766
|
+
return { commitment_hex, coin, depositScalarHex, precommitementHex };
|
|
767
|
+
}
|
|
768
|
+
async prepareDepositTransactProof(parameters) {
|
|
769
|
+
const sdk = await this.getInitializedSdk();
|
|
770
|
+
const stateRoot = merkleRootBufferToFrDecimal(parameters.merkleRootBytes);
|
|
771
|
+
const recipientPublicKeys = recipientPublicKeysDecimalFromPrivateAddress(
|
|
772
|
+
parameters.privateAddressStpl1
|
|
773
|
+
);
|
|
774
|
+
const applicationId = this.getApplicationId();
|
|
775
|
+
const audit = buildPoolTransactionAuditParameters({
|
|
776
|
+
applicationId,
|
|
777
|
+
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {}
|
|
778
|
+
});
|
|
779
|
+
const deposit = {
|
|
780
|
+
value: parameters.coin.value,
|
|
781
|
+
nullifier: parameters.coin.nullifier,
|
|
782
|
+
ephemeralKeyScalar: scalarHexToFrDecimal2(parameters.depositScalarHex),
|
|
783
|
+
asset: [parameters.coin.asset_hi, parameters.coin.asset_lo],
|
|
784
|
+
applicationId,
|
|
785
|
+
recipientPublicKeys
|
|
786
|
+
};
|
|
787
|
+
const publicInput = withTokenAddressPublicInputs(
|
|
788
|
+
{
|
|
789
|
+
stateRoot,
|
|
790
|
+
withdrawAddressHi: "0",
|
|
791
|
+
withdrawAddressLo: "0",
|
|
792
|
+
privKeyScalar: randomFrDecimal253()
|
|
793
|
+
},
|
|
794
|
+
parameters.tokenAddress
|
|
795
|
+
);
|
|
796
|
+
const proof = await sdk.proveTransaction(
|
|
797
|
+
publicInput,
|
|
798
|
+
buildPublicDepositLegs(parameters.tokenAddress, parameters.coin.value),
|
|
799
|
+
["dummy", "dummy"],
|
|
800
|
+
[deposit, "dummy"],
|
|
801
|
+
audit
|
|
802
|
+
);
|
|
803
|
+
const applicationIdsPlaintext = [
|
|
804
|
+
"0",
|
|
805
|
+
"0",
|
|
806
|
+
applicationId,
|
|
807
|
+
"0"
|
|
808
|
+
];
|
|
809
|
+
return { ...proof, applicationIdsPlaintext };
|
|
810
|
+
}
|
|
811
|
+
async calculateNullifierHash(nullifier) {
|
|
812
|
+
const sdk = await this.getInitializedSdk();
|
|
813
|
+
return sdk.calculateNullifierHash(nullifier);
|
|
814
|
+
}
|
|
815
|
+
async prepareWithdrawTransactProof(parameters) {
|
|
816
|
+
await this.ensureInit();
|
|
817
|
+
if (!this.sdk) {
|
|
818
|
+
throw new Error("SDK not initialized");
|
|
819
|
+
}
|
|
820
|
+
return proveWithdrawTransact({
|
|
821
|
+
sdk: this.sdk,
|
|
822
|
+
applicationId: this.getApplicationId(),
|
|
823
|
+
buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
|
|
824
|
+
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
|
|
825
|
+
...parameters
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
async prepareWithdrawTransactProofDual(parameters) {
|
|
829
|
+
await this.ensureInit();
|
|
830
|
+
if (!this.sdk) {
|
|
831
|
+
throw new Error("SDK not initialized");
|
|
832
|
+
}
|
|
833
|
+
return proveWithdrawTransactDual({
|
|
834
|
+
sdk: this.sdk,
|
|
835
|
+
applicationId: this.getApplicationId(),
|
|
836
|
+
buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
|
|
837
|
+
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
|
|
838
|
+
coinA: parameters.coinA,
|
|
839
|
+
coinB: parameters.coinB,
|
|
840
|
+
state: parameters.state,
|
|
841
|
+
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
842
|
+
privKeyScalarHex: parameters.privKeyScalarHex,
|
|
843
|
+
ephemeralAKey: parameters.depositorEphemeralAKey,
|
|
844
|
+
ephemeralBKey: parameters.depositorEphemeralBKey,
|
|
845
|
+
withdrawAmountStroops: parameters.withdrawAmountStroops,
|
|
846
|
+
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
847
|
+
tokenAddress: parameters.tokenAddress
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
// src/transact/pool/singleton.ts
|
|
853
|
+
function createPrivacyPoolService(input) {
|
|
854
|
+
return new PrivacyPoolService(
|
|
855
|
+
input?.assets,
|
|
856
|
+
input?.applicationId,
|
|
857
|
+
input?.auditPublicKey
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
var configuredPrivacyPoolService;
|
|
861
|
+
function configurePrivacyPoolService(service) {
|
|
862
|
+
configuredPrivacyPoolService = service;
|
|
863
|
+
}
|
|
864
|
+
function getPrivacyPoolService() {
|
|
865
|
+
if (!configuredPrivacyPoolService) {
|
|
866
|
+
throw new Error(
|
|
867
|
+
"PrivacyPoolService is not configured. Call configurePrivacyPoolService first."
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
return configuredPrivacyPoolService;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// src/transact/assets/load-browser.ts
|
|
874
|
+
async function loadStellarBrowserAssets(input) {
|
|
875
|
+
const cacheKey = input.cacheBust ? `?v=${Date.now()}` : "";
|
|
876
|
+
const [sdkWasm, circuitWasm, provingKey] = await Promise.all([
|
|
877
|
+
fetch(`${input.sdkWasmUrl}${cacheKey}`).then((response) => response.arrayBuffer()),
|
|
878
|
+
fetch(input.circuitWasmUrl).then((response) => response.arrayBuffer()),
|
|
879
|
+
fetch(input.provingKeyUrl).then((response) => response.arrayBuffer())
|
|
880
|
+
]);
|
|
881
|
+
return { sdkWasm, circuitWasm, provingKey };
|
|
882
|
+
}
|
|
883
|
+
async function loadDefaultStellarBrowserAssets(options) {
|
|
884
|
+
await import("@auditable/privacy-pool-zk-sdk");
|
|
885
|
+
const sdkWasmUrl = new URL("@auditable/privacy-pool-zk-sdk/sdk.wasm", import.meta.url).href;
|
|
886
|
+
const circuitWasmUrl = new URL(
|
|
887
|
+
"@auditable/privacy-pool-zk-sdk/witness.wasm",
|
|
888
|
+
import.meta.url
|
|
889
|
+
).href;
|
|
890
|
+
const provingKeyUrl = new URL(
|
|
891
|
+
"@auditable/privacy-pool-zk-sdk/main.zkey",
|
|
892
|
+
import.meta.url
|
|
893
|
+
).href;
|
|
894
|
+
return loadStellarBrowserAssets({
|
|
895
|
+
sdkWasmUrl,
|
|
896
|
+
circuitWasmUrl,
|
|
897
|
+
provingKeyUrl,
|
|
898
|
+
...options?.cacheBust ? { cacheBust: true } : {}
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// src/transact/onboarding/build-payload.ts
|
|
903
|
+
import { Buffer as Buffer9 } from "buffer";
|
|
904
|
+
import { PrivacyPoolSDK as PrivacyPoolSDK4 } from "@auditable/privacy-pool-zk-sdk";
|
|
905
|
+
|
|
906
|
+
// src/transact/encoding/fr-decimal-to-bytes.ts
|
|
907
|
+
var BN254_SCALAR_MOD = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
908
|
+
var FIELD_BYTE_LENGTH = 32;
|
|
909
|
+
var BYTE_MASK = 0xffn;
|
|
910
|
+
var BITS_PER_BYTE = 8n;
|
|
911
|
+
function frDecimalToPaddedBytes32(decimal) {
|
|
912
|
+
let value = BigInt(decimal.trim());
|
|
913
|
+
value = (value % BN254_SCALAR_MOD + BN254_SCALAR_MOD) % BN254_SCALAR_MOD;
|
|
914
|
+
const bytes = Buffer.alloc(FIELD_BYTE_LENGTH);
|
|
915
|
+
for (let index = FIELD_BYTE_LENGTH - 1; index >= 0; index -= 1) {
|
|
916
|
+
bytes[index] = Number(value & BYTE_MASK);
|
|
917
|
+
value >>= BITS_PER_BYTE;
|
|
918
|
+
}
|
|
919
|
+
return bytes;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
// src/transact/onboarding/recipient.ts
|
|
923
|
+
import { PrivacyPoolSDK as PrivacyPoolSDK3 } from "@auditable/privacy-pool-zk-sdk";
|
|
924
|
+
var COORDINATE_HEX_LENGTH = 64;
|
|
925
|
+
async function generateTemporaryRecipientPrivateAddress() {
|
|
926
|
+
await getPrivacyPoolService().getInitializedSdk();
|
|
927
|
+
const temporaryScalarHex = PrivacyPoolSDK3.generateRandomScalarHex32();
|
|
928
|
+
const sdk = await getPrivacyPoolService().getInitializedSdk();
|
|
929
|
+
const point = sdk.ecdhEphemeralPublicKeyFromScalarHex(temporaryScalarHex);
|
|
930
|
+
const publicKeyXHex = point.x.padStart(COORDINATE_HEX_LENGTH, "0");
|
|
931
|
+
const publicKeyYHex = point.y.padStart(COORDINATE_HEX_LENGTH, "0");
|
|
932
|
+
return {
|
|
933
|
+
temporaryScalarHex,
|
|
934
|
+
temporaryPrivateAddressStpl1: encodePrivateAddressFromHexCoordinates(
|
|
935
|
+
publicKeyXHex,
|
|
936
|
+
publicKeyYHex
|
|
937
|
+
)
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
// src/transact/onboarding/build-payload.ts
|
|
942
|
+
var COORDINATE_HEX_LENGTH2 = 64;
|
|
943
|
+
function noneOptionalRegistration() {
|
|
944
|
+
return { tag: "None", values: void 0 };
|
|
945
|
+
}
|
|
946
|
+
function coinToPlaintextNote(coin) {
|
|
947
|
+
const [assetHi, assetLo] = tokenAddressToAssetLeg(coin.tokenAddress);
|
|
948
|
+
return {
|
|
949
|
+
asset_hi: frDecimalToPaddedBytes32(assetHi),
|
|
950
|
+
asset_lo: frDecimalToPaddedBytes32(assetLo),
|
|
951
|
+
deposited_ephemeral_scalar: void 0,
|
|
952
|
+
nullifier: frDecimalToPaddedBytes32(coin.nullifier),
|
|
953
|
+
secret: frDecimalToPaddedBytes32(coin.secret),
|
|
954
|
+
value: BigInt(coin.value)
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
async function generateRandomDepositScalarHex() {
|
|
958
|
+
await getPrivacyPoolService().getInitializedSdk();
|
|
959
|
+
return PrivacyPoolSDK4.generateRandomScalarHex32();
|
|
960
|
+
}
|
|
961
|
+
function buildOnboardingPayload(parameters) {
|
|
962
|
+
const notes = parameters.recipientNotes.map((coin) => coinToPlaintextNote(coin));
|
|
963
|
+
const temporaryDecoded = decodePrivateAddress(
|
|
964
|
+
parameters.temporaryKey.temporaryPrivateAddressStpl1.trim()
|
|
965
|
+
);
|
|
966
|
+
let privateAddressRegistration = noneOptionalRegistration();
|
|
967
|
+
if (parameters.permanentPrivateAddressStpl1?.trim()) {
|
|
968
|
+
const decoded = decodePrivateAddress(
|
|
969
|
+
parameters.permanentPrivateAddressStpl1.trim()
|
|
970
|
+
);
|
|
971
|
+
const registration = {
|
|
972
|
+
owner: parameters.ownerStellarAddress.trim(),
|
|
973
|
+
public_key_x: Buffer9.from(decoded.x.padStart(COORDINATE_HEX_LENGTH2, "0"), "hex"),
|
|
974
|
+
public_key_y: Buffer9.from(decoded.y.padStart(COORDINATE_HEX_LENGTH2, "0"), "hex")
|
|
975
|
+
};
|
|
976
|
+
privateAddressRegistration = { tag: "Some", values: [registration] };
|
|
977
|
+
}
|
|
978
|
+
return {
|
|
979
|
+
owner: parameters.ownerStellarAddress.trim(),
|
|
980
|
+
temp_public_key_x: Buffer9.from(
|
|
981
|
+
temporaryDecoded.x.padStart(COORDINATE_HEX_LENGTH2, "0"),
|
|
982
|
+
"hex"
|
|
983
|
+
),
|
|
984
|
+
temp_public_key_y: Buffer9.from(
|
|
985
|
+
temporaryDecoded.y.padStart(COORDINATE_HEX_LENGTH2, "0"),
|
|
986
|
+
"hex"
|
|
987
|
+
),
|
|
988
|
+
encrypted_private_key: Buffer9.from(
|
|
989
|
+
parameters.temporaryKey.temporaryScalarHex,
|
|
990
|
+
"utf8"
|
|
991
|
+
),
|
|
992
|
+
notes: { notes },
|
|
993
|
+
private_address_registration: privateAddressRegistration
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
async function buildTransferOnboardingAtExecute(input) {
|
|
997
|
+
return buildOnboardingPayload({
|
|
998
|
+
ownerStellarAddress: input.ownerStellarAddress,
|
|
999
|
+
temporaryKey: {
|
|
1000
|
+
temporaryScalarHex: input.temporaryRecipientKey.temporaryScalarHex,
|
|
1001
|
+
temporaryPrivateAddressStpl1: input.temporaryRecipientKey.temporaryPrivateAddressStpl1
|
|
1002
|
+
},
|
|
1003
|
+
recipientNotes: [input.recipientNote]
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// src/transact/kyt/inspect-error.ts
|
|
1008
|
+
var KytInspectError = class extends Error {
|
|
1009
|
+
reasonCode;
|
|
1010
|
+
decisionId;
|
|
1011
|
+
detailAddress;
|
|
1012
|
+
constructor(parameters) {
|
|
1013
|
+
super(parameters.message);
|
|
1014
|
+
this.name = "KytInspectError";
|
|
1015
|
+
this.reasonCode = parameters.reasonCode;
|
|
1016
|
+
if (parameters.decisionId !== void 0) {
|
|
1017
|
+
this.decisionId = parameters.decisionId;
|
|
1018
|
+
}
|
|
1019
|
+
if (parameters.detailAddress !== void 0) {
|
|
1020
|
+
this.detailAddress = parameters.detailAddress;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
};
|
|
1024
|
+
function parseKytReasonCode(reasonCode) {
|
|
1025
|
+
const separatorIndex = reasonCode.indexOf(":");
|
|
1026
|
+
if (separatorIndex === -1) {
|
|
1027
|
+
return { code: reasonCode };
|
|
1028
|
+
}
|
|
1029
|
+
return {
|
|
1030
|
+
code: reasonCode.slice(0, separatorIndex),
|
|
1031
|
+
address: reasonCode.slice(separatorIndex + 1)
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
// src/contracts/contract-context.ts
|
|
1036
|
+
function requireContractContext(environment) {
|
|
1037
|
+
if (!environment || !("contractContext" in environment)) {
|
|
1038
|
+
throw new Error("Contract context is not configured on the transact environment.");
|
|
1039
|
+
}
|
|
1040
|
+
const resolved = environment;
|
|
1041
|
+
return resolved.contractContext;
|
|
1042
|
+
}
|
|
1043
|
+
function readPoolClientFactory(environment) {
|
|
1044
|
+
return requireContractContext(environment).createPoolClient;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
// src/transact/kyt/passage/poll.ts
|
|
1048
|
+
import "@stellar/stellar-sdk";
|
|
1049
|
+
var KYT_REGISTER_MAX_POLLS = 60;
|
|
1050
|
+
var KYT_REGISTER_POLL_INTERVAL_MS = 1e3;
|
|
1051
|
+
function parseLedgerSequence(value) {
|
|
1052
|
+
if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0) {
|
|
1053
|
+
return value;
|
|
1054
|
+
}
|
|
1055
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
1056
|
+
const parsed = Number(value);
|
|
1057
|
+
if (Number.isSafeInteger(parsed) && parsed >= 0) {
|
|
1058
|
+
return parsed;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
return void 0;
|
|
1062
|
+
}
|
|
1063
|
+
async function fetchCurrentLedger(sorobanRpcUrl) {
|
|
1064
|
+
const response = await fetch(sorobanRpcUrl, {
|
|
1065
|
+
method: "POST",
|
|
1066
|
+
headers: { "content-type": "application/json" },
|
|
1067
|
+
body: JSON.stringify({
|
|
1068
|
+
jsonrpc: "2.0",
|
|
1069
|
+
id: 1,
|
|
1070
|
+
method: "getLatestLedger"
|
|
1071
|
+
})
|
|
1072
|
+
});
|
|
1073
|
+
const body = await response.json();
|
|
1074
|
+
if (!response.ok || body.error) {
|
|
1075
|
+
const details = body.error?.message ?? response.statusText;
|
|
1076
|
+
throw new Error(`Failed to fetch current ledger from Soroban RPC: ${details}`);
|
|
1077
|
+
}
|
|
1078
|
+
const sequence = parseLedgerSequence(body.result?.sequence) ?? parseLedgerSequence(body.result?.latestLedger);
|
|
1079
|
+
if (sequence === void 0) {
|
|
1080
|
+
throw new Error("Failed to fetch current ledger from Soroban RPC: invalid payload");
|
|
1081
|
+
}
|
|
1082
|
+
return sequence;
|
|
1083
|
+
}
|
|
1084
|
+
async function waitForKytRegistration(parameters) {
|
|
1085
|
+
for (let attempt = 0; attempt < KYT_REGISTER_MAX_POLLS; attempt += 1) {
|
|
1086
|
+
const response = await parameters.server.getTransaction(parameters.hash);
|
|
1087
|
+
if (response.status === "SUCCESS") {
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
if (response.status === "FAILED") {
|
|
1091
|
+
throw new Error("KYT passage registration failed on-chain");
|
|
1092
|
+
}
|
|
1093
|
+
await new Promise((resolve) => {
|
|
1094
|
+
setTimeout(resolve, KYT_REGISTER_POLL_INTERVAL_MS);
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
throw new Error("KYT passage registration was not confirmed in time");
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
// src/transact/kyt/passage/submit.ts
|
|
1101
|
+
import { Buffer as Buffer10 } from "buffer";
|
|
1102
|
+
import { Operation, TransactionBuilder, rpc as rpc2, xdr } from "@stellar/stellar-sdk";
|
|
1103
|
+
var KYT_REGISTER_FEE_STROOPS = "1000000";
|
|
1104
|
+
var KYT_REGISTER_TIMEOUT_SECONDS = 300;
|
|
1105
|
+
function passageIdToScValue(passageId) {
|
|
1106
|
+
return xdr.ScVal.scvBytes(Buffer10.from(passageId.replace(/^0x/, ""), "hex"));
|
|
1107
|
+
}
|
|
1108
|
+
function approvalSignatureToBytes(signature) {
|
|
1109
|
+
const clean = signature.trim();
|
|
1110
|
+
return /^(0x)?[0-9a-fA-F]{128}$/.test(clean) ? Buffer10.from(clean.replace(/^0x/i, ""), "hex") : Buffer10.from(clean, "base64");
|
|
1111
|
+
}
|
|
1112
|
+
function signatureToScValue(signature) {
|
|
1113
|
+
const bytes = approvalSignatureToBytes(signature);
|
|
1114
|
+
return xdr.ScVal.scvBytes(bytes);
|
|
1115
|
+
}
|
|
1116
|
+
async function registerKytPassage(parameters) {
|
|
1117
|
+
const signTransaction = parameters.transactEnvironment.signTransaction;
|
|
1118
|
+
if (!signTransaction) {
|
|
1119
|
+
throw new Error(
|
|
1120
|
+
"KYT passage registration requires a wallet signTransaction adapter."
|
|
1121
|
+
);
|
|
1122
|
+
}
|
|
1123
|
+
const kytRegistry = parameters.transactEnvironment.kyt.kytPassageRegistryContract;
|
|
1124
|
+
const server = new rpc2.Server(parameters.sorobanRpcUrl, { allowHttp: true });
|
|
1125
|
+
const sourceAccount = await server.getAccount(parameters.owner);
|
|
1126
|
+
const transaction = new TransactionBuilder(sourceAccount, {
|
|
1127
|
+
fee: KYT_REGISTER_FEE_STROOPS,
|
|
1128
|
+
networkPassphrase: parameters.networkPassphrase
|
|
1129
|
+
}).addOperation(
|
|
1130
|
+
Operation.invokeContractFunction({
|
|
1131
|
+
contract: kytRegistry,
|
|
1132
|
+
function: "register_passage",
|
|
1133
|
+
args: [
|
|
1134
|
+
passageIdToScValue(parameters.approval.passageId),
|
|
1135
|
+
xdr.ScVal.scvU32(parameters.approval.expiresAtLedger),
|
|
1136
|
+
signatureToScValue(parameters.approval.signature)
|
|
1137
|
+
]
|
|
1138
|
+
})
|
|
1139
|
+
).setTimeout(KYT_REGISTER_TIMEOUT_SECONDS).build();
|
|
1140
|
+
const preparedTransaction = await server.prepareTransaction(transaction);
|
|
1141
|
+
const { signedTxXdr } = await signTransaction({
|
|
1142
|
+
xdr: preparedTransaction.toXDR(),
|
|
1143
|
+
networkPassphrase: parameters.networkPassphrase,
|
|
1144
|
+
address: parameters.owner
|
|
1145
|
+
});
|
|
1146
|
+
const signedTransaction = TransactionBuilder.fromXDR(
|
|
1147
|
+
signedTxXdr,
|
|
1148
|
+
parameters.networkPassphrase
|
|
1149
|
+
);
|
|
1150
|
+
const result = await server.sendTransaction(signedTransaction);
|
|
1151
|
+
const status = String(result.status);
|
|
1152
|
+
if (status !== "PENDING" && status !== "SUCCESS") {
|
|
1153
|
+
throw new Error(`KYT passage registration submit failed: ${status}`);
|
|
1154
|
+
}
|
|
1155
|
+
await waitForKytRegistration({ server, hash: result.hash });
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// src/transact/kyt/passage/inspect.ts
|
|
1159
|
+
function buildApplicationIdHints(applicationId) {
|
|
1160
|
+
return [applicationId, applicationId, applicationId, applicationId];
|
|
1161
|
+
}
|
|
1162
|
+
function buildNonce() {
|
|
1163
|
+
return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}`;
|
|
1164
|
+
}
|
|
1165
|
+
function kytJsonReplacer(_key, value) {
|
|
1166
|
+
if (typeof value === "bigint") {
|
|
1167
|
+
return value.toString();
|
|
1168
|
+
}
|
|
1169
|
+
return value;
|
|
1170
|
+
}
|
|
1171
|
+
async function parseInspectResponse(response) {
|
|
1172
|
+
const body = await response.json();
|
|
1173
|
+
if (!response.ok) {
|
|
1174
|
+
throw new Error(`KYT inspect failed: ${JSON.stringify(body)}`);
|
|
1175
|
+
}
|
|
1176
|
+
return body;
|
|
1177
|
+
}
|
|
1178
|
+
function throwKytInspectRejected(body) {
|
|
1179
|
+
const reasonCode = body.reasonCode ?? body.status;
|
|
1180
|
+
const parsed = parseKytReasonCode(reasonCode);
|
|
1181
|
+
throw new KytInspectError({
|
|
1182
|
+
message: reasonCode,
|
|
1183
|
+
reasonCode,
|
|
1184
|
+
...body.decisionId ? { decisionId: body.decisionId } : {},
|
|
1185
|
+
...parsed.address ? { detailAddress: parsed.address } : {}
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
async function requestKytPassageForPoolInteraction(input) {
|
|
1189
|
+
const applicationId = resolvePoolApplicationId(
|
|
1190
|
+
input.transactEnvironment.network.applicationId
|
|
1191
|
+
);
|
|
1192
|
+
const applicationIdsPlaintext = input.applicationIdsPlaintext ?? buildApplicationIdHints(applicationId);
|
|
1193
|
+
const kytRegistry = input.transactEnvironment.kyt.kytPassageRegistryContract;
|
|
1194
|
+
const currentLedger = await fetchCurrentLedger(input.sorobanRpcUrl);
|
|
1195
|
+
const response = await fetch(
|
|
1196
|
+
`${input.transactEnvironment.kyt.apiBaseUrl}/kyt/passages/inspect`,
|
|
1197
|
+
{
|
|
1198
|
+
method: "POST",
|
|
1199
|
+
headers: { "content-type": "application/json" },
|
|
1200
|
+
body: JSON.stringify(
|
|
1201
|
+
{
|
|
1202
|
+
owner: input.owner,
|
|
1203
|
+
poolContract: input.poolContract,
|
|
1204
|
+
kytRegistry,
|
|
1205
|
+
proofBytes: input.proofHex,
|
|
1206
|
+
publicSignalsBytes: input.publicHex,
|
|
1207
|
+
applicationIdsPlaintext,
|
|
1208
|
+
decryptedAuditSlots: input.decryptedAuditSlots,
|
|
1209
|
+
onboarding: input.onboarding,
|
|
1210
|
+
nonce: buildNonce(),
|
|
1211
|
+
currentLedger
|
|
1212
|
+
},
|
|
1213
|
+
kytJsonReplacer
|
|
1214
|
+
)
|
|
1215
|
+
}
|
|
1216
|
+
);
|
|
1217
|
+
const body = await parseInspectResponse(response);
|
|
1218
|
+
if (body.status !== "approved") {
|
|
1219
|
+
throwKytInspectRejected(body);
|
|
1220
|
+
}
|
|
1221
|
+
if (input.transactEnvironment.kyt.registerPassageOnChain) {
|
|
1222
|
+
await registerKytPassage({
|
|
1223
|
+
approval: body,
|
|
1224
|
+
owner: input.owner,
|
|
1225
|
+
networkPassphrase: input.networkPassphrase,
|
|
1226
|
+
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
1227
|
+
transactEnvironment: input.transactEnvironment
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
return body;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
// src/transact/submit/ttl-preflight.ts
|
|
1234
|
+
function getNested(source, path) {
|
|
1235
|
+
let cursor = source;
|
|
1236
|
+
for (const key of path) {
|
|
1237
|
+
if (typeof cursor !== "object" || cursor === null) {
|
|
1238
|
+
return void 0;
|
|
1239
|
+
}
|
|
1240
|
+
cursor = cursor[key];
|
|
1241
|
+
}
|
|
1242
|
+
return cursor;
|
|
1243
|
+
}
|
|
1244
|
+
function needsRestore(simulation) {
|
|
1245
|
+
const restorePreamble = getNested(simulation, ["restorePreamble"]) ?? getNested(simulation, ["result", "restorePreamble"]) ?? getNested(simulation, ["simulation", "restorePreamble"]);
|
|
1246
|
+
if (restorePreamble && typeof restorePreamble === "object") {
|
|
1247
|
+
return true;
|
|
1248
|
+
}
|
|
1249
|
+
const isSimulationError = getNested(simulation, ["error"]);
|
|
1250
|
+
if (typeof isSimulationError === "string") {
|
|
1251
|
+
return isSimulationError.toLowerCase().includes("restore");
|
|
1252
|
+
}
|
|
1253
|
+
return false;
|
|
1254
|
+
}
|
|
1255
|
+
async function maybeCallFunction(target, methodName) {
|
|
1256
|
+
if (typeof target !== "object" || target === null) {
|
|
1257
|
+
return void 0;
|
|
1258
|
+
}
|
|
1259
|
+
const method = target[methodName];
|
|
1260
|
+
if (typeof method !== "function") {
|
|
1261
|
+
return void 0;
|
|
1262
|
+
}
|
|
1263
|
+
return method();
|
|
1264
|
+
}
|
|
1265
|
+
async function runTtlPreflight(assembledTransaction) {
|
|
1266
|
+
const simulation = await maybeCallFunction(assembledTransaction, "simulate");
|
|
1267
|
+
if (!simulation || !needsRestore(simulation)) {
|
|
1268
|
+
return;
|
|
1269
|
+
}
|
|
1270
|
+
const restoreResult = await maybeCallFunction(assembledTransaction, "restoreFootprint") ?? await maybeCallFunction(assembledTransaction, "restore");
|
|
1271
|
+
if (!restoreResult) {
|
|
1272
|
+
return;
|
|
1273
|
+
}
|
|
1274
|
+
await maybeCallFunction(assembledTransaction, "simulate");
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
// src/transact/submit/pool-transact.ts
|
|
1278
|
+
import { Buffer as Buffer11 } from "buffer";
|
|
1279
|
+
async function submitPoolTransact(parameters) {
|
|
1280
|
+
const assembledTransaction = await parameters.contractClient.transact({
|
|
1281
|
+
from: parameters.from,
|
|
1282
|
+
proof_bytes: Buffer11.from(parameters.proofHex.replace(/^0x/iu, ""), "hex"),
|
|
1283
|
+
pub_signals_bytes: Buffer11.from(parameters.publicHex.replace(/^0x/iu, ""), "hex"),
|
|
1284
|
+
onboarding: parameters.onboarding,
|
|
1285
|
+
kyt_authorization: {
|
|
1286
|
+
expiration_ledger: parameters.approval.expiresAtLedger,
|
|
1287
|
+
signature: approvalSignatureToBytes(parameters.approval.signature)
|
|
1288
|
+
}
|
|
1289
|
+
});
|
|
1290
|
+
await runTtlPreflight(assembledTransaction);
|
|
1291
|
+
const sentTransaction = await assembledTransaction.signAndSend();
|
|
1292
|
+
const transactionHash = sentTransaction.sendTransactionResponse?.hash ?? "";
|
|
1293
|
+
if (!transactionHash) {
|
|
1294
|
+
throw new Error("Transaction failed");
|
|
1295
|
+
}
|
|
1296
|
+
return transactionHash;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
// src/transact/submit/soroban-deposit.ts
|
|
1300
|
+
async function submitSorobanDeposit(input) {
|
|
1301
|
+
const poolClient = readPoolClientFactory(input.transactEnvironment)({
|
|
1302
|
+
contractId: input.contractId,
|
|
1303
|
+
walletPublicKey: input.walletPublicKey,
|
|
1304
|
+
networkPassphrase: input.networkPassphrase,
|
|
1305
|
+
sorobanRpcUrl: input.sorobanRpcUrl
|
|
1306
|
+
});
|
|
1307
|
+
const merkleTx = await poolClient.get_merkle_root();
|
|
1308
|
+
const merkleRootBuffer = merkleTx.result;
|
|
1309
|
+
const { applicationIdsPlaintext, proof_hex, public_hex } = await input.privacyPoolService.prepareDepositTransactProof({
|
|
1310
|
+
privateAddressStpl1: input.privateAddressStpl1,
|
|
1311
|
+
coin: input.coin,
|
|
1312
|
+
depositScalarHex: input.depositScalarHex,
|
|
1313
|
+
merkleRootBytes: merkleRootBuffer,
|
|
1314
|
+
tokenAddress: input.tokenAddress
|
|
1315
|
+
});
|
|
1316
|
+
const approval = await requestKytPassageForPoolInteraction({
|
|
1317
|
+
owner: input.walletPublicKey,
|
|
1318
|
+
poolContract: input.contractId,
|
|
1319
|
+
proofHex: proof_hex,
|
|
1320
|
+
publicHex: public_hex,
|
|
1321
|
+
applicationIdsPlaintext,
|
|
1322
|
+
networkPassphrase: input.networkPassphrase,
|
|
1323
|
+
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
1324
|
+
transactEnvironment: input.transactEnvironment
|
|
1325
|
+
});
|
|
1326
|
+
return submitPoolTransact({
|
|
1327
|
+
contractClient: poolClient,
|
|
1328
|
+
from: input.walletPublicKey,
|
|
1329
|
+
proofHex: proof_hex,
|
|
1330
|
+
publicHex: public_hex,
|
|
1331
|
+
approval
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
// src/transact/submit/soroban-confidential-transfer.ts
|
|
1336
|
+
async function submitSorobanConfidentialTransfer(input) {
|
|
1337
|
+
const poolClient = readPoolClientFactory(input.transactEnvironment)({
|
|
1338
|
+
contractId: input.contractId,
|
|
1339
|
+
walletPublicKey: input.walletPublicKey,
|
|
1340
|
+
networkPassphrase: input.networkPassphrase,
|
|
1341
|
+
sorobanRpcUrl: input.sorobanRpcUrl
|
|
1342
|
+
});
|
|
1343
|
+
const approval = await requestKytPassageForPoolInteraction({
|
|
1344
|
+
owner: input.walletPublicKey,
|
|
1345
|
+
poolContract: input.contractId,
|
|
1346
|
+
proofHex: input.proofHex,
|
|
1347
|
+
publicHex: input.publicHex,
|
|
1348
|
+
...input.onboarding ? { onboarding: input.onboarding } : {},
|
|
1349
|
+
...input.applicationIdsPlaintext ? { applicationIdsPlaintext: input.applicationIdsPlaintext } : {},
|
|
1350
|
+
networkPassphrase: input.networkPassphrase,
|
|
1351
|
+
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
1352
|
+
transactEnvironment: input.transactEnvironment
|
|
1353
|
+
});
|
|
1354
|
+
return submitPoolTransact({
|
|
1355
|
+
contractClient: poolClient,
|
|
1356
|
+
from: input.walletPublicKey,
|
|
1357
|
+
proofHex: input.proofHex,
|
|
1358
|
+
publicHex: input.publicHex,
|
|
1359
|
+
...input.onboarding ? { onboarding: input.onboarding } : {},
|
|
1360
|
+
approval
|
|
1361
|
+
});
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
// src/transact/onboarding/recipient-change-deposits.ts
|
|
1365
|
+
async function buildPaddingDepositPair(recipientPrivateAddressStpl1, tokenAddress, recipientDeposit) {
|
|
1366
|
+
const paddingSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
|
|
1367
|
+
privateAddressStpl1: recipientPrivateAddressStpl1,
|
|
1368
|
+
amountStroops: ZERO_STROOPS,
|
|
1369
|
+
tokenAddress
|
|
1370
|
+
});
|
|
1371
|
+
return [recipientDeposit, paddingSlot.deposit];
|
|
1372
|
+
}
|
|
1373
|
+
async function buildChangeDepositPair(parameters) {
|
|
1374
|
+
const changeSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
|
|
1375
|
+
privateAddressStpl1: parameters.selfPrivateAddressStpl1ForChange.trim(),
|
|
1376
|
+
amountStroops: parameters.changeStroops,
|
|
1377
|
+
tokenAddress: parameters.tokenAddress
|
|
1378
|
+
});
|
|
1379
|
+
return {
|
|
1380
|
+
deposits: [parameters.recipientDeposit, changeSlot.deposit],
|
|
1381
|
+
changeCoin: {
|
|
1382
|
+
commitment_hex: changeSlot.commitment_hex,
|
|
1383
|
+
coin: changeSlot.coin,
|
|
1384
|
+
depositScalarHex: changeSlot.depositScalarHex,
|
|
1385
|
+
precommitementHex: changeSlot.precommitementHex
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
async function buildRecipientAndOptionalChangeDeposits(parameters) {
|
|
1390
|
+
const recipientPrivateAddress = parameters.recipientPrivateAddressStpl1.trim();
|
|
1391
|
+
const recipientSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
|
|
1392
|
+
privateAddressStpl1: recipientPrivateAddress,
|
|
1393
|
+
amountStroops: parameters.transferStroops,
|
|
1394
|
+
tokenAddress: parameters.tokenAddress
|
|
1395
|
+
});
|
|
1396
|
+
if (parameters.changeStroops <= ZERO_STROOPS) {
|
|
1397
|
+
return {
|
|
1398
|
+
recipientSlot,
|
|
1399
|
+
deposits: await buildPaddingDepositPair(
|
|
1400
|
+
recipientPrivateAddress,
|
|
1401
|
+
parameters.tokenAddress,
|
|
1402
|
+
recipientSlot.deposit
|
|
1403
|
+
)
|
|
1404
|
+
};
|
|
1405
|
+
}
|
|
1406
|
+
const changeResult = await buildChangeDepositPair({
|
|
1407
|
+
recipientPrivateAddressStpl1: recipientPrivateAddress,
|
|
1408
|
+
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1409
|
+
changeStroops: parameters.changeStroops,
|
|
1410
|
+
tokenAddress: parameters.tokenAddress,
|
|
1411
|
+
recipientDeposit: recipientSlot.deposit
|
|
1412
|
+
});
|
|
1413
|
+
return {
|
|
1414
|
+
recipientSlot,
|
|
1415
|
+
deposits: changeResult.deposits,
|
|
1416
|
+
changeCoin: changeResult.changeCoin
|
|
1417
|
+
};
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
// src/transact/proofs/confidential/shared.ts
|
|
1421
|
+
function generatedOutputCoinFromSlot(slot) {
|
|
1422
|
+
return {
|
|
1423
|
+
commitment_hex: slot.commitment_hex,
|
|
1424
|
+
coin: slot.coin,
|
|
1425
|
+
depositScalarHex: slot.depositScalarHex,
|
|
1426
|
+
precommitementHex: slot.precommitementHex
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
async function buildTransferDepositsAndPublicInput(parameters) {
|
|
1430
|
+
const { recipientSlot, deposits, changeCoin } = await buildRecipientAndOptionalChangeDeposits({
|
|
1431
|
+
recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
|
|
1432
|
+
transferStroops: parameters.transferStroops,
|
|
1433
|
+
changeStroops: parameters.changeStroops,
|
|
1434
|
+
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1435
|
+
tokenAddress: parameters.tokenAddress
|
|
1436
|
+
});
|
|
1437
|
+
const publicInput = withTokenAddressPublicInputs(
|
|
1438
|
+
{
|
|
1439
|
+
stateRoot: parameters.stateRoot,
|
|
1440
|
+
withdrawAddressHi: parameters.withdrawAddressHi,
|
|
1441
|
+
withdrawAddressLo: parameters.withdrawAddressLo,
|
|
1442
|
+
privKeyScalar: parameters.privKeyScalar
|
|
1443
|
+
},
|
|
1444
|
+
parameters.tokenAddress
|
|
1445
|
+
);
|
|
1446
|
+
return {
|
|
1447
|
+
recipientSlot,
|
|
1448
|
+
deposits,
|
|
1449
|
+
...changeCoin ? { changeCoin } : {},
|
|
1450
|
+
publicInput
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
async function buildSenderTransferDepositsAndPublicInput(parameters) {
|
|
1454
|
+
const { hi, lo, privKeyScalar } = senderWithdrawFrAndScalar({
|
|
1455
|
+
senderGAddress: parameters.senderGAddress,
|
|
1456
|
+
senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex
|
|
1457
|
+
});
|
|
1458
|
+
return buildTransferDepositsAndPublicInput({
|
|
1459
|
+
recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
|
|
1460
|
+
transferStroops: parameters.transferStroops,
|
|
1461
|
+
changeStroops: parameters.changeStroops,
|
|
1462
|
+
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1463
|
+
tokenAddress: parameters.tokenAddress,
|
|
1464
|
+
stateRoot: parameters.stateRoot,
|
|
1465
|
+
withdrawAddressHi: hi,
|
|
1466
|
+
withdrawAddressLo: lo,
|
|
1467
|
+
privKeyScalar
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
// src/transact/proofs/confidential/dual.ts
|
|
1472
|
+
function buildDualTransferApplicationIds(applicationId, changeCoin) {
|
|
1473
|
+
return [
|
|
1474
|
+
applicationId,
|
|
1475
|
+
applicationId,
|
|
1476
|
+
applicationId,
|
|
1477
|
+
changeCoin ? applicationId : "0"
|
|
1478
|
+
];
|
|
1479
|
+
}
|
|
1480
|
+
async function proveDualConfidentialTransfer(parameters) {
|
|
1481
|
+
const audit = buildPoolTransactionAuditParameters({
|
|
1482
|
+
applicationId: parameters.applicationId,
|
|
1483
|
+
...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
|
|
1484
|
+
});
|
|
1485
|
+
return parameters.sdk.proveTransaction(
|
|
1486
|
+
parameters.publicInput,
|
|
1487
|
+
buildZeroPublicLegs(),
|
|
1488
|
+
[parameters.legA.withdrawObject, parameters.legB.withdrawObject],
|
|
1489
|
+
parameters.deposits,
|
|
1490
|
+
audit
|
|
1491
|
+
);
|
|
1492
|
+
}
|
|
1493
|
+
async function buildDualTransferProofContext(parameters, applicationId, sdk) {
|
|
1494
|
+
const totalNotes = BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value);
|
|
1495
|
+
const changeStroops = changeStroopsAfterDualTransfer(
|
|
1496
|
+
parameters.transferStroops,
|
|
1497
|
+
totalNotes
|
|
1498
|
+
);
|
|
1499
|
+
requireChangeRecipientWhenPartial(
|
|
1500
|
+
changeStroops,
|
|
1501
|
+
parameters.selfPrivateAddressStpl1ForChange
|
|
1502
|
+
);
|
|
1503
|
+
const { legA, legB } = dualWithdrawLegsWithSharedRoot({
|
|
1504
|
+
sdk,
|
|
1505
|
+
coinA: parameters.coinA,
|
|
1506
|
+
coinB: parameters.coinB,
|
|
1507
|
+
state: parameters.state,
|
|
1508
|
+
ephemeralA: parseEphemeralKeyString(parameters.ephemeralAKey),
|
|
1509
|
+
ephemeralB: parseEphemeralKeyString(parameters.ephemeralBKey),
|
|
1510
|
+
applicationId
|
|
1511
|
+
});
|
|
1512
|
+
const transferInputs = await buildSenderTransferDepositsAndPublicInput({
|
|
1513
|
+
senderGAddress: parameters.senderGAddress,
|
|
1514
|
+
senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex,
|
|
1515
|
+
recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
|
|
1516
|
+
transferStroops: parameters.transferStroops,
|
|
1517
|
+
changeStroops,
|
|
1518
|
+
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1519
|
+
tokenAddress: parameters.tokenAddress,
|
|
1520
|
+
stateRoot: legA.witness.stateRoot
|
|
1521
|
+
});
|
|
1522
|
+
return { legA, legB, applicationId, ...transferInputs };
|
|
1523
|
+
}
|
|
1524
|
+
async function prepareConfidentialTransferProofDual(parameters) {
|
|
1525
|
+
const poolService = getPrivacyPoolService();
|
|
1526
|
+
const sdk = await poolService.getInitializedSdk();
|
|
1527
|
+
const applicationId = poolService.getApplicationId();
|
|
1528
|
+
const { legA, legB, recipientSlot, deposits, changeCoin, publicInput } = await buildDualTransferProofContext(parameters, applicationId, sdk);
|
|
1529
|
+
const auditPublicKey = poolService.getAuditPublicKey();
|
|
1530
|
+
const proof = await (auditPublicKey ? proveDualConfidentialTransfer({
|
|
1531
|
+
sdk,
|
|
1532
|
+
publicInput,
|
|
1533
|
+
legA,
|
|
1534
|
+
legB,
|
|
1535
|
+
deposits,
|
|
1536
|
+
applicationId,
|
|
1537
|
+
auditPublicKey
|
|
1538
|
+
}) : proveDualConfidentialTransfer({
|
|
1539
|
+
sdk,
|
|
1540
|
+
publicInput,
|
|
1541
|
+
legA,
|
|
1542
|
+
legB,
|
|
1543
|
+
deposits,
|
|
1544
|
+
applicationId
|
|
1545
|
+
}));
|
|
1546
|
+
return {
|
|
1547
|
+
...proof,
|
|
1548
|
+
applicationIdsPlaintext: buildDualTransferApplicationIds(applicationId, changeCoin),
|
|
1549
|
+
recipientCoin: generatedOutputCoinFromSlot(recipientSlot),
|
|
1550
|
+
...changeCoin ? { changeCoin } : {}
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
// src/transact/proofs/confidential/single.ts
|
|
1555
|
+
function validateSingleCoinTransferAmounts(transferStroops, noteStroops, selfPrivateAddressStpl1ForChange) {
|
|
1556
|
+
if (transferStroops < MIN_CONFIDENTIAL_TRANSFER_STROOPS) {
|
|
1557
|
+
throw new Error("Transfer amount must be positive");
|
|
1558
|
+
}
|
|
1559
|
+
if (transferStroops > noteStroops) {
|
|
1560
|
+
throw new Error("Transfer amount exceeds note value");
|
|
1561
|
+
}
|
|
1562
|
+
const changeStroops = noteStroops - transferStroops;
|
|
1563
|
+
requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange);
|
|
1564
|
+
return changeStroops;
|
|
1565
|
+
}
|
|
1566
|
+
function buildSingleTransferApplicationIds(applicationId, changeCoin) {
|
|
1567
|
+
return [applicationId, "0", applicationId, changeCoin ? applicationId : "0"];
|
|
1568
|
+
}
|
|
1569
|
+
function buildTransferAuditParameters(parameters) {
|
|
1570
|
+
const auditPublicKey = parameters.poolService.getAuditPublicKey();
|
|
1571
|
+
return buildPoolTransactionAuditParameters({
|
|
1572
|
+
applicationId: parameters.applicationId,
|
|
1573
|
+
...auditPublicKey ? { auditPublicKey } : {}
|
|
1574
|
+
});
|
|
1575
|
+
}
|
|
1576
|
+
async function proveTransaction(parameters) {
|
|
1577
|
+
return parameters.sdk.proveTransaction(
|
|
1578
|
+
parameters.publicInput,
|
|
1579
|
+
buildZeroPublicLegs(),
|
|
1580
|
+
[parameters.withdrawObject, "dummy"],
|
|
1581
|
+
parameters.deposits,
|
|
1582
|
+
parameters.audit
|
|
1583
|
+
);
|
|
1584
|
+
}
|
|
1585
|
+
async function buildTransferProofInputs(parameters) {
|
|
1586
|
+
const changeStroops = validateSingleCoinTransferAmounts(
|
|
1587
|
+
parameters.input.transferStroops,
|
|
1588
|
+
parameters.noteStroops,
|
|
1589
|
+
parameters.input.selfPrivateAddressStpl1ForChange
|
|
1590
|
+
);
|
|
1591
|
+
const { witness, withdrawObject } = withdrawWitnessForCoin({
|
|
1592
|
+
sdk: parameters.sdk,
|
|
1593
|
+
coin: parameters.input.coin,
|
|
1594
|
+
state: parameters.input.state,
|
|
1595
|
+
...parseEphemeralKeyString(parameters.input.depositorEphemeralKey),
|
|
1596
|
+
applicationId: parameters.applicationId
|
|
1597
|
+
});
|
|
1598
|
+
const { recipientSlot, deposits, changeCoin, publicInput } = await buildSenderTransferDepositsAndPublicInput({
|
|
1599
|
+
senderGAddress: parameters.input.senderGAddress,
|
|
1600
|
+
senderPrivKeyScalarHex: parameters.input.senderPrivKeyScalarHex,
|
|
1601
|
+
recipientPrivateAddressStpl1: parameters.input.recipientPrivateAddressStpl1,
|
|
1602
|
+
transferStroops: parameters.input.transferStroops,
|
|
1603
|
+
changeStroops,
|
|
1604
|
+
selfPrivateAddressStpl1ForChange: parameters.input.selfPrivateAddressStpl1ForChange,
|
|
1605
|
+
tokenAddress: parameters.input.tokenAddress,
|
|
1606
|
+
stateRoot: witness.stateRoot
|
|
1607
|
+
});
|
|
1608
|
+
return {
|
|
1609
|
+
witness,
|
|
1610
|
+
withdrawObject,
|
|
1611
|
+
recipientSlot,
|
|
1612
|
+
deposits,
|
|
1613
|
+
changeCoin,
|
|
1614
|
+
publicInput
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
async function prepareConfidentialTransferProof(parameters) {
|
|
1618
|
+
const poolService = getPrivacyPoolService();
|
|
1619
|
+
const sdk = await poolService.getInitializedSdk();
|
|
1620
|
+
const applicationId = poolService.getApplicationId();
|
|
1621
|
+
const noteStroops = BigInt(parameters.coin.value);
|
|
1622
|
+
const { withdrawObject, recipientSlot, deposits, changeCoin, publicInput } = await buildTransferProofInputs({
|
|
1623
|
+
sdk,
|
|
1624
|
+
applicationId,
|
|
1625
|
+
input: parameters,
|
|
1626
|
+
noteStroops
|
|
1627
|
+
});
|
|
1628
|
+
const audit = buildTransferAuditParameters({ poolService, applicationId });
|
|
1629
|
+
const proof = await proveTransaction({
|
|
1630
|
+
sdk,
|
|
1631
|
+
publicInput,
|
|
1632
|
+
withdrawObject,
|
|
1633
|
+
deposits,
|
|
1634
|
+
audit
|
|
1635
|
+
});
|
|
1636
|
+
return {
|
|
1637
|
+
...proof,
|
|
1638
|
+
applicationIdsPlaintext: buildSingleTransferApplicationIds(
|
|
1639
|
+
applicationId,
|
|
1640
|
+
changeCoin
|
|
1641
|
+
),
|
|
1642
|
+
recipientCoin: generatedOutputCoinFromSlot(recipientSlot),
|
|
1643
|
+
...changeCoin ? { changeCoin } : {}
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
// src/transact/merkle/fetch-contract.ts
|
|
1648
|
+
import { Buffer as Buffer13 } from "buffer";
|
|
1649
|
+
|
|
1650
|
+
// src/transact/merkle/encoding.ts
|
|
1651
|
+
import "buffer";
|
|
1652
|
+
var FR_ORDER = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n;
|
|
1653
|
+
function bufferToDecimal(buf) {
|
|
1654
|
+
const hex = buf.toString("hex");
|
|
1655
|
+
const bigintFromHex = BigInt(`0x${hex}`);
|
|
1656
|
+
const reduced = bigintFromHex % FR_ORDER;
|
|
1657
|
+
return reduced.toString();
|
|
1658
|
+
}
|
|
1659
|
+
function commitmentsBuffersToDecimal(buffers) {
|
|
1660
|
+
return buffers.map((bufferRow) => bufferToDecimal(bufferRow));
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
// src/transact/merkle/state-port.ts
|
|
1664
|
+
function poolMerkleStateToCachedView(state) {
|
|
1665
|
+
return {
|
|
1666
|
+
commitments: state.commitments,
|
|
1667
|
+
updatedAt: state.updatedAt,
|
|
1668
|
+
merkleRootHex: state.merkleRootHex
|
|
1669
|
+
};
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
// src/transact/merkle/fetch-contract.ts
|
|
1673
|
+
function normalizeCommitmentBuffers(rawBuffers) {
|
|
1674
|
+
return rawBuffers.map(
|
|
1675
|
+
(bufferRow) => Buffer13.isBuffer(bufferRow) ? bufferRow : Buffer13.from(bufferRow)
|
|
1676
|
+
);
|
|
1677
|
+
}
|
|
1678
|
+
function mergeContractMerkleWithCache(parameters) {
|
|
1679
|
+
const cachedCount = parameters.cachedState?.commitments.length ?? 0;
|
|
1680
|
+
const shouldPreferContract = parameters.contractCount > cachedCount || !parameters.cachedState || cachedCount === 0;
|
|
1681
|
+
if (shouldPreferContract) {
|
|
1682
|
+
const updatedAt = Date.now();
|
|
1683
|
+
void parameters.poolMerkleState?.set({
|
|
1684
|
+
poolContract: parameters.poolContractId,
|
|
1685
|
+
commitments: parameters.contractCommitments,
|
|
1686
|
+
commitmentCount: parameters.contractCount,
|
|
1687
|
+
merkleRootHex: parameters.merkleRootHex,
|
|
1688
|
+
updatedAt
|
|
1689
|
+
});
|
|
1690
|
+
return {
|
|
1691
|
+
commitments: parameters.contractCommitments,
|
|
1692
|
+
updatedAt,
|
|
1693
|
+
merkleRootHex: parameters.merkleRootHex,
|
|
1694
|
+
commitmentCount: parameters.contractCount
|
|
1695
|
+
};
|
|
1696
|
+
}
|
|
1697
|
+
return {
|
|
1698
|
+
commitments: parameters.cachedState.commitments,
|
|
1699
|
+
updatedAt: parameters.cachedState.updatedAt,
|
|
1700
|
+
merkleRootHex: parameters.cachedState.merkleRootHex ?? parameters.merkleRootHex,
|
|
1701
|
+
commitmentCount: parameters.cachedState.commitments.length
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
async function readCachedPoolMerkleView(poolMerkleState, poolContractId) {
|
|
1705
|
+
if (!poolMerkleState) {
|
|
1706
|
+
return void 0;
|
|
1707
|
+
}
|
|
1708
|
+
const cached = await poolMerkleState.get(poolContractId);
|
|
1709
|
+
return cached ? poolMerkleStateToCachedView(cached) : void 0;
|
|
1710
|
+
}
|
|
1711
|
+
async function fetchAndMergeMerkleState(parameters) {
|
|
1712
|
+
const client = readPoolClientFactory(parameters.transactEnvironment)({
|
|
1713
|
+
contractId: parameters.poolContractId,
|
|
1714
|
+
walletPublicKey: parameters.walletPublicKey,
|
|
1715
|
+
networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
|
|
1716
|
+
sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
|
|
1717
|
+
});
|
|
1718
|
+
const commitmentsRead = await client.get_commitments();
|
|
1719
|
+
const rawBuffers = commitmentsRead.result;
|
|
1720
|
+
const buffers = normalizeCommitmentBuffers(rawBuffers);
|
|
1721
|
+
const contractCommitments = commitmentsBuffersToDecimal(buffers);
|
|
1722
|
+
const contractCount = contractCommitments.length;
|
|
1723
|
+
const rootRead = await client.get_merkle_root();
|
|
1724
|
+
const merkleRootBuffer = rootRead.result;
|
|
1725
|
+
const merkleRootHex = Buffer13.from(merkleRootBuffer).toString("hex");
|
|
1726
|
+
const cachedState = await readCachedPoolMerkleView(
|
|
1727
|
+
parameters.poolMerkleState,
|
|
1728
|
+
parameters.poolContractId
|
|
1729
|
+
);
|
|
1730
|
+
return mergeContractMerkleWithCache({
|
|
1731
|
+
poolContractId: parameters.poolContractId,
|
|
1732
|
+
contractCommitments,
|
|
1733
|
+
contractCount,
|
|
1734
|
+
merkleRootHex,
|
|
1735
|
+
cachedState,
|
|
1736
|
+
...parameters.poolMerkleState ? { poolMerkleState: parameters.poolMerkleState } : {}
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
async function readLeafEphemeralHex(parameters) {
|
|
1740
|
+
const cached = await parameters.leafEphemeral?.get({
|
|
1741
|
+
poolContract: parameters.poolContractId,
|
|
1742
|
+
leafIndex: parameters.leafIndex
|
|
1743
|
+
});
|
|
1744
|
+
if (cached?.xHex && cached.yHex) {
|
|
1745
|
+
return { xHex: cached.xHex, yHex: cached.yHex };
|
|
1746
|
+
}
|
|
1747
|
+
const client = readPoolClientFactory(parameters.transactEnvironment)({
|
|
1748
|
+
contractId: parameters.poolContractId,
|
|
1749
|
+
walletPublicKey: parameters.walletPublicKey,
|
|
1750
|
+
networkPassphrase: parameters.transactEnvironment.network.networkPassphrase,
|
|
1751
|
+
sorobanRpcUrl: parameters.transactEnvironment.network.rpcUrl
|
|
1752
|
+
});
|
|
1753
|
+
const read = await client.get_leaf_ephemeral({ leaf_index: parameters.leafIndex });
|
|
1754
|
+
const coords = read.result;
|
|
1755
|
+
if (!coords?.x || !coords?.y) {
|
|
1756
|
+
throw new Error("Missing leaf ephemeral key on contract");
|
|
1757
|
+
}
|
|
1758
|
+
const xHex = Buffer13.from(coords.x).toString("hex");
|
|
1759
|
+
const yHex = Buffer13.from(coords.y).toString("hex");
|
|
1760
|
+
await parameters.leafEphemeral?.set({
|
|
1761
|
+
poolContract: parameters.poolContractId,
|
|
1762
|
+
leafIndex: parameters.leafIndex,
|
|
1763
|
+
xHex,
|
|
1764
|
+
yHex,
|
|
1765
|
+
cachedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1766
|
+
});
|
|
1767
|
+
return { xHex, yHex };
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
// src/state/foundation/paths.ts
|
|
1771
|
+
var STELLAR_STATE_PATHS = {
|
|
1772
|
+
privateRecords: "$.privateRecords",
|
|
1773
|
+
pendingClaimsItems: "$.pendingClaims.items",
|
|
1774
|
+
pendingClaimsPagination: "$.pendingClaims.pagination",
|
|
1775
|
+
pendingClaimsCountByOwner: "$.pendingClaims.countByOwner",
|
|
1776
|
+
registryPrivateAddresses: "$.registry.privateAddresses",
|
|
1777
|
+
registryRegisteredAddresses: "$.registry.registeredAddresses",
|
|
1778
|
+
registryLookups: "$.registry.lookups",
|
|
1779
|
+
assets: "$.assets",
|
|
1780
|
+
assetsById: "$.assets.byId",
|
|
1781
|
+
assetsListOrder: "$.assets.listOrder",
|
|
1782
|
+
publicBalances: "$.balances.publicByOwnerAsset",
|
|
1783
|
+
poolsByContract: "$.pools.byContract",
|
|
1784
|
+
poolsLeafEphemeral: "$.pools.leafEphemeralByContractAndIndex",
|
|
1785
|
+
deliveriesIncomingById: "$.deliveries.incomingById",
|
|
1786
|
+
deliveriesSync: "$.deliveries.syncByPrivateAddressAsset",
|
|
1787
|
+
transactionsByHash: "$.transactions.byHash",
|
|
1788
|
+
walletPrivateAddressScalars: "$.wallet.privateAddressScalars",
|
|
1789
|
+
walletPrivateAddressRecords: "$.wallet.privateAddressRecords",
|
|
1790
|
+
walletDefaultPrivateAddressNonce: "$.wallet.defaultPrivateAddressNonce"
|
|
1791
|
+
};
|
|
1792
|
+
|
|
1793
|
+
// src/state/schemas/shared.ts
|
|
1794
|
+
import { z } from "zod";
|
|
1795
|
+
var pendingClaimSchema = z.object({
|
|
1796
|
+
id: z.string().min(1),
|
|
1797
|
+
owner: z.string().min(1),
|
|
1798
|
+
asset: z.string().min(1),
|
|
1799
|
+
amount: z.coerce.bigint(),
|
|
1800
|
+
createdAt: z.string().min(1),
|
|
1801
|
+
poolTxId: z.string().optional(),
|
|
1802
|
+
commitmentHex: z.string().optional(),
|
|
1803
|
+
nullifierHex: z.string().optional(),
|
|
1804
|
+
futureNullifierHashHex: z.string().optional(),
|
|
1805
|
+
assetHiHex: z.string().optional(),
|
|
1806
|
+
assetLoHex: z.string().optional(),
|
|
1807
|
+
nullifierFieldHex: z.string().optional(),
|
|
1808
|
+
secretHex: z.string().optional(),
|
|
1809
|
+
tempPublicKeyXHex: z.string().optional(),
|
|
1810
|
+
tempPublicKeyYHex: z.string().optional(),
|
|
1811
|
+
encryptedRecoveryBase64: z.string().optional(),
|
|
1812
|
+
createdAtLedger: z.number().int().optional()
|
|
1813
|
+
});
|
|
1814
|
+
var paginationSchema = z.object({
|
|
1815
|
+
total: z.number().int().nonnegative(),
|
|
1816
|
+
page: z.number().int().positive(),
|
|
1817
|
+
pageSize: z.number().int().positive(),
|
|
1818
|
+
hasMore: z.boolean()
|
|
1819
|
+
});
|
|
1820
|
+
var stellarPrivateCoinNoteSchema = z.object({
|
|
1821
|
+
value: z.string(),
|
|
1822
|
+
nullifier: z.string(),
|
|
1823
|
+
secret: z.string(),
|
|
1824
|
+
commitment: z.string(),
|
|
1825
|
+
asset_hi: z.string(),
|
|
1826
|
+
asset_lo: z.string(),
|
|
1827
|
+
application_id: z.string().optional()
|
|
1828
|
+
});
|
|
1829
|
+
var privateRecordSchema = z.object({
|
|
1830
|
+
id: z.string().min(1),
|
|
1831
|
+
owner: z.string().min(1),
|
|
1832
|
+
asset: z.string().min(1),
|
|
1833
|
+
amount: z.coerce.bigint(),
|
|
1834
|
+
consumed: z.boolean(),
|
|
1835
|
+
status: z.enum(["pending", "finalized", "spent"]).optional(),
|
|
1836
|
+
poolContract: z.string().optional(),
|
|
1837
|
+
commitmentHex: z.string().optional(),
|
|
1838
|
+
nullifierHex: z.string().optional(),
|
|
1839
|
+
amountDisplay: z.number().optional(),
|
|
1840
|
+
deliveryId: z.number().int().optional(),
|
|
1841
|
+
privateAddress: z.string().optional(),
|
|
1842
|
+
txHash: z.string().optional(),
|
|
1843
|
+
coinNote: stellarPrivateCoinNoteSchema.optional(),
|
|
1844
|
+
depositScalarHex: z.string().optional(),
|
|
1845
|
+
precommitementHex: z.string().optional()
|
|
1846
|
+
});
|
|
1847
|
+
var assetSchema = z.object({
|
|
1848
|
+
id: z.number().int(),
|
|
1849
|
+
assetId: z.string().min(1),
|
|
1850
|
+
name: z.string().min(1),
|
|
1851
|
+
logoUrl: z.string().nullable(),
|
|
1852
|
+
issuerAddress: z.string().nullable(),
|
|
1853
|
+
clientContract: z.string().nullable(),
|
|
1854
|
+
poolContracts: z.array(z.string()),
|
|
1855
|
+
poolContract: z.string().min(1),
|
|
1856
|
+
mintable: z.boolean(),
|
|
1857
|
+
mintAmount: z.string().nullable(),
|
|
1858
|
+
decimals: z.number().int().nullable().optional()
|
|
1859
|
+
});
|
|
1860
|
+
var publicBalanceSchema = z.object({
|
|
1861
|
+
owner: z.string().min(1),
|
|
1862
|
+
asset: z.string().min(1),
|
|
1863
|
+
balance: z.string(),
|
|
1864
|
+
trustlineStatus: z.enum(["active", "inactive", "none"])
|
|
1865
|
+
});
|
|
1866
|
+
var registryLookupSchema = z.object({
|
|
1867
|
+
owner: z.string().min(1),
|
|
1868
|
+
status: z.enum(["registered", "unregistered"]),
|
|
1869
|
+
privateAddressStpl1: z.string().optional(),
|
|
1870
|
+
publicKeyXHex: z.string().optional(),
|
|
1871
|
+
publicKeyYHex: z.string().optional(),
|
|
1872
|
+
updatedAtLedger: z.number().int().optional(),
|
|
1873
|
+
cachedAt: z.string().optional()
|
|
1874
|
+
});
|
|
1875
|
+
var walletPrivateAddressScalarSchema = z.object({
|
|
1876
|
+
owner: z.string().min(1),
|
|
1877
|
+
nonce: z.string().min(1),
|
|
1878
|
+
scalarHex: z.string().min(1),
|
|
1879
|
+
updatedAt: z.string().optional()
|
|
1880
|
+
});
|
|
1881
|
+
var walletPrivateAddressRecordSchema = z.object({
|
|
1882
|
+
owner: z.string().min(1),
|
|
1883
|
+
nonce: z.string().min(1),
|
|
1884
|
+
privateAddress: z.string().min(1),
|
|
1885
|
+
createdAt: z.number()
|
|
1886
|
+
});
|
|
1887
|
+
var poolMerkleStateSchema = z.object({
|
|
1888
|
+
poolContract: z.string().min(1),
|
|
1889
|
+
commitments: z.array(z.string()),
|
|
1890
|
+
commitmentCount: z.number().int().nonnegative(),
|
|
1891
|
+
merkleRootHex: z.string().min(1),
|
|
1892
|
+
updatedAt: z.number(),
|
|
1893
|
+
syncedLedger: z.number().int().optional()
|
|
1894
|
+
});
|
|
1895
|
+
var leafEphemeralSchema = z.object({
|
|
1896
|
+
poolContract: z.string().min(1),
|
|
1897
|
+
leafIndex: z.number().int().nonnegative(),
|
|
1898
|
+
xHex: z.string().min(1),
|
|
1899
|
+
yHex: z.string().min(1),
|
|
1900
|
+
cachedAt: z.string().optional()
|
|
1901
|
+
});
|
|
1902
|
+
var incomingDeliverySchema = z.object({
|
|
1903
|
+
id: z.number().int(),
|
|
1904
|
+
privateAddress: z.string().min(1),
|
|
1905
|
+
asset: z.string().min(1),
|
|
1906
|
+
ciphertextBase64: z.string().min(1),
|
|
1907
|
+
ephemeralKey: z.string().min(1),
|
|
1908
|
+
tagBase64: z.string().min(1),
|
|
1909
|
+
createdAt: z.string().min(1),
|
|
1910
|
+
processed: z.boolean().optional()
|
|
1911
|
+
});
|
|
1912
|
+
var deliverySyncStateSchema = z.object({
|
|
1913
|
+
privateAddress: z.string().min(1),
|
|
1914
|
+
asset: z.string().min(1),
|
|
1915
|
+
bloomM: z.number().int().positive(),
|
|
1916
|
+
bloomK: z.number().int().positive(),
|
|
1917
|
+
bloomBitsBase64: z.string().optional(),
|
|
1918
|
+
lastPage: z.number().int().positive().optional(),
|
|
1919
|
+
lastPolledAt: z.string().optional()
|
|
1920
|
+
});
|
|
1921
|
+
var transactionStatusSchema = z.object({
|
|
1922
|
+
txHash: z.string().min(1),
|
|
1923
|
+
status: z.enum(["pending", "success", "failed"]),
|
|
1924
|
+
ledger: z.number().int().optional(),
|
|
1925
|
+
createdAt: z.string().optional()
|
|
1926
|
+
});
|
|
1927
|
+
|
|
1928
|
+
// src/state/foundation/coerce.ts
|
|
1929
|
+
function withoutUndefinedFields(value) {
|
|
1930
|
+
const next = {};
|
|
1931
|
+
for (const [key, fieldValue] of Object.entries(value)) {
|
|
1932
|
+
if (fieldValue !== void 0) {
|
|
1933
|
+
Reflect.set(next, key, fieldValue);
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
return next;
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
// src/state/read/normalize/assets.ts
|
|
1940
|
+
function normalizeAssetsCatalog(value) {
|
|
1941
|
+
if (typeof value !== "object" || value === null) {
|
|
1942
|
+
return { byId: {}, listOrder: [] };
|
|
1943
|
+
}
|
|
1944
|
+
const record = value;
|
|
1945
|
+
const byIdRaw = record.byId;
|
|
1946
|
+
const listOrderRaw = record.listOrder;
|
|
1947
|
+
const byId = {};
|
|
1948
|
+
if (typeof byIdRaw === "object" && byIdRaw !== null) {
|
|
1949
|
+
for (const [key, entry] of Object.entries(byIdRaw)) {
|
|
1950
|
+
const parsed = assetSchema.safeParse(entry);
|
|
1951
|
+
if (parsed.success) {
|
|
1952
|
+
byId[key] = withoutUndefinedFields(parsed.data);
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
const listOrder = Array.isArray(listOrderRaw) ? listOrderRaw.filter((item) => typeof item === "string") : [];
|
|
1957
|
+
return { byId, listOrder };
|
|
1958
|
+
}
|
|
1959
|
+
function normalizeAsset(value) {
|
|
1960
|
+
const parsed = assetSchema.safeParse(value);
|
|
1961
|
+
return parsed.success ? withoutUndefinedFields(parsed.data) : void 0;
|
|
1962
|
+
}
|
|
1963
|
+
function normalizePublicBalance(value) {
|
|
1964
|
+
const parsed = publicBalanceSchema.safeParse(value);
|
|
1965
|
+
return parsed.success ? parsed.data : void 0;
|
|
1966
|
+
}
|
|
1967
|
+
function normalizePublicBalancesFromEntries(value, owner) {
|
|
1968
|
+
if (!Array.isArray(value)) {
|
|
1969
|
+
return [];
|
|
1970
|
+
}
|
|
1971
|
+
return value.map((entry) => {
|
|
1972
|
+
if (!Array.isArray(entry) || entry.length < 2) {
|
|
1973
|
+
return;
|
|
1974
|
+
}
|
|
1975
|
+
const [key, balanceValue] = entry;
|
|
1976
|
+
if (typeof key !== "string" || !key.startsWith(`${owner}:`)) {
|
|
1977
|
+
return;
|
|
1978
|
+
}
|
|
1979
|
+
return normalizePublicBalance(balanceValue);
|
|
1980
|
+
}).filter((balance) => balance !== void 0);
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
// src/state/read/normalize/claims.ts
|
|
1984
|
+
function normalizePendingClaimsState(value) {
|
|
1985
|
+
if (typeof value !== "object" || value === null) {
|
|
1986
|
+
return { items: [] };
|
|
1987
|
+
}
|
|
1988
|
+
const record = value;
|
|
1989
|
+
const items = Array.isArray(record.items) ? record.items.flatMap((item) => {
|
|
1990
|
+
const parsed = pendingClaimSchema.safeParse(item);
|
|
1991
|
+
return parsed.success ? [withoutUndefinedFields(parsed.data)] : [];
|
|
1992
|
+
}) : [];
|
|
1993
|
+
const paginationResult = paginationSchema.safeParse(record.pagination);
|
|
1994
|
+
if (paginationResult.success) {
|
|
1995
|
+
return { items, pagination: paginationResult.data };
|
|
1996
|
+
}
|
|
1997
|
+
return { items };
|
|
1998
|
+
}
|
|
1999
|
+
function normalizePendingClaimsCount(value) {
|
|
2000
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
2001
|
+
}
|
|
2002
|
+
|
|
2003
|
+
// src/state/read/normalize/deliveries.ts
|
|
2004
|
+
function normalizeIncomingDeliveries(value) {
|
|
2005
|
+
const entries = typeof value === "object" && value !== null && !Array.isArray(value) ? Object.values(value) : value;
|
|
2006
|
+
if (!Array.isArray(entries)) {
|
|
2007
|
+
return [];
|
|
2008
|
+
}
|
|
2009
|
+
return entries.flatMap((entry) => {
|
|
2010
|
+
const parsed = incomingDeliverySchema.safeParse(entry);
|
|
2011
|
+
return parsed.success ? [withoutUndefinedFields(parsed.data)] : [];
|
|
2012
|
+
});
|
|
2013
|
+
}
|
|
2014
|
+
function normalizeDeliverySyncState(value) {
|
|
2015
|
+
const parsed = deliverySyncStateSchema.safeParse(value);
|
|
2016
|
+
return parsed.success ? withoutUndefinedFields(parsed.data) : void 0;
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
// src/state/read/normalize/pool.ts
|
|
2020
|
+
function normalizePoolMerkleState(value) {
|
|
2021
|
+
const parsed = poolMerkleStateSchema.safeParse(value);
|
|
2022
|
+
return parsed.success ? withoutUndefinedFields(parsed.data) : void 0;
|
|
2023
|
+
}
|
|
2024
|
+
function normalizeLeafEphemeral(value) {
|
|
2025
|
+
const parsed = leafEphemeralSchema.safeParse(value);
|
|
2026
|
+
return parsed.success ? withoutUndefinedFields(parsed.data) : void 0;
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
// src/state/read/normalize/registry.ts
|
|
2030
|
+
function normalizeCachedPrivateAddress(value) {
|
|
2031
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2032
|
+
}
|
|
2033
|
+
function normalizeRegistryLookup(value) {
|
|
2034
|
+
const parsed = registryLookupSchema.safeParse(value);
|
|
2035
|
+
return parsed.success ? withoutUndefinedFields(parsed.data) : void 0;
|
|
2036
|
+
}
|
|
2037
|
+
function normalizeRegistryLookupFromLegacy(input) {
|
|
2038
|
+
const lookup = normalizeRegistryLookup(
|
|
2039
|
+
typeof input.registered === "object" && input.registered !== null ? input.registered : void 0
|
|
2040
|
+
);
|
|
2041
|
+
if (lookup) {
|
|
2042
|
+
return lookup;
|
|
2043
|
+
}
|
|
2044
|
+
if (input.registered === void 0 && input.privateAddress === void 0) {
|
|
2045
|
+
return void 0;
|
|
2046
|
+
}
|
|
2047
|
+
const registered2 = Boolean(input.registered);
|
|
2048
|
+
const privateAddressStpl1 = normalizeCachedPrivateAddress(input.privateAddress);
|
|
2049
|
+
if (!registered2 && privateAddressStpl1 === void 0) {
|
|
2050
|
+
return { owner: input.address, status: "unregistered" };
|
|
2051
|
+
}
|
|
2052
|
+
return withoutUndefinedFields({
|
|
2053
|
+
owner: input.address,
|
|
2054
|
+
status: registered2 ? "registered" : "unregistered",
|
|
2055
|
+
...privateAddressStpl1 === void 0 ? {} : { privateAddressStpl1 }
|
|
2056
|
+
});
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
// src/state/read/normalize/records.ts
|
|
2060
|
+
import "zod";
|
|
2061
|
+
function normalizePrivateRecords(value) {
|
|
2062
|
+
if (!Array.isArray(value)) {
|
|
2063
|
+
return [];
|
|
2064
|
+
}
|
|
2065
|
+
const records = value.flatMap((item) => {
|
|
2066
|
+
const parsed = privateRecordSchema.safeParse(item);
|
|
2067
|
+
return parsed.success ? [normalizePrivateRecordFields(parsed.data)] : [];
|
|
2068
|
+
});
|
|
2069
|
+
return deduplicatePrivateRecords(records);
|
|
2070
|
+
}
|
|
2071
|
+
function normalizeTransactionStatus(value) {
|
|
2072
|
+
const parsed = transactionStatusSchema.safeParse(value);
|
|
2073
|
+
return parsed.success ? withoutUndefinedFields(parsed.data) : void 0;
|
|
2074
|
+
}
|
|
2075
|
+
function privateRecordCommitmentKey(record) {
|
|
2076
|
+
return (record.commitmentHex?.trim() || record.coinNote?.commitment.trim() || record.id.trim()).replace(/^0x/iu, "").toLowerCase();
|
|
2077
|
+
}
|
|
2078
|
+
function normalizePrivateRecordFields(record) {
|
|
2079
|
+
const normalized = withoutUndefinedFields(record);
|
|
2080
|
+
if (!normalized.privateAddress && normalized.owner.trim().startsWith("stpl")) {
|
|
2081
|
+
return { ...normalized, privateAddress: normalized.owner.trim() };
|
|
2082
|
+
}
|
|
2083
|
+
return normalized;
|
|
2084
|
+
}
|
|
2085
|
+
function preferPrivateRecord(current, incoming, key) {
|
|
2086
|
+
if (privateRecordIdKey(incoming) === key) {
|
|
2087
|
+
return incoming;
|
|
2088
|
+
}
|
|
2089
|
+
if (privateRecordIdKey(current) === key) {
|
|
2090
|
+
return current;
|
|
2091
|
+
}
|
|
2092
|
+
return incoming;
|
|
2093
|
+
}
|
|
2094
|
+
function privateRecordIdKey(record) {
|
|
2095
|
+
return record.id.trim().replace(/^0x/iu, "").toLowerCase();
|
|
2096
|
+
}
|
|
2097
|
+
function deduplicatePrivateRecords(records) {
|
|
2098
|
+
const byCommitment = /* @__PURE__ */ new Map();
|
|
2099
|
+
for (const record of records) {
|
|
2100
|
+
const key = privateRecordCommitmentKey(record);
|
|
2101
|
+
const current = byCommitment.get(key);
|
|
2102
|
+
byCommitment.set(key, current ? preferPrivateRecord(current, record, key) : record);
|
|
2103
|
+
}
|
|
2104
|
+
return [...byCommitment.values()];
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
// src/state/read/normalize/wallet.ts
|
|
2108
|
+
function normalizeWalletPrivateAddressScalar(value) {
|
|
2109
|
+
const parsed = walletPrivateAddressScalarSchema.safeParse(value);
|
|
2110
|
+
return parsed.success ? withoutUndefinedFields(parsed.data) : void 0;
|
|
2111
|
+
}
|
|
2112
|
+
function normalizeWalletPrivateAddressRecord(value) {
|
|
2113
|
+
const parsed = walletPrivateAddressRecordSchema.safeParse(value);
|
|
2114
|
+
return parsed.success ? withoutUndefinedFields(parsed.data) : void 0;
|
|
2115
|
+
}
|
|
2116
|
+
function normalizeWalletDefaultPrivateAddressNonce(value) {
|
|
2117
|
+
return typeof value === "string" ? value.trim() || void 0 : void 0;
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
// src/state/filters/register-schemas.ts
|
|
2121
|
+
import { registerArrayFilterItemSchema } from "@arcanetech/privacy-sdk-core/state";
|
|
2122
|
+
|
|
2123
|
+
// src/state/filters/ops.ts
|
|
2124
|
+
var stellarArrayFilterSchemaKeys = {
|
|
2125
|
+
privateRecord: "privateRecord",
|
|
2126
|
+
pendingClaim: "pendingClaim"
|
|
2127
|
+
};
|
|
2128
|
+
function rejectPrivateRecordsByIds(ids) {
|
|
2129
|
+
return {
|
|
2130
|
+
opType: "arrayFilter",
|
|
2131
|
+
jsonPath: STELLAR_STATE_PATHS.privateRecords,
|
|
2132
|
+
itemSchemaKey: stellarArrayFilterSchemaKeys.privateRecord,
|
|
2133
|
+
rejectWhen: {
|
|
2134
|
+
op: "fieldIn",
|
|
2135
|
+
field: "id",
|
|
2136
|
+
values: ids
|
|
2137
|
+
}
|
|
2138
|
+
};
|
|
2139
|
+
}
|
|
2140
|
+
function rejectConsumedPrivateRecords() {
|
|
2141
|
+
return {
|
|
2142
|
+
opType: "arrayFilter",
|
|
2143
|
+
jsonPath: STELLAR_STATE_PATHS.privateRecords,
|
|
2144
|
+
itemSchemaKey: stellarArrayFilterSchemaKeys.privateRecord,
|
|
2145
|
+
rejectWhen: {
|
|
2146
|
+
op: "fieldEquals",
|
|
2147
|
+
field: "consumed",
|
|
2148
|
+
value: true
|
|
2149
|
+
}
|
|
2150
|
+
};
|
|
2151
|
+
}
|
|
2152
|
+
function rejectPendingClaimsByOwner(owner) {
|
|
2153
|
+
return {
|
|
2154
|
+
opType: "arrayFilter",
|
|
2155
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2156
|
+
itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
|
|
2157
|
+
rejectWhen: {
|
|
2158
|
+
op: "fieldEquals",
|
|
2159
|
+
field: "owner",
|
|
2160
|
+
value: owner
|
|
2161
|
+
}
|
|
2162
|
+
};
|
|
2163
|
+
}
|
|
2164
|
+
function rejectPendingClaimsByIds(ids) {
|
|
2165
|
+
return {
|
|
2166
|
+
opType: "arrayFilter",
|
|
2167
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2168
|
+
itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
|
|
2169
|
+
rejectWhen: {
|
|
2170
|
+
op: "fieldIn",
|
|
2171
|
+
field: "id",
|
|
2172
|
+
values: ids
|
|
2173
|
+
}
|
|
2174
|
+
};
|
|
2175
|
+
}
|
|
2176
|
+
function rejectPendingClaimsByOwnerAndAsset(input) {
|
|
2177
|
+
const matches = [];
|
|
2178
|
+
if (input.owner !== void 0) {
|
|
2179
|
+
matches.push({
|
|
2180
|
+
op: "fieldEquals",
|
|
2181
|
+
field: "owner",
|
|
2182
|
+
value: input.owner
|
|
2183
|
+
});
|
|
2184
|
+
}
|
|
2185
|
+
if (input.asset !== void 0) {
|
|
2186
|
+
matches.push({
|
|
2187
|
+
op: "fieldEquals",
|
|
2188
|
+
field: "asset",
|
|
2189
|
+
value: input.asset
|
|
2190
|
+
});
|
|
2191
|
+
}
|
|
2192
|
+
return {
|
|
2193
|
+
opType: "arrayFilter",
|
|
2194
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2195
|
+
itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
|
|
2196
|
+
rejectWhen: {
|
|
2197
|
+
op: "and",
|
|
2198
|
+
matches
|
|
2199
|
+
}
|
|
2200
|
+
};
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
// src/state/filters/register-schemas.ts
|
|
2204
|
+
var registered = false;
|
|
2205
|
+
function registerStellarArrayFilterSchemas() {
|
|
2206
|
+
if (registered) {
|
|
2207
|
+
return;
|
|
2208
|
+
}
|
|
2209
|
+
registerArrayFilterItemSchema(
|
|
2210
|
+
stellarArrayFilterSchemaKeys.privateRecord,
|
|
2211
|
+
privateRecordSchema
|
|
2212
|
+
);
|
|
2213
|
+
registerArrayFilterItemSchema(
|
|
2214
|
+
stellarArrayFilterSchemaKeys.pendingClaim,
|
|
2215
|
+
pendingClaimSchema
|
|
2216
|
+
);
|
|
2217
|
+
registered = true;
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
// src/state/bridge/call-types.ts
|
|
2221
|
+
import "@arcanetech/privacy-sdk-core/state";
|
|
2222
|
+
var stellarStateCallTypes = {
|
|
2223
|
+
pendingClaims: "pendingClaims",
|
|
2224
|
+
clearPendingClaims: "clearPendingClaims",
|
|
2225
|
+
readPendingClaims: "readPendingClaims",
|
|
2226
|
+
replacePendingClaimsPage: "replacePendingClaimsPage",
|
|
2227
|
+
upsertPendingClaims: "upsertPendingClaims",
|
|
2228
|
+
removePendingClaims: "removePendingClaims",
|
|
2229
|
+
setPendingClaimsCount: "setPendingClaimsCount",
|
|
2230
|
+
readPendingClaimsCount: "readPendingClaimsCount",
|
|
2231
|
+
readStellarAddressRegistered: "readStellarAddressRegistered",
|
|
2232
|
+
readCachedPrivateAddress: "readCachedPrivateAddress",
|
|
2233
|
+
readRegistryLookup: "readRegistryLookup",
|
|
2234
|
+
saveRegisteredPrivateAddress: "saveRegisteredPrivateAddress",
|
|
2235
|
+
saveRegistryLookup: "saveRegistryLookup",
|
|
2236
|
+
invalidateRegisteredAddress: "invalidateRegisteredAddress",
|
|
2237
|
+
invalidateRegistryLookup: "invalidateRegistryLookup",
|
|
2238
|
+
readAssetsCatalog: "readAssetsCatalog",
|
|
2239
|
+
readAsset: "readAsset",
|
|
2240
|
+
replaceAssets: "replaceAssets",
|
|
2241
|
+
upsertAssets: "upsertAssets",
|
|
2242
|
+
readPublicBalance: "readPublicBalance",
|
|
2243
|
+
readPublicBalances: "readPublicBalances",
|
|
2244
|
+
setPublicBalance: "setPublicBalance",
|
|
2245
|
+
setPublicBalances: "setPublicBalances",
|
|
2246
|
+
readPoolMerkleState: "readPoolMerkleState",
|
|
2247
|
+
setPoolMerkleState: "setPoolMerkleState",
|
|
2248
|
+
readLeafEphemeral: "readLeafEphemeral",
|
|
2249
|
+
setLeafEphemeral: "setLeafEphemeral",
|
|
2250
|
+
listPrivateRecords: "listPrivateRecords",
|
|
2251
|
+
savePrivateRecords: "savePrivateRecords",
|
|
2252
|
+
replacePrivateRecords: "replacePrivateRecords",
|
|
2253
|
+
upsertPrivateRecords: "upsertPrivateRecords",
|
|
2254
|
+
pruneConsumedPrivateRecords: "pruneConsumedPrivateRecords",
|
|
2255
|
+
readIncomingDeliveries: "readIncomingDeliveries",
|
|
2256
|
+
upsertIncomingDeliveries: "upsertIncomingDeliveries",
|
|
2257
|
+
readDeliverySyncState: "readDeliverySyncState",
|
|
2258
|
+
setDeliverySyncState: "setDeliverySyncState",
|
|
2259
|
+
readTransactionStatus: "readTransactionStatus",
|
|
2260
|
+
setTransactionStatus: "setTransactionStatus",
|
|
2261
|
+
clearTransactionStatus: "clearTransactionStatus",
|
|
2262
|
+
saveWalletPrivateAddressScalar: "saveWalletPrivateAddressScalar",
|
|
2263
|
+
readWalletPrivateAddressScalar: "readWalletPrivateAddressScalar",
|
|
2264
|
+
saveWalletPrivateAddressRecord: "saveWalletPrivateAddressRecord",
|
|
2265
|
+
readWalletPrivateAddressRecord: "readWalletPrivateAddressRecord",
|
|
2266
|
+
setWalletDefaultPrivateAddressNonce: "setWalletDefaultPrivateAddressNonce",
|
|
2267
|
+
readWalletDefaultPrivateAddressNonce: "readWalletDefaultPrivateAddressNonce",
|
|
2268
|
+
deleteWalletPrivateAddressScalar: "deleteWalletPrivateAddressScalar"
|
|
2269
|
+
};
|
|
2270
|
+
|
|
2271
|
+
// src/state/schemas/assets/catalog.ts
|
|
2272
|
+
import { z as z3 } from "zod";
|
|
2273
|
+
var readAssetsCatalogSchema = z3.object({
|
|
2274
|
+
type: z3.literal(stellarStateCallTypes.readAssetsCatalog)
|
|
2275
|
+
}).transform(({ type }) => ({
|
|
2276
|
+
type,
|
|
2277
|
+
operations: [
|
|
2278
|
+
{
|
|
2279
|
+
opType: "primitiveGet",
|
|
2280
|
+
jsonPath: STELLAR_STATE_PATHS.assets
|
|
2281
|
+
}
|
|
2282
|
+
]
|
|
2283
|
+
}));
|
|
2284
|
+
var readAssetSchema = z3.object({
|
|
2285
|
+
type: z3.literal(stellarStateCallTypes.readAsset),
|
|
2286
|
+
assetId: z3.string().min(1)
|
|
2287
|
+
}).transform(({ type, assetId }) => ({
|
|
2288
|
+
type,
|
|
2289
|
+
operations: [
|
|
2290
|
+
{
|
|
2291
|
+
opType: "recordGet",
|
|
2292
|
+
jsonPath: STELLAR_STATE_PATHS.assetsById,
|
|
2293
|
+
key: assetId
|
|
2294
|
+
}
|
|
2295
|
+
]
|
|
2296
|
+
}));
|
|
2297
|
+
var replaceAssetsSchema = z3.object({
|
|
2298
|
+
type: z3.literal(stellarStateCallTypes.replaceAssets),
|
|
2299
|
+
assets: z3.array(assetSchema)
|
|
2300
|
+
}).transform(({ type, assets }) => {
|
|
2301
|
+
const byId = {};
|
|
2302
|
+
const listOrder = [];
|
|
2303
|
+
for (const asset of assets) {
|
|
2304
|
+
Reflect.set(byId, asset.assetId, withoutUndefinedFields(asset));
|
|
2305
|
+
listOrder.push(asset.assetId);
|
|
2306
|
+
}
|
|
2307
|
+
return {
|
|
2308
|
+
type,
|
|
2309
|
+
operations: [
|
|
2310
|
+
{
|
|
2311
|
+
opType: "primitiveSet",
|
|
2312
|
+
jsonPath: STELLAR_STATE_PATHS.assets,
|
|
2313
|
+
value: { byId, listOrder }
|
|
2314
|
+
}
|
|
2315
|
+
]
|
|
2316
|
+
};
|
|
2317
|
+
});
|
|
2318
|
+
var upsertAssetsSchema = z3.object({
|
|
2319
|
+
type: z3.literal(stellarStateCallTypes.upsertAssets),
|
|
2320
|
+
assets: z3.array(assetSchema)
|
|
2321
|
+
}).transform(({ type, assets }) => ({
|
|
2322
|
+
type,
|
|
2323
|
+
operations: assets.map((asset) => ({
|
|
2324
|
+
opType: "recordSet",
|
|
2325
|
+
jsonPath: STELLAR_STATE_PATHS.assetsById,
|
|
2326
|
+
key: asset.assetId,
|
|
2327
|
+
value: asset
|
|
2328
|
+
}))
|
|
2329
|
+
}));
|
|
2330
|
+
|
|
2331
|
+
// src/state/definitions/assets.ts
|
|
2332
|
+
var stellarAssetsStateDefinitions = [
|
|
2333
|
+
{
|
|
2334
|
+
type: stellarStateCallTypes.readAssetsCatalog,
|
|
2335
|
+
mode: "read",
|
|
2336
|
+
schema: readAssetsCatalogSchema
|
|
2337
|
+
},
|
|
2338
|
+
{
|
|
2339
|
+
type: stellarStateCallTypes.readAsset,
|
|
2340
|
+
mode: "read",
|
|
2341
|
+
schema: readAssetSchema
|
|
2342
|
+
},
|
|
2343
|
+
{
|
|
2344
|
+
type: stellarStateCallTypes.replaceAssets,
|
|
2345
|
+
mode: "write",
|
|
2346
|
+
schema: replaceAssetsSchema
|
|
2347
|
+
},
|
|
2348
|
+
{
|
|
2349
|
+
type: stellarStateCallTypes.upsertAssets,
|
|
2350
|
+
mode: "write",
|
|
2351
|
+
schema: upsertAssetsSchema
|
|
2352
|
+
}
|
|
2353
|
+
];
|
|
2354
|
+
|
|
2355
|
+
// src/state/schemas/assets/balances.ts
|
|
2356
|
+
import { z as z4 } from "zod";
|
|
2357
|
+
|
|
2358
|
+
// src/state/foundation/keys.ts
|
|
2359
|
+
function ownerAssetKey(owner, asset) {
|
|
2360
|
+
return `${owner}:${asset}`;
|
|
2361
|
+
}
|
|
2362
|
+
function readRecordValue(record, key) {
|
|
2363
|
+
if (!Object.hasOwn(record, key)) {
|
|
2364
|
+
return void 0;
|
|
2365
|
+
}
|
|
2366
|
+
return Reflect.get(record, key);
|
|
2367
|
+
}
|
|
2368
|
+
function poolLeafKey(poolContract, leafIndex) {
|
|
2369
|
+
return `${poolContract}:${leafIndex}`;
|
|
2370
|
+
}
|
|
2371
|
+
function privateAddressAssetKey(privateAddress, asset) {
|
|
2372
|
+
return `${privateAddress}:${asset}`;
|
|
2373
|
+
}
|
|
2374
|
+
function walletOwnerNonceKey(owner, nonce) {
|
|
2375
|
+
return `${owner}:${nonce}`;
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
// src/state/schemas/assets/balances.ts
|
|
2379
|
+
var readPublicBalanceSchema = z4.object({
|
|
2380
|
+
type: z4.literal(stellarStateCallTypes.readPublicBalance),
|
|
2381
|
+
owner: z4.string().min(1),
|
|
2382
|
+
asset: z4.string().min(1)
|
|
2383
|
+
}).transform(({ type, owner, asset }) => ({
|
|
2384
|
+
type,
|
|
2385
|
+
operations: [
|
|
2386
|
+
{
|
|
2387
|
+
opType: "recordGet",
|
|
2388
|
+
jsonPath: STELLAR_STATE_PATHS.publicBalances,
|
|
2389
|
+
key: ownerAssetKey(owner, asset)
|
|
2390
|
+
}
|
|
2391
|
+
]
|
|
2392
|
+
}));
|
|
2393
|
+
var readPublicBalancesSchema = z4.object({
|
|
2394
|
+
type: z4.literal(stellarStateCallTypes.readPublicBalances),
|
|
2395
|
+
owner: z4.string().min(1)
|
|
2396
|
+
}).transform(({ type }) => ({
|
|
2397
|
+
type,
|
|
2398
|
+
operations: [
|
|
2399
|
+
{
|
|
2400
|
+
opType: "recordEntries",
|
|
2401
|
+
jsonPath: STELLAR_STATE_PATHS.publicBalances
|
|
2402
|
+
}
|
|
2403
|
+
]
|
|
2404
|
+
}));
|
|
2405
|
+
var setPublicBalanceSchema = z4.object({
|
|
2406
|
+
type: z4.literal(stellarStateCallTypes.setPublicBalance),
|
|
2407
|
+
balance: publicBalanceSchema
|
|
2408
|
+
}).transform(({ type, balance }) => ({
|
|
2409
|
+
type,
|
|
2410
|
+
operations: [
|
|
2411
|
+
{
|
|
2412
|
+
opType: "recordSet",
|
|
2413
|
+
jsonPath: STELLAR_STATE_PATHS.publicBalances,
|
|
2414
|
+
key: ownerAssetKey(balance.owner, balance.asset),
|
|
2415
|
+
value: balance
|
|
2416
|
+
}
|
|
2417
|
+
]
|
|
2418
|
+
}));
|
|
2419
|
+
var setPublicBalancesSchema = z4.object({
|
|
2420
|
+
type: z4.literal(stellarStateCallTypes.setPublicBalances),
|
|
2421
|
+
owner: z4.string().min(1),
|
|
2422
|
+
balances: z4.array(publicBalanceSchema)
|
|
2423
|
+
}).transform(({ type, owner, balances }) => ({
|
|
2424
|
+
type,
|
|
2425
|
+
operations: balances.map((balance) => ({
|
|
2426
|
+
opType: "recordSet",
|
|
2427
|
+
jsonPath: STELLAR_STATE_PATHS.publicBalances,
|
|
2428
|
+
key: ownerAssetKey(owner, balance.asset),
|
|
2429
|
+
value: { ...balance, owner }
|
|
2430
|
+
}))
|
|
2431
|
+
}));
|
|
2432
|
+
|
|
2433
|
+
// src/state/definitions/balances.ts
|
|
2434
|
+
var stellarBalancesStateDefinitions = [
|
|
2435
|
+
{
|
|
2436
|
+
type: stellarStateCallTypes.readPublicBalance,
|
|
2437
|
+
mode: "read",
|
|
2438
|
+
schema: readPublicBalanceSchema
|
|
2439
|
+
},
|
|
2440
|
+
{
|
|
2441
|
+
type: stellarStateCallTypes.readPublicBalances,
|
|
2442
|
+
mode: "read",
|
|
2443
|
+
schema: readPublicBalancesSchema
|
|
2444
|
+
},
|
|
2445
|
+
{
|
|
2446
|
+
type: stellarStateCallTypes.setPublicBalance,
|
|
2447
|
+
mode: "write",
|
|
2448
|
+
schema: setPublicBalanceSchema
|
|
2449
|
+
},
|
|
2450
|
+
{
|
|
2451
|
+
type: stellarStateCallTypes.setPublicBalances,
|
|
2452
|
+
mode: "write",
|
|
2453
|
+
schema: setPublicBalancesSchema
|
|
2454
|
+
}
|
|
2455
|
+
];
|
|
2456
|
+
|
|
2457
|
+
// src/state/schemas/claims/write.ts
|
|
2458
|
+
import { z as z5 } from "zod";
|
|
2459
|
+
var pendingClaimsWriteSchema = z5.object({
|
|
2460
|
+
type: z5.literal(stellarStateCallTypes.pendingClaims),
|
|
2461
|
+
claims: z5.array(pendingClaimSchema),
|
|
2462
|
+
paginationInfo: paginationSchema
|
|
2463
|
+
}).transform(({ type, claims, paginationInfo }) => ({
|
|
2464
|
+
type,
|
|
2465
|
+
operations: [
|
|
2466
|
+
{
|
|
2467
|
+
opType: "arrayPush",
|
|
2468
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2469
|
+
items: claims
|
|
2470
|
+
},
|
|
2471
|
+
{
|
|
2472
|
+
opType: "primitiveSet",
|
|
2473
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsPagination,
|
|
2474
|
+
value: paginationInfo
|
|
2475
|
+
}
|
|
2476
|
+
]
|
|
2477
|
+
}));
|
|
2478
|
+
var clearPendingClaimsSchema = z5.object({
|
|
2479
|
+
type: z5.literal(stellarStateCallTypes.clearPendingClaims),
|
|
2480
|
+
owner: z5.string().optional(),
|
|
2481
|
+
asset: z5.string().optional()
|
|
2482
|
+
}).transform(({ type, owner, asset }) => {
|
|
2483
|
+
if (owner === void 0 && asset === void 0) {
|
|
2484
|
+
return {
|
|
2485
|
+
type,
|
|
2486
|
+
operations: [
|
|
2487
|
+
{
|
|
2488
|
+
opType: "arrayClean",
|
|
2489
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems
|
|
2490
|
+
}
|
|
2491
|
+
]
|
|
2492
|
+
};
|
|
2493
|
+
}
|
|
2494
|
+
return {
|
|
2495
|
+
type,
|
|
2496
|
+
operations: [rejectPendingClaimsByOwnerAndAsset({ owner, asset })]
|
|
2497
|
+
};
|
|
2498
|
+
});
|
|
2499
|
+
var readPendingClaimsSchema = z5.object({
|
|
2500
|
+
type: z5.literal(stellarStateCallTypes.readPendingClaims)
|
|
2501
|
+
}).transform(({ type }) => ({
|
|
2502
|
+
type,
|
|
2503
|
+
operations: [
|
|
2504
|
+
{
|
|
2505
|
+
opType: "primitiveGet",
|
|
2506
|
+
jsonPath: "$.pendingClaims"
|
|
2507
|
+
}
|
|
2508
|
+
]
|
|
2509
|
+
}));
|
|
2510
|
+
|
|
2511
|
+
// src/state/schemas/claims/page.ts
|
|
2512
|
+
import { z as z6 } from "zod";
|
|
2513
|
+
var pendingClaimBridgeItemSchema = pendingClaimSchema;
|
|
2514
|
+
var replacePendingClaimsPageSchema = z6.object({
|
|
2515
|
+
type: z6.literal(stellarStateCallTypes.replacePendingClaimsPage),
|
|
2516
|
+
owner: z6.string().min(1),
|
|
2517
|
+
claims: z6.array(pendingClaimBridgeItemSchema),
|
|
2518
|
+
paginationInfo: z6.object({
|
|
2519
|
+
total: z6.number().int().nonnegative(),
|
|
2520
|
+
page: z6.number().int().positive(),
|
|
2521
|
+
pageSize: z6.number().int().positive(),
|
|
2522
|
+
hasMore: z6.boolean()
|
|
2523
|
+
}),
|
|
2524
|
+
count: z6.number().int().nonnegative().optional()
|
|
2525
|
+
}).transform(({ type, owner, claims, paginationInfo, count }) => ({
|
|
2526
|
+
type,
|
|
2527
|
+
operations: [
|
|
2528
|
+
rejectPendingClaimsByOwner(owner),
|
|
2529
|
+
{
|
|
2530
|
+
opType: "arrayPush",
|
|
2531
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2532
|
+
items: claims
|
|
2533
|
+
},
|
|
2534
|
+
{
|
|
2535
|
+
opType: "primitiveSet",
|
|
2536
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsPagination,
|
|
2537
|
+
value: paginationInfo
|
|
2538
|
+
},
|
|
2539
|
+
{
|
|
2540
|
+
opType: "recordSet",
|
|
2541
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
|
|
2542
|
+
key: owner,
|
|
2543
|
+
value: count ?? paginationInfo.total
|
|
2544
|
+
}
|
|
2545
|
+
]
|
|
2546
|
+
}));
|
|
2547
|
+
var upsertPendingClaimsSchema = z6.object({
|
|
2548
|
+
type: z6.literal(stellarStateCallTypes.upsertPendingClaims),
|
|
2549
|
+
claims: z6.array(pendingClaimBridgeItemSchema)
|
|
2550
|
+
}).transform(({ type, claims }) => ({
|
|
2551
|
+
type,
|
|
2552
|
+
operations: [
|
|
2553
|
+
rejectPendingClaimsByIds(claims.map((claim) => claim.id)),
|
|
2554
|
+
{
|
|
2555
|
+
opType: "arrayPush",
|
|
2556
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2557
|
+
items: claims
|
|
2558
|
+
}
|
|
2559
|
+
]
|
|
2560
|
+
}));
|
|
2561
|
+
var removePendingClaimsSchema = z6.object({
|
|
2562
|
+
type: z6.literal(stellarStateCallTypes.removePendingClaims),
|
|
2563
|
+
ids: z6.array(z6.string().min(1))
|
|
2564
|
+
}).transform(({ type, ids }) => ({
|
|
2565
|
+
type,
|
|
2566
|
+
operations: [rejectPendingClaimsByIds(ids)]
|
|
2567
|
+
}));
|
|
2568
|
+
var readPendingClaimsCountSchema = z6.object({
|
|
2569
|
+
type: z6.literal(stellarStateCallTypes.readPendingClaimsCount),
|
|
2570
|
+
owner: z6.string().min(1)
|
|
2571
|
+
}).transform(({ type, owner }) => ({
|
|
2572
|
+
type,
|
|
2573
|
+
operations: [
|
|
2574
|
+
{
|
|
2575
|
+
opType: "recordGet",
|
|
2576
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
|
|
2577
|
+
key: owner
|
|
2578
|
+
}
|
|
2579
|
+
]
|
|
2580
|
+
}));
|
|
2581
|
+
var setPendingClaimsCountSchema = z6.object({
|
|
2582
|
+
type: z6.literal(stellarStateCallTypes.setPendingClaimsCount),
|
|
2583
|
+
owner: z6.string().min(1),
|
|
2584
|
+
count: z6.number().int().nonnegative()
|
|
2585
|
+
}).transform(({ type, owner, count }) => ({
|
|
2586
|
+
type,
|
|
2587
|
+
operations: [
|
|
2588
|
+
{
|
|
2589
|
+
opType: "recordSet",
|
|
2590
|
+
jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
|
|
2591
|
+
key: owner,
|
|
2592
|
+
value: count
|
|
2593
|
+
}
|
|
2594
|
+
]
|
|
2595
|
+
}));
|
|
2596
|
+
|
|
2597
|
+
// src/state/definitions/claims.ts
|
|
2598
|
+
var stellarClaimsStateDefinitions = [
|
|
2599
|
+
{
|
|
2600
|
+
type: stellarStateCallTypes.pendingClaims,
|
|
2601
|
+
mode: "write",
|
|
2602
|
+
schema: pendingClaimsWriteSchema
|
|
2603
|
+
},
|
|
2604
|
+
{
|
|
2605
|
+
type: stellarStateCallTypes.clearPendingClaims,
|
|
2606
|
+
mode: "write",
|
|
2607
|
+
schema: clearPendingClaimsSchema
|
|
2608
|
+
},
|
|
2609
|
+
{
|
|
2610
|
+
type: stellarStateCallTypes.readPendingClaims,
|
|
2611
|
+
mode: "read",
|
|
2612
|
+
schema: readPendingClaimsSchema
|
|
2613
|
+
},
|
|
2614
|
+
{
|
|
2615
|
+
type: stellarStateCallTypes.replacePendingClaimsPage,
|
|
2616
|
+
mode: "write",
|
|
2617
|
+
schema: replacePendingClaimsPageSchema
|
|
2618
|
+
},
|
|
2619
|
+
{
|
|
2620
|
+
type: stellarStateCallTypes.upsertPendingClaims,
|
|
2621
|
+
mode: "write",
|
|
2622
|
+
schema: upsertPendingClaimsSchema
|
|
2623
|
+
},
|
|
2624
|
+
{
|
|
2625
|
+
type: stellarStateCallTypes.removePendingClaims,
|
|
2626
|
+
mode: "write",
|
|
2627
|
+
schema: removePendingClaimsSchema
|
|
2628
|
+
},
|
|
2629
|
+
{
|
|
2630
|
+
type: stellarStateCallTypes.readPendingClaimsCount,
|
|
2631
|
+
mode: "read",
|
|
2632
|
+
schema: readPendingClaimsCountSchema
|
|
2633
|
+
},
|
|
2634
|
+
{
|
|
2635
|
+
type: stellarStateCallTypes.setPendingClaimsCount,
|
|
2636
|
+
mode: "write",
|
|
2637
|
+
schema: setPendingClaimsCountSchema
|
|
2638
|
+
}
|
|
2639
|
+
];
|
|
2640
|
+
|
|
2641
|
+
// src/state/schemas/claims/deliveries.ts
|
|
2642
|
+
import { z as z7 } from "zod";
|
|
2643
|
+
var readIncomingDeliveriesSchema = z7.object({
|
|
2644
|
+
type: z7.literal(stellarStateCallTypes.readIncomingDeliveries)
|
|
2645
|
+
}).transform(({ type }) => ({
|
|
2646
|
+
type,
|
|
2647
|
+
operations: [
|
|
2648
|
+
{
|
|
2649
|
+
opType: "primitiveGet",
|
|
2650
|
+
jsonPath: STELLAR_STATE_PATHS.deliveriesIncomingById
|
|
2651
|
+
}
|
|
2652
|
+
]
|
|
2653
|
+
}));
|
|
2654
|
+
var upsertIncomingDeliveriesSchema = z7.object({
|
|
2655
|
+
type: z7.literal(stellarStateCallTypes.upsertIncomingDeliveries),
|
|
2656
|
+
deliveries: z7.array(incomingDeliverySchema)
|
|
2657
|
+
}).transform(({ type, deliveries }) => ({
|
|
2658
|
+
type,
|
|
2659
|
+
operations: deliveries.map((delivery) => ({
|
|
2660
|
+
opType: "recordSet",
|
|
2661
|
+
jsonPath: STELLAR_STATE_PATHS.deliveriesIncomingById,
|
|
2662
|
+
key: String(delivery.id),
|
|
2663
|
+
value: delivery
|
|
2664
|
+
}))
|
|
2665
|
+
}));
|
|
2666
|
+
var readDeliverySyncStateSchema = z7.object({
|
|
2667
|
+
type: z7.literal(stellarStateCallTypes.readDeliverySyncState),
|
|
2668
|
+
privateAddress: z7.string().min(1),
|
|
2669
|
+
asset: z7.string().min(1)
|
|
2670
|
+
}).transform(({ type, privateAddress, asset }) => ({
|
|
2671
|
+
type,
|
|
2672
|
+
operations: [
|
|
2673
|
+
{
|
|
2674
|
+
opType: "recordGet",
|
|
2675
|
+
jsonPath: STELLAR_STATE_PATHS.deliveriesSync,
|
|
2676
|
+
key: privateAddressAssetKey(privateAddress, asset)
|
|
2677
|
+
}
|
|
2678
|
+
]
|
|
2679
|
+
}));
|
|
2680
|
+
var setDeliverySyncStateSchema = z7.object({
|
|
2681
|
+
type: z7.literal(stellarStateCallTypes.setDeliverySyncState),
|
|
2682
|
+
syncState: deliverySyncStateSchema
|
|
2683
|
+
}).transform(({ type, syncState }) => ({
|
|
2684
|
+
type,
|
|
2685
|
+
operations: [
|
|
2686
|
+
{
|
|
2687
|
+
opType: "recordSet",
|
|
2688
|
+
jsonPath: STELLAR_STATE_PATHS.deliveriesSync,
|
|
2689
|
+
key: privateAddressAssetKey(syncState.privateAddress, syncState.asset),
|
|
2690
|
+
value: syncState
|
|
2691
|
+
}
|
|
2692
|
+
]
|
|
2693
|
+
}));
|
|
2694
|
+
|
|
2695
|
+
// src/state/definitions/deliveries.ts
|
|
2696
|
+
var stellarDeliveriesStateDefinitions = [
|
|
2697
|
+
{
|
|
2698
|
+
type: stellarStateCallTypes.readIncomingDeliveries,
|
|
2699
|
+
mode: "read",
|
|
2700
|
+
schema: readIncomingDeliveriesSchema
|
|
2701
|
+
},
|
|
2702
|
+
{
|
|
2703
|
+
type: stellarStateCallTypes.upsertIncomingDeliveries,
|
|
2704
|
+
mode: "write",
|
|
2705
|
+
schema: upsertIncomingDeliveriesSchema
|
|
2706
|
+
},
|
|
2707
|
+
{
|
|
2708
|
+
type: stellarStateCallTypes.readDeliverySyncState,
|
|
2709
|
+
mode: "read",
|
|
2710
|
+
schema: readDeliverySyncStateSchema
|
|
2711
|
+
},
|
|
2712
|
+
{
|
|
2713
|
+
type: stellarStateCallTypes.setDeliverySyncState,
|
|
2714
|
+
mode: "write",
|
|
2715
|
+
schema: setDeliverySyncStateSchema
|
|
2716
|
+
}
|
|
2717
|
+
];
|
|
2718
|
+
|
|
2719
|
+
// src/state/schemas/pool/merkle.ts
|
|
2720
|
+
import { z as z8 } from "zod";
|
|
2721
|
+
var readPoolMerkleStateSchema = z8.object({
|
|
2722
|
+
type: z8.literal(stellarStateCallTypes.readPoolMerkleState),
|
|
2723
|
+
poolContract: z8.string().min(1)
|
|
2724
|
+
}).transform(({ type, poolContract }) => ({
|
|
2725
|
+
type,
|
|
2726
|
+
operations: [
|
|
2727
|
+
{
|
|
2728
|
+
opType: "recordGet",
|
|
2729
|
+
jsonPath: STELLAR_STATE_PATHS.poolsByContract,
|
|
2730
|
+
key: poolContract
|
|
2731
|
+
}
|
|
2732
|
+
]
|
|
2733
|
+
}));
|
|
2734
|
+
var setPoolMerkleStateSchema = z8.object({
|
|
2735
|
+
type: z8.literal(stellarStateCallTypes.setPoolMerkleState),
|
|
2736
|
+
state: poolMerkleStateSchema
|
|
2737
|
+
}).transform(({ type, state }) => ({
|
|
2738
|
+
type,
|
|
2739
|
+
operations: [
|
|
2740
|
+
{
|
|
2741
|
+
opType: "recordSet",
|
|
2742
|
+
jsonPath: STELLAR_STATE_PATHS.poolsByContract,
|
|
2743
|
+
key: state.poolContract,
|
|
2744
|
+
value: state
|
|
2745
|
+
}
|
|
2746
|
+
]
|
|
2747
|
+
}));
|
|
2748
|
+
var readLeafEphemeralSchema = z8.object({
|
|
2749
|
+
type: z8.literal(stellarStateCallTypes.readLeafEphemeral),
|
|
2750
|
+
poolContract: z8.string().min(1),
|
|
2751
|
+
leafIndex: z8.number().int().nonnegative()
|
|
2752
|
+
}).transform(({ type, poolContract, leafIndex }) => ({
|
|
2753
|
+
type,
|
|
2754
|
+
operations: [
|
|
2755
|
+
{
|
|
2756
|
+
opType: "recordGet",
|
|
2757
|
+
jsonPath: STELLAR_STATE_PATHS.poolsLeafEphemeral,
|
|
2758
|
+
key: poolLeafKey(poolContract, leafIndex)
|
|
2759
|
+
}
|
|
2760
|
+
]
|
|
2761
|
+
}));
|
|
2762
|
+
var setLeafEphemeralSchema = z8.object({
|
|
2763
|
+
type: z8.literal(stellarStateCallTypes.setLeafEphemeral),
|
|
2764
|
+
ephemeral: leafEphemeralSchema
|
|
2765
|
+
}).transform(({ type, ephemeral }) => ({
|
|
2766
|
+
type,
|
|
2767
|
+
operations: [
|
|
2768
|
+
{
|
|
2769
|
+
opType: "recordSet",
|
|
2770
|
+
jsonPath: STELLAR_STATE_PATHS.poolsLeafEphemeral,
|
|
2771
|
+
key: poolLeafKey(ephemeral.poolContract, ephemeral.leafIndex),
|
|
2772
|
+
value: ephemeral
|
|
2773
|
+
}
|
|
2774
|
+
]
|
|
2775
|
+
}));
|
|
2776
|
+
|
|
2777
|
+
// src/state/definitions/pool.ts
|
|
2778
|
+
var stellarPoolStateDefinitions = [
|
|
2779
|
+
{
|
|
2780
|
+
type: stellarStateCallTypes.readPoolMerkleState,
|
|
2781
|
+
mode: "read",
|
|
2782
|
+
schema: readPoolMerkleStateSchema
|
|
2783
|
+
},
|
|
2784
|
+
{
|
|
2785
|
+
type: stellarStateCallTypes.setPoolMerkleState,
|
|
2786
|
+
mode: "write",
|
|
2787
|
+
schema: setPoolMerkleStateSchema
|
|
2788
|
+
},
|
|
2789
|
+
{
|
|
2790
|
+
type: stellarStateCallTypes.readLeafEphemeral,
|
|
2791
|
+
mode: "read",
|
|
2792
|
+
schema: readLeafEphemeralSchema
|
|
2793
|
+
},
|
|
2794
|
+
{
|
|
2795
|
+
type: stellarStateCallTypes.setLeafEphemeral,
|
|
2796
|
+
mode: "write",
|
|
2797
|
+
schema: setLeafEphemeralSchema
|
|
2798
|
+
}
|
|
2799
|
+
];
|
|
2800
|
+
|
|
2801
|
+
// src/state/schemas/records/private.ts
|
|
2802
|
+
import { z as z9 } from "zod";
|
|
2803
|
+
var listPrivateRecordsSchema = z9.object({
|
|
2804
|
+
type: z9.literal(stellarStateCallTypes.listPrivateRecords)
|
|
2805
|
+
}).transform(({ type }) => ({
|
|
2806
|
+
type,
|
|
2807
|
+
operations: [
|
|
2808
|
+
{
|
|
2809
|
+
opType: "primitiveGet",
|
|
2810
|
+
jsonPath: STELLAR_STATE_PATHS.privateRecords
|
|
2811
|
+
}
|
|
2812
|
+
]
|
|
2813
|
+
}));
|
|
2814
|
+
var savePrivateRecordsSchema = z9.object({
|
|
2815
|
+
type: z9.literal(stellarStateCallTypes.savePrivateRecords),
|
|
2816
|
+
records: z9.array(privateRecordSchema)
|
|
2817
|
+
}).transform(({ type, records }) => ({
|
|
2818
|
+
type,
|
|
2819
|
+
operations: [
|
|
2820
|
+
{
|
|
2821
|
+
opType: "arrayPush",
|
|
2822
|
+
jsonPath: STELLAR_STATE_PATHS.privateRecords,
|
|
2823
|
+
items: records
|
|
2824
|
+
}
|
|
2825
|
+
]
|
|
2826
|
+
}));
|
|
2827
|
+
var replacePrivateRecordsSchema = z9.object({
|
|
2828
|
+
type: z9.literal(stellarStateCallTypes.replacePrivateRecords),
|
|
2829
|
+
records: z9.array(privateRecordSchema)
|
|
2830
|
+
}).transform(({ type, records }) => ({
|
|
2831
|
+
type,
|
|
2832
|
+
operations: [
|
|
2833
|
+
{
|
|
2834
|
+
opType: "arrayClean",
|
|
2835
|
+
jsonPath: STELLAR_STATE_PATHS.privateRecords
|
|
2836
|
+
},
|
|
2837
|
+
{
|
|
2838
|
+
opType: "arrayPush",
|
|
2839
|
+
jsonPath: STELLAR_STATE_PATHS.privateRecords,
|
|
2840
|
+
items: records
|
|
2841
|
+
}
|
|
2842
|
+
]
|
|
2843
|
+
}));
|
|
2844
|
+
var pruneConsumedPrivateRecordsSchema = z9.object({
|
|
2845
|
+
type: z9.literal(stellarStateCallTypes.pruneConsumedPrivateRecords)
|
|
2846
|
+
}).transform(({ type }) => ({
|
|
2847
|
+
type,
|
|
2848
|
+
operations: [rejectConsumedPrivateRecords()]
|
|
2849
|
+
}));
|
|
2850
|
+
|
|
2851
|
+
// src/state/schemas/records/transactions.ts
|
|
2852
|
+
import { z as z10 } from "zod";
|
|
2853
|
+
var upsertPrivateRecordsSchema = z10.object({
|
|
2854
|
+
type: z10.literal(stellarStateCallTypes.upsertPrivateRecords),
|
|
2855
|
+
records: z10.array(privateRecordSchema)
|
|
2856
|
+
}).transform(({ type, records }) => ({
|
|
2857
|
+
type,
|
|
2858
|
+
operations: [
|
|
2859
|
+
rejectPrivateRecordsByIds(records.map((record) => record.id)),
|
|
2860
|
+
{
|
|
2861
|
+
opType: "arrayPush",
|
|
2862
|
+
jsonPath: STELLAR_STATE_PATHS.privateRecords,
|
|
2863
|
+
items: records
|
|
2864
|
+
}
|
|
2865
|
+
]
|
|
2866
|
+
}));
|
|
2867
|
+
var readTransactionStatusSchema = z10.object({
|
|
2868
|
+
type: z10.literal(stellarStateCallTypes.readTransactionStatus),
|
|
2869
|
+
txHash: z10.string().min(1)
|
|
2870
|
+
}).transform(({ type, txHash }) => ({
|
|
2871
|
+
type,
|
|
2872
|
+
operations: [
|
|
2873
|
+
{
|
|
2874
|
+
opType: "recordGet",
|
|
2875
|
+
jsonPath: STELLAR_STATE_PATHS.transactionsByHash,
|
|
2876
|
+
key: txHash
|
|
2877
|
+
}
|
|
2878
|
+
]
|
|
2879
|
+
}));
|
|
2880
|
+
var setTransactionStatusSchema = z10.object({
|
|
2881
|
+
type: z10.literal(stellarStateCallTypes.setTransactionStatus),
|
|
2882
|
+
status: transactionStatusSchema
|
|
2883
|
+
}).transform(({ type, status }) => ({
|
|
2884
|
+
type,
|
|
2885
|
+
operations: [
|
|
2886
|
+
{
|
|
2887
|
+
opType: "recordSet",
|
|
2888
|
+
jsonPath: STELLAR_STATE_PATHS.transactionsByHash,
|
|
2889
|
+
key: status.txHash,
|
|
2890
|
+
value: status
|
|
2891
|
+
}
|
|
2892
|
+
]
|
|
2893
|
+
}));
|
|
2894
|
+
var clearTransactionStatusSchema = z10.object({
|
|
2895
|
+
type: z10.literal(stellarStateCallTypes.clearTransactionStatus),
|
|
2896
|
+
txHash: z10.string().min(1)
|
|
2897
|
+
}).transform(({ type, txHash }) => ({
|
|
2898
|
+
type,
|
|
2899
|
+
operations: [
|
|
2900
|
+
{
|
|
2901
|
+
opType: "recordDelete",
|
|
2902
|
+
jsonPath: STELLAR_STATE_PATHS.transactionsByHash,
|
|
2903
|
+
key: txHash
|
|
2904
|
+
}
|
|
2905
|
+
]
|
|
2906
|
+
}));
|
|
2907
|
+
|
|
2908
|
+
// src/state/definitions/records.ts
|
|
2909
|
+
var stellarRecordsStateDefinitions = [
|
|
2910
|
+
{
|
|
2911
|
+
type: stellarStateCallTypes.listPrivateRecords,
|
|
2912
|
+
mode: "read",
|
|
2913
|
+
schema: listPrivateRecordsSchema
|
|
2914
|
+
},
|
|
2915
|
+
{
|
|
2916
|
+
type: stellarStateCallTypes.savePrivateRecords,
|
|
2917
|
+
mode: "write",
|
|
2918
|
+
schema: savePrivateRecordsSchema
|
|
2919
|
+
},
|
|
2920
|
+
{
|
|
2921
|
+
type: stellarStateCallTypes.replacePrivateRecords,
|
|
2922
|
+
mode: "write",
|
|
2923
|
+
schema: replacePrivateRecordsSchema
|
|
2924
|
+
},
|
|
2925
|
+
{
|
|
2926
|
+
type: stellarStateCallTypes.upsertPrivateRecords,
|
|
2927
|
+
mode: "write",
|
|
2928
|
+
schema: upsertPrivateRecordsSchema
|
|
2929
|
+
},
|
|
2930
|
+
{
|
|
2931
|
+
type: stellarStateCallTypes.pruneConsumedPrivateRecords,
|
|
2932
|
+
mode: "write",
|
|
2933
|
+
schema: pruneConsumedPrivateRecordsSchema
|
|
2934
|
+
}
|
|
2935
|
+
];
|
|
2936
|
+
|
|
2937
|
+
// src/state/schemas/registry/lookup.ts
|
|
2938
|
+
import { z as z11 } from "zod";
|
|
2939
|
+
var readStellarAddressRegisteredSchema = z11.object({
|
|
2940
|
+
type: z11.literal(stellarStateCallTypes.readStellarAddressRegistered),
|
|
2941
|
+
address: z11.string().min(1)
|
|
2942
|
+
}).transform(({ type, address }) => ({
|
|
2943
|
+
type,
|
|
2944
|
+
operations: [
|
|
2945
|
+
{
|
|
2946
|
+
opType: "recordGet",
|
|
2947
|
+
jsonPath: STELLAR_STATE_PATHS.registryRegisteredAddresses,
|
|
2948
|
+
key: address
|
|
2949
|
+
}
|
|
2950
|
+
]
|
|
2951
|
+
}));
|
|
2952
|
+
var readCachedPrivateAddressSchema = z11.object({
|
|
2953
|
+
type: z11.literal(stellarStateCallTypes.readCachedPrivateAddress),
|
|
2954
|
+
address: z11.string().min(1)
|
|
2955
|
+
}).transform(({ type, address }) => ({
|
|
2956
|
+
type,
|
|
2957
|
+
operations: [
|
|
2958
|
+
{
|
|
2959
|
+
opType: "recordGet",
|
|
2960
|
+
jsonPath: STELLAR_STATE_PATHS.registryPrivateAddresses,
|
|
2961
|
+
key: address
|
|
2962
|
+
}
|
|
2963
|
+
]
|
|
2964
|
+
}));
|
|
2965
|
+
var saveRegisteredPrivateAddressSchema = z11.object({
|
|
2966
|
+
type: z11.literal(stellarStateCallTypes.saveRegisteredPrivateAddress),
|
|
2967
|
+
address: z11.string().min(1),
|
|
2968
|
+
privateAddress: z11.string().min(1),
|
|
2969
|
+
registered: z11.boolean()
|
|
2970
|
+
}).transform(({ type, address, privateAddress, registered: registered2 }) => {
|
|
2971
|
+
const lookup = registryLookupSchema.parse({
|
|
2972
|
+
owner: address,
|
|
2973
|
+
status: registered2 ? "registered" : "unregistered",
|
|
2974
|
+
privateAddressStpl1: registered2 ? privateAddress : void 0,
|
|
2975
|
+
cachedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2976
|
+
});
|
|
2977
|
+
return {
|
|
2978
|
+
type,
|
|
2979
|
+
operations: [
|
|
2980
|
+
{
|
|
2981
|
+
opType: "recordSet",
|
|
2982
|
+
jsonPath: STELLAR_STATE_PATHS.registryPrivateAddresses,
|
|
2983
|
+
key: address,
|
|
2984
|
+
value: privateAddress
|
|
2985
|
+
},
|
|
2986
|
+
{
|
|
2987
|
+
opType: "recordSet",
|
|
2988
|
+
jsonPath: STELLAR_STATE_PATHS.registryRegisteredAddresses,
|
|
2989
|
+
key: address,
|
|
2990
|
+
value: registered2
|
|
2991
|
+
},
|
|
2992
|
+
{
|
|
2993
|
+
opType: "recordSet",
|
|
2994
|
+
jsonPath: STELLAR_STATE_PATHS.registryLookups,
|
|
2995
|
+
key: address,
|
|
2996
|
+
value: lookup
|
|
2997
|
+
}
|
|
2998
|
+
]
|
|
2999
|
+
};
|
|
3000
|
+
});
|
|
3001
|
+
var invalidateRegisteredAddressSchema = z11.object({
|
|
3002
|
+
type: z11.literal(stellarStateCallTypes.invalidateRegisteredAddress),
|
|
3003
|
+
address: z11.string().min(1)
|
|
3004
|
+
}).transform(({ type, address }) => ({
|
|
3005
|
+
type,
|
|
3006
|
+
operations: [
|
|
3007
|
+
{
|
|
3008
|
+
opType: "recordDelete",
|
|
3009
|
+
jsonPath: STELLAR_STATE_PATHS.registryPrivateAddresses,
|
|
3010
|
+
key: address
|
|
3011
|
+
},
|
|
3012
|
+
{
|
|
3013
|
+
opType: "recordDelete",
|
|
3014
|
+
jsonPath: STELLAR_STATE_PATHS.registryRegisteredAddresses,
|
|
3015
|
+
key: address
|
|
3016
|
+
},
|
|
3017
|
+
{
|
|
3018
|
+
opType: "recordDelete",
|
|
3019
|
+
jsonPath: STELLAR_STATE_PATHS.registryLookups,
|
|
3020
|
+
key: address
|
|
3021
|
+
}
|
|
3022
|
+
]
|
|
3023
|
+
}));
|
|
3024
|
+
var readRegistryLookupSchema = z11.object({
|
|
3025
|
+
type: z11.literal(stellarStateCallTypes.readRegistryLookup),
|
|
3026
|
+
address: z11.string().min(1)
|
|
3027
|
+
}).transform(({ type, address }) => ({
|
|
3028
|
+
type,
|
|
3029
|
+
operations: [
|
|
3030
|
+
{
|
|
3031
|
+
opType: "recordGet",
|
|
3032
|
+
jsonPath: STELLAR_STATE_PATHS.registryLookups,
|
|
3033
|
+
key: address
|
|
3034
|
+
}
|
|
3035
|
+
]
|
|
3036
|
+
}));
|
|
3037
|
+
var saveRegistryLookupSchema = z11.object({
|
|
3038
|
+
type: z11.literal(stellarStateCallTypes.saveRegistryLookup),
|
|
3039
|
+
lookup: registryLookupSchema
|
|
3040
|
+
}).transform(({ type, lookup }) => {
|
|
3041
|
+
const operations = [
|
|
3042
|
+
{
|
|
3043
|
+
opType: "recordSet",
|
|
3044
|
+
jsonPath: STELLAR_STATE_PATHS.registryLookups,
|
|
3045
|
+
key: lookup.owner,
|
|
3046
|
+
value: lookup
|
|
3047
|
+
}
|
|
3048
|
+
];
|
|
3049
|
+
if (lookup.status === "registered" && lookup.privateAddressStpl1) {
|
|
3050
|
+
operations.push(
|
|
3051
|
+
{
|
|
3052
|
+
opType: "recordSet",
|
|
3053
|
+
jsonPath: STELLAR_STATE_PATHS.registryPrivateAddresses,
|
|
3054
|
+
key: lookup.owner,
|
|
3055
|
+
value: lookup.privateAddressStpl1
|
|
3056
|
+
},
|
|
3057
|
+
{
|
|
3058
|
+
opType: "recordSet",
|
|
3059
|
+
jsonPath: STELLAR_STATE_PATHS.registryRegisteredAddresses,
|
|
3060
|
+
key: lookup.owner,
|
|
3061
|
+
value: true
|
|
3062
|
+
}
|
|
3063
|
+
);
|
|
3064
|
+
} else {
|
|
3065
|
+
operations.push({
|
|
3066
|
+
opType: "recordSet",
|
|
3067
|
+
jsonPath: STELLAR_STATE_PATHS.registryRegisteredAddresses,
|
|
3068
|
+
key: lookup.owner,
|
|
3069
|
+
value: false
|
|
3070
|
+
});
|
|
3071
|
+
}
|
|
3072
|
+
return { type, operations };
|
|
3073
|
+
});
|
|
3074
|
+
var invalidateRegistryLookupSchema = z11.object({
|
|
3075
|
+
type: z11.literal(stellarStateCallTypes.invalidateRegistryLookup),
|
|
3076
|
+
address: z11.string().min(1)
|
|
3077
|
+
}).transform(({ type, address }) => ({
|
|
3078
|
+
type,
|
|
3079
|
+
operations: [
|
|
3080
|
+
{
|
|
3081
|
+
opType: "recordDelete",
|
|
3082
|
+
jsonPath: STELLAR_STATE_PATHS.registryLookups,
|
|
3083
|
+
key: address
|
|
3084
|
+
},
|
|
3085
|
+
{
|
|
3086
|
+
opType: "recordDelete",
|
|
3087
|
+
jsonPath: STELLAR_STATE_PATHS.registryPrivateAddresses,
|
|
3088
|
+
key: address
|
|
3089
|
+
},
|
|
3090
|
+
{
|
|
3091
|
+
opType: "recordDelete",
|
|
3092
|
+
jsonPath: STELLAR_STATE_PATHS.registryRegisteredAddresses,
|
|
3093
|
+
key: address
|
|
3094
|
+
}
|
|
3095
|
+
]
|
|
3096
|
+
}));
|
|
3097
|
+
|
|
3098
|
+
// src/state/definitions/registry.ts
|
|
3099
|
+
var stellarRegistryStateDefinitions = [
|
|
3100
|
+
{
|
|
3101
|
+
type: stellarStateCallTypes.readStellarAddressRegistered,
|
|
3102
|
+
mode: "read",
|
|
3103
|
+
schema: readStellarAddressRegisteredSchema
|
|
3104
|
+
},
|
|
3105
|
+
{
|
|
3106
|
+
type: stellarStateCallTypes.readCachedPrivateAddress,
|
|
3107
|
+
mode: "read",
|
|
3108
|
+
schema: readCachedPrivateAddressSchema
|
|
3109
|
+
},
|
|
3110
|
+
{
|
|
3111
|
+
type: stellarStateCallTypes.readRegistryLookup,
|
|
3112
|
+
mode: "read",
|
|
3113
|
+
schema: readRegistryLookupSchema
|
|
3114
|
+
},
|
|
3115
|
+
{
|
|
3116
|
+
type: stellarStateCallTypes.saveRegisteredPrivateAddress,
|
|
3117
|
+
mode: "write",
|
|
3118
|
+
schema: saveRegisteredPrivateAddressSchema
|
|
3119
|
+
},
|
|
3120
|
+
{
|
|
3121
|
+
type: stellarStateCallTypes.saveRegistryLookup,
|
|
3122
|
+
mode: "write",
|
|
3123
|
+
schema: saveRegistryLookupSchema
|
|
3124
|
+
},
|
|
3125
|
+
{
|
|
3126
|
+
type: stellarStateCallTypes.invalidateRegisteredAddress,
|
|
3127
|
+
mode: "write",
|
|
3128
|
+
schema: invalidateRegisteredAddressSchema
|
|
3129
|
+
},
|
|
3130
|
+
{
|
|
3131
|
+
type: stellarStateCallTypes.invalidateRegistryLookup,
|
|
3132
|
+
mode: "write",
|
|
3133
|
+
schema: invalidateRegistryLookupSchema
|
|
3134
|
+
}
|
|
3135
|
+
];
|
|
3136
|
+
|
|
3137
|
+
// src/state/definitions/transactions.ts
|
|
3138
|
+
var stellarTransactionStateDefinitions = [
|
|
3139
|
+
{
|
|
3140
|
+
type: stellarStateCallTypes.readTransactionStatus,
|
|
3141
|
+
mode: "read",
|
|
3142
|
+
schema: readTransactionStatusSchema
|
|
3143
|
+
},
|
|
3144
|
+
{
|
|
3145
|
+
type: stellarStateCallTypes.setTransactionStatus,
|
|
3146
|
+
mode: "write",
|
|
3147
|
+
schema: setTransactionStatusSchema
|
|
3148
|
+
},
|
|
3149
|
+
{
|
|
3150
|
+
type: stellarStateCallTypes.clearTransactionStatus,
|
|
3151
|
+
mode: "write",
|
|
3152
|
+
schema: clearTransactionStatusSchema
|
|
3153
|
+
}
|
|
3154
|
+
];
|
|
3155
|
+
|
|
3156
|
+
// src/state/schemas/wallet/scalar.ts
|
|
3157
|
+
import { z as z12 } from "zod";
|
|
3158
|
+
var saveWalletPrivateAddressScalarSchema = z12.object({
|
|
3159
|
+
type: z12.literal(stellarStateCallTypes.saveWalletPrivateAddressScalar),
|
|
3160
|
+
scalar: walletPrivateAddressScalarSchema
|
|
3161
|
+
}).transform(({ type, scalar }) => ({
|
|
3162
|
+
type,
|
|
3163
|
+
operations: [
|
|
3164
|
+
{
|
|
3165
|
+
opType: "recordSet",
|
|
3166
|
+
jsonPath: STELLAR_STATE_PATHS.walletPrivateAddressScalars,
|
|
3167
|
+
key: walletOwnerNonceKey(scalar.owner, scalar.nonce),
|
|
3168
|
+
value: scalar
|
|
3169
|
+
}
|
|
3170
|
+
]
|
|
3171
|
+
}));
|
|
3172
|
+
var readWalletPrivateAddressScalarSchema = z12.object({
|
|
3173
|
+
type: z12.literal(stellarStateCallTypes.readWalletPrivateAddressScalar),
|
|
3174
|
+
owner: z12.string().min(1),
|
|
3175
|
+
nonce: z12.string().min(1)
|
|
3176
|
+
}).transform(({ type, owner, nonce }) => ({
|
|
3177
|
+
type,
|
|
3178
|
+
operations: [
|
|
3179
|
+
{
|
|
3180
|
+
opType: "recordGet",
|
|
3181
|
+
jsonPath: STELLAR_STATE_PATHS.walletPrivateAddressScalars,
|
|
3182
|
+
key: walletOwnerNonceKey(owner, nonce)
|
|
3183
|
+
}
|
|
3184
|
+
]
|
|
3185
|
+
}));
|
|
3186
|
+
|
|
3187
|
+
// src/state/schemas/wallet/private-address.ts
|
|
3188
|
+
import { z as z13 } from "zod";
|
|
3189
|
+
var saveWalletPrivateAddressRecordSchema = z13.object({
|
|
3190
|
+
type: z13.literal(stellarStateCallTypes.saveWalletPrivateAddressRecord),
|
|
3191
|
+
record: walletPrivateAddressRecordSchema
|
|
3192
|
+
}).transform(({ type, record }) => ({
|
|
3193
|
+
type,
|
|
3194
|
+
operations: [
|
|
3195
|
+
{
|
|
3196
|
+
opType: "recordSet",
|
|
3197
|
+
jsonPath: STELLAR_STATE_PATHS.walletPrivateAddressRecords,
|
|
3198
|
+
key: walletOwnerNonceKey(record.owner, record.nonce),
|
|
3199
|
+
value: record
|
|
3200
|
+
}
|
|
3201
|
+
]
|
|
3202
|
+
}));
|
|
3203
|
+
var readWalletPrivateAddressRecordSchema = z13.object({
|
|
3204
|
+
type: z13.literal(stellarStateCallTypes.readWalletPrivateAddressRecord),
|
|
3205
|
+
owner: z13.string().min(1),
|
|
3206
|
+
nonce: z13.string().min(1)
|
|
3207
|
+
}).transform(({ type, owner, nonce }) => ({
|
|
3208
|
+
type,
|
|
3209
|
+
operations: [
|
|
3210
|
+
{
|
|
3211
|
+
opType: "recordGet",
|
|
3212
|
+
jsonPath: STELLAR_STATE_PATHS.walletPrivateAddressRecords,
|
|
3213
|
+
key: walletOwnerNonceKey(owner, nonce)
|
|
3214
|
+
}
|
|
3215
|
+
]
|
|
3216
|
+
}));
|
|
3217
|
+
var setWalletDefaultPrivateAddressNonceSchema = z13.object({
|
|
3218
|
+
type: z13.literal(stellarStateCallTypes.setWalletDefaultPrivateAddressNonce),
|
|
3219
|
+
owner: z13.string().min(1),
|
|
3220
|
+
nonce: z13.string().min(1)
|
|
3221
|
+
}).transform(({ type, owner, nonce }) => ({
|
|
3222
|
+
type,
|
|
3223
|
+
operations: [
|
|
3224
|
+
{
|
|
3225
|
+
opType: "recordSet",
|
|
3226
|
+
jsonPath: STELLAR_STATE_PATHS.walletDefaultPrivateAddressNonce,
|
|
3227
|
+
key: owner,
|
|
3228
|
+
value: nonce
|
|
3229
|
+
}
|
|
3230
|
+
]
|
|
3231
|
+
}));
|
|
3232
|
+
var readWalletDefaultPrivateAddressNonceSchema = z13.object({
|
|
3233
|
+
type: z13.literal(stellarStateCallTypes.readWalletDefaultPrivateAddressNonce),
|
|
3234
|
+
owner: z13.string().min(1)
|
|
3235
|
+
}).transform(({ type, owner }) => ({
|
|
3236
|
+
type,
|
|
3237
|
+
operations: [
|
|
3238
|
+
{
|
|
3239
|
+
opType: "recordGet",
|
|
3240
|
+
jsonPath: STELLAR_STATE_PATHS.walletDefaultPrivateAddressNonce,
|
|
3241
|
+
key: owner
|
|
3242
|
+
}
|
|
3243
|
+
]
|
|
3244
|
+
}));
|
|
3245
|
+
var deleteWalletPrivateAddressScalarSchema = z13.object({
|
|
3246
|
+
type: z13.literal(stellarStateCallTypes.deleteWalletPrivateAddressScalar),
|
|
3247
|
+
owner: z13.string().min(1),
|
|
3248
|
+
nonce: z13.string().min(1)
|
|
3249
|
+
}).transform(({ type, owner, nonce }) => ({
|
|
3250
|
+
type,
|
|
3251
|
+
operations: [
|
|
3252
|
+
{
|
|
3253
|
+
opType: "recordDelete",
|
|
3254
|
+
jsonPath: STELLAR_STATE_PATHS.walletPrivateAddressScalars,
|
|
3255
|
+
key: walletOwnerNonceKey(owner, nonce)
|
|
3256
|
+
}
|
|
3257
|
+
]
|
|
3258
|
+
}));
|
|
3259
|
+
|
|
3260
|
+
// src/state/definitions/wallet.ts
|
|
3261
|
+
var stellarWalletStateDefinitions = [
|
|
3262
|
+
{
|
|
3263
|
+
type: stellarStateCallTypes.saveWalletPrivateAddressScalar,
|
|
3264
|
+
mode: "write",
|
|
3265
|
+
schema: saveWalletPrivateAddressScalarSchema
|
|
3266
|
+
},
|
|
3267
|
+
{
|
|
3268
|
+
type: stellarStateCallTypes.readWalletPrivateAddressScalar,
|
|
3269
|
+
mode: "read",
|
|
3270
|
+
schema: readWalletPrivateAddressScalarSchema
|
|
3271
|
+
},
|
|
3272
|
+
{
|
|
3273
|
+
type: stellarStateCallTypes.saveWalletPrivateAddressRecord,
|
|
3274
|
+
mode: "write",
|
|
3275
|
+
schema: saveWalletPrivateAddressRecordSchema
|
|
3276
|
+
},
|
|
3277
|
+
{
|
|
3278
|
+
type: stellarStateCallTypes.readWalletPrivateAddressRecord,
|
|
3279
|
+
mode: "read",
|
|
3280
|
+
schema: readWalletPrivateAddressRecordSchema
|
|
3281
|
+
},
|
|
3282
|
+
{
|
|
3283
|
+
type: stellarStateCallTypes.setWalletDefaultPrivateAddressNonce,
|
|
3284
|
+
mode: "write",
|
|
3285
|
+
schema: setWalletDefaultPrivateAddressNonceSchema
|
|
3286
|
+
},
|
|
3287
|
+
{
|
|
3288
|
+
type: stellarStateCallTypes.readWalletDefaultPrivateAddressNonce,
|
|
3289
|
+
mode: "read",
|
|
3290
|
+
schema: readWalletDefaultPrivateAddressNonceSchema
|
|
3291
|
+
},
|
|
3292
|
+
{
|
|
3293
|
+
type: stellarStateCallTypes.deleteWalletPrivateAddressScalar,
|
|
3294
|
+
mode: "write",
|
|
3295
|
+
schema: deleteWalletPrivateAddressScalarSchema
|
|
3296
|
+
}
|
|
3297
|
+
];
|
|
3298
|
+
|
|
3299
|
+
// src/state/definitions/index.ts
|
|
3300
|
+
registerStellarArrayFilterSchemas();
|
|
3301
|
+
var stellarStateDefinitions = [
|
|
3302
|
+
...stellarClaimsStateDefinitions,
|
|
3303
|
+
...stellarRegistryStateDefinitions,
|
|
3304
|
+
...stellarAssetsStateDefinitions,
|
|
3305
|
+
...stellarBalancesStateDefinitions,
|
|
3306
|
+
...stellarPoolStateDefinitions,
|
|
3307
|
+
...stellarRecordsStateDefinitions,
|
|
3308
|
+
...stellarDeliveriesStateDefinitions,
|
|
3309
|
+
...stellarWalletStateDefinitions,
|
|
3310
|
+
...stellarTransactionStateDefinitions
|
|
3311
|
+
];
|
|
3312
|
+
|
|
3313
|
+
// src/state/service/base.ts
|
|
3314
|
+
import {
|
|
3315
|
+
createStateBridge
|
|
3316
|
+
} from "@arcanetech/privacy-sdk-core/state";
|
|
3317
|
+
var StellarStateServiceBase = class {
|
|
3318
|
+
bridge;
|
|
3319
|
+
constructor(adapter) {
|
|
3320
|
+
this.bridge = createStateBridge(adapter);
|
|
3321
|
+
this.bridge.init(stellarStateDefinitions);
|
|
3322
|
+
}
|
|
3323
|
+
};
|
|
3324
|
+
|
|
3325
|
+
// src/state/service/assets/balance-methods.ts
|
|
3326
|
+
function createPublicBalanceMethods(context) {
|
|
3327
|
+
const { bridge } = context;
|
|
3328
|
+
return {
|
|
3329
|
+
async getPublicBalance(input) {
|
|
3330
|
+
const value = await bridge.read({
|
|
3331
|
+
type: stellarStateCallTypes.readPublicBalance,
|
|
3332
|
+
owner: input.owner,
|
|
3333
|
+
asset: input.asset
|
|
3334
|
+
});
|
|
3335
|
+
return normalizePublicBalance(value);
|
|
3336
|
+
},
|
|
3337
|
+
async getPublicBalances(owner) {
|
|
3338
|
+
const entries = await bridge.read({
|
|
3339
|
+
type: stellarStateCallTypes.readPublicBalances,
|
|
3340
|
+
owner
|
|
3341
|
+
});
|
|
3342
|
+
return normalizePublicBalancesFromEntries(entries, owner);
|
|
3343
|
+
},
|
|
3344
|
+
setPublicBalance(balance) {
|
|
3345
|
+
return bridge.write({
|
|
3346
|
+
type: stellarStateCallTypes.setPublicBalance,
|
|
3347
|
+
balance
|
|
3348
|
+
});
|
|
3349
|
+
},
|
|
3350
|
+
setPublicBalances(input) {
|
|
3351
|
+
return bridge.write({
|
|
3352
|
+
type: stellarStateCallTypes.setPublicBalances,
|
|
3353
|
+
owner: input.owner,
|
|
3354
|
+
balances: input.balances
|
|
3355
|
+
});
|
|
3356
|
+
}
|
|
3357
|
+
};
|
|
3358
|
+
}
|
|
3359
|
+
|
|
3360
|
+
// src/state/service/assets/upsert-methods.ts
|
|
3361
|
+
function createAssetsUpsertMethods(_context, deps) {
|
|
3362
|
+
return {
|
|
3363
|
+
async upsertAssets(assets) {
|
|
3364
|
+
if (assets.length === 0) {
|
|
3365
|
+
return;
|
|
3366
|
+
}
|
|
3367
|
+
const catalog = await deps.getAssetsCatalog();
|
|
3368
|
+
const byId = { ...catalog.byId };
|
|
3369
|
+
const listOrder = [...catalog.listOrder];
|
|
3370
|
+
for (const asset of assets) {
|
|
3371
|
+
byId[asset.assetId] = asset;
|
|
3372
|
+
if (!listOrder.includes(asset.assetId)) {
|
|
3373
|
+
listOrder.push(asset.assetId);
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
const merged = listOrder.map((assetId) => readRecordValue(byId, assetId)).filter((asset) => asset !== void 0);
|
|
3377
|
+
await deps.replaceAssets(merged);
|
|
3378
|
+
}
|
|
3379
|
+
};
|
|
3380
|
+
}
|
|
3381
|
+
|
|
3382
|
+
// src/state/service/assets/catalog-methods.ts
|
|
3383
|
+
function createAssetsCatalogMethods(context) {
|
|
3384
|
+
const { bridge } = context;
|
|
3385
|
+
async function getAssetsCatalog() {
|
|
3386
|
+
const value = await bridge.read({
|
|
3387
|
+
type: stellarStateCallTypes.readAssetsCatalog
|
|
3388
|
+
});
|
|
3389
|
+
return normalizeAssetsCatalog(value);
|
|
3390
|
+
}
|
|
3391
|
+
function replaceAssets(assets) {
|
|
3392
|
+
return bridge.write({
|
|
3393
|
+
type: stellarStateCallTypes.replaceAssets,
|
|
3394
|
+
assets
|
|
3395
|
+
});
|
|
3396
|
+
}
|
|
3397
|
+
const coreMethods = {
|
|
3398
|
+
getAssetsCatalog,
|
|
3399
|
+
async getAsset(assetId) {
|
|
3400
|
+
const value = await bridge.read({
|
|
3401
|
+
type: stellarStateCallTypes.readAsset,
|
|
3402
|
+
assetId
|
|
3403
|
+
});
|
|
3404
|
+
return normalizeAsset(value);
|
|
3405
|
+
},
|
|
3406
|
+
async getAssets() {
|
|
3407
|
+
const catalog = await getAssetsCatalog();
|
|
3408
|
+
return catalog.listOrder.map((assetId) => readRecordValue(catalog.byId, assetId)).filter((asset) => asset !== void 0);
|
|
3409
|
+
},
|
|
3410
|
+
async getAssetsForPool(poolContract) {
|
|
3411
|
+
const assets = await coreMethods.getAssets();
|
|
3412
|
+
return assets.filter((asset) => asset.poolContracts.includes(poolContract));
|
|
3413
|
+
},
|
|
3414
|
+
replaceAssets
|
|
3415
|
+
};
|
|
3416
|
+
return {
|
|
3417
|
+
...coreMethods,
|
|
3418
|
+
...createAssetsUpsertMethods(context, {
|
|
3419
|
+
getAssetsCatalog,
|
|
3420
|
+
replaceAssets
|
|
3421
|
+
})
|
|
3422
|
+
};
|
|
3423
|
+
}
|
|
3424
|
+
|
|
3425
|
+
// src/state/service/assets/index.ts
|
|
3426
|
+
function createAssetsService(context) {
|
|
3427
|
+
return {
|
|
3428
|
+
...createAssetsCatalogMethods(context),
|
|
3429
|
+
...createPublicBalanceMethods(context)
|
|
3430
|
+
};
|
|
3431
|
+
}
|
|
3432
|
+
|
|
3433
|
+
// src/state/service/claims/read-methods.ts
|
|
3434
|
+
function createClaimsReadMethods(context) {
|
|
3435
|
+
const { bridge } = context;
|
|
3436
|
+
async function getPendingClaims(filter = {}) {
|
|
3437
|
+
const value = await bridge.read({
|
|
3438
|
+
type: stellarStateCallTypes.readPendingClaims
|
|
3439
|
+
});
|
|
3440
|
+
const state = normalizePendingClaimsState(value);
|
|
3441
|
+
const items = state.items.filter((claim) => {
|
|
3442
|
+
if (filter.owner !== void 0 && claim.owner !== filter.owner) {
|
|
3443
|
+
return false;
|
|
3444
|
+
}
|
|
3445
|
+
if (filter.asset !== void 0 && claim.asset !== filter.asset) {
|
|
3446
|
+
return false;
|
|
3447
|
+
}
|
|
3448
|
+
return true;
|
|
3449
|
+
});
|
|
3450
|
+
if (state.pagination !== void 0) {
|
|
3451
|
+
return { items, pagination: state.pagination };
|
|
3452
|
+
}
|
|
3453
|
+
return { items };
|
|
3454
|
+
}
|
|
3455
|
+
return {
|
|
3456
|
+
getPendingClaims,
|
|
3457
|
+
async getPendingClaimsCount(owner) {
|
|
3458
|
+
const value = await bridge.read({
|
|
3459
|
+
type: stellarStateCallTypes.readPendingClaimsCount,
|
|
3460
|
+
owner
|
|
3461
|
+
});
|
|
3462
|
+
const count = normalizePendingClaimsCount(value);
|
|
3463
|
+
if (count !== void 0) {
|
|
3464
|
+
return count;
|
|
3465
|
+
}
|
|
3466
|
+
const claims = await getPendingClaims({ owner });
|
|
3467
|
+
return claims.items.length;
|
|
3468
|
+
}
|
|
3469
|
+
};
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3472
|
+
// src/state/service/claims/write-methods.ts
|
|
3473
|
+
function appendPendingClaims(bridge, claims, paginationInfo) {
|
|
3474
|
+
return bridge.write({
|
|
3475
|
+
type: stellarStateCallTypes.pendingClaims,
|
|
3476
|
+
claims,
|
|
3477
|
+
paginationInfo
|
|
3478
|
+
});
|
|
3479
|
+
}
|
|
3480
|
+
function replacePendingClaimsPage(bridge, input) {
|
|
3481
|
+
return bridge.write({
|
|
3482
|
+
type: stellarStateCallTypes.replacePendingClaimsPage,
|
|
3483
|
+
owner: input.owner,
|
|
3484
|
+
claims: input.claims,
|
|
3485
|
+
paginationInfo: input.paginationInfo,
|
|
3486
|
+
...input.count === void 0 ? {} : { count: input.count }
|
|
3487
|
+
});
|
|
3488
|
+
}
|
|
3489
|
+
function upsertPendingClaims(bridge, claims) {
|
|
3490
|
+
return bridge.write({
|
|
3491
|
+
type: stellarStateCallTypes.upsertPendingClaims,
|
|
3492
|
+
claims
|
|
3493
|
+
});
|
|
3494
|
+
}
|
|
3495
|
+
function removePendingClaims(bridge, ids) {
|
|
3496
|
+
return bridge.write({
|
|
3497
|
+
type: stellarStateCallTypes.removePendingClaims,
|
|
3498
|
+
ids
|
|
3499
|
+
});
|
|
3500
|
+
}
|
|
3501
|
+
function clearPendingClaims(bridge, input = {}) {
|
|
3502
|
+
return bridge.write({
|
|
3503
|
+
type: stellarStateCallTypes.clearPendingClaims,
|
|
3504
|
+
...input.owner === void 0 ? {} : { owner: input.owner },
|
|
3505
|
+
...input.asset === void 0 ? {} : { asset: input.asset }
|
|
3506
|
+
});
|
|
3507
|
+
}
|
|
3508
|
+
function setPendingClaimsCount(bridge, owner, count) {
|
|
3509
|
+
return bridge.write({
|
|
3510
|
+
type: stellarStateCallTypes.setPendingClaimsCount,
|
|
3511
|
+
owner,
|
|
3512
|
+
count
|
|
3513
|
+
});
|
|
3514
|
+
}
|
|
3515
|
+
function createClaimsWriteMethods(context) {
|
|
3516
|
+
const { bridge } = context;
|
|
3517
|
+
return {
|
|
3518
|
+
appendPendingClaims: (claims, paginationInfo) => appendPendingClaims(bridge, claims, paginationInfo),
|
|
3519
|
+
replacePendingClaimsPage: (input) => replacePendingClaimsPage(bridge, input),
|
|
3520
|
+
upsertPendingClaims: (claims) => upsertPendingClaims(bridge, claims),
|
|
3521
|
+
removePendingClaims: (ids) => removePendingClaims(bridge, ids),
|
|
3522
|
+
clearPendingClaims: (input = {}) => clearPendingClaims(bridge, input),
|
|
3523
|
+
setPendingClaimsCount: (owner, count) => setPendingClaimsCount(bridge, owner, count)
|
|
3524
|
+
};
|
|
3525
|
+
}
|
|
3526
|
+
|
|
3527
|
+
// src/state/service/claims/index.ts
|
|
3528
|
+
function createClaimsService(context) {
|
|
3529
|
+
return {
|
|
3530
|
+
...createClaimsWriteMethods(context),
|
|
3531
|
+
...createClaimsReadMethods(context)
|
|
3532
|
+
};
|
|
3533
|
+
}
|
|
3534
|
+
|
|
3535
|
+
// src/state/service/deliveries/incoming-methods.ts
|
|
3536
|
+
function createIncomingDeliveryMethods(context) {
|
|
3537
|
+
const { bridge } = context;
|
|
3538
|
+
async function getIncomingDeliveries(filter) {
|
|
3539
|
+
const values = await bridge.read({
|
|
3540
|
+
type: stellarStateCallTypes.readIncomingDeliveries
|
|
3541
|
+
});
|
|
3542
|
+
const deliveries = normalizeIncomingDeliveries(values);
|
|
3543
|
+
return deliveries.filter((delivery) => {
|
|
3544
|
+
if (delivery.privateAddress !== filter.privateAddress) {
|
|
3545
|
+
return false;
|
|
3546
|
+
}
|
|
3547
|
+
if (filter.asset !== void 0 && delivery.asset !== filter.asset) {
|
|
3548
|
+
return false;
|
|
3549
|
+
}
|
|
3550
|
+
if (!filter.includeProcessed && delivery.processed) {
|
|
3551
|
+
return false;
|
|
3552
|
+
}
|
|
3553
|
+
return true;
|
|
3554
|
+
});
|
|
3555
|
+
}
|
|
3556
|
+
function upsertIncomingDeliveries(deliveries) {
|
|
3557
|
+
return bridge.write({
|
|
3558
|
+
type: stellarStateCallTypes.upsertIncomingDeliveries,
|
|
3559
|
+
deliveries
|
|
3560
|
+
});
|
|
3561
|
+
}
|
|
3562
|
+
return {
|
|
3563
|
+
getIncomingDeliveries,
|
|
3564
|
+
upsertIncomingDeliveries,
|
|
3565
|
+
async markDeliveryProcessed(id) {
|
|
3566
|
+
const deliveries = await bridge.read({
|
|
3567
|
+
type: stellarStateCallTypes.readIncomingDeliveries
|
|
3568
|
+
});
|
|
3569
|
+
const match = normalizeIncomingDeliveries(deliveries).find(
|
|
3570
|
+
(delivery) => delivery.id === id
|
|
3571
|
+
);
|
|
3572
|
+
if (!match) {
|
|
3573
|
+
return;
|
|
3574
|
+
}
|
|
3575
|
+
await upsertIncomingDeliveries([{ ...match, processed: true }]);
|
|
3576
|
+
}
|
|
3577
|
+
};
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3580
|
+
// src/state/service/deliveries/sync-methods.ts
|
|
3581
|
+
function createDeliverySyncMethods(context) {
|
|
3582
|
+
const { bridge } = context;
|
|
3583
|
+
return {
|
|
3584
|
+
async getDeliverySyncState(input) {
|
|
3585
|
+
const value = await bridge.read({
|
|
3586
|
+
type: stellarStateCallTypes.readDeliverySyncState,
|
|
3587
|
+
privateAddress: input.privateAddress,
|
|
3588
|
+
asset: input.asset
|
|
3589
|
+
});
|
|
3590
|
+
return normalizeDeliverySyncState(value);
|
|
3591
|
+
},
|
|
3592
|
+
setDeliverySyncState(syncState) {
|
|
3593
|
+
return bridge.write({
|
|
3594
|
+
type: stellarStateCallTypes.setDeliverySyncState,
|
|
3595
|
+
syncState
|
|
3596
|
+
});
|
|
3597
|
+
}
|
|
3598
|
+
};
|
|
3599
|
+
}
|
|
3600
|
+
|
|
3601
|
+
// src/state/service/deliveries/index.ts
|
|
3602
|
+
function createDeliveriesService(context) {
|
|
3603
|
+
return {
|
|
3604
|
+
...createIncomingDeliveryMethods(context),
|
|
3605
|
+
...createDeliverySyncMethods(context)
|
|
3606
|
+
};
|
|
3607
|
+
}
|
|
3608
|
+
|
|
3609
|
+
// src/state/service/pool/ephemeral.ts
|
|
3610
|
+
function isMissingStatePathError(error) {
|
|
3611
|
+
if (!(error instanceof Error)) {
|
|
3612
|
+
return false;
|
|
3613
|
+
}
|
|
3614
|
+
return error.message.includes("Record path not found:") || error.message.includes("JSONPath segment not found:");
|
|
3615
|
+
}
|
|
3616
|
+
function createPoolEphemeralService(context) {
|
|
3617
|
+
const { bridge } = context;
|
|
3618
|
+
return {
|
|
3619
|
+
async getLeafEphemeral(input) {
|
|
3620
|
+
try {
|
|
3621
|
+
const value = await bridge.read({
|
|
3622
|
+
type: stellarStateCallTypes.readLeafEphemeral,
|
|
3623
|
+
poolContract: input.poolContract,
|
|
3624
|
+
leafIndex: input.leafIndex
|
|
3625
|
+
});
|
|
3626
|
+
return normalizeLeafEphemeral(value);
|
|
3627
|
+
} catch (error) {
|
|
3628
|
+
if (isMissingStatePathError(error)) {
|
|
3629
|
+
return void 0;
|
|
3630
|
+
}
|
|
3631
|
+
throw error;
|
|
3632
|
+
}
|
|
3633
|
+
},
|
|
3634
|
+
setLeafEphemeral(ephemeral) {
|
|
3635
|
+
return bridge.write({
|
|
3636
|
+
type: stellarStateCallTypes.setLeafEphemeral,
|
|
3637
|
+
ephemeral
|
|
3638
|
+
});
|
|
3639
|
+
}
|
|
3640
|
+
};
|
|
3641
|
+
}
|
|
3642
|
+
|
|
3643
|
+
// src/state/service/pool/merkle.ts
|
|
3644
|
+
function isMissingStatePathError2(error) {
|
|
3645
|
+
if (!(error instanceof Error)) {
|
|
3646
|
+
return false;
|
|
3647
|
+
}
|
|
3648
|
+
return error.message.includes("Record path not found:") || error.message.includes("JSONPath segment not found:");
|
|
3649
|
+
}
|
|
3650
|
+
function createPoolMerkleService(context) {
|
|
3651
|
+
const { bridge } = context;
|
|
3652
|
+
return {
|
|
3653
|
+
async getPoolMerkleState(poolContract) {
|
|
3654
|
+
try {
|
|
3655
|
+
const value = await bridge.read({
|
|
3656
|
+
type: stellarStateCallTypes.readPoolMerkleState,
|
|
3657
|
+
poolContract
|
|
3658
|
+
});
|
|
3659
|
+
return normalizePoolMerkleState(value);
|
|
3660
|
+
} catch (error) {
|
|
3661
|
+
if (isMissingStatePathError2(error)) {
|
|
3662
|
+
return void 0;
|
|
3663
|
+
}
|
|
3664
|
+
throw error;
|
|
3665
|
+
}
|
|
3666
|
+
},
|
|
3667
|
+
setPoolMerkleState(state) {
|
|
3668
|
+
return bridge.write({
|
|
3669
|
+
type: stellarStateCallTypes.setPoolMerkleState,
|
|
3670
|
+
state
|
|
3671
|
+
});
|
|
3672
|
+
},
|
|
3673
|
+
async appendPoolCommitments(input) {
|
|
3674
|
+
const current = await this.getPoolMerkleState(input.poolContract);
|
|
3675
|
+
const mergedCommitments = [...current?.commitments ?? [], ...input.commitments];
|
|
3676
|
+
await this.setPoolMerkleState(
|
|
3677
|
+
withoutUndefinedFields({
|
|
3678
|
+
poolContract: input.poolContract,
|
|
3679
|
+
commitments: mergedCommitments,
|
|
3680
|
+
commitmentCount: mergedCommitments.length,
|
|
3681
|
+
merkleRootHex: input.merkleRootHex,
|
|
3682
|
+
updatedAt: Date.now(),
|
|
3683
|
+
syncedLedger: input.syncedLedger ?? current?.syncedLedger
|
|
3684
|
+
})
|
|
3685
|
+
);
|
|
3686
|
+
}
|
|
3687
|
+
};
|
|
3688
|
+
}
|
|
3689
|
+
|
|
3690
|
+
// src/state/service/records/private-record-upsert.ts
|
|
3691
|
+
function privateCoinNotesEqual(left, right) {
|
|
3692
|
+
if (left === void 0 || right === void 0) {
|
|
3693
|
+
return left === right;
|
|
3694
|
+
}
|
|
3695
|
+
return left.value === right.value && left.nullifier === right.nullifier && left.secret === right.secret && left.commitment === right.commitment && left.asset_hi === right.asset_hi && left.asset_lo === right.asset_lo && left.application_id === right.application_id;
|
|
3696
|
+
}
|
|
3697
|
+
function privateRecordCoreFieldsEqual(left, right) {
|
|
3698
|
+
return left.id === right.id && left.owner === right.owner && left.asset === right.asset && left.amount === right.amount && left.consumed === right.consumed && left.status === right.status && left.poolContract === right.poolContract && left.amountDisplay === right.amountDisplay;
|
|
3699
|
+
}
|
|
3700
|
+
function privateRecordChainFieldsEqual(left, right) {
|
|
3701
|
+
return left.commitmentHex === right.commitmentHex && left.nullifierHex === right.nullifierHex && left.deliveryId === right.deliveryId && left.privateAddress === right.privateAddress && left.txHash === right.txHash;
|
|
3702
|
+
}
|
|
3703
|
+
function privateRecordSecretFieldsEqual(left, right) {
|
|
3704
|
+
return left.depositScalarHex === right.depositScalarHex && left.precommitementHex === right.precommitementHex && privateCoinNotesEqual(left.coinNote, right.coinNote);
|
|
3705
|
+
}
|
|
3706
|
+
function privateRecordsEqual(left, right) {
|
|
3707
|
+
return privateRecordCoreFieldsEqual(left, right) && privateRecordChainFieldsEqual(left, right) && privateRecordSecretFieldsEqual(left, right);
|
|
3708
|
+
}
|
|
3709
|
+
function privateRecordArraysEqual(left, right) {
|
|
3710
|
+
return left.length === right.length && left.every((record, index) => {
|
|
3711
|
+
const rightRecord = right.at(index);
|
|
3712
|
+
return rightRecord !== void 0 && privateRecordsEqual(record, rightRecord);
|
|
3713
|
+
});
|
|
3714
|
+
}
|
|
3715
|
+
function mergePrivateRecords(current, records) {
|
|
3716
|
+
const ids = new Set(records.map((record) => record.id));
|
|
3717
|
+
return [...current.filter((record) => !ids.has(record.id)), ...records];
|
|
3718
|
+
}
|
|
3719
|
+
|
|
3720
|
+
// src/state/service/records/private-methods.ts
|
|
3721
|
+
async function readPrivateRecords(bridge) {
|
|
3722
|
+
const value = await bridge.read({
|
|
3723
|
+
type: stellarStateCallTypes.listPrivateRecords
|
|
3724
|
+
});
|
|
3725
|
+
return normalizePrivateRecords(value);
|
|
3726
|
+
}
|
|
3727
|
+
function writeReplacePrivateRecords(bridge, records) {
|
|
3728
|
+
return bridge.write({
|
|
3729
|
+
type: stellarStateCallTypes.replacePrivateRecords,
|
|
3730
|
+
records
|
|
3731
|
+
});
|
|
3732
|
+
}
|
|
3733
|
+
async function readAvailablePrivateRecords(bridge, filter) {
|
|
3734
|
+
const records = await readPrivateRecords(bridge);
|
|
3735
|
+
return records.filter((record) => matchesPrivateRecordFilter(record, filter, false));
|
|
3736
|
+
}
|
|
3737
|
+
async function applyPrivateRecordsStatus(bridge, records, status) {
|
|
3738
|
+
const current = await readPrivateRecords(bridge);
|
|
3739
|
+
const ids = new Set(records.map((record) => record.id));
|
|
3740
|
+
const next = current.map(
|
|
3741
|
+
(record) => ids.has(record.id) ? {
|
|
3742
|
+
...record,
|
|
3743
|
+
status,
|
|
3744
|
+
consumed: status === "spent" ? true : record.consumed
|
|
3745
|
+
} : record
|
|
3746
|
+
);
|
|
3747
|
+
await writeReplacePrivateRecords(bridge, next);
|
|
3748
|
+
}
|
|
3749
|
+
function aggregatePrivateAssetRows(records, owner) {
|
|
3750
|
+
const available = records.filter(
|
|
3751
|
+
(record) => record.owner === owner && !record.consumed && record.status !== "spent"
|
|
3752
|
+
);
|
|
3753
|
+
const byAsset = /* @__PURE__ */ new Map();
|
|
3754
|
+
for (const record of available) {
|
|
3755
|
+
const existing = byAsset.get(record.asset);
|
|
3756
|
+
const amountDisplay = record.amountDisplay ?? Number(record.amount);
|
|
3757
|
+
if (existing) {
|
|
3758
|
+
existing.totalAmount += record.amount;
|
|
3759
|
+
existing.totalAmountDisplay += amountDisplay;
|
|
3760
|
+
} else {
|
|
3761
|
+
byAsset.set(record.asset, {
|
|
3762
|
+
assetId: record.asset,
|
|
3763
|
+
poolContract: record.poolContract ?? "",
|
|
3764
|
+
totalAmount: record.amount,
|
|
3765
|
+
totalAmountDisplay: amountDisplay
|
|
3766
|
+
});
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
return [...byAsset.values()].toSorted(
|
|
3770
|
+
(left, right) => left.assetId.localeCompare(right.assetId)
|
|
3771
|
+
);
|
|
3772
|
+
}
|
|
3773
|
+
function pruneConsumedPrivateRecords(bridge) {
|
|
3774
|
+
return bridge.write({
|
|
3775
|
+
type: stellarStateCallTypes.pruneConsumedPrivateRecords
|
|
3776
|
+
});
|
|
3777
|
+
}
|
|
3778
|
+
function savePrivateRecords(bridge, records) {
|
|
3779
|
+
return bridge.write({
|
|
3780
|
+
type: stellarStateCallTypes.savePrivateRecords,
|
|
3781
|
+
records
|
|
3782
|
+
});
|
|
3783
|
+
}
|
|
3784
|
+
async function upsertPrivateRecords(bridge, records) {
|
|
3785
|
+
if (records.length === 0) {
|
|
3786
|
+
return;
|
|
3787
|
+
}
|
|
3788
|
+
const current = await readPrivateRecords(bridge);
|
|
3789
|
+
const next = mergePrivateRecords(current, records);
|
|
3790
|
+
if (privateRecordArraysEqual(current, next)) {
|
|
3791
|
+
return;
|
|
3792
|
+
}
|
|
3793
|
+
return bridge.write({
|
|
3794
|
+
type: stellarStateCallTypes.upsertPrivateRecords,
|
|
3795
|
+
records
|
|
3796
|
+
});
|
|
3797
|
+
}
|
|
3798
|
+
async function readPrivateBalance(bridge, input) {
|
|
3799
|
+
const records = await readAvailablePrivateRecords(bridge, {
|
|
3800
|
+
owner: input.owner,
|
|
3801
|
+
asset: input.asset
|
|
3802
|
+
});
|
|
3803
|
+
return records.reduce((total, record) => total + record.amount, 0n);
|
|
3804
|
+
}
|
|
3805
|
+
async function readPrivateAssetRows(bridge, owner) {
|
|
3806
|
+
const records = await readPrivateRecords(bridge);
|
|
3807
|
+
return aggregatePrivateAssetRows(records, owner);
|
|
3808
|
+
}
|
|
3809
|
+
function createPrivateRecordMethods(context) {
|
|
3810
|
+
const { bridge } = context;
|
|
3811
|
+
return {
|
|
3812
|
+
pruneConsumedPrivateRecords: () => pruneConsumedPrivateRecords(bridge),
|
|
3813
|
+
getPrivateRecords: () => readPrivateRecords(bridge),
|
|
3814
|
+
getAvailablePrivateRecords: (filter) => readAvailablePrivateRecords(bridge, filter),
|
|
3815
|
+
listPrivateRecords: (filter) => readAvailablePrivateRecords(bridge, filter),
|
|
3816
|
+
savePrivateRecords: (records) => savePrivateRecords(bridge, records),
|
|
3817
|
+
upsertPrivateRecords: (records) => upsertPrivateRecords(bridge, records),
|
|
3818
|
+
markPrivateRecordsUsed: (records) => applyPrivateRecordsStatus(bridge, records, "spent"),
|
|
3819
|
+
markPrivateRecordsStatus: (records, status) => applyPrivateRecordsStatus(bridge, records, status),
|
|
3820
|
+
getPrivateBalance: (input) => readPrivateBalance(bridge, input),
|
|
3821
|
+
getPrivateAssetRows: (owner) => readPrivateAssetRows(bridge, owner)
|
|
3822
|
+
};
|
|
3823
|
+
}
|
|
3824
|
+
function matchesPrivateRecordFilter(record, filter, includeConsumed) {
|
|
3825
|
+
if (filter.owner !== void 0 && record.owner !== filter.owner) {
|
|
3826
|
+
return false;
|
|
3827
|
+
}
|
|
3828
|
+
if (filter.privateAddress !== void 0 && record.privateAddress !== filter.privateAddress) {
|
|
3829
|
+
return false;
|
|
3830
|
+
}
|
|
3831
|
+
if (filter.owner === void 0 && filter.privateAddress === void 0) {
|
|
3832
|
+
return false;
|
|
3833
|
+
}
|
|
3834
|
+
if (filter.asset !== void 0 && record.asset !== filter.asset) {
|
|
3835
|
+
return false;
|
|
3836
|
+
}
|
|
3837
|
+
if (!includeConsumed && (record.consumed || record.status === "spent")) {
|
|
3838
|
+
return false;
|
|
3839
|
+
}
|
|
3840
|
+
return true;
|
|
3841
|
+
}
|
|
3842
|
+
|
|
3843
|
+
// src/state/service/records/transaction-methods.ts
|
|
3844
|
+
function createTransactionRecordMethods(context) {
|
|
3845
|
+
const { bridge } = context;
|
|
3846
|
+
return {
|
|
3847
|
+
async getTransactionStatus(txHash) {
|
|
3848
|
+
const value = await bridge.read({
|
|
3849
|
+
type: stellarStateCallTypes.readTransactionStatus,
|
|
3850
|
+
txHash
|
|
3851
|
+
});
|
|
3852
|
+
return normalizeTransactionStatus(value);
|
|
3853
|
+
},
|
|
3854
|
+
setTransactionStatus(status) {
|
|
3855
|
+
return bridge.write({
|
|
3856
|
+
type: stellarStateCallTypes.setTransactionStatus,
|
|
3857
|
+
status
|
|
3858
|
+
});
|
|
3859
|
+
},
|
|
3860
|
+
clearTransactionStatus(txHash) {
|
|
3861
|
+
return bridge.write({
|
|
3862
|
+
type: stellarStateCallTypes.clearTransactionStatus,
|
|
3863
|
+
txHash
|
|
3864
|
+
});
|
|
3865
|
+
}
|
|
3866
|
+
};
|
|
3867
|
+
}
|
|
3868
|
+
|
|
3869
|
+
// src/state/service/records/index.ts
|
|
3870
|
+
function createRecordsService(context) {
|
|
3871
|
+
return {
|
|
3872
|
+
...createPrivateRecordMethods(context),
|
|
3873
|
+
...createTransactionRecordMethods(context)
|
|
3874
|
+
};
|
|
3875
|
+
}
|
|
3876
|
+
|
|
3877
|
+
// src/state/service/registry/lookup-read.ts
|
|
3878
|
+
async function readRegistryLookup(bridge, address) {
|
|
3879
|
+
try {
|
|
3880
|
+
const value = await bridge.read({
|
|
3881
|
+
type: stellarStateCallTypes.readRegistryLookup,
|
|
3882
|
+
address
|
|
3883
|
+
});
|
|
3884
|
+
const lookup = normalizeRegistryLookup(value);
|
|
3885
|
+
if (lookup) {
|
|
3886
|
+
return lookup;
|
|
3887
|
+
}
|
|
3888
|
+
} catch {
|
|
3889
|
+
}
|
|
3890
|
+
let registered2;
|
|
3891
|
+
let privateAddress;
|
|
3892
|
+
try {
|
|
3893
|
+
registered2 = await bridge.read({
|
|
3894
|
+
type: stellarStateCallTypes.readStellarAddressRegistered,
|
|
3895
|
+
address
|
|
3896
|
+
});
|
|
3897
|
+
} catch {
|
|
3898
|
+
registered2 = void 0;
|
|
3899
|
+
}
|
|
3900
|
+
try {
|
|
3901
|
+
privateAddress = await bridge.read({
|
|
3902
|
+
type: stellarStateCallTypes.readCachedPrivateAddress,
|
|
3903
|
+
address
|
|
3904
|
+
});
|
|
3905
|
+
} catch {
|
|
3906
|
+
privateAddress = void 0;
|
|
3907
|
+
}
|
|
3908
|
+
return normalizeRegistryLookupFromLegacy({
|
|
3909
|
+
address,
|
|
3910
|
+
registered: registered2,
|
|
3911
|
+
privateAddress
|
|
3912
|
+
});
|
|
3913
|
+
}
|
|
3914
|
+
async function readCachedPrivateAddress(bridge, address) {
|
|
3915
|
+
const lookup = await readRegistryLookup(bridge, address);
|
|
3916
|
+
if (lookup?.privateAddressStpl1) {
|
|
3917
|
+
return lookup.privateAddressStpl1;
|
|
3918
|
+
}
|
|
3919
|
+
const value = await bridge.read({
|
|
3920
|
+
type: stellarStateCallTypes.readCachedPrivateAddress,
|
|
3921
|
+
address
|
|
3922
|
+
});
|
|
3923
|
+
return normalizeCachedPrivateAddress(value);
|
|
3924
|
+
}
|
|
3925
|
+
function createRegistryLookupReadMethods(context) {
|
|
3926
|
+
const { bridge } = context;
|
|
3927
|
+
return {
|
|
3928
|
+
getRegistryLookup: (address) => readRegistryLookup(bridge, address),
|
|
3929
|
+
async isStellarAddressRegistered(address) {
|
|
3930
|
+
const lookup = await readRegistryLookup(bridge, address);
|
|
3931
|
+
if (lookup === void 0) {
|
|
3932
|
+
return void 0;
|
|
3933
|
+
}
|
|
3934
|
+
return lookup.status === "registered";
|
|
3935
|
+
},
|
|
3936
|
+
getCachedPrivateAddress: (address) => readCachedPrivateAddress(bridge, address)
|
|
3937
|
+
};
|
|
3938
|
+
}
|
|
3939
|
+
|
|
3940
|
+
// src/state/service/registry/lookup-write.ts
|
|
3941
|
+
function createRegistryLookupWriteMethods(context) {
|
|
3942
|
+
const { bridge } = context;
|
|
3943
|
+
async function invalidateRegistryLookup(address) {
|
|
3944
|
+
return bridge.write({
|
|
3945
|
+
type: stellarStateCallTypes.invalidateRegistryLookup,
|
|
3946
|
+
address
|
|
3947
|
+
});
|
|
3948
|
+
}
|
|
3949
|
+
return {
|
|
3950
|
+
saveRegistryLookup(lookup) {
|
|
3951
|
+
return bridge.write({
|
|
3952
|
+
type: stellarStateCallTypes.saveRegistryLookup,
|
|
3953
|
+
lookup
|
|
3954
|
+
});
|
|
3955
|
+
},
|
|
3956
|
+
saveRegisteredPrivateAddress(input) {
|
|
3957
|
+
return bridge.write({
|
|
3958
|
+
type: stellarStateCallTypes.saveRegisteredPrivateAddress,
|
|
3959
|
+
address: input.address,
|
|
3960
|
+
privateAddress: input.privateAddress,
|
|
3961
|
+
registered: input.registered
|
|
3962
|
+
});
|
|
3963
|
+
},
|
|
3964
|
+
invalidateRegistryLookup,
|
|
3965
|
+
invalidateRegisteredAddress(address) {
|
|
3966
|
+
return invalidateRegistryLookup(address);
|
|
3967
|
+
}
|
|
3968
|
+
};
|
|
3969
|
+
}
|
|
3970
|
+
|
|
3971
|
+
// src/state/service/registry/lookup.ts
|
|
3972
|
+
function createRegistryLookupService(context) {
|
|
3973
|
+
return {
|
|
3974
|
+
...createRegistryLookupReadMethods(context),
|
|
3975
|
+
...createRegistryLookupWriteMethods(context)
|
|
3976
|
+
};
|
|
3977
|
+
}
|
|
3978
|
+
|
|
3979
|
+
// src/state/service/registry/wallet-record-methods.ts
|
|
3980
|
+
function createWalletRecordMethods(context) {
|
|
3981
|
+
const { bridge } = context;
|
|
3982
|
+
return {
|
|
3983
|
+
async getWalletPrivateAddressRecord(input) {
|
|
3984
|
+
const value = await bridge.read({
|
|
3985
|
+
type: stellarStateCallTypes.readWalletPrivateAddressRecord,
|
|
3986
|
+
owner: input.owner,
|
|
3987
|
+
nonce: input.nonce
|
|
3988
|
+
});
|
|
3989
|
+
return normalizeWalletPrivateAddressRecord(value);
|
|
3990
|
+
},
|
|
3991
|
+
saveWalletPrivateAddressRecord(record) {
|
|
3992
|
+
return bridge.write({
|
|
3993
|
+
type: stellarStateCallTypes.saveWalletPrivateAddressRecord,
|
|
3994
|
+
record
|
|
3995
|
+
});
|
|
3996
|
+
},
|
|
3997
|
+
async getWalletDefaultPrivateAddressNonce(owner) {
|
|
3998
|
+
const value = await bridge.read({
|
|
3999
|
+
type: stellarStateCallTypes.readWalletDefaultPrivateAddressNonce,
|
|
4000
|
+
owner
|
|
4001
|
+
});
|
|
4002
|
+
return normalizeWalletDefaultPrivateAddressNonce(value);
|
|
4003
|
+
},
|
|
4004
|
+
setWalletDefaultPrivateAddressNonce(input) {
|
|
4005
|
+
return bridge.write({
|
|
4006
|
+
type: stellarStateCallTypes.setWalletDefaultPrivateAddressNonce,
|
|
4007
|
+
owner: input.owner,
|
|
4008
|
+
nonce: input.nonce
|
|
4009
|
+
});
|
|
4010
|
+
}
|
|
4011
|
+
};
|
|
4012
|
+
}
|
|
4013
|
+
|
|
4014
|
+
// src/state/service/registry/wallet-scalar-methods.ts
|
|
4015
|
+
function createWalletScalarMethods(context) {
|
|
4016
|
+
const { bridge } = context;
|
|
4017
|
+
return {
|
|
4018
|
+
async getWalletPrivateAddressScalar(input) {
|
|
4019
|
+
const value = await bridge.read({
|
|
4020
|
+
type: stellarStateCallTypes.readWalletPrivateAddressScalar,
|
|
4021
|
+
owner: input.owner,
|
|
4022
|
+
nonce: input.nonce
|
|
4023
|
+
});
|
|
4024
|
+
return normalizeWalletPrivateAddressScalar(value);
|
|
4025
|
+
},
|
|
4026
|
+
saveWalletPrivateAddressScalar(scalar) {
|
|
4027
|
+
return bridge.write({
|
|
4028
|
+
type: stellarStateCallTypes.saveWalletPrivateAddressScalar,
|
|
4029
|
+
scalar
|
|
4030
|
+
});
|
|
4031
|
+
},
|
|
4032
|
+
deleteWalletPrivateAddressScalar(input) {
|
|
4033
|
+
return bridge.write({
|
|
4034
|
+
type: stellarStateCallTypes.deleteWalletPrivateAddressScalar,
|
|
4035
|
+
owner: input.owner,
|
|
4036
|
+
nonce: input.nonce
|
|
4037
|
+
});
|
|
4038
|
+
}
|
|
4039
|
+
};
|
|
4040
|
+
}
|
|
4041
|
+
|
|
4042
|
+
// src/state/service/registry/wallet-address.ts
|
|
4043
|
+
function createWalletAddressService(context) {
|
|
4044
|
+
return {
|
|
4045
|
+
...createWalletScalarMethods(context),
|
|
4046
|
+
...createWalletRecordMethods(context)
|
|
4047
|
+
};
|
|
4048
|
+
}
|
|
4049
|
+
|
|
4050
|
+
// src/state/service/compose.ts
|
|
4051
|
+
function composeStellarStateService(adapter) {
|
|
4052
|
+
const base = new StellarStateServiceBase(adapter);
|
|
4053
|
+
return {
|
|
4054
|
+
bridge: base.bridge,
|
|
4055
|
+
...createAssetsService(base),
|
|
4056
|
+
...createRegistryLookupService(base),
|
|
4057
|
+
...createWalletAddressService(base),
|
|
4058
|
+
...createPoolMerkleService(base),
|
|
4059
|
+
...createPoolEphemeralService(base),
|
|
4060
|
+
...createClaimsService(base),
|
|
4061
|
+
...createDeliveriesService(base),
|
|
4062
|
+
...createRecordsService(base)
|
|
4063
|
+
};
|
|
4064
|
+
}
|
|
4065
|
+
|
|
4066
|
+
// src/state/service/index.ts
|
|
4067
|
+
function createStellarStateService(adapter) {
|
|
4068
|
+
return composeStellarStateService(adapter);
|
|
4069
|
+
}
|
|
4070
|
+
|
|
4071
|
+
// src/transact/merkle/attach-state-ports.ts
|
|
4072
|
+
function createPoolMerkleStatePort(state) {
|
|
4073
|
+
const stateService = createStellarStateService(state);
|
|
4074
|
+
return {
|
|
4075
|
+
get: (poolContract) => stateService.getPoolMerkleState(poolContract),
|
|
4076
|
+
set: (merkleState) => stateService.setPoolMerkleState(merkleState)
|
|
4077
|
+
};
|
|
4078
|
+
}
|
|
4079
|
+
function createLeafEphemeralStatePort(state) {
|
|
4080
|
+
const stateService = createStellarStateService(state);
|
|
4081
|
+
return {
|
|
4082
|
+
get: (input) => stateService.getLeafEphemeral(input),
|
|
4083
|
+
set: (ephemeral) => stateService.setLeafEphemeral(ephemeral)
|
|
4084
|
+
};
|
|
4085
|
+
}
|
|
4086
|
+
function createSenderScalarStateResolver(state) {
|
|
4087
|
+
const stateService = createStellarStateService(state);
|
|
4088
|
+
return async (input) => {
|
|
4089
|
+
const owner = input.owner.trim();
|
|
4090
|
+
if (!owner) {
|
|
4091
|
+
return;
|
|
4092
|
+
}
|
|
4093
|
+
const defaultNonce = await stateService.getWalletDefaultPrivateAddressNonce(owner);
|
|
4094
|
+
if (!defaultNonce) {
|
|
4095
|
+
return;
|
|
4096
|
+
}
|
|
4097
|
+
const requestedAddress = input.privateAddressStpl1.trim();
|
|
4098
|
+
const record = await stateService.getWalletPrivateAddressRecord({
|
|
4099
|
+
owner,
|
|
4100
|
+
nonce: defaultNonce
|
|
4101
|
+
});
|
|
4102
|
+
const recordAddress = record?.privateAddress?.trim();
|
|
4103
|
+
if (recordAddress !== requestedAddress) {
|
|
4104
|
+
return;
|
|
4105
|
+
}
|
|
4106
|
+
const scalar = await stateService.getWalletPrivateAddressScalar({
|
|
4107
|
+
owner,
|
|
4108
|
+
nonce: defaultNonce
|
|
4109
|
+
});
|
|
4110
|
+
const normalized = scalar?.scalarHex?.trim() ?? "";
|
|
4111
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
4112
|
+
};
|
|
4113
|
+
}
|
|
4114
|
+
function attachPoolStatePorts(transactEnvironment, state) {
|
|
4115
|
+
if (!transactEnvironment) {
|
|
4116
|
+
return void 0;
|
|
4117
|
+
}
|
|
4118
|
+
return {
|
|
4119
|
+
...transactEnvironment,
|
|
4120
|
+
poolMerkleState: createPoolMerkleStatePort(state),
|
|
4121
|
+
leafEphemeral: createLeafEphemeralStatePort(state),
|
|
4122
|
+
resolveSenderPrivKeyScalarFromState: createSenderScalarStateResolver(state)
|
|
4123
|
+
};
|
|
4124
|
+
}
|
|
4125
|
+
export {
|
|
4126
|
+
DEFAULT_STEALTH_SIGN_NONCE as DEFAULT_PRIVATE_ADDRESS_SIGN_NONCE,
|
|
4127
|
+
KytInspectError,
|
|
4128
|
+
MIN_CONFIDENTIAL_TRANSFER_STROOPS,
|
|
4129
|
+
PrivacyPoolService,
|
|
4130
|
+
ZERO_STROOPS,
|
|
4131
|
+
assetLegToTokenAddress,
|
|
4132
|
+
attachPoolStatePorts,
|
|
4133
|
+
buildOnboardingPayload,
|
|
4134
|
+
buildPoolTransactionAuditParameters,
|
|
4135
|
+
buildPrivateAddressSignMessage,
|
|
4136
|
+
buildTransferOnboardingAtExecute,
|
|
4137
|
+
configurePrivacyPoolService,
|
|
4138
|
+
createPrivacyPoolService,
|
|
4139
|
+
decodePrivateAddress,
|
|
4140
|
+
encodePrivateAddress,
|
|
4141
|
+
encodePrivateAddressFromHexCoordinates,
|
|
4142
|
+
fetchAndMergeMerkleState,
|
|
4143
|
+
frDecimalToPaddedBytes32,
|
|
4144
|
+
generateRandomDepositScalarHex,
|
|
4145
|
+
generateTemporaryRecipientPrivateAddress,
|
|
4146
|
+
getPrivacyPoolService,
|
|
4147
|
+
loadDefaultStellarBrowserAssets,
|
|
4148
|
+
loadStellarBrowserAssets,
|
|
4149
|
+
parseAuditPublicKeyFromEnvHex,
|
|
4150
|
+
parseKytReasonCode,
|
|
4151
|
+
prepareConfidentialTransferProof,
|
|
4152
|
+
prepareConfidentialTransferProofDual,
|
|
4153
|
+
privateAddressSdk,
|
|
4154
|
+
readLeafEphemeralHex,
|
|
4155
|
+
recipientPublicKeysDecimalFromPrivateAddress,
|
|
4156
|
+
requestKytPassageForPoolInteraction,
|
|
4157
|
+
resolvePoolApplicationId,
|
|
4158
|
+
runTtlPreflight,
|
|
4159
|
+
submitSorobanConfidentialTransfer,
|
|
4160
|
+
submitSorobanDeposit,
|
|
4161
|
+
tokenAddressToAssetLeg
|
|
4162
|
+
};
|
|
4163
|
+
//# sourceMappingURL=index.js.map
|