@arcanetech/privacy-sdk-stellar 0.2.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/index.d.ts +310 -157
- package/dist/index.js +2505 -1817
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +53 -116
- package/dist/node.js +1506 -1622
- package/dist/node.js.map +1 -1
- package/dist/state/index.d.ts +7 -122
- package/dist/state/index.js +96 -490
- package/dist/state/index.js.map +1 -1
- package/dist/testing/index.d.ts +14 -32
- package/dist/transact/index.d.ts +366 -59
- package/dist/transact/index.js +2484 -924
- package/dist/transact/index.js.map +1 -1
- package/generated/contract/README.md +4 -4
- package/generated/contract/dist/index.d.ts +270 -197
- package/generated/contract/dist/index.js +94 -52
- package/generated/contract/package.json +1 -1
- package/generated/contract/src/index.ts +239 -183
- package/generated/registry/README.md +4 -4
- package/generated/registry/dist/index.d.ts +56 -123
- package/generated/registry/dist/index.js +39 -37
- package/generated/registry/package.json +1 -1
- package/generated/registry/src/index.ts +56 -132
- package/package.json +8 -8
package/dist/transact/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// src/transact/pool/service.ts
|
|
2
2
|
import {
|
|
3
|
+
PrivacyPoolSDK as PrivacyPoolSDK2,
|
|
3
4
|
decodeDecodedEphemeralKey,
|
|
4
5
|
randomFrDecimal253,
|
|
5
6
|
scalarHexToFrDecimal as scalarHexToFrDecimal2
|
|
6
|
-
} from "@
|
|
7
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
7
8
|
|
|
8
9
|
// src/transact/merkle/field-decimal.ts
|
|
9
10
|
import { Buffer as Buffer2 } from "buffer";
|
|
@@ -26,11 +27,18 @@ import {
|
|
|
26
27
|
decodeStealthAddress,
|
|
27
28
|
encodeStealthAddress,
|
|
28
29
|
recipientPublicKeysDecimalFromStealthAddress
|
|
29
|
-
} from "@
|
|
30
|
-
import { DEFAULT_STEALTH_SIGN_NONCE } from "@
|
|
31
|
-
|
|
30
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
31
|
+
import { DEFAULT_STEALTH_SIGN_NONCE } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
32
|
+
import {
|
|
33
|
+
OWNER_BOUND_NOTE_SCHEMA_VERSION,
|
|
34
|
+
spendScalarHexFromStellarSignature
|
|
35
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
36
|
+
function buildPrivateAddressSignMessage(publicKey, domain, nonce) {
|
|
32
37
|
const buildMessage = buildStealthAddressSignMessage;
|
|
33
|
-
|
|
38
|
+
if (nonce === void 0) {
|
|
39
|
+
return buildMessage(publicKey, domain);
|
|
40
|
+
}
|
|
41
|
+
return buildMessage(publicKey, domain, nonce);
|
|
34
42
|
}
|
|
35
43
|
function decodePrivateAddress(value) {
|
|
36
44
|
const decodeAddress = decodeStealthAddress;
|
|
@@ -60,12 +68,12 @@ function privateAddressSdk(sdk) {
|
|
|
60
68
|
);
|
|
61
69
|
}
|
|
62
70
|
return {
|
|
63
|
-
generatePrivateAddressFromStellarSignature: (signature) => generator.call(sdk, signature)
|
|
71
|
+
generatePrivateAddressFromStellarSignature: (signature, domain) => generator.call(sdk, signature, domain)
|
|
64
72
|
};
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
// src/transact/proofs/withdraw/transact-proof.ts
|
|
68
|
-
import { withdrawObjectFromMerkleWitness as withdrawObjectFromMerkleWitness2 } from "@
|
|
76
|
+
import { withdrawObjectFromMerkleWitness as withdrawObjectFromMerkleWitness2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
69
77
|
|
|
70
78
|
// src/transact/proofs/transaction-input.ts
|
|
71
79
|
import { Buffer as Buffer4 } from "buffer";
|
|
@@ -105,6 +113,10 @@ function resolveTokenContractId(tokenContractRaw) {
|
|
|
105
113
|
}
|
|
106
114
|
|
|
107
115
|
// src/transact/proofs/transaction-input.ts
|
|
116
|
+
var ZERO_PUBLIC_WITHDRAW_ADDRESS = {
|
|
117
|
+
withdrawAddressHi: "0",
|
|
118
|
+
withdrawAddressLo: "0"
|
|
119
|
+
};
|
|
108
120
|
var CONTRACT_ADDRESS_HALF_BYTES = 16;
|
|
109
121
|
var CONTRACT_ADDRESS_BYTES = 32;
|
|
110
122
|
function bytes16ToDecimal(bytes) {
|
|
@@ -131,7 +143,25 @@ function withTokenAddressPublicInputs(base, tokenAddress) {
|
|
|
131
143
|
return {
|
|
132
144
|
...base,
|
|
133
145
|
tokenAddressHi: hi,
|
|
134
|
-
tokenAddressLo: lo
|
|
146
|
+
tokenAddressLo: lo,
|
|
147
|
+
withdrawAddressHi: base.withdrawAddressHi ?? ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressHi,
|
|
148
|
+
withdrawAddressLo: base.withdrawAddressLo ?? ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressLo,
|
|
149
|
+
escrowRecipientHi: base.escrowRecipientHi ?? "0",
|
|
150
|
+
escrowRecipientLo: base.escrowRecipientLo ?? "0",
|
|
151
|
+
sweepOutputOwnerPubX: base.sweepOutputOwnerPubX ?? "0",
|
|
152
|
+
sweepOutputOwnerPubY: base.sweepOutputOwnerPubY ?? "0"
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function publicWithdrawAddressLimbs(parameters) {
|
|
156
|
+
if (parameters.publicWithdrawalAmount === "0") {
|
|
157
|
+
return {
|
|
158
|
+
withdrawAddressHi: ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressHi,
|
|
159
|
+
withdrawAddressLo: ZERO_PUBLIC_WITHDRAW_ADDRESS.withdrawAddressLo
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
withdrawAddressHi: parameters.destinationHi,
|
|
164
|
+
withdrawAddressLo: parameters.destinationLo
|
|
135
165
|
};
|
|
136
166
|
}
|
|
137
167
|
function tokenAddressToAssetLeg(tokenAddress) {
|
|
@@ -142,91 +172,91 @@ function assetLegToTokenAddress(assetHi, assetLo) {
|
|
|
142
172
|
const payload = Buffer4.concat([decimalToBytes16(assetHi), decimalToBytes16(assetLo)]);
|
|
143
173
|
return StrKey2.encodeContract(payload);
|
|
144
174
|
}
|
|
145
|
-
function buildZeroPublicLegs() {
|
|
175
|
+
function buildZeroPublicLegs(publicNInputs = 1, publicNOutputs = 1) {
|
|
146
176
|
return {
|
|
147
|
-
publicWithdrawnAssets:
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
177
|
+
publicWithdrawnAssets: Array.from(
|
|
178
|
+
{ length: publicNOutputs },
|
|
179
|
+
() => ["0", "0"]
|
|
180
|
+
),
|
|
181
|
+
publicDepositedAssets: Array.from(
|
|
182
|
+
{ length: publicNInputs },
|
|
183
|
+
() => ["0", "0"]
|
|
184
|
+
),
|
|
185
|
+
publicDeposits: Array.from({ length: publicNInputs }, () => "0"),
|
|
186
|
+
publicWithdrawals: Array.from({ length: publicNOutputs }, () => "0")
|
|
151
187
|
};
|
|
152
188
|
}
|
|
153
|
-
function buildPublicDepositLegs(tokenAddress, amount) {
|
|
154
|
-
const legs = buildZeroPublicLegs();
|
|
189
|
+
function buildPublicDepositLegs(tokenAddress, amount, publicNInputs = 1, publicNOutputs = 1) {
|
|
190
|
+
const legs = buildZeroPublicLegs(publicNInputs, publicNOutputs);
|
|
155
191
|
return {
|
|
156
192
|
...legs,
|
|
157
|
-
publicDepositedAssets: [
|
|
158
|
-
|
|
193
|
+
publicDepositedAssets: [
|
|
194
|
+
tokenAddressToAssetLeg(tokenAddress),
|
|
195
|
+
...legs.publicDepositedAssets.slice(1)
|
|
196
|
+
],
|
|
197
|
+
publicDeposits: [amount, ...legs.publicDeposits.slice(1)]
|
|
159
198
|
};
|
|
160
199
|
}
|
|
161
|
-
function buildPublicWithdrawLegs(tokenAddress, amount) {
|
|
162
|
-
const legs = buildZeroPublicLegs();
|
|
200
|
+
function buildPublicWithdrawLegs(tokenAddress, amount, publicNInputs = 1, publicNOutputs = 1) {
|
|
201
|
+
const legs = buildZeroPublicLegs(publicNInputs, publicNOutputs);
|
|
163
202
|
return {
|
|
164
203
|
...legs,
|
|
165
|
-
publicWithdrawnAssets: [
|
|
166
|
-
|
|
204
|
+
publicWithdrawnAssets: [
|
|
205
|
+
tokenAddressToAssetLeg(tokenAddress),
|
|
206
|
+
...legs.publicWithdrawnAssets.slice(1)
|
|
207
|
+
],
|
|
208
|
+
publicWithdrawals: [amount, ...legs.publicWithdrawals.slice(1)]
|
|
167
209
|
};
|
|
168
210
|
}
|
|
169
211
|
|
|
170
|
-
// src/transact/
|
|
212
|
+
// src/transact/zk/slots.ts
|
|
171
213
|
import {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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) {
|
|
214
|
+
padDepositSlots,
|
|
215
|
+
padPublicLegs,
|
|
216
|
+
padWithdrawSlots
|
|
217
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
218
|
+
function padWithdrawSlotsToLayout(sdk, slots) {
|
|
219
|
+
return padWithdrawSlots(slots, sdk.getLayout().nIns);
|
|
220
|
+
}
|
|
221
|
+
function padDepositSlotsToLayout(sdk, slots) {
|
|
222
|
+
return padDepositSlots(slots, sdk.getLayout().nOuts);
|
|
223
|
+
}
|
|
224
|
+
function padPublicLegsToLayout(sdk, legs) {
|
|
225
|
+
const { publicNInputs, publicNOutputs } = sdk.getLayout();
|
|
226
|
+
return padPublicLegs(legs, publicNInputs, publicNOutputs);
|
|
227
|
+
}
|
|
228
|
+
function padStrings(values, length, fill) {
|
|
229
|
+
if (values.length > length) {
|
|
192
230
|
throw new Error(
|
|
193
|
-
`
|
|
231
|
+
`expected at most ${String(length)} application-id slots, got ${String(values.length)}`
|
|
194
232
|
);
|
|
195
233
|
}
|
|
196
|
-
return
|
|
234
|
+
return [...values, ...Array.from({ length: length - values.length }, () => fill)];
|
|
197
235
|
}
|
|
198
|
-
function
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
236
|
+
function buildApplicationIdHints(input) {
|
|
237
|
+
const { nIns, nOuts } = input.sdk.getLayout();
|
|
238
|
+
return [
|
|
239
|
+
...padStrings(input.inputIds, nIns, "0"),
|
|
240
|
+
...padStrings(input.outputIds, nOuts, "0")
|
|
241
|
+
];
|
|
242
|
+
}
|
|
243
|
+
function uniformApplicationIdHints(applicationId, nAuditSlots) {
|
|
244
|
+
return Array.from({ length: nAuditSlots }, () => applicationId);
|
|
203
245
|
}
|
|
204
246
|
|
|
205
247
|
// src/transact/proofs/confidential/helpers.ts
|
|
248
|
+
import { withdrawObjectFromMerkleWitness } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
206
249
|
var MIN_CONFIDENTIAL_TRANSFER_STROOPS = 1n;
|
|
207
250
|
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
251
|
function withdrawWitnessForCoin(parameters) {
|
|
223
|
-
const { sdk, coin, state
|
|
252
|
+
const { sdk, coin, state } = parameters;
|
|
224
253
|
const witness = sdk.buildWithdrawMerkleWitness(coin, state);
|
|
225
254
|
const withdrawApplicationId = coin.application_id ?? parameters.applicationId;
|
|
226
255
|
const withdrawObject = withdrawObjectFromMerkleWitness(
|
|
227
256
|
witness,
|
|
228
|
-
|
|
229
|
-
withdrawApplicationId
|
|
257
|
+
parameters.ownerPubHex,
|
|
258
|
+
withdrawApplicationId,
|
|
259
|
+
parameters.privKeyScalar
|
|
230
260
|
);
|
|
231
261
|
return { witness, withdrawObject };
|
|
232
262
|
}
|
|
@@ -235,16 +265,16 @@ function dualWithdrawLegsWithSharedRoot(parameters) {
|
|
|
235
265
|
sdk: parameters.sdk,
|
|
236
266
|
coin: parameters.coinA,
|
|
237
267
|
state: parameters.state,
|
|
238
|
-
|
|
239
|
-
|
|
268
|
+
ownerPubHex: parameters.ownerPubHex,
|
|
269
|
+
privKeyScalar: parameters.privKeyScalar,
|
|
240
270
|
applicationId: parameters.applicationId
|
|
241
271
|
});
|
|
242
272
|
const legB = withdrawWitnessForCoin({
|
|
243
273
|
sdk: parameters.sdk,
|
|
244
274
|
coin: parameters.coinB,
|
|
245
275
|
state: parameters.state,
|
|
246
|
-
|
|
247
|
-
|
|
276
|
+
ownerPubHex: parameters.ownerPubHex,
|
|
277
|
+
privKeyScalar: parameters.privKeyScalar,
|
|
248
278
|
applicationId: parameters.applicationId
|
|
249
279
|
});
|
|
250
280
|
if (legA.witness.stateRoot !== legB.witness.stateRoot) {
|
|
@@ -252,15 +282,6 @@ function dualWithdrawLegsWithSharedRoot(parameters) {
|
|
|
252
282
|
}
|
|
253
283
|
return { legA, legB };
|
|
254
284
|
}
|
|
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
285
|
function requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange) {
|
|
265
286
|
if (changeStroops > ZERO_STROOPS) {
|
|
266
287
|
const stpl1 = selfPrivateAddressStpl1ForChange?.trim() ?? "";
|
|
@@ -285,15 +306,15 @@ function changeStroopsAfterDualTransfer(transferStroops, totalNotes) {
|
|
|
285
306
|
import {
|
|
286
307
|
DEMO_AUDIT_PUBLIC_KEY,
|
|
287
308
|
resolveTransactionAuditParams
|
|
288
|
-
} from "@
|
|
289
|
-
import { Buffer as
|
|
309
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
310
|
+
import { Buffer as Buffer5 } from "buffer";
|
|
290
311
|
var UNCOMPRESSED_PREFIX = "04";
|
|
291
312
|
var UNCOMPRESSED_HEX_LENGTH = 130;
|
|
292
313
|
var XY_HEX_LENGTH = 128;
|
|
293
314
|
var X_OFFSET_END = 32;
|
|
294
315
|
var Y_OFFSET_START = 32;
|
|
295
316
|
var Y_OFFSET_END = 64;
|
|
296
|
-
var
|
|
317
|
+
var DECIMAL_RADIX = 10;
|
|
297
318
|
var BN254_FR_MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
298
319
|
var BABYJUBJUB_A = 168700n;
|
|
299
320
|
var BABYJUBJUB_D = 168696n;
|
|
@@ -313,13 +334,13 @@ function parseAuditPublicKeyFromEnvHex(raw) {
|
|
|
313
334
|
"Audit public key must be uncompressed 65-byte hex (04 + X + Y) or 64-byte X+Y hex"
|
|
314
335
|
);
|
|
315
336
|
}
|
|
316
|
-
const bytes =
|
|
337
|
+
const bytes = Buffer5.from(payload, "hex");
|
|
317
338
|
const auditPublicKeyXDecimal = BigInt(
|
|
318
339
|
`0x${bytes.subarray(0, X_OFFSET_END).toString("hex")}`
|
|
319
|
-
).toString(
|
|
340
|
+
).toString(DECIMAL_RADIX);
|
|
320
341
|
const auditPublicKeyYDecimal = BigInt(
|
|
321
342
|
`0x${bytes.subarray(Y_OFFSET_START, Y_OFFSET_END).toString("hex")}`
|
|
322
|
-
).toString(
|
|
343
|
+
).toString(DECIMAL_RADIX);
|
|
323
344
|
if (!passesBabyJubCurveCheck(
|
|
324
345
|
BigInt(auditPublicKeyXDecimal),
|
|
325
346
|
BigInt(auditPublicKeyYDecimal)
|
|
@@ -331,7 +352,8 @@ function parseAuditPublicKeyFromEnvHex(raw) {
|
|
|
331
352
|
function buildPoolTransactionAuditParameters(input) {
|
|
332
353
|
return resolveTransactionAuditParams(
|
|
333
354
|
input.applicationId,
|
|
334
|
-
input.auditPublicKey ?? DEMO_AUDIT_PUBLIC_KEY
|
|
355
|
+
input.auditPublicKey ?? DEMO_AUDIT_PUBLIC_KEY,
|
|
356
|
+
input.nAuditSlots
|
|
335
357
|
);
|
|
336
358
|
}
|
|
337
359
|
function resolvePoolApplicationId(applicationId) {
|
|
@@ -345,24 +367,24 @@ function resolvePoolApplicationId(applicationId) {
|
|
|
345
367
|
}
|
|
346
368
|
|
|
347
369
|
// src/transact/proofs/withdraw/helpers.ts
|
|
348
|
-
import { ed25519PubkeyPayloadHexToWithdrawFrDecimals
|
|
370
|
+
import { ed25519PubkeyPayloadHexToWithdrawFrDecimals } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
349
371
|
|
|
350
372
|
// src/transact/stellar/account.ts
|
|
351
|
-
import { StrKey as
|
|
352
|
-
import { Buffer as
|
|
373
|
+
import { StrKey as StrKey3 } from "@stellar/stellar-sdk";
|
|
374
|
+
import { Buffer as Buffer6 } from "buffer";
|
|
353
375
|
var MUXED_ACCOUNT_ID_BYTE_LENGTH = 8;
|
|
354
376
|
var ED25519_PUBLIC_KEY_BYTE_LENGTH = 32;
|
|
355
377
|
function ed25519HexFromGAddress(trimmed) {
|
|
356
378
|
try {
|
|
357
|
-
const raw =
|
|
358
|
-
return
|
|
379
|
+
const raw = StrKey3.decodeEd25519PublicKey(trimmed);
|
|
380
|
+
return Buffer6.from(raw).toString("hex");
|
|
359
381
|
} catch {
|
|
360
382
|
return void 0;
|
|
361
383
|
}
|
|
362
384
|
}
|
|
363
385
|
function ed25519HexFromMuxedAddress(trimmed) {
|
|
364
386
|
try {
|
|
365
|
-
const raw =
|
|
387
|
+
const raw = StrKey3.decodeMed25519PublicKey(trimmed);
|
|
366
388
|
if (raw.length === MUXED_ACCOUNT_ID_BYTE_LENGTH + ED25519_PUBLIC_KEY_BYTE_LENGTH) {
|
|
367
389
|
return raw.subarray(MUXED_ACCOUNT_ID_BYTE_LENGTH).toString("hex");
|
|
368
390
|
}
|
|
@@ -387,26 +409,29 @@ function ed25519PublicKeyHexFromStellarAccount(address) {
|
|
|
387
409
|
throw new Error("Invalid destination Stellar address");
|
|
388
410
|
}
|
|
389
411
|
|
|
390
|
-
// src/transact/encoding/
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
412
|
+
// src/transact/encoding/priv-key-scalar-from-recipient-hex.ts
|
|
413
|
+
import { canonicalBabyJubScalarFromInteger } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
414
|
+
var SCALAR_HEX_CHAR_LENGTH = 64;
|
|
415
|
+
var DECIMAL_RADIX2 = 10;
|
|
416
|
+
function normalizeRecipientScalarHex(hexInput) {
|
|
417
|
+
const trimmed = hexInput.trim().replace(/^0x/iu, "");
|
|
418
|
+
if (!/^[0-9a-f]*$/iu.test(trimmed)) {
|
|
419
|
+
throw new Error("recipient scalar hex must be hexadecimal");
|
|
396
420
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
if (!xRaw || !yRaw || extra !== void 0) {
|
|
421
|
+
const withLeadingNibble = trimmed.length % 2 === 0 ? trimmed : `0${trimmed}`;
|
|
422
|
+
const lower = withLeadingNibble.toLowerCase();
|
|
423
|
+
const padded = lower.padStart(SCALAR_HEX_CHAR_LENGTH, "0").slice(-SCALAR_HEX_CHAR_LENGTH);
|
|
424
|
+
if (padded.length !== SCALAR_HEX_CHAR_LENGTH) {
|
|
402
425
|
throw new Error(
|
|
403
|
-
|
|
426
|
+
`recipient scalar hex must fit 32 bytes (${SCALAR_HEX_CHAR_LENGTH} hex chars)`
|
|
404
427
|
);
|
|
405
428
|
}
|
|
406
|
-
return
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
429
|
+
return padded;
|
|
430
|
+
}
|
|
431
|
+
function privKeyScalarDecimalFromRecipientScalarHex(hexInput) {
|
|
432
|
+
const hex = normalizeRecipientScalarHex(hexInput);
|
|
433
|
+
const value = BigInt(`0x${hex}`);
|
|
434
|
+
return canonicalBabyJubScalarFromInteger(value).toString(DECIMAL_RADIX2);
|
|
410
435
|
}
|
|
411
436
|
|
|
412
437
|
// src/transact/proofs/withdraw/helpers.ts
|
|
@@ -414,7 +439,7 @@ function destinationWithdrawFrAndScalar(parameters) {
|
|
|
414
439
|
const pkHex = ed25519PublicKeyHexFromStellarAccount(
|
|
415
440
|
parameters.destinationStellarAddress
|
|
416
441
|
);
|
|
417
|
-
const { hi, lo } =
|
|
442
|
+
const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals(pkHex);
|
|
418
443
|
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
419
444
|
parameters.privKeyScalarHex
|
|
420
445
|
);
|
|
@@ -428,8 +453,11 @@ function buildWithdrawPublicInput(parameters) {
|
|
|
428
453
|
return withTokenAddressPublicInputs(
|
|
429
454
|
{
|
|
430
455
|
stateRoot: parameters.stateRoot,
|
|
431
|
-
|
|
432
|
-
|
|
456
|
+
...publicWithdrawAddressLimbs({
|
|
457
|
+
publicWithdrawalAmount: parameters.publicWithdrawalAmount,
|
|
458
|
+
destinationHi: hi,
|
|
459
|
+
destinationLo: lo
|
|
460
|
+
}),
|
|
433
461
|
privKeyScalar
|
|
434
462
|
},
|
|
435
463
|
parameters.tokenAddress
|
|
@@ -437,7 +465,7 @@ function buildWithdrawPublicInput(parameters) {
|
|
|
437
465
|
}
|
|
438
466
|
async function resolveWithdrawChangeDeposits(parameters) {
|
|
439
467
|
if (parameters.changeStroops <= ZERO_STROOPS) {
|
|
440
|
-
return { deposits: [
|
|
468
|
+
return { deposits: [] };
|
|
441
469
|
}
|
|
442
470
|
const stpl1 = parameters.changePrivateAddressStpl1?.trim() ?? "";
|
|
443
471
|
if (!stpl1) {
|
|
@@ -451,7 +479,7 @@ async function resolveWithdrawChangeDeposits(parameters) {
|
|
|
451
479
|
tokenAddress: parameters.tokenAddress
|
|
452
480
|
});
|
|
453
481
|
return {
|
|
454
|
-
deposits: [slot.deposit
|
|
482
|
+
deposits: [slot.deposit],
|
|
455
483
|
changeCoin: {
|
|
456
484
|
commitment_hex: slot.commitment_hex,
|
|
457
485
|
coin: slot.coin,
|
|
@@ -476,14 +504,14 @@ function buildDualWithdrawPublicInput(parameters) {
|
|
|
476
504
|
stateRoot: parameters.stateRoot,
|
|
477
505
|
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
478
506
|
privKeyScalarHex: parameters.privKeyScalarHex,
|
|
479
|
-
tokenAddress: parameters.tokenAddress
|
|
507
|
+
tokenAddress: parameters.tokenAddress,
|
|
508
|
+
publicWithdrawalAmount: parameters.publicWithdrawalAmount
|
|
480
509
|
});
|
|
481
510
|
}
|
|
482
511
|
async function prepareDualWithdrawProofInputs(parameters) {
|
|
483
|
-
const totalNotes = BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value);
|
|
484
512
|
const changeStroops = validateDualWithdrawAmounts(
|
|
485
513
|
parameters.withdrawAmountStroops,
|
|
486
|
-
|
|
514
|
+
BigInt(parameters.coinA.value) + BigInt(parameters.coinB.value),
|
|
487
515
|
parameters.changePrivateAddressStpl1
|
|
488
516
|
);
|
|
489
517
|
const { legA, legB } = dualWithdrawLegsWithSharedRoot({
|
|
@@ -491,8 +519,12 @@ async function prepareDualWithdrawProofInputs(parameters) {
|
|
|
491
519
|
coinA: parameters.coinA,
|
|
492
520
|
coinB: parameters.coinB,
|
|
493
521
|
state: parameters.state,
|
|
494
|
-
|
|
495
|
-
|
|
522
|
+
ownerPubHex: parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
|
|
523
|
+
parameters.privKeyScalarHex
|
|
524
|
+
),
|
|
525
|
+
privKeyScalar: privKeyScalarDecimalFromRecipientScalarHex(
|
|
526
|
+
parameters.privKeyScalarHex
|
|
527
|
+
),
|
|
496
528
|
applicationId: parameters.applicationId
|
|
497
529
|
});
|
|
498
530
|
const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
|
|
@@ -505,17 +537,19 @@ async function prepareDualWithdrawProofInputs(parameters) {
|
|
|
505
537
|
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
506
538
|
privKeyScalarHex: parameters.privKeyScalarHex,
|
|
507
539
|
tokenAddress: parameters.tokenAddress,
|
|
508
|
-
stateRoot: legA.witness.stateRoot
|
|
540
|
+
stateRoot: legA.witness.stateRoot,
|
|
541
|
+
publicWithdrawalAmount: parameters.withdrawAmountStroops.toString()
|
|
509
542
|
});
|
|
510
543
|
const audit = buildPoolTransactionAuditParameters({
|
|
511
544
|
applicationId: parameters.applicationId,
|
|
545
|
+
nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
|
|
512
546
|
...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
|
|
513
547
|
});
|
|
514
548
|
return {
|
|
515
549
|
publicInput,
|
|
516
550
|
audit,
|
|
517
|
-
withdrawLegs: [legA.withdrawObject, legB.withdrawObject],
|
|
518
551
|
deposits,
|
|
552
|
+
withdrawLegs: [legA.withdrawObject, legB.withdrawObject],
|
|
519
553
|
...changeCoin ? { changeCoin } : {}
|
|
520
554
|
};
|
|
521
555
|
}
|
|
@@ -533,35 +567,49 @@ function validateSingleWithdrawAmounts(withdrawAmountStroops, noteStroops) {
|
|
|
533
567
|
async function proveSingleWithdrawTransaction(parameters) {
|
|
534
568
|
return parameters.sdk.proveTransaction(
|
|
535
569
|
parameters.publicInput,
|
|
536
|
-
|
|
537
|
-
parameters.
|
|
538
|
-
|
|
570
|
+
padPublicLegsToLayout(
|
|
571
|
+
parameters.sdk,
|
|
572
|
+
buildPublicWithdrawLegs(
|
|
573
|
+
parameters.tokenAddress,
|
|
574
|
+
parameters.withdrawAmountStroops.toString()
|
|
575
|
+
)
|
|
539
576
|
),
|
|
540
|
-
[parameters.primaryWithdraw
|
|
541
|
-
parameters.deposits,
|
|
577
|
+
padWithdrawSlotsToLayout(parameters.sdk, [parameters.primaryWithdraw]),
|
|
578
|
+
padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
|
|
542
579
|
parameters.audit
|
|
543
580
|
);
|
|
544
581
|
}
|
|
545
582
|
function buildPrimaryWithdrawForCoin(parameters) {
|
|
546
|
-
const ephemeralPoint = parseEphemeralKeyString(parameters.depositorEphemeralKey);
|
|
547
583
|
const witness = parameters.sdk.buildWithdrawMerkleWitness(
|
|
548
584
|
parameters.coin,
|
|
549
585
|
parameters.state
|
|
550
586
|
);
|
|
587
|
+
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
588
|
+
parameters.privKeyScalarHex
|
|
589
|
+
);
|
|
590
|
+
const ownerPubHex = parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
|
|
591
|
+
parameters.privKeyScalarHex
|
|
592
|
+
);
|
|
551
593
|
const primaryWithdraw = withdrawObjectFromMerkleWitness2(
|
|
552
594
|
witness,
|
|
553
|
-
|
|
554
|
-
parameters.applicationId
|
|
595
|
+
ownerPubHex,
|
|
596
|
+
parameters.applicationId,
|
|
597
|
+
privKeyScalar
|
|
555
598
|
);
|
|
556
599
|
return { witness, primaryWithdraw };
|
|
557
600
|
}
|
|
558
601
|
async function prepareSingleWithdrawProofInputs(parameters) {
|
|
559
|
-
const noteStroops = BigInt(parameters.coin.value);
|
|
560
602
|
const changeStroops = validateSingleWithdrawAmounts(
|
|
561
603
|
parameters.withdrawAmountStroops,
|
|
562
|
-
|
|
604
|
+
BigInt(parameters.coin.value)
|
|
563
605
|
);
|
|
564
|
-
const { witness, primaryWithdraw } = buildPrimaryWithdrawForCoin(
|
|
606
|
+
const { witness, primaryWithdraw } = buildPrimaryWithdrawForCoin({
|
|
607
|
+
sdk: parameters.sdk,
|
|
608
|
+
applicationId: parameters.applicationId,
|
|
609
|
+
coin: parameters.coin,
|
|
610
|
+
state: parameters.state,
|
|
611
|
+
privKeyScalarHex: parameters.privKeyScalarHex
|
|
612
|
+
});
|
|
565
613
|
const { deposits, changeCoin } = await resolveWithdrawChangeDeposits({
|
|
566
614
|
changeStroops,
|
|
567
615
|
changePrivateAddressStpl1: parameters.changePrivateAddressStpl1,
|
|
@@ -572,18 +620,19 @@ async function prepareSingleWithdrawProofInputs(parameters) {
|
|
|
572
620
|
stateRoot: witness.stateRoot,
|
|
573
621
|
destinationStellarAddress: parameters.destinationStellarAddress,
|
|
574
622
|
privKeyScalarHex: parameters.privKeyScalarHex,
|
|
575
|
-
tokenAddress: parameters.tokenAddress
|
|
576
|
-
|
|
577
|
-
const audit = buildPoolTransactionAuditParameters({
|
|
578
|
-
applicationId: parameters.applicationId,
|
|
579
|
-
...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
|
|
623
|
+
tokenAddress: parameters.tokenAddress,
|
|
624
|
+
publicWithdrawalAmount: parameters.withdrawAmountStroops.toString()
|
|
580
625
|
});
|
|
581
626
|
return {
|
|
582
627
|
primaryWithdraw,
|
|
583
628
|
deposits,
|
|
584
629
|
changeCoin,
|
|
585
630
|
publicInput,
|
|
586
|
-
audit
|
|
631
|
+
audit: buildPoolTransactionAuditParameters({
|
|
632
|
+
applicationId: parameters.applicationId,
|
|
633
|
+
nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
|
|
634
|
+
...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
|
|
635
|
+
})
|
|
587
636
|
};
|
|
588
637
|
}
|
|
589
638
|
async function proveWithdrawTransact(parameters) {
|
|
@@ -599,12 +648,11 @@ async function proveWithdrawTransact(parameters) {
|
|
|
599
648
|
});
|
|
600
649
|
return {
|
|
601
650
|
...proof,
|
|
602
|
-
applicationIdsPlaintext:
|
|
603
|
-
parameters.
|
|
604
|
-
|
|
605
|
-
changeCoin ? parameters.applicationId : "0"
|
|
606
|
-
|
|
607
|
-
],
|
|
651
|
+
applicationIdsPlaintext: buildApplicationIdHints({
|
|
652
|
+
sdk: parameters.sdk,
|
|
653
|
+
inputIds: [parameters.applicationId],
|
|
654
|
+
outputIds: [changeCoin ? parameters.applicationId : "0"]
|
|
655
|
+
}),
|
|
608
656
|
...changeCoin ? { changeCoin } : {}
|
|
609
657
|
};
|
|
610
658
|
}
|
|
@@ -612,33 +660,146 @@ async function proveWithdrawTransactDual(parameters) {
|
|
|
612
660
|
const { publicInput, audit, withdrawLegs, deposits, changeCoin } = await prepareDualWithdrawProofInputs(parameters);
|
|
613
661
|
const proof = await parameters.sdk.proveTransaction(
|
|
614
662
|
publicInput,
|
|
615
|
-
|
|
616
|
-
parameters.
|
|
617
|
-
|
|
663
|
+
padPublicLegsToLayout(
|
|
664
|
+
parameters.sdk,
|
|
665
|
+
buildPublicWithdrawLegs(
|
|
666
|
+
parameters.tokenAddress,
|
|
667
|
+
parameters.withdrawAmountStroops.toString()
|
|
668
|
+
)
|
|
618
669
|
),
|
|
619
|
-
withdrawLegs,
|
|
620
|
-
deposits,
|
|
670
|
+
padWithdrawSlotsToLayout(parameters.sdk, withdrawLegs),
|
|
671
|
+
padDepositSlotsToLayout(parameters.sdk, deposits),
|
|
621
672
|
audit
|
|
622
673
|
);
|
|
623
674
|
return {
|
|
624
675
|
...proof,
|
|
625
|
-
applicationIdsPlaintext:
|
|
626
|
-
|
|
627
|
-
audit.applicationId,
|
|
628
|
-
changeCoin ? audit.applicationId : "0"
|
|
629
|
-
|
|
630
|
-
],
|
|
676
|
+
applicationIdsPlaintext: buildApplicationIdHints({
|
|
677
|
+
sdk: parameters.sdk,
|
|
678
|
+
inputIds: [audit.applicationId, audit.applicationId],
|
|
679
|
+
outputIds: [changeCoin ? audit.applicationId : "0"]
|
|
680
|
+
}),
|
|
631
681
|
...changeCoin ? { changeCoin } : {}
|
|
632
682
|
};
|
|
633
683
|
}
|
|
634
684
|
|
|
635
685
|
// src/transact/pool/service.ts
|
|
636
686
|
import "buffer";
|
|
637
|
-
|
|
687
|
+
|
|
688
|
+
// src/transact/zk/circuit-config.ts
|
|
689
|
+
import {
|
|
690
|
+
BundledZkCircuit
|
|
691
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
692
|
+
|
|
693
|
+
// src/transact/environment/zk-config-nonce.ts
|
|
694
|
+
var STANDARD_ZK_CONFIG_NONCE = 0n;
|
|
695
|
+
var COMMITMENT_V2_ZK_NONCE = 2n;
|
|
696
|
+
var BINDING_ZK_NONCE = 3n;
|
|
697
|
+
var SIX_BY_SIX_ZK_NONCE = 6n;
|
|
698
|
+
var SIX_BY_SIX_BINDING_ZK_NONCE = 7n;
|
|
699
|
+
var DEFAULT_ZK_CONFIG_NONCE = BINDING_ZK_NONCE;
|
|
700
|
+
function resolveZkConfigNonce(transactEnvironment) {
|
|
701
|
+
return transactEnvironment.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// src/transact/zk/circuit-config.ts
|
|
705
|
+
import { BundledZkCircuit as BundledZkCircuit2 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
706
|
+
var DEFAULT_STELLAR_ZK_CIRCUITS = {
|
|
707
|
+
[BINDING_ZK_NONCE.toString()]: {
|
|
708
|
+
nIns: 2,
|
|
709
|
+
nOuts: 2,
|
|
710
|
+
publicNInputs: 1,
|
|
711
|
+
publicNOutputs: 1,
|
|
712
|
+
circuit: BundledZkCircuit.TwoByTwo
|
|
713
|
+
},
|
|
714
|
+
[SIX_BY_SIX_BINDING_ZK_NONCE.toString()]: {
|
|
715
|
+
nIns: 6,
|
|
716
|
+
nOuts: 6,
|
|
717
|
+
publicNInputs: 1,
|
|
718
|
+
publicNOutputs: 1,
|
|
719
|
+
circuit: BundledZkCircuit.SixBySix
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
function isBundledDefinition(definition) {
|
|
723
|
+
return "circuit" in definition;
|
|
724
|
+
}
|
|
725
|
+
async function fetchBuffer(url) {
|
|
726
|
+
const response = await fetch(url);
|
|
727
|
+
if (!response.ok) {
|
|
728
|
+
throw new Error(`Failed to fetch ZK artifact ${url}: ${String(response.status)}`);
|
|
729
|
+
}
|
|
730
|
+
return response.arrayBuffer();
|
|
731
|
+
}
|
|
732
|
+
async function materializeDefinition(definition) {
|
|
733
|
+
if (isBundledDefinition(definition)) {
|
|
734
|
+
const bundled = {
|
|
735
|
+
nIns: definition.nIns,
|
|
736
|
+
nOuts: definition.nOuts,
|
|
737
|
+
publicNInputs: definition.publicNInputs,
|
|
738
|
+
publicNOutputs: definition.publicNOutputs,
|
|
739
|
+
circuit: definition.circuit
|
|
740
|
+
};
|
|
741
|
+
return bundled;
|
|
742
|
+
}
|
|
743
|
+
const [zkey, circuitGraph, r1cs, provingKey] = await Promise.all([
|
|
744
|
+
fetchBuffer(definition.zkeyUrl),
|
|
745
|
+
fetchBuffer(definition.circuitGraphUrl),
|
|
746
|
+
fetchBuffer(definition.r1csUrl),
|
|
747
|
+
fetchBuffer(definition.provingKeyUrl)
|
|
748
|
+
]);
|
|
749
|
+
const custom = {
|
|
750
|
+
nIns: definition.nIns,
|
|
751
|
+
nOuts: definition.nOuts,
|
|
752
|
+
publicNInputs: definition.publicNInputs,
|
|
753
|
+
publicNOutputs: definition.publicNOutputs,
|
|
754
|
+
zkey,
|
|
755
|
+
circuitGraph,
|
|
756
|
+
r1cs,
|
|
757
|
+
provingKey
|
|
758
|
+
};
|
|
759
|
+
return custom;
|
|
760
|
+
}
|
|
761
|
+
async function materializeSelectedZkCircuit(circuits, nonce) {
|
|
762
|
+
const map = stellarCircuitsOrDefault(circuits);
|
|
763
|
+
const key = nonce.toString();
|
|
764
|
+
const definition = Object.entries(map).find(([nonceKey]) => nonceKey === key)?.[1];
|
|
765
|
+
if (!definition) {
|
|
766
|
+
throw new Error(`no zk circuit configured for nonce ${key}`);
|
|
767
|
+
}
|
|
768
|
+
return { [key]: await materializeDefinition(definition) };
|
|
769
|
+
}
|
|
770
|
+
function stellarCircuitsOrDefault(circuits) {
|
|
771
|
+
return circuits ?? DEFAULT_STELLAR_ZK_CIRCUITS;
|
|
772
|
+
}
|
|
773
|
+
function optionalZkArtifactBaseUrl(value) {
|
|
774
|
+
if (value === void 0) {
|
|
775
|
+
return {};
|
|
776
|
+
}
|
|
777
|
+
const trimmed = value.trim();
|
|
778
|
+
if (trimmed === "") {
|
|
779
|
+
return {};
|
|
780
|
+
}
|
|
781
|
+
let withoutSlash = trimmed;
|
|
782
|
+
while (withoutSlash.endsWith("/")) {
|
|
783
|
+
withoutSlash = withoutSlash.slice(0, -1);
|
|
784
|
+
}
|
|
785
|
+
return { zkArtifactBaseUrl: withoutSlash };
|
|
786
|
+
}
|
|
638
787
|
|
|
639
788
|
// src/transact/pool/aligned-deposit.ts
|
|
640
|
-
import {
|
|
789
|
+
import {
|
|
790
|
+
PrivacyPoolSDK,
|
|
791
|
+
scalarHexToFrDecimal
|
|
792
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
641
793
|
var SAMPLE_SCALAR_ATTEMPTS = 10;
|
|
794
|
+
function escrowDepositFields(parameters) {
|
|
795
|
+
if (!parameters.recipientHi || !parameters.recipientLo) {
|
|
796
|
+
return {};
|
|
797
|
+
}
|
|
798
|
+
return {
|
|
799
|
+
...parameters.escrowNonce ? { escrowNonce: parameters.escrowNonce } : {},
|
|
800
|
+
recipientStellar: [parameters.recipientHi, parameters.recipientLo]
|
|
801
|
+
};
|
|
802
|
+
}
|
|
642
803
|
function sampleValidDepositScalarHex() {
|
|
643
804
|
for (let index = 0; index < SAMPLE_SCALAR_ATTEMPTS; index++) {
|
|
644
805
|
const candidate = PrivacyPoolSDK.generateRandomScalarHex32();
|
|
@@ -654,17 +815,12 @@ function sampleValidDepositScalarHex() {
|
|
|
654
815
|
async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
|
|
655
816
|
const privateAddressPoint = decodePrivateAddress(parameters.privateAddressStpl1);
|
|
656
817
|
const scalarHex = sampleValidDepositScalarHex();
|
|
657
|
-
const shared = sdk.ecdhSharedKey(
|
|
658
|
-
scalarHex,
|
|
659
|
-
privateAddressPoint.x,
|
|
660
|
-
privateAddressPoint.y
|
|
661
|
-
);
|
|
662
818
|
const [assetHi, assetLo] = tokenAddressToAssetLeg(parameters.tokenAddress);
|
|
663
819
|
const resolvedApplicationId = resolvePoolApplicationId(applicationId);
|
|
664
|
-
const generated = sdk.
|
|
820
|
+
const generated = sdk.generateCoinForDepositWithOwnerPubHex(
|
|
665
821
|
scalarHex,
|
|
666
|
-
|
|
667
|
-
|
|
822
|
+
privateAddressPoint.x,
|
|
823
|
+
privateAddressPoint.y,
|
|
668
824
|
parameters.amountStroops,
|
|
669
825
|
assetHi,
|
|
670
826
|
assetLo,
|
|
@@ -679,27 +835,34 @@ async function buildAlignedDepositSlotForSdk(sdk, applicationId, parameters) {
|
|
|
679
835
|
ephemeralKeyScalar: scalarHexToFrDecimal(scalarHex),
|
|
680
836
|
asset: [generated.coin.asset_hi, generated.coin.asset_lo],
|
|
681
837
|
applicationId: resolvedApplicationId,
|
|
682
|
-
recipientPublicKeys
|
|
838
|
+
recipientPublicKeys,
|
|
839
|
+
...escrowDepositFields(parameters)
|
|
683
840
|
};
|
|
684
841
|
return {
|
|
685
842
|
deposit,
|
|
686
843
|
commitment_hex: generated.commitment_hex,
|
|
687
844
|
coin: generated.coin,
|
|
688
845
|
depositScalarHex: scalarHex,
|
|
689
|
-
precommitementHex: generated.
|
|
846
|
+
precommitementHex: generated.precommitementHex
|
|
690
847
|
};
|
|
691
848
|
}
|
|
692
849
|
|
|
693
850
|
// src/transact/pool/service.ts
|
|
694
851
|
var PrivacyPoolService = class {
|
|
695
|
-
constructor(assets, applicationId, auditPublicKey) {
|
|
852
|
+
constructor(assets, applicationId, auditPublicKey, zkCircuits, zkConfigNonce, zkArtifactBaseUrl) {
|
|
696
853
|
this.assets = assets;
|
|
697
854
|
this.applicationId = applicationId;
|
|
698
855
|
this.auditPublicKey = auditPublicKey;
|
|
856
|
+
this.zkCircuits = zkCircuits;
|
|
857
|
+
this.zkConfigNonce = zkConfigNonce;
|
|
858
|
+
this.zkArtifactBaseUrl = zkArtifactBaseUrl;
|
|
699
859
|
}
|
|
700
860
|
assets;
|
|
701
861
|
applicationId;
|
|
702
862
|
auditPublicKey;
|
|
863
|
+
zkCircuits;
|
|
864
|
+
zkConfigNonce;
|
|
865
|
+
zkArtifactBaseUrl;
|
|
703
866
|
sdk = void 0;
|
|
704
867
|
initPromise = void 0;
|
|
705
868
|
async ensureInit() {
|
|
@@ -715,10 +878,16 @@ var PrivacyPoolService = class {
|
|
|
715
878
|
"PrivacyPoolService requires browser ZK assets before initialization."
|
|
716
879
|
);
|
|
717
880
|
}
|
|
718
|
-
this.
|
|
881
|
+
const zkConfigNonce = this.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
|
|
882
|
+
const zkCircuits = await materializeSelectedZkCircuit(
|
|
883
|
+
this.zkCircuits,
|
|
884
|
+
zkConfigNonce
|
|
885
|
+
);
|
|
886
|
+
this.sdk = await PrivacyPoolSDK2.init({
|
|
719
887
|
wasmBinary: this.assets.sdkWasm,
|
|
720
|
-
|
|
721
|
-
|
|
888
|
+
zkCircuits,
|
|
889
|
+
zkConfigNonce,
|
|
890
|
+
...optionalZkArtifactBaseUrl(this.zkArtifactBaseUrl)
|
|
722
891
|
});
|
|
723
892
|
})();
|
|
724
893
|
return this.initPromise;
|
|
@@ -736,22 +905,17 @@ var PrivacyPoolService = class {
|
|
|
736
905
|
getApplicationId() {
|
|
737
906
|
return resolvePoolApplicationId(this.applicationId);
|
|
738
907
|
}
|
|
739
|
-
async generatePrivateAddressFromStellarSignature(signature) {
|
|
740
|
-
await this.
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
return privateAddressSdk(this.sdk).generatePrivateAddressFromStellarSignature(
|
|
745
|
-
signature
|
|
908
|
+
async generatePrivateAddressFromStellarSignature(signature, domain) {
|
|
909
|
+
const sdk = await this.getInitializedSdk();
|
|
910
|
+
return privateAddressSdk(sdk).generatePrivateAddressFromStellarSignature(
|
|
911
|
+
signature,
|
|
912
|
+
domain
|
|
746
913
|
);
|
|
747
914
|
}
|
|
748
915
|
async sharedSecretX(recipientScalarHex, ephemeralKeyEncoded) {
|
|
749
|
-
await this.
|
|
750
|
-
if (!this.sdk) {
|
|
751
|
-
throw new Error("SDK not initialized");
|
|
752
|
-
}
|
|
916
|
+
const sdk = await this.getInitializedSdk();
|
|
753
917
|
const ephemeralKey = decodeDecodedEphemeralKey(ephemeralKeyEncoded);
|
|
754
|
-
const shared =
|
|
918
|
+
const shared = sdk.sharedSecretFromRecipientPreimage({
|
|
755
919
|
recipientScalar: recipientScalarHex,
|
|
756
920
|
ephemeralKey
|
|
757
921
|
});
|
|
@@ -774,6 +938,7 @@ var PrivacyPoolService = class {
|
|
|
774
938
|
const applicationId = this.getApplicationId();
|
|
775
939
|
const audit = buildPoolTransactionAuditParameters({
|
|
776
940
|
applicationId,
|
|
941
|
+
nAuditSlots: sdk.getLayout().nAuditSlots,
|
|
777
942
|
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {}
|
|
778
943
|
});
|
|
779
944
|
const deposit = {
|
|
@@ -787,38 +952,35 @@ var PrivacyPoolService = class {
|
|
|
787
952
|
const publicInput = withTokenAddressPublicInputs(
|
|
788
953
|
{
|
|
789
954
|
stateRoot,
|
|
790
|
-
withdrawAddressHi: "0",
|
|
791
|
-
withdrawAddressLo: "0",
|
|
792
955
|
privKeyScalar: randomFrDecimal253()
|
|
793
956
|
},
|
|
794
957
|
parameters.tokenAddress
|
|
795
958
|
);
|
|
796
959
|
const proof = await sdk.proveTransaction(
|
|
797
960
|
publicInput,
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
961
|
+
padPublicLegsToLayout(
|
|
962
|
+
sdk,
|
|
963
|
+
buildPublicDepositLegs(parameters.tokenAddress, parameters.coin.value)
|
|
964
|
+
),
|
|
965
|
+
padWithdrawSlotsToLayout(sdk, []),
|
|
966
|
+
padDepositSlotsToLayout(sdk, [deposit]),
|
|
801
967
|
audit
|
|
802
968
|
);
|
|
803
|
-
const applicationIdsPlaintext =
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
applicationId
|
|
807
|
-
|
|
808
|
-
];
|
|
969
|
+
const applicationIdsPlaintext = buildApplicationIdHints({
|
|
970
|
+
sdk,
|
|
971
|
+
inputIds: [],
|
|
972
|
+
outputIds: [applicationId]
|
|
973
|
+
});
|
|
809
974
|
return { ...proof, applicationIdsPlaintext };
|
|
810
975
|
}
|
|
811
|
-
async calculateNullifierHash(nullifier) {
|
|
976
|
+
async calculateNullifierHash(nullifier, privKeyScalar) {
|
|
812
977
|
const sdk = await this.getInitializedSdk();
|
|
813
|
-
return sdk.calculateNullifierHash(nullifier);
|
|
978
|
+
return sdk.calculateNullifierHash(nullifier, privKeyScalar);
|
|
814
979
|
}
|
|
815
980
|
async prepareWithdrawTransactProof(parameters) {
|
|
816
|
-
await this.
|
|
817
|
-
if (!this.sdk) {
|
|
818
|
-
throw new Error("SDK not initialized");
|
|
819
|
-
}
|
|
981
|
+
const sdk = await this.getInitializedSdk();
|
|
820
982
|
return proveWithdrawTransact({
|
|
821
|
-
sdk
|
|
983
|
+
sdk,
|
|
822
984
|
applicationId: this.getApplicationId(),
|
|
823
985
|
buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
|
|
824
986
|
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
|
|
@@ -826,12 +988,9 @@ var PrivacyPoolService = class {
|
|
|
826
988
|
});
|
|
827
989
|
}
|
|
828
990
|
async prepareWithdrawTransactProofDual(parameters) {
|
|
829
|
-
await this.
|
|
830
|
-
if (!this.sdk) {
|
|
831
|
-
throw new Error("SDK not initialized");
|
|
832
|
-
}
|
|
991
|
+
const sdk = await this.getInitializedSdk();
|
|
833
992
|
return proveWithdrawTransactDual({
|
|
834
|
-
sdk
|
|
993
|
+
sdk,
|
|
835
994
|
applicationId: this.getApplicationId(),
|
|
836
995
|
buildAlignedDepositSlot: (input) => this.buildAlignedDepositSlot(input),
|
|
837
996
|
...this.auditPublicKey ? { auditPublicKey: this.auditPublicKey } : {},
|
|
@@ -854,7 +1013,10 @@ function createPrivacyPoolService(input) {
|
|
|
854
1013
|
return new PrivacyPoolService(
|
|
855
1014
|
input?.assets,
|
|
856
1015
|
input?.applicationId,
|
|
857
|
-
input?.auditPublicKey
|
|
1016
|
+
input?.auditPublicKey,
|
|
1017
|
+
input?.zkCircuits,
|
|
1018
|
+
input?.zkConfigNonce,
|
|
1019
|
+
input?.zkArtifactBaseUrl
|
|
858
1020
|
);
|
|
859
1021
|
}
|
|
860
1022
|
var configuredPrivacyPoolService;
|
|
@@ -870,146 +1032,476 @@ function getPrivacyPoolService() {
|
|
|
870
1032
|
return configuredPrivacyPoolService;
|
|
871
1033
|
}
|
|
872
1034
|
|
|
873
|
-
// src/transact/
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
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
|
-
});
|
|
1035
|
+
// src/transact/escrow/tag-challenge-message.ts
|
|
1036
|
+
function buildBlindedRecipientTagChallengeMessage(fields) {
|
|
1037
|
+
return [
|
|
1038
|
+
"Arcane privacy layer: issue your blinded recipient tags.",
|
|
1039
|
+
"",
|
|
1040
|
+
`Wallet: ${fields.stellarAddress}`,
|
|
1041
|
+
`Network: ${fields.networkPassphrase}`,
|
|
1042
|
+
`Issued: ${fields.issuedAt}`,
|
|
1043
|
+
`Expires: ${fields.expiresAt}`,
|
|
1044
|
+
`Nonce: ${fields.nonce}`,
|
|
1045
|
+
"",
|
|
1046
|
+
"This signature proves you control the wallet. It is the same kind of signed challenge used to derive your private-note spend key."
|
|
1047
|
+
].join("\n");
|
|
900
1048
|
}
|
|
901
1049
|
|
|
902
|
-
// src/transact/
|
|
903
|
-
import { Buffer as
|
|
904
|
-
import {
|
|
1050
|
+
// src/transact/escrow/derived-escrow-recipient.ts
|
|
1051
|
+
import { Buffer as Buffer8 } from "buffer";
|
|
1052
|
+
import { StrKey as StrKey4 } from "@stellar/stellar-sdk";
|
|
1053
|
+
import {
|
|
1054
|
+
derivedEscrowKey,
|
|
1055
|
+
ed25519PubkeyPayloadHexToWithdrawFrDecimals as ed25519PubkeyPayloadHexToWithdrawFrDecimals2,
|
|
1056
|
+
sampleDerivedEscrowKey
|
|
1057
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
1058
|
+
var COORDINATE_HEX_LENGTH = 64;
|
|
1059
|
+
function stellarAccountToFieldLimbs(stellarAddress) {
|
|
1060
|
+
const pkRaw = StrKey4.decodeEd25519PublicKey(stellarAddress.trim());
|
|
1061
|
+
const pkHex = Buffer8.from(pkRaw).toString("hex");
|
|
1062
|
+
const { hi, lo } = ed25519PubkeyPayloadHexToWithdrawFrDecimals2(pkHex);
|
|
1063
|
+
return { recipientHi: hi, recipientLo: lo };
|
|
1064
|
+
}
|
|
1065
|
+
function padCoordinateHex(value) {
|
|
1066
|
+
return value.replace(/^0x/iu, "").padStart(COORDINATE_HEX_LENGTH, "0");
|
|
1067
|
+
}
|
|
1068
|
+
async function deriveEscrowRecipientFromStellarAddress(input) {
|
|
1069
|
+
const recipientStellarAddress = input.recipientStellarAddress.trim();
|
|
1070
|
+
if (!StrKey4.isValidEd25519PublicKey(recipientStellarAddress)) {
|
|
1071
|
+
throw new Error("Escrow recipient must be a Stellar G-address.");
|
|
1072
|
+
}
|
|
1073
|
+
const { recipientHi, recipientLo } = stellarAccountToFieldLimbs(
|
|
1074
|
+
recipientStellarAddress
|
|
1075
|
+
);
|
|
1076
|
+
const deriveKey = input.deriveKey ?? derivedEscrowKey;
|
|
1077
|
+
let nonceDecimal;
|
|
1078
|
+
let key;
|
|
1079
|
+
if (input.nonceDecimal) {
|
|
1080
|
+
nonceDecimal = input.nonceDecimal;
|
|
1081
|
+
key = await deriveKey(
|
|
1082
|
+
BigInt(nonceDecimal),
|
|
1083
|
+
BigInt(recipientHi),
|
|
1084
|
+
BigInt(recipientLo)
|
|
1085
|
+
);
|
|
1086
|
+
} else {
|
|
1087
|
+
const sampled = await sampleDerivedEscrowKey(
|
|
1088
|
+
BigInt(recipientHi),
|
|
1089
|
+
BigInt(recipientLo)
|
|
1090
|
+
);
|
|
1091
|
+
nonceDecimal = sampled.nonce.toString();
|
|
1092
|
+
key = sampled.key;
|
|
1093
|
+
}
|
|
1094
|
+
return {
|
|
1095
|
+
nonceDecimal,
|
|
1096
|
+
recipientHi,
|
|
1097
|
+
recipientLo,
|
|
1098
|
+
recipientStellarAddress,
|
|
1099
|
+
privateAddressStpl1: encodePrivateAddressFromHexCoordinates(
|
|
1100
|
+
padCoordinateHex(key.pointXHex),
|
|
1101
|
+
padCoordinateHex(key.pointYHex)
|
|
1102
|
+
),
|
|
1103
|
+
scalarHex: padCoordinateHex(key.scalarHex)
|
|
1104
|
+
};
|
|
1105
|
+
}
|
|
905
1106
|
|
|
906
|
-
// src/transact/
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
1107
|
+
// src/transact/escrow/assert-escrow-sweep-claimant.ts
|
|
1108
|
+
import { insufficientStateError } from "@arcanetech/privacy-sdk-core";
|
|
1109
|
+
function assertEscrowSweepClaimant(input) {
|
|
1110
|
+
const walletPublicKey = input.walletPublicKey.trim();
|
|
1111
|
+
const claimantAddress = input.claimantAddress.trim();
|
|
1112
|
+
if (!walletPublicKey || walletPublicKey !== claimantAddress) {
|
|
1113
|
+
const error = insufficientStateError(
|
|
1114
|
+
"escrow_sweep_claimant_mismatch",
|
|
1115
|
+
"Escrow sweep requires the connected account that owns the note.",
|
|
1116
|
+
{ walletPublicKey, claimantAddress }
|
|
1117
|
+
);
|
|
1118
|
+
throw new Error(error.message, { cause: error });
|
|
918
1119
|
}
|
|
919
|
-
return bytes;
|
|
920
1120
|
}
|
|
921
1121
|
|
|
922
|
-
// src/transact/
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
1122
|
+
// src/transact/escrow/reconstruct-escrow-note.ts
|
|
1123
|
+
var FIELD_HEX_LENGTH = 64;
|
|
1124
|
+
function hexToDecimal(hex) {
|
|
1125
|
+
const clean = hex.trim().replace(/^0x/u, "");
|
|
1126
|
+
return BigInt(`0x${clean || "0"}`).toString();
|
|
1127
|
+
}
|
|
1128
|
+
function padFieldHex(value) {
|
|
1129
|
+
return value.replace(/^0x/iu, "").padStart(FIELD_HEX_LENGTH, "0");
|
|
1130
|
+
}
|
|
1131
|
+
async function defaultDecryptOutputNote(input) {
|
|
1132
|
+
const module = await import("@arcanetech/stellar-privacy-pool-zk-sdk");
|
|
1133
|
+
if (typeof module.decryptOutputNoteEvent !== "function") {
|
|
1134
|
+
throw new TypeError("Output note decryption is not available.");
|
|
1135
|
+
}
|
|
1136
|
+
return module.decryptOutputNoteEvent(input);
|
|
1137
|
+
}
|
|
1138
|
+
async function reconstructEscrowNote(input) {
|
|
1139
|
+
const derived = await deriveEscrowRecipientFromStellarAddress({
|
|
1140
|
+
recipientStellarAddress: input.claimantAddress,
|
|
1141
|
+
nonceDecimal: input.nonceDecimal,
|
|
1142
|
+
...input.deriveKey ? { deriveKey: input.deriveKey } : {}
|
|
1143
|
+
});
|
|
1144
|
+
const event = input.events.find((entry) => entry.outputIndex === input.seq);
|
|
1145
|
+
if (!event) {
|
|
1146
|
+
throw new Error("Escrow output note event was not found for this sequence.");
|
|
1147
|
+
}
|
|
1148
|
+
const decrypt = input.decrypt ?? defaultDecryptOutputNote;
|
|
1149
|
+
const decrypted = await decrypt({
|
|
1150
|
+
recipientScalarHex: derived.scalarHex,
|
|
1151
|
+
commitmentHashHex: event.commitmentHashHex,
|
|
1152
|
+
createdEphemeralKey: event.createdEphemeralKey,
|
|
1153
|
+
ciphertext: event.ciphertext,
|
|
1154
|
+
tag: event.tag,
|
|
1155
|
+
ownerMode: 1n
|
|
1156
|
+
});
|
|
932
1157
|
return {
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1158
|
+
coin: {
|
|
1159
|
+
value: decrypted.value,
|
|
1160
|
+
nullifier: decrypted.nullifier,
|
|
1161
|
+
secret: decrypted.secret,
|
|
1162
|
+
commitment: hexToDecimal(decrypted.commitmentHex),
|
|
1163
|
+
asset_hi: decrypted.assetHi,
|
|
1164
|
+
asset_lo: decrypted.assetLo,
|
|
1165
|
+
application_id: decrypted.applicationId
|
|
1166
|
+
},
|
|
1167
|
+
scalarHex: derived.scalarHex,
|
|
1168
|
+
privateAddressStpl1: derived.privateAddressStpl1,
|
|
1169
|
+
recipientHi: derived.recipientHi,
|
|
1170
|
+
recipientLo: derived.recipientLo,
|
|
1171
|
+
nonceDecimal: derived.nonceDecimal,
|
|
1172
|
+
tokenAddress: assetLegToTokenAddress(decrypted.assetHi, decrypted.assetLo),
|
|
1173
|
+
commitmentHex: padFieldHex(decrypted.commitmentHex)
|
|
938
1174
|
};
|
|
939
1175
|
}
|
|
940
1176
|
|
|
941
|
-
// src/transact/
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
1177
|
+
// src/transact/escrow/prepare-escrow-sweep.ts
|
|
1178
|
+
import { StrKey as StrKey5 } from "@stellar/stellar-sdk";
|
|
1179
|
+
var PRIVATE_DISCLOSURE = {
|
|
1180
|
+
senderAddress: "private",
|
|
1181
|
+
recipientAddress: "private",
|
|
1182
|
+
assetAddress: "private",
|
|
1183
|
+
amount: "private"
|
|
1184
|
+
};
|
|
1185
|
+
function requireRegisteredPrivateAddress(value) {
|
|
1186
|
+
const trimmed = value.trim();
|
|
1187
|
+
if (!trimmed || StrKey5.isValidEd25519PublicKey(trimmed)) {
|
|
1188
|
+
throw new Error("Escrow sweep recipient must be a registered private address.");
|
|
1189
|
+
}
|
|
1190
|
+
return trimmed;
|
|
945
1191
|
}
|
|
946
|
-
function
|
|
947
|
-
const [assetHi, assetLo] = tokenAddressToAssetLeg(coin.tokenAddress);
|
|
1192
|
+
function consumedEscrowRecord(input) {
|
|
948
1193
|
return {
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1194
|
+
id: input.reconstructed.commitmentHex,
|
|
1195
|
+
owner: input.walletPublicKey,
|
|
1196
|
+
asset: input.asset,
|
|
1197
|
+
amount: BigInt(input.reconstructed.coin.value),
|
|
1198
|
+
consumed: false,
|
|
1199
|
+
status: "finalized",
|
|
1200
|
+
poolContract: input.poolContract,
|
|
1201
|
+
coinNote: input.reconstructed.coin,
|
|
1202
|
+
privateAddress: input.reconstructed.privateAddressStpl1,
|
|
1203
|
+
commitmentHex: input.reconstructed.commitmentHex
|
|
955
1204
|
};
|
|
956
1205
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
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] };
|
|
1206
|
+
function attachEscrowAuthorization(prepared, escrowAuthorization) {
|
|
1207
|
+
const credential = escrowAuthorization.trim();
|
|
1208
|
+
if (!credential) {
|
|
1209
|
+
throw new Error("Escrow sweep requires a signed authorization entry.");
|
|
977
1210
|
}
|
|
978
1211
|
return {
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
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
|
|
1212
|
+
...prepared,
|
|
1213
|
+
transactArtifacts: {
|
|
1214
|
+
...prepared.transactArtifacts,
|
|
1215
|
+
escrowAuthorization: credential
|
|
1216
|
+
}
|
|
994
1217
|
};
|
|
995
1218
|
}
|
|
996
|
-
|
|
997
|
-
return
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1219
|
+
function sweepTransactArtifacts(input) {
|
|
1220
|
+
return {
|
|
1221
|
+
spendSource: "escrow",
|
|
1222
|
+
escrowRecipient: input.claimantAddress.trim(),
|
|
1223
|
+
escrowSpendScalarHex: input.reconstructed.scalarHex,
|
|
1224
|
+
escrowClaimantLimbs: {
|
|
1225
|
+
recipientHi: input.reconstructed.recipientHi,
|
|
1226
|
+
recipientLo: input.reconstructed.recipientLo,
|
|
1227
|
+
nonceDecimal: input.reconstructed.nonceDecimal
|
|
1002
1228
|
},
|
|
1003
|
-
|
|
1004
|
-
|
|
1229
|
+
executeFinalizeRequired: true,
|
|
1230
|
+
walletPublicKey: input.walletPublicKey
|
|
1231
|
+
};
|
|
1005
1232
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1233
|
+
function prepareEscrowSweepOperation(input) {
|
|
1234
|
+
assertEscrowSweepClaimant({
|
|
1235
|
+
walletPublicKey: input.walletPublicKey,
|
|
1236
|
+
claimantAddress: input.claimantAddress
|
|
1237
|
+
});
|
|
1238
|
+
const walletPublicKey = input.walletPublicKey.trim();
|
|
1239
|
+
const registeredPrivateAddress = requireRegisteredPrivateAddress(
|
|
1240
|
+
input.registeredPrivateAddress
|
|
1241
|
+
);
|
|
1242
|
+
const amount = BigInt(input.reconstructed.coin.value);
|
|
1243
|
+
return {
|
|
1244
|
+
kind: "transfer",
|
|
1245
|
+
intent: {
|
|
1246
|
+
from: input.reconstructed.privateAddressStpl1,
|
|
1247
|
+
to: registeredPrivateAddress,
|
|
1248
|
+
asset: input.asset,
|
|
1249
|
+
amount,
|
|
1250
|
+
disclosure: PRIVATE_DISCLOSURE
|
|
1251
|
+
},
|
|
1252
|
+
consumedRecords: [
|
|
1253
|
+
consumedEscrowRecord({
|
|
1254
|
+
reconstructed: input.reconstructed,
|
|
1255
|
+
walletPublicKey,
|
|
1256
|
+
poolContract: input.poolContract,
|
|
1257
|
+
asset: input.asset
|
|
1258
|
+
})
|
|
1259
|
+
],
|
|
1260
|
+
outputRecords: [],
|
|
1261
|
+
submissionPayload: { operationId: crypto.randomUUID(), signed: false },
|
|
1262
|
+
transactArtifacts: sweepTransactArtifacts({
|
|
1263
|
+
claimantAddress: input.claimantAddress,
|
|
1264
|
+
reconstructed: input.reconstructed,
|
|
1265
|
+
walletPublicKey
|
|
1266
|
+
})
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
// src/transact/escrow/fetch-output-note-events.ts
|
|
1271
|
+
import { Api } from "@stellar/stellar-sdk/rpc";
|
|
1272
|
+
|
|
1273
|
+
// src/rpc/soroban-transaction-meta.ts
|
|
1274
|
+
import { Address, StrKey as StrKey6 } from "@stellar/stellar-sdk";
|
|
1275
|
+
var TRANSACTION_META_SWITCH_SOROBAN_V3 = 3;
|
|
1276
|
+
var TRANSACTION_META_SWITCH_SOROBAN_V4 = 4;
|
|
1277
|
+
function pushSorobanV3ContractEvents(out, meta) {
|
|
1278
|
+
const soroban = meta.v3().sorobanMeta();
|
|
1279
|
+
if (!soroban) {
|
|
1280
|
+
return;
|
|
1281
|
+
}
|
|
1282
|
+
for (const event of soroban.events()) {
|
|
1283
|
+
out.push(event);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
function pushSorobanV4ContractEvents(out, meta) {
|
|
1287
|
+
const v4 = meta.v4();
|
|
1288
|
+
for (const txEvent of v4.events()) {
|
|
1289
|
+
out.push(txEvent.event());
|
|
1290
|
+
}
|
|
1291
|
+
for (const op of v4.operations()) {
|
|
1292
|
+
for (const event of op.events()) {
|
|
1293
|
+
out.push(event);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
function collectContractEventsFromMeta(meta) {
|
|
1298
|
+
const out = [];
|
|
1299
|
+
const code = meta.switch();
|
|
1300
|
+
if (code === TRANSACTION_META_SWITCH_SOROBAN_V3) {
|
|
1301
|
+
pushSorobanV3ContractEvents(out, meta);
|
|
1302
|
+
}
|
|
1303
|
+
if (code === TRANSACTION_META_SWITCH_SOROBAN_V4) {
|
|
1304
|
+
pushSorobanV4ContractEvents(out, meta);
|
|
1305
|
+
}
|
|
1306
|
+
return out;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
// src/rpc/server.ts
|
|
1310
|
+
import { rpc } from "@stellar/stellar-sdk";
|
|
1311
|
+
function createStellarRpcServer(rpcUrl) {
|
|
1312
|
+
return new rpc.Server(rpcUrl.trim(), { allowHttp: true });
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
// src/transact/escrow/parse-output-note-events.ts
|
|
1316
|
+
import { StrKey as StrKey7 } from "@stellar/stellar-sdk";
|
|
1317
|
+
var FIELD_BYTE_LENGTH = 32;
|
|
1318
|
+
var FIELD_HEX_LENGTH2 = 64;
|
|
1319
|
+
var CONTRACT_EVENT_BODY_V0 = 0;
|
|
1320
|
+
var OUTPUT_NOTE_TOPIC_COUNT = 3;
|
|
1321
|
+
function extractSymbol(value) {
|
|
1322
|
+
try {
|
|
1323
|
+
if (value.switch().name === "scvSymbol") {
|
|
1324
|
+
return value.sym().toString();
|
|
1325
|
+
}
|
|
1326
|
+
if (value.switch().name === "scvString") {
|
|
1327
|
+
return value.str().toString();
|
|
1328
|
+
}
|
|
1329
|
+
} catch {
|
|
1330
|
+
return void 0;
|
|
1331
|
+
}
|
|
1332
|
+
return void 0;
|
|
1333
|
+
}
|
|
1334
|
+
function readBytes(value) {
|
|
1335
|
+
if (!value) {
|
|
1336
|
+
return void 0;
|
|
1337
|
+
}
|
|
1338
|
+
try {
|
|
1339
|
+
if (value.switch().name !== "scvBytes") {
|
|
1340
|
+
return void 0;
|
|
1341
|
+
}
|
|
1342
|
+
return Buffer.from(value.bytes());
|
|
1343
|
+
} catch {
|
|
1344
|
+
return void 0;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
function readU32(value) {
|
|
1348
|
+
if (!value) {
|
|
1349
|
+
return void 0;
|
|
1350
|
+
}
|
|
1351
|
+
try {
|
|
1352
|
+
if (value.switch().name !== "scvU32") {
|
|
1353
|
+
return void 0;
|
|
1354
|
+
}
|
|
1355
|
+
return value.u32();
|
|
1356
|
+
} catch {
|
|
1357
|
+
return void 0;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
function fieldHex(bytes) {
|
|
1361
|
+
return bytes.toString("hex").padStart(FIELD_HEX_LENGTH2, "0");
|
|
1362
|
+
}
|
|
1363
|
+
function ciphertextLimbs(bytes) {
|
|
1364
|
+
if (bytes.length === 0 || bytes.length % FIELD_BYTE_LENGTH !== 0) {
|
|
1365
|
+
return [];
|
|
1366
|
+
}
|
|
1367
|
+
const limbs = [];
|
|
1368
|
+
for (let offset = 0; offset < bytes.length; offset += FIELD_BYTE_LENGTH) {
|
|
1369
|
+
limbs.push(fieldHex(bytes.subarray(offset, offset + FIELD_BYTE_LENGTH)));
|
|
1370
|
+
}
|
|
1371
|
+
return limbs;
|
|
1372
|
+
}
|
|
1373
|
+
function payloadMap(data) {
|
|
1374
|
+
const entries = /* @__PURE__ */ new Map();
|
|
1375
|
+
try {
|
|
1376
|
+
if (data.switch().name !== "scvMap") {
|
|
1377
|
+
return entries;
|
|
1378
|
+
}
|
|
1379
|
+
const mapped = data.map();
|
|
1380
|
+
if (!mapped) {
|
|
1381
|
+
return entries;
|
|
1382
|
+
}
|
|
1383
|
+
for (const entry of mapped) {
|
|
1384
|
+
const key = extractSymbol(entry.key());
|
|
1385
|
+
if (key) {
|
|
1386
|
+
entries.set(key, entry.val());
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
} catch {
|
|
1390
|
+
return entries;
|
|
1391
|
+
}
|
|
1392
|
+
return entries;
|
|
1393
|
+
}
|
|
1394
|
+
function hashToBuffer(value) {
|
|
1395
|
+
return Buffer.isBuffer(value) ? value : void 0;
|
|
1396
|
+
}
|
|
1397
|
+
function eventContractId(event) {
|
|
1398
|
+
try {
|
|
1399
|
+
const contractId = hashToBuffer(event.contractId());
|
|
1400
|
+
if (!contractId) {
|
|
1401
|
+
return void 0;
|
|
1402
|
+
}
|
|
1403
|
+
return StrKey7.encodeContract(contractId);
|
|
1404
|
+
} catch {
|
|
1405
|
+
return void 0;
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
function eventMatchesPool(event, poolAddress) {
|
|
1409
|
+
const contractId = eventContractId(event);
|
|
1410
|
+
return contractId === void 0 || contractId === poolAddress.trim();
|
|
1411
|
+
}
|
|
1412
|
+
function outputNoteEventBody(event) {
|
|
1413
|
+
if (event.type().name !== "contract") {
|
|
1414
|
+
return void 0;
|
|
1415
|
+
}
|
|
1416
|
+
const body = event.body();
|
|
1417
|
+
if (body.switch() !== CONTRACT_EVENT_BODY_V0) {
|
|
1418
|
+
return void 0;
|
|
1419
|
+
}
|
|
1420
|
+
return body.v0();
|
|
1421
|
+
}
|
|
1422
|
+
function outputNoteFromPayload(topics, payload) {
|
|
1423
|
+
const commitment = readBytes(topics[2]);
|
|
1424
|
+
const outputIndex = readU32(payload.get("output_index"));
|
|
1425
|
+
const ephemeralX = readBytes(payload.get("ephemeral_x"));
|
|
1426
|
+
const ephemeralY = readBytes(payload.get("ephemeral_y"));
|
|
1427
|
+
const ciphertextBytes = readBytes(payload.get("ciphertext"));
|
|
1428
|
+
const tag = readBytes(payload.get("tag"));
|
|
1429
|
+
const ciphertext = ciphertextBytes ? ciphertextLimbs(ciphertextBytes) : [];
|
|
1430
|
+
if (!commitment || outputIndex === void 0 || !ephemeralX || !ephemeralY || ciphertext.length === 0 || !tag) {
|
|
1431
|
+
return void 0;
|
|
1432
|
+
}
|
|
1433
|
+
return {
|
|
1434
|
+
outputIndex,
|
|
1435
|
+
commitmentHashHex: fieldHex(commitment),
|
|
1436
|
+
createdEphemeralKey: [fieldHex(ephemeralX), fieldHex(ephemeralY)],
|
|
1437
|
+
ciphertext,
|
|
1438
|
+
tag: fieldHex(tag)
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
function parseEscrowOutputNoteEvent(event, poolAddress) {
|
|
1442
|
+
if (!eventMatchesPool(event, poolAddress)) {
|
|
1443
|
+
return void 0;
|
|
1444
|
+
}
|
|
1445
|
+
const v0 = outputNoteEventBody(event);
|
|
1446
|
+
const topics = v0?.topics();
|
|
1447
|
+
if (!v0 || !Array.isArray(topics) || topics.length < OUTPUT_NOTE_TOPIC_COUNT) {
|
|
1448
|
+
return void 0;
|
|
1449
|
+
}
|
|
1450
|
+
if (extractSymbol(topics[0]) !== "audit" || extractSymbol(topics[1]) !== "output_note") {
|
|
1451
|
+
return void 0;
|
|
1452
|
+
}
|
|
1453
|
+
return outputNoteFromPayload(topics, payloadMap(v0.data()));
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
// src/transact/escrow/fetch-output-note-events.ts
|
|
1457
|
+
async function fetchEscrowOutputNoteEvents(input) {
|
|
1458
|
+
const txId = input.txId.trim();
|
|
1459
|
+
if (!txId) {
|
|
1460
|
+
throw new Error("Escrow output-note transaction id is missing.");
|
|
1461
|
+
}
|
|
1462
|
+
const response = await createStellarRpcServer(
|
|
1463
|
+
input.transactEnvironment.network.rpcUrl
|
|
1464
|
+
).getTransaction(txId);
|
|
1465
|
+
if (response.status !== Api.GetTransactionStatus.SUCCESS) {
|
|
1466
|
+
throw new Error("Escrow output-note transaction was not found.");
|
|
1467
|
+
}
|
|
1468
|
+
const meta = response.resultMetaXdr;
|
|
1469
|
+
if (!meta) {
|
|
1470
|
+
return [];
|
|
1471
|
+
}
|
|
1472
|
+
const events = [];
|
|
1473
|
+
for (const event of collectContractEventsFromMeta(meta)) {
|
|
1474
|
+
const parsed = parseEscrowOutputNoteEvent(event, input.poolAddress);
|
|
1475
|
+
if (parsed) {
|
|
1476
|
+
events.push(parsed);
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
return events;
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
// src/transact/escrow/simulate-escrow-authorization.ts
|
|
1483
|
+
import {
|
|
1484
|
+
Account,
|
|
1485
|
+
Address as Address3,
|
|
1486
|
+
Contract,
|
|
1487
|
+
nativeToScVal as nativeToScVal2,
|
|
1488
|
+
TransactionBuilder as TransactionBuilder2,
|
|
1489
|
+
rpc as rpc4
|
|
1490
|
+
} from "@stellar/stellar-sdk";
|
|
1491
|
+
import { Buffer as Buffer10 } from "buffer";
|
|
1492
|
+
|
|
1493
|
+
// src/transact/kyt/passage/inspect.ts
|
|
1494
|
+
import {
|
|
1495
|
+
layoutForKnownNonce,
|
|
1496
|
+
zeroBindingTagsInPublicSignals
|
|
1497
|
+
} from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
1498
|
+
|
|
1499
|
+
// src/transact/kyt/inspect-error.ts
|
|
1500
|
+
var KytInspectError = class extends Error {
|
|
1501
|
+
reasonCode;
|
|
1502
|
+
decisionId;
|
|
1503
|
+
detailAddress;
|
|
1504
|
+
constructor(parameters) {
|
|
1013
1505
|
super(parameters.message);
|
|
1014
1506
|
this.name = "KytInspectError";
|
|
1015
1507
|
this.reasonCode = parameters.reasonCode;
|
|
@@ -1032,18 +1524,6 @@ function parseKytReasonCode(reasonCode) {
|
|
|
1032
1524
|
};
|
|
1033
1525
|
}
|
|
1034
1526
|
|
|
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
1527
|
// src/transact/kyt/passage/poll.ts
|
|
1048
1528
|
import "@stellar/stellar-sdk";
|
|
1049
1529
|
var KYT_REGISTER_MAX_POLLS = 60;
|
|
@@ -1098,20 +1578,20 @@ async function waitForKytRegistration(parameters) {
|
|
|
1098
1578
|
}
|
|
1099
1579
|
|
|
1100
1580
|
// src/transact/kyt/passage/submit.ts
|
|
1101
|
-
import { Buffer as
|
|
1102
|
-
import { Operation, TransactionBuilder, rpc as
|
|
1581
|
+
import { Buffer as Buffer9 } from "buffer";
|
|
1582
|
+
import { Operation, TransactionBuilder, rpc as rpc3, xdr as xdr3 } from "@stellar/stellar-sdk";
|
|
1103
1583
|
var KYT_REGISTER_FEE_STROOPS = "1000000";
|
|
1104
1584
|
var KYT_REGISTER_TIMEOUT_SECONDS = 300;
|
|
1105
1585
|
function passageIdToScValue(passageId) {
|
|
1106
|
-
return
|
|
1586
|
+
return xdr3.ScVal.scvBytes(Buffer9.from(passageId.replace(/^0x/, ""), "hex"));
|
|
1107
1587
|
}
|
|
1108
1588
|
function approvalSignatureToBytes(signature) {
|
|
1109
1589
|
const clean = signature.trim();
|
|
1110
|
-
return /^(0x)?[0-9a-fA-F]{128}$/.test(clean) ?
|
|
1590
|
+
return /^(0x)?[0-9a-fA-F]{128}$/.test(clean) ? Buffer9.from(clean.replace(/^0x/i, ""), "hex") : Buffer9.from(clean, "base64");
|
|
1111
1591
|
}
|
|
1112
1592
|
function signatureToScValue(signature) {
|
|
1113
1593
|
const bytes = approvalSignatureToBytes(signature);
|
|
1114
|
-
return
|
|
1594
|
+
return xdr3.ScVal.scvBytes(bytes);
|
|
1115
1595
|
}
|
|
1116
1596
|
async function registerKytPassage(parameters) {
|
|
1117
1597
|
const signTransaction = parameters.transactEnvironment.signTransaction;
|
|
@@ -1121,7 +1601,7 @@ async function registerKytPassage(parameters) {
|
|
|
1121
1601
|
);
|
|
1122
1602
|
}
|
|
1123
1603
|
const kytRegistry = parameters.transactEnvironment.kyt.kytPassageRegistryContract;
|
|
1124
|
-
const server = new
|
|
1604
|
+
const server = new rpc3.Server(parameters.sorobanRpcUrl, { allowHttp: true });
|
|
1125
1605
|
const sourceAccount = await server.getAccount(parameters.owner);
|
|
1126
1606
|
const transaction = new TransactionBuilder(sourceAccount, {
|
|
1127
1607
|
fee: KYT_REGISTER_FEE_STROOPS,
|
|
@@ -1132,7 +1612,7 @@ async function registerKytPassage(parameters) {
|
|
|
1132
1612
|
function: "register_passage",
|
|
1133
1613
|
args: [
|
|
1134
1614
|
passageIdToScValue(parameters.approval.passageId),
|
|
1135
|
-
|
|
1615
|
+
xdr3.ScVal.scvU32(parameters.approval.expiresAtLedger),
|
|
1136
1616
|
signatureToScValue(parameters.approval.signature)
|
|
1137
1617
|
]
|
|
1138
1618
|
})
|
|
@@ -1156,8 +1636,8 @@ async function registerKytPassage(parameters) {
|
|
|
1156
1636
|
}
|
|
1157
1637
|
|
|
1158
1638
|
// src/transact/kyt/passage/inspect.ts
|
|
1159
|
-
function
|
|
1160
|
-
return
|
|
1639
|
+
function buildApplicationIdHints2(applicationId, nAuditSlots) {
|
|
1640
|
+
return uniformApplicationIdHints(applicationId, nAuditSlots);
|
|
1161
1641
|
}
|
|
1162
1642
|
function buildNonce() {
|
|
1163
1643
|
return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}`;
|
|
@@ -1185,36 +1665,61 @@ function throwKytInspectRejected(body) {
|
|
|
1185
1665
|
...parsed.address ? { detailAddress: parsed.address } : {}
|
|
1186
1666
|
});
|
|
1187
1667
|
}
|
|
1188
|
-
|
|
1189
|
-
const
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1668
|
+
function inspectRequestHeaders(inspectAuthorization) {
|
|
1669
|
+
const token = inspectAuthorization?.trim();
|
|
1670
|
+
return {
|
|
1671
|
+
"content-type": "application/json",
|
|
1672
|
+
...token ? { authorization: `Bearer ${token}` } : {}
|
|
1673
|
+
};
|
|
1674
|
+
}
|
|
1675
|
+
async function postKytInspect(input, applicationIdsPlaintext, zkConfigNonce, currentLedger) {
|
|
1195
1676
|
const response = await fetch(
|
|
1196
1677
|
`${input.transactEnvironment.kyt.apiBaseUrl}/kyt/passages/inspect`,
|
|
1197
1678
|
{
|
|
1198
1679
|
method: "POST",
|
|
1199
|
-
headers:
|
|
1680
|
+
headers: inspectRequestHeaders(
|
|
1681
|
+
input.transactEnvironment.kyt.inspectAuthorization
|
|
1682
|
+
),
|
|
1200
1683
|
body: JSON.stringify(
|
|
1201
1684
|
{
|
|
1202
1685
|
owner: input.owner,
|
|
1203
1686
|
poolContract: input.poolContract,
|
|
1204
|
-
kytRegistry,
|
|
1687
|
+
kytRegistry: input.transactEnvironment.kyt.kytPassageRegistryContract,
|
|
1205
1688
|
proofBytes: input.proofHex,
|
|
1206
|
-
publicSignalsBytes:
|
|
1689
|
+
publicSignalsBytes: zeroBindingTagsInPublicSignals(
|
|
1690
|
+
input.publicHex,
|
|
1691
|
+
zkConfigNonce
|
|
1692
|
+
).toString("hex"),
|
|
1207
1693
|
applicationIdsPlaintext,
|
|
1208
1694
|
decryptedAuditSlots: input.decryptedAuditSlots,
|
|
1209
|
-
onboarding: input.onboarding,
|
|
1210
1695
|
nonce: buildNonce(),
|
|
1211
|
-
|
|
1696
|
+
zkConfigNonce,
|
|
1697
|
+
currentLedger,
|
|
1698
|
+
...input.ciphertextHex ? { ciphertextBytes: input.ciphertextHex } : {},
|
|
1699
|
+
...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {}
|
|
1212
1700
|
},
|
|
1213
1701
|
kytJsonReplacer
|
|
1214
1702
|
)
|
|
1215
1703
|
}
|
|
1216
1704
|
);
|
|
1217
|
-
|
|
1705
|
+
return parseInspectResponse(response);
|
|
1706
|
+
}
|
|
1707
|
+
async function requestKytPassageForPoolInteraction(input) {
|
|
1708
|
+
const applicationId = resolvePoolApplicationId(
|
|
1709
|
+
input.transactEnvironment.network.applicationId
|
|
1710
|
+
);
|
|
1711
|
+
const zkConfigNonce = resolveZkConfigNonce(input.transactEnvironment);
|
|
1712
|
+
const applicationIdsPlaintext = input.applicationIdsPlaintext ?? buildApplicationIdHints2(
|
|
1713
|
+
applicationId,
|
|
1714
|
+
layoutForKnownNonce(zkConfigNonce).nAuditSlots
|
|
1715
|
+
);
|
|
1716
|
+
const currentLedger = await fetchCurrentLedger(input.sorobanRpcUrl);
|
|
1717
|
+
const body = await postKytInspect(
|
|
1718
|
+
input,
|
|
1719
|
+
applicationIdsPlaintext,
|
|
1720
|
+
zkConfigNonce,
|
|
1721
|
+
currentLedger
|
|
1722
|
+
);
|
|
1218
1723
|
if (body.status !== "approved") {
|
|
1219
1724
|
throwKytInspectRejected(body);
|
|
1220
1725
|
}
|
|
@@ -1230,6 +1735,216 @@ async function requestKytPassageForPoolInteraction(input) {
|
|
|
1230
1735
|
return body;
|
|
1231
1736
|
}
|
|
1232
1737
|
|
|
1738
|
+
// src/transact/escrow/kyt-authorization-sc-value.ts
|
|
1739
|
+
import { nativeToScVal } from "@stellar/stellar-sdk";
|
|
1740
|
+
function kytAuthorizationScValue(parameters) {
|
|
1741
|
+
return nativeToScVal(
|
|
1742
|
+
{
|
|
1743
|
+
expiration_ledger: parameters.expirationLedger,
|
|
1744
|
+
signature: parameters.signature
|
|
1745
|
+
},
|
|
1746
|
+
{
|
|
1747
|
+
type: {
|
|
1748
|
+
expiration_ledger: ["symbol", "u32"],
|
|
1749
|
+
signature: ["symbol", "bytes"]
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
);
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
// src/transact/escrow/pick-escrow-authorization.ts
|
|
1756
|
+
import { Address as Address2 } from "@stellar/stellar-sdk";
|
|
1757
|
+
function credentialAddress(entry) {
|
|
1758
|
+
try {
|
|
1759
|
+
const credentials = entry.credentials();
|
|
1760
|
+
if (credentials.switch().name !== "sorobanCredentialsAddress") {
|
|
1761
|
+
return void 0;
|
|
1762
|
+
}
|
|
1763
|
+
return Address2.fromScAddress(credentials.address().address()).toString();
|
|
1764
|
+
} catch {
|
|
1765
|
+
return void 0;
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
function pickUnsignedEscrowAuthorization(input) {
|
|
1769
|
+
const claimant = input.claimantAddress.trim();
|
|
1770
|
+
const match = input.auth.find((entry) => credentialAddress(entry) === claimant);
|
|
1771
|
+
if (!match) {
|
|
1772
|
+
throw new Error("Simulation did not return a claimant authorization entry.");
|
|
1773
|
+
}
|
|
1774
|
+
return match.toXDR("base64");
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
// src/transact/escrow/simulate-escrow-authorization.ts
|
|
1778
|
+
var SIMULATE_FEE = "100";
|
|
1779
|
+
var SIMULATE_TIMEOUT_SECONDS = 30;
|
|
1780
|
+
var RECORD_NONROOT_AUTH = "record_allow_nonroot";
|
|
1781
|
+
function hexToBytes(hex) {
|
|
1782
|
+
return Buffer10.from(hex.replace(/^0x/iu, ""), "hex");
|
|
1783
|
+
}
|
|
1784
|
+
function optionalSweepCiphertext(artifacts) {
|
|
1785
|
+
return {
|
|
1786
|
+
...artifacts?.ciphertextHex ? { ciphertextHex: artifacts.ciphertextHex } : {},
|
|
1787
|
+
...artifacts?.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: artifacts.outputNoteEphemeralScalars } : {}
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1790
|
+
function requireSweepArtifacts(prepared) {
|
|
1791
|
+
const artifacts = prepared.transactArtifacts;
|
|
1792
|
+
const proofHex = artifacts?.proofHex?.trim();
|
|
1793
|
+
const publicHex = artifacts?.publicHex?.trim();
|
|
1794
|
+
const escrowRecipient = artifacts?.escrowRecipient?.trim();
|
|
1795
|
+
if (!proofHex || !publicHex || !escrowRecipient) {
|
|
1796
|
+
throw new Error("Prepared sweep is missing proof, public signals, or claimant.");
|
|
1797
|
+
}
|
|
1798
|
+
return {
|
|
1799
|
+
proofHex,
|
|
1800
|
+
publicHex,
|
|
1801
|
+
escrowRecipient,
|
|
1802
|
+
...optionalSweepCiphertext(artifacts)
|
|
1803
|
+
};
|
|
1804
|
+
}
|
|
1805
|
+
function requireRelayerPublicKey(value) {
|
|
1806
|
+
const relayerPublicKey = value.trim();
|
|
1807
|
+
if (!relayerPublicKey) {
|
|
1808
|
+
throw new Error("Escrow sweep simulation requires the relayer public key.");
|
|
1809
|
+
}
|
|
1810
|
+
return relayerPublicKey;
|
|
1811
|
+
}
|
|
1812
|
+
async function inspectRelayerSweepKyt(input) {
|
|
1813
|
+
const environment = input.transactEnvironment;
|
|
1814
|
+
return requestKytPassageForPoolInteraction({
|
|
1815
|
+
owner: input.relayerPublicKey,
|
|
1816
|
+
poolContract: environment.network.poolContract,
|
|
1817
|
+
proofHex: input.artifacts.proofHex,
|
|
1818
|
+
publicHex: input.artifacts.publicHex,
|
|
1819
|
+
...input.artifacts.ciphertextHex ? { ciphertextHex: input.artifacts.ciphertextHex } : {},
|
|
1820
|
+
...input.artifacts.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.artifacts.outputNoteEphemeralScalars } : {},
|
|
1821
|
+
...input.prepared.transactArtifacts?.applicationIdsPlaintext ? {
|
|
1822
|
+
applicationIdsPlaintext: input.prepared.transactArtifacts.applicationIdsPlaintext
|
|
1823
|
+
} : {},
|
|
1824
|
+
networkPassphrase: environment.network.networkPassphrase,
|
|
1825
|
+
sorobanRpcUrl: environment.network.rpcUrl,
|
|
1826
|
+
transactEnvironment: environment
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1829
|
+
async function simulateSweepAuthEntries(input) {
|
|
1830
|
+
const environment = input.transactEnvironment;
|
|
1831
|
+
const server = createStellarRpcServer(environment.network.rpcUrl);
|
|
1832
|
+
const account = await server.getAccount(input.relayerPublicKey);
|
|
1833
|
+
const operation = new Contract(environment.network.poolContract).call(
|
|
1834
|
+
"transact",
|
|
1835
|
+
new Address3(input.relayerPublicKey).toScVal(),
|
|
1836
|
+
nativeToScVal2(resolveZkConfigNonce(environment), { type: "u64" }),
|
|
1837
|
+
nativeToScVal2(hexToBytes(input.artifacts.proofHex), { type: "bytes" }),
|
|
1838
|
+
nativeToScVal2(hexToBytes(input.artifacts.publicHex), { type: "bytes" }),
|
|
1839
|
+
nativeToScVal2(hexToBytes(input.artifacts.ciphertextHex ?? ""), { type: "bytes" }),
|
|
1840
|
+
kytAuthorizationScValue({
|
|
1841
|
+
expirationLedger: input.approval.expiresAtLedger,
|
|
1842
|
+
signature: approvalSignatureToBytes(input.approval.signature)
|
|
1843
|
+
})
|
|
1844
|
+
);
|
|
1845
|
+
const built = new TransactionBuilder2(
|
|
1846
|
+
new Account(account.accountId(), account.sequenceNumber()),
|
|
1847
|
+
{
|
|
1848
|
+
fee: SIMULATE_FEE,
|
|
1849
|
+
networkPassphrase: environment.network.networkPassphrase
|
|
1850
|
+
}
|
|
1851
|
+
).addOperation(operation).setTimeout(SIMULATE_TIMEOUT_SECONDS).build();
|
|
1852
|
+
const simulated = await server.simulateTransaction(
|
|
1853
|
+
built,
|
|
1854
|
+
{ cpuInstructions: 0 },
|
|
1855
|
+
RECORD_NONROOT_AUTH
|
|
1856
|
+
);
|
|
1857
|
+
if (rpc4.Api.isSimulationError(simulated)) {
|
|
1858
|
+
throw new Error(`Escrow sweep authorization simulation failed: ${simulated.error}`);
|
|
1859
|
+
}
|
|
1860
|
+
return simulated.result?.auth ?? [];
|
|
1861
|
+
}
|
|
1862
|
+
async function unsignedEscrowAuthorizationForSweep(input) {
|
|
1863
|
+
const relayerPublicKey = requireRelayerPublicKey(input.relayerPublicKey);
|
|
1864
|
+
const artifacts = requireSweepArtifacts(input.prepared);
|
|
1865
|
+
const approval = await inspectRelayerSweepKyt({
|
|
1866
|
+
artifacts,
|
|
1867
|
+
prepared: input.prepared,
|
|
1868
|
+
transactEnvironment: input.transactEnvironment,
|
|
1869
|
+
relayerPublicKey
|
|
1870
|
+
});
|
|
1871
|
+
const auth = await simulateSweepAuthEntries({
|
|
1872
|
+
artifacts,
|
|
1873
|
+
transactEnvironment: input.transactEnvironment,
|
|
1874
|
+
relayerPublicKey,
|
|
1875
|
+
approval
|
|
1876
|
+
});
|
|
1877
|
+
return pickUnsignedEscrowAuthorization({
|
|
1878
|
+
auth,
|
|
1879
|
+
claimantAddress: artifacts.escrowRecipient
|
|
1880
|
+
});
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
// src/transact/assets/load-browser.ts
|
|
1884
|
+
async function loadStellarBrowserAssets(input) {
|
|
1885
|
+
const cacheKey = input.cacheBust ? `?v=${Date.now()}` : "";
|
|
1886
|
+
const sdkWasm = await fetch(`${input.sdkWasmUrl}${cacheKey}`).then(
|
|
1887
|
+
(response) => response.arrayBuffer()
|
|
1888
|
+
);
|
|
1889
|
+
return { sdkWasm };
|
|
1890
|
+
}
|
|
1891
|
+
async function loadDefaultStellarBrowserAssets(options) {
|
|
1892
|
+
await import("@arcanetech/stellar-privacy-pool-zk-sdk");
|
|
1893
|
+
const sdkWasmUrl = new URL(
|
|
1894
|
+
"@arcanetech/stellar-privacy-pool-zk-sdk/sdk.wasm",
|
|
1895
|
+
import.meta.url
|
|
1896
|
+
).href;
|
|
1897
|
+
return loadStellarBrowserAssets({
|
|
1898
|
+
sdkWasmUrl,
|
|
1899
|
+
...options?.cacheBust ? { cacheBust: true } : {}
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
// src/transact/private-address/temporary-recipient.ts
|
|
1904
|
+
import { PrivacyPoolSDK as PrivacyPoolSDK3 } from "@arcanetech/stellar-privacy-pool-zk-sdk";
|
|
1905
|
+
var COORDINATE_HEX_LENGTH2 = 64;
|
|
1906
|
+
async function generateRandomDepositScalarHex() {
|
|
1907
|
+
await getPrivacyPoolService().getInitializedSdk();
|
|
1908
|
+
return PrivacyPoolSDK3.generateRandomScalarHex32();
|
|
1909
|
+
}
|
|
1910
|
+
async function generateTemporaryRecipientPrivateAddress() {
|
|
1911
|
+
await getPrivacyPoolService().getInitializedSdk();
|
|
1912
|
+
const temporaryScalarHex = PrivacyPoolSDK3.generateRandomScalarHex32();
|
|
1913
|
+
const sdk = await getPrivacyPoolService().getInitializedSdk();
|
|
1914
|
+
const point = sdk.ecdhEphemeralPublicKeyFromScalarHex(temporaryScalarHex);
|
|
1915
|
+
const publicKeyXHex = point.x.padStart(COORDINATE_HEX_LENGTH2, "0");
|
|
1916
|
+
const publicKeyYHex = point.y.padStart(COORDINATE_HEX_LENGTH2, "0");
|
|
1917
|
+
return {
|
|
1918
|
+
temporaryScalarHex,
|
|
1919
|
+
temporaryPrivateAddressStpl1: encodePrivateAddressFromHexCoordinates(
|
|
1920
|
+
publicKeyXHex,
|
|
1921
|
+
publicKeyYHex
|
|
1922
|
+
)
|
|
1923
|
+
};
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
// src/contracts/contract-context.ts
|
|
1927
|
+
function requireContractContext(environment) {
|
|
1928
|
+
if (!environment || !("contractContext" in environment)) {
|
|
1929
|
+
throw new Error("Contract context is not configured on the transact environment.");
|
|
1930
|
+
}
|
|
1931
|
+
const resolved = environment;
|
|
1932
|
+
return resolved.contractContext;
|
|
1933
|
+
}
|
|
1934
|
+
function readPoolClientFactory(environment) {
|
|
1935
|
+
return requireContractContext(environment).createPoolClient;
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
// src/transact/pool/proof-types.ts
|
|
1939
|
+
function ciphertextArtifactsFromProof(proof) {
|
|
1940
|
+
return {
|
|
1941
|
+
...proof.ciphertext_hex === void 0 ? {} : { ciphertextHex: proof.ciphertext_hex },
|
|
1942
|
+
...proof.output_note_ephemeral_scalars === void 0 ? {} : {
|
|
1943
|
+
outputNoteEphemeralScalars: [...proof.output_note_ephemeral_scalars]
|
|
1944
|
+
}
|
|
1945
|
+
};
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1233
1948
|
// src/transact/submit/ttl-preflight.ts
|
|
1234
1949
|
function getNested(source, path) {
|
|
1235
1950
|
let cursor = source;
|
|
@@ -1274,14 +1989,129 @@ async function runTtlPreflight(assembledTransaction) {
|
|
|
1274
1989
|
await maybeCallFunction(assembledTransaction, "simulate");
|
|
1275
1990
|
}
|
|
1276
1991
|
|
|
1992
|
+
// src/transact/submit/zk-config-ttl.ts
|
|
1993
|
+
import {
|
|
1994
|
+
Address as Address4,
|
|
1995
|
+
Operation as Operation2,
|
|
1996
|
+
SorobanDataBuilder,
|
|
1997
|
+
TransactionBuilder as TransactionBuilder3,
|
|
1998
|
+
rpc as rpc5,
|
|
1999
|
+
xdr as xdr5
|
|
2000
|
+
} from "@stellar/stellar-sdk";
|
|
2001
|
+
var ZK_CONFIG_TTL_THRESHOLD_LEDGERS = 1e5;
|
|
2002
|
+
var ZK_CONFIG_TTL_EXTEND_TO_LEDGERS = 5e5;
|
|
2003
|
+
var EXTEND_TTL_FEE_STROOPS = "1000000";
|
|
2004
|
+
var EXTEND_TTL_TIMEOUT_SECONDS = 300;
|
|
2005
|
+
var EXTEND_TTL_MAX_POLLS = 60;
|
|
2006
|
+
var EXTEND_TTL_POLL_INTERVAL_MS = 1e3;
|
|
2007
|
+
async function waitForExtendFootprintTtlConfirmation(parameters) {
|
|
2008
|
+
for (let attempt = 0; attempt < EXTEND_TTL_MAX_POLLS; attempt += 1) {
|
|
2009
|
+
const response = await parameters.server.getTransaction(parameters.hash);
|
|
2010
|
+
if (response.status === "SUCCESS") {
|
|
2011
|
+
return;
|
|
2012
|
+
}
|
|
2013
|
+
if (response.status === "FAILED") {
|
|
2014
|
+
throw new Error("ZK config TTL extension failed on-chain");
|
|
2015
|
+
}
|
|
2016
|
+
await new Promise((resolve) => {
|
|
2017
|
+
setTimeout(resolve, EXTEND_TTL_POLL_INTERVAL_MS);
|
|
2018
|
+
});
|
|
2019
|
+
}
|
|
2020
|
+
throw new Error("ZK config TTL extension was not confirmed in time");
|
|
2021
|
+
}
|
|
2022
|
+
function zkConfigLedgerKey(contractId, nonce) {
|
|
2023
|
+
const configKeyScValue = xdr5.ScVal.scvVec([
|
|
2024
|
+
xdr5.ScVal.scvSymbol("Config"),
|
|
2025
|
+
xdr5.ScVal.scvU64(xdr5.Uint64.fromString(nonce.toString()))
|
|
2026
|
+
]);
|
|
2027
|
+
return xdr5.LedgerKey.contractData(
|
|
2028
|
+
new xdr5.LedgerKeyContractData({
|
|
2029
|
+
contract: new Address4(contractId).toScAddress(),
|
|
2030
|
+
key: configKeyScValue,
|
|
2031
|
+
durability: xdr5.ContractDataDurability.persistent()
|
|
2032
|
+
})
|
|
2033
|
+
);
|
|
2034
|
+
}
|
|
2035
|
+
async function needsTtlExtension(parameters) {
|
|
2036
|
+
const [entriesResponse, latestLedger] = await Promise.all([
|
|
2037
|
+
parameters.server.getLedgerEntries(parameters.ledgerKey),
|
|
2038
|
+
parameters.server.getLatestLedger()
|
|
2039
|
+
]);
|
|
2040
|
+
const entry = entriesResponse.entries.at(0);
|
|
2041
|
+
if (!entry || entry.liveUntilLedgerSeq === void 0) {
|
|
2042
|
+
return false;
|
|
2043
|
+
}
|
|
2044
|
+
const remainingLedgers = entry.liveUntilLedgerSeq - latestLedger.sequence;
|
|
2045
|
+
return remainingLedgers < ZK_CONFIG_TTL_THRESHOLD_LEDGERS;
|
|
2046
|
+
}
|
|
2047
|
+
async function submitExtendFootprintTtlTransaction(parameters) {
|
|
2048
|
+
const sourceAccount = await parameters.server.getAccount(parameters.sourcePublicKey);
|
|
2049
|
+
const transaction = new TransactionBuilder3(sourceAccount, {
|
|
2050
|
+
fee: EXTEND_TTL_FEE_STROOPS,
|
|
2051
|
+
networkPassphrase: parameters.networkPassphrase
|
|
2052
|
+
}).addOperation(
|
|
2053
|
+
Operation2.extendFootprintTtl({ extendTo: ZK_CONFIG_TTL_EXTEND_TO_LEDGERS })
|
|
2054
|
+
).setSorobanData(
|
|
2055
|
+
new SorobanDataBuilder().setReadOnly([parameters.ledgerKey]).build()
|
|
2056
|
+
).setTimeout(EXTEND_TTL_TIMEOUT_SECONDS).build();
|
|
2057
|
+
const preparedTransaction = await parameters.server.prepareTransaction(transaction);
|
|
2058
|
+
const { signedTxXdr } = await parameters.signTransaction({
|
|
2059
|
+
xdr: preparedTransaction.toXDR(),
|
|
2060
|
+
networkPassphrase: parameters.networkPassphrase,
|
|
2061
|
+
address: parameters.sourcePublicKey
|
|
2062
|
+
});
|
|
2063
|
+
const signedTransaction = TransactionBuilder3.fromXDR(
|
|
2064
|
+
signedTxXdr,
|
|
2065
|
+
parameters.networkPassphrase
|
|
2066
|
+
);
|
|
2067
|
+
const result = await parameters.server.sendTransaction(signedTransaction);
|
|
2068
|
+
const status = String(result.status);
|
|
2069
|
+
if (status !== "PENDING" && status !== "SUCCESS") {
|
|
2070
|
+
throw new Error(`ZK config TTL extension submit failed: ${status}`);
|
|
2071
|
+
}
|
|
2072
|
+
await waitForExtendFootprintTtlConfirmation({
|
|
2073
|
+
server: parameters.server,
|
|
2074
|
+
hash: result.hash
|
|
2075
|
+
});
|
|
2076
|
+
}
|
|
2077
|
+
async function extendZkConfigTtlIfNeeded(parameters) {
|
|
2078
|
+
if (!parameters.signTransaction) {
|
|
2079
|
+
return;
|
|
2080
|
+
}
|
|
2081
|
+
const server = new rpc5.Server(parameters.sorobanRpcUrl, { allowHttp: true });
|
|
2082
|
+
const ledgerKey = zkConfigLedgerKey(parameters.contractId, parameters.nonce);
|
|
2083
|
+
if (!await needsTtlExtension({ server, ledgerKey })) {
|
|
2084
|
+
return;
|
|
2085
|
+
}
|
|
2086
|
+
await submitExtendFootprintTtlTransaction({
|
|
2087
|
+
server,
|
|
2088
|
+
ledgerKey,
|
|
2089
|
+
networkPassphrase: parameters.networkPassphrase,
|
|
2090
|
+
sourcePublicKey: parameters.sourcePublicKey,
|
|
2091
|
+
signTransaction: parameters.signTransaction
|
|
2092
|
+
});
|
|
2093
|
+
}
|
|
2094
|
+
|
|
1277
2095
|
// src/transact/submit/pool-transact.ts
|
|
1278
2096
|
import { Buffer as Buffer11 } from "buffer";
|
|
1279
2097
|
async function submitPoolTransact(parameters) {
|
|
2098
|
+
await extendZkConfigTtlIfNeeded({
|
|
2099
|
+
sorobanRpcUrl: parameters.sorobanRpcUrl,
|
|
2100
|
+
networkPassphrase: parameters.networkPassphrase,
|
|
2101
|
+
contractId: parameters.contractId,
|
|
2102
|
+
nonce: parameters.nonce,
|
|
2103
|
+
sourcePublicKey: parameters.from,
|
|
2104
|
+
signTransaction: parameters.transactEnvironment.signTransaction
|
|
2105
|
+
});
|
|
1280
2106
|
const assembledTransaction = await parameters.contractClient.transact({
|
|
1281
2107
|
from: parameters.from,
|
|
2108
|
+
nonce: parameters.nonce,
|
|
1282
2109
|
proof_bytes: Buffer11.from(parameters.proofHex.replace(/^0x/iu, ""), "hex"),
|
|
1283
2110
|
pub_signals_bytes: Buffer11.from(parameters.publicHex.replace(/^0x/iu, ""), "hex"),
|
|
1284
|
-
|
|
2111
|
+
ciphertext_bytes: Buffer11.from(
|
|
2112
|
+
(parameters.ciphertextHex ?? "").replace(/^0x/iu, ""),
|
|
2113
|
+
"hex"
|
|
2114
|
+
),
|
|
1285
2115
|
kyt_authorization: {
|
|
1286
2116
|
expiration_ledger: parameters.approval.expiresAtLedger,
|
|
1287
2117
|
signature: approvalSignatureToBytes(parameters.approval.signature)
|
|
@@ -1306,29 +2136,37 @@ async function submitSorobanDeposit(input) {
|
|
|
1306
2136
|
});
|
|
1307
2137
|
const merkleTx = await poolClient.get_merkle_root();
|
|
1308
2138
|
const merkleRootBuffer = merkleTx.result;
|
|
1309
|
-
const
|
|
2139
|
+
const proof = await input.privacyPoolService.prepareDepositTransactProof({
|
|
1310
2140
|
privateAddressStpl1: input.privateAddressStpl1,
|
|
1311
2141
|
coin: input.coin,
|
|
1312
2142
|
depositScalarHex: input.depositScalarHex,
|
|
1313
2143
|
merkleRootBytes: merkleRootBuffer,
|
|
1314
2144
|
tokenAddress: input.tokenAddress
|
|
1315
2145
|
});
|
|
2146
|
+
const ciphertext = ciphertextArtifactsFromProof(proof);
|
|
1316
2147
|
const approval = await requestKytPassageForPoolInteraction({
|
|
1317
2148
|
owner: input.walletPublicKey,
|
|
1318
2149
|
poolContract: input.contractId,
|
|
1319
|
-
proofHex: proof_hex,
|
|
1320
|
-
publicHex: public_hex,
|
|
1321
|
-
applicationIdsPlaintext,
|
|
2150
|
+
proofHex: proof.proof_hex,
|
|
2151
|
+
publicHex: proof.public_hex,
|
|
2152
|
+
applicationIdsPlaintext: proof.applicationIdsPlaintext,
|
|
2153
|
+
...ciphertext,
|
|
1322
2154
|
networkPassphrase: input.networkPassphrase,
|
|
1323
2155
|
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
1324
2156
|
transactEnvironment: input.transactEnvironment
|
|
1325
2157
|
});
|
|
1326
2158
|
return submitPoolTransact({
|
|
1327
2159
|
contractClient: poolClient,
|
|
2160
|
+
contractId: input.contractId,
|
|
1328
2161
|
from: input.walletPublicKey,
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
2162
|
+
nonce: resolveZkConfigNonce(input.transactEnvironment),
|
|
2163
|
+
proofHex: proof.proof_hex,
|
|
2164
|
+
publicHex: proof.public_hex,
|
|
2165
|
+
...ciphertext,
|
|
2166
|
+
approval,
|
|
2167
|
+
networkPassphrase: input.networkPassphrase,
|
|
2168
|
+
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
2169
|
+
transactEnvironment: input.transactEnvironment
|
|
1332
2170
|
});
|
|
1333
2171
|
}
|
|
1334
2172
|
|
|
@@ -1345,7 +2183,8 @@ async function submitSorobanConfidentialTransfer(input) {
|
|
|
1345
2183
|
poolContract: input.contractId,
|
|
1346
2184
|
proofHex: input.proofHex,
|
|
1347
2185
|
publicHex: input.publicHex,
|
|
1348
|
-
...input.
|
|
2186
|
+
...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
|
|
2187
|
+
...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {},
|
|
1349
2188
|
...input.applicationIdsPlaintext ? { applicationIdsPlaintext: input.applicationIdsPlaintext } : {},
|
|
1350
2189
|
networkPassphrase: input.networkPassphrase,
|
|
1351
2190
|
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
@@ -1353,22 +2192,32 @@ async function submitSorobanConfidentialTransfer(input) {
|
|
|
1353
2192
|
});
|
|
1354
2193
|
return submitPoolTransact({
|
|
1355
2194
|
contractClient: poolClient,
|
|
2195
|
+
contractId: input.contractId,
|
|
1356
2196
|
from: input.walletPublicKey,
|
|
2197
|
+
nonce: resolveZkConfigNonce(input.transactEnvironment),
|
|
1357
2198
|
proofHex: input.proofHex,
|
|
1358
2199
|
publicHex: input.publicHex,
|
|
1359
|
-
...input.
|
|
1360
|
-
approval
|
|
2200
|
+
...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
|
|
2201
|
+
approval,
|
|
2202
|
+
networkPassphrase: input.networkPassphrase,
|
|
2203
|
+
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
2204
|
+
transactEnvironment: input.transactEnvironment
|
|
1361
2205
|
});
|
|
1362
2206
|
}
|
|
1363
2207
|
|
|
1364
|
-
// src/transact/
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
2208
|
+
// src/transact/proofs/confidential/recipient-change-deposits.ts
|
|
2209
|
+
function escrowOutputFields(input) {
|
|
2210
|
+
if (!input.escrowSend) {
|
|
2211
|
+
return {};
|
|
2212
|
+
}
|
|
2213
|
+
return {
|
|
2214
|
+
escrowNonce: input.escrowSend.nonceDecimal,
|
|
2215
|
+
recipientHi: input.escrowSend.recipientHi,
|
|
2216
|
+
recipientLo: input.escrowSend.recipientLo
|
|
2217
|
+
};
|
|
2218
|
+
}
|
|
2219
|
+
function paddingDepositPair(recipientDeposit) {
|
|
2220
|
+
return [recipientDeposit, "dummy"];
|
|
1372
2221
|
}
|
|
1373
2222
|
async function buildChangeDepositPair(parameters) {
|
|
1374
2223
|
const changeSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
|
|
@@ -1387,24 +2236,24 @@ async function buildChangeDepositPair(parameters) {
|
|
|
1387
2236
|
};
|
|
1388
2237
|
}
|
|
1389
2238
|
async function buildRecipientAndOptionalChangeDeposits(parameters) {
|
|
2239
|
+
const escrow = {
|
|
2240
|
+
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
2241
|
+
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
2242
|
+
};
|
|
1390
2243
|
const recipientPrivateAddress = parameters.recipientPrivateAddressStpl1.trim();
|
|
1391
2244
|
const recipientSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
|
|
1392
2245
|
privateAddressStpl1: recipientPrivateAddress,
|
|
1393
2246
|
amountStroops: parameters.transferStroops,
|
|
1394
|
-
tokenAddress: parameters.tokenAddress
|
|
2247
|
+
tokenAddress: parameters.tokenAddress,
|
|
2248
|
+
...escrowOutputFields(escrow)
|
|
1395
2249
|
});
|
|
1396
2250
|
if (parameters.changeStroops <= ZERO_STROOPS) {
|
|
1397
2251
|
return {
|
|
1398
2252
|
recipientSlot,
|
|
1399
|
-
deposits:
|
|
1400
|
-
recipientPrivateAddress,
|
|
1401
|
-
parameters.tokenAddress,
|
|
1402
|
-
recipientSlot.deposit
|
|
1403
|
-
)
|
|
2253
|
+
deposits: paddingDepositPair(recipientSlot.deposit)
|
|
1404
2254
|
};
|
|
1405
2255
|
}
|
|
1406
2256
|
const changeResult = await buildChangeDepositPair({
|
|
1407
|
-
recipientPrivateAddressStpl1: recipientPrivateAddress,
|
|
1408
2257
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1409
2258
|
changeStroops: parameters.changeStroops,
|
|
1410
2259
|
tokenAddress: parameters.tokenAddress,
|
|
@@ -1426,20 +2275,61 @@ function generatedOutputCoinFromSlot(slot) {
|
|
|
1426
2275
|
precommitementHex: slot.precommitementHex
|
|
1427
2276
|
};
|
|
1428
2277
|
}
|
|
2278
|
+
function publicEscrowRecipientLimbs(parameters) {
|
|
2279
|
+
const limbs = parameters.escrowClaimantLimbs;
|
|
2280
|
+
if (!limbs) {
|
|
2281
|
+
return void 0;
|
|
2282
|
+
}
|
|
2283
|
+
return {
|
|
2284
|
+
escrowRecipientHi: limbs.recipientHi,
|
|
2285
|
+
escrowRecipientLo: limbs.recipientLo
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2288
|
+
function sweepWithdrawStamp(parameters) {
|
|
2289
|
+
const publicLimbs = publicEscrowRecipientLimbs(parameters);
|
|
2290
|
+
if (!publicLimbs) {
|
|
2291
|
+
return void 0;
|
|
2292
|
+
}
|
|
2293
|
+
return {
|
|
2294
|
+
...publicLimbs,
|
|
2295
|
+
...parameters.escrowClaimantLimbs?.nonceDecimal ? { escrowNonce: parameters.escrowClaimantLimbs.nonceDecimal } : {}
|
|
2296
|
+
};
|
|
2297
|
+
}
|
|
2298
|
+
function stampWithdrawEscrowLimbs(withdrawObject, limbs) {
|
|
2299
|
+
if (!limbs) {
|
|
2300
|
+
return withdrawObject;
|
|
2301
|
+
}
|
|
2302
|
+
return {
|
|
2303
|
+
...withdrawObject,
|
|
2304
|
+
recipientStellar: [limbs.escrowRecipientHi, limbs.escrowRecipientLo],
|
|
2305
|
+
...limbs.escrowNonce ? { escrowNonce: limbs.escrowNonce } : {}
|
|
2306
|
+
};
|
|
2307
|
+
}
|
|
2308
|
+
function sweepOutputOwnerFields(parameters) {
|
|
2309
|
+
if (!parameters.escrowClaimantLimbs) {
|
|
2310
|
+
return void 0;
|
|
2311
|
+
}
|
|
2312
|
+
const [sweepOutputOwnerPubX, sweepOutputOwnerPubY] = recipientPublicKeysDecimalFromPrivateAddress(
|
|
2313
|
+
parameters.recipientPrivateAddressStpl1
|
|
2314
|
+
);
|
|
2315
|
+
return { sweepOutputOwnerPubX, sweepOutputOwnerPubY };
|
|
2316
|
+
}
|
|
1429
2317
|
async function buildTransferDepositsAndPublicInput(parameters) {
|
|
1430
2318
|
const { recipientSlot, deposits, changeCoin } = await buildRecipientAndOptionalChangeDeposits({
|
|
1431
2319
|
recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
|
|
1432
2320
|
transferStroops: parameters.transferStroops,
|
|
1433
2321
|
changeStroops: parameters.changeStroops,
|
|
1434
2322
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1435
|
-
tokenAddress: parameters.tokenAddress
|
|
2323
|
+
tokenAddress: parameters.tokenAddress,
|
|
2324
|
+
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
2325
|
+
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
1436
2326
|
});
|
|
1437
2327
|
const publicInput = withTokenAddressPublicInputs(
|
|
1438
2328
|
{
|
|
1439
2329
|
stateRoot: parameters.stateRoot,
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
2330
|
+
privKeyScalar: parameters.privKeyScalar,
|
|
2331
|
+
...publicEscrowRecipientLimbs(parameters),
|
|
2332
|
+
...sweepOutputOwnerFields(parameters)
|
|
1443
2333
|
},
|
|
1444
2334
|
parameters.tokenAddress
|
|
1445
2335
|
);
|
|
@@ -1451,10 +2341,6 @@ async function buildTransferDepositsAndPublicInput(parameters) {
|
|
|
1451
2341
|
};
|
|
1452
2342
|
}
|
|
1453
2343
|
async function buildSenderTransferDepositsAndPublicInput(parameters) {
|
|
1454
|
-
const { hi, lo, privKeyScalar } = senderWithdrawFrAndScalar({
|
|
1455
|
-
senderGAddress: parameters.senderGAddress,
|
|
1456
|
-
senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex
|
|
1457
|
-
});
|
|
1458
2344
|
return buildTransferDepositsAndPublicInput({
|
|
1459
2345
|
recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
|
|
1460
2346
|
transferStroops: parameters.transferStroops,
|
|
@@ -1462,31 +2348,55 @@ async function buildSenderTransferDepositsAndPublicInput(parameters) {
|
|
|
1462
2348
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1463
2349
|
tokenAddress: parameters.tokenAddress,
|
|
1464
2350
|
stateRoot: parameters.stateRoot,
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
2351
|
+
privKeyScalar: privKeyScalarDecimalFromRecipientScalarHex(
|
|
2352
|
+
parameters.senderPrivKeyScalarHex
|
|
2353
|
+
),
|
|
2354
|
+
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
2355
|
+
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
1468
2356
|
});
|
|
1469
2357
|
}
|
|
1470
2358
|
|
|
1471
2359
|
// src/transact/proofs/confidential/dual.ts
|
|
1472
|
-
function
|
|
1473
|
-
return
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
2360
|
+
function confidentialEscrowFields(parameters) {
|
|
2361
|
+
return {
|
|
2362
|
+
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
2363
|
+
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
2364
|
+
};
|
|
2365
|
+
}
|
|
2366
|
+
function stampDualWithdrawLegs(legs, parameters) {
|
|
2367
|
+
const escrowLimbs = sweepWithdrawStamp(confidentialEscrowFields(parameters));
|
|
2368
|
+
return {
|
|
2369
|
+
legA: {
|
|
2370
|
+
...legs.legA,
|
|
2371
|
+
withdrawObject: stampWithdrawEscrowLimbs(legs.legA.withdrawObject, escrowLimbs)
|
|
2372
|
+
},
|
|
2373
|
+
legB: {
|
|
2374
|
+
...legs.legB,
|
|
2375
|
+
withdrawObject: stampWithdrawEscrowLimbs(legs.legB.withdrawObject, escrowLimbs)
|
|
2376
|
+
}
|
|
2377
|
+
};
|
|
2378
|
+
}
|
|
2379
|
+
function buildDualTransferApplicationIds(sdk, applicationId, changeCoin) {
|
|
2380
|
+
return buildApplicationIdHints({
|
|
2381
|
+
sdk,
|
|
2382
|
+
inputIds: [applicationId, applicationId],
|
|
2383
|
+
outputIds: [applicationId, changeCoin ? applicationId : "0"]
|
|
2384
|
+
});
|
|
1479
2385
|
}
|
|
1480
2386
|
async function proveDualConfidentialTransfer(parameters) {
|
|
1481
2387
|
const audit = buildPoolTransactionAuditParameters({
|
|
1482
2388
|
applicationId: parameters.applicationId,
|
|
2389
|
+
nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
|
|
1483
2390
|
...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
|
|
1484
2391
|
});
|
|
1485
2392
|
return parameters.sdk.proveTransaction(
|
|
1486
2393
|
parameters.publicInput,
|
|
1487
|
-
buildZeroPublicLegs(),
|
|
1488
|
-
|
|
1489
|
-
|
|
2394
|
+
padPublicLegsToLayout(parameters.sdk, buildZeroPublicLegs()),
|
|
2395
|
+
padWithdrawSlotsToLayout(parameters.sdk, [
|
|
2396
|
+
parameters.legA.withdrawObject,
|
|
2397
|
+
parameters.legB.withdrawObject
|
|
2398
|
+
]),
|
|
2399
|
+
padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
|
|
1490
2400
|
audit
|
|
1491
2401
|
);
|
|
1492
2402
|
}
|
|
@@ -1500,24 +2410,33 @@ async function buildDualTransferProofContext(parameters, applicationId, sdk) {
|
|
|
1500
2410
|
changeStroops,
|
|
1501
2411
|
parameters.selfPrivateAddressStpl1ForChange
|
|
1502
2412
|
);
|
|
1503
|
-
const
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
2413
|
+
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
2414
|
+
parameters.senderPrivKeyScalarHex
|
|
2415
|
+
);
|
|
2416
|
+
const ownerPubHex = sdk.ecdhEphemeralPublicKeyFromScalarHex(
|
|
2417
|
+
parameters.senderPrivKeyScalarHex
|
|
2418
|
+
);
|
|
2419
|
+
const { legA, legB } = stampDualWithdrawLegs(
|
|
2420
|
+
dualWithdrawLegsWithSharedRoot({
|
|
2421
|
+
sdk,
|
|
2422
|
+
coinA: parameters.coinA,
|
|
2423
|
+
coinB: parameters.coinB,
|
|
2424
|
+
state: parameters.state,
|
|
2425
|
+
ownerPubHex,
|
|
2426
|
+
privKeyScalar,
|
|
2427
|
+
applicationId
|
|
2428
|
+
}),
|
|
2429
|
+
parameters
|
|
2430
|
+
);
|
|
1512
2431
|
const transferInputs = await buildSenderTransferDepositsAndPublicInput({
|
|
1513
|
-
senderGAddress: parameters.senderGAddress,
|
|
1514
2432
|
senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex,
|
|
1515
2433
|
recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
|
|
1516
2434
|
transferStroops: parameters.transferStroops,
|
|
1517
2435
|
changeStroops,
|
|
1518
2436
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1519
2437
|
tokenAddress: parameters.tokenAddress,
|
|
1520
|
-
stateRoot: legA.witness.stateRoot
|
|
2438
|
+
stateRoot: legA.witness.stateRoot,
|
|
2439
|
+
...confidentialEscrowFields(parameters)
|
|
1521
2440
|
});
|
|
1522
2441
|
return { legA, legB, applicationId, ...transferInputs };
|
|
1523
2442
|
}
|
|
@@ -1545,7 +2464,11 @@ async function prepareConfidentialTransferProofDual(parameters) {
|
|
|
1545
2464
|
}));
|
|
1546
2465
|
return {
|
|
1547
2466
|
...proof,
|
|
1548
|
-
applicationIdsPlaintext: buildDualTransferApplicationIds(
|
|
2467
|
+
applicationIdsPlaintext: buildDualTransferApplicationIds(
|
|
2468
|
+
sdk,
|
|
2469
|
+
applicationId,
|
|
2470
|
+
changeCoin
|
|
2471
|
+
),
|
|
1549
2472
|
recipientCoin: generatedOutputCoinFromSlot(recipientSlot),
|
|
1550
2473
|
...changeCoin ? { changeCoin } : {}
|
|
1551
2474
|
};
|
|
@@ -1563,51 +2486,72 @@ function validateSingleCoinTransferAmounts(transferStroops, noteStroops, selfPri
|
|
|
1563
2486
|
requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange);
|
|
1564
2487
|
return changeStroops;
|
|
1565
2488
|
}
|
|
1566
|
-
function buildSingleTransferApplicationIds(applicationId, changeCoin) {
|
|
1567
|
-
return
|
|
2489
|
+
function buildSingleTransferApplicationIds(sdk, applicationId, changeCoin) {
|
|
2490
|
+
return buildApplicationIdHints({
|
|
2491
|
+
sdk,
|
|
2492
|
+
inputIds: [applicationId],
|
|
2493
|
+
outputIds: [applicationId, changeCoin ? applicationId : "0"]
|
|
2494
|
+
});
|
|
1568
2495
|
}
|
|
1569
2496
|
function buildTransferAuditParameters(parameters) {
|
|
1570
2497
|
const auditPublicKey = parameters.poolService.getAuditPublicKey();
|
|
1571
2498
|
return buildPoolTransactionAuditParameters({
|
|
1572
2499
|
applicationId: parameters.applicationId,
|
|
2500
|
+
nAuditSlots: parameters.nAuditSlots,
|
|
1573
2501
|
...auditPublicKey ? { auditPublicKey } : {}
|
|
1574
2502
|
});
|
|
1575
2503
|
}
|
|
1576
2504
|
async function proveTransaction(parameters) {
|
|
1577
2505
|
return parameters.sdk.proveTransaction(
|
|
1578
2506
|
parameters.publicInput,
|
|
1579
|
-
buildZeroPublicLegs(),
|
|
1580
|
-
[parameters.withdrawObject
|
|
1581
|
-
parameters.deposits,
|
|
2507
|
+
padPublicLegsToLayout(parameters.sdk, buildZeroPublicLegs()),
|
|
2508
|
+
padWithdrawSlotsToLayout(parameters.sdk, [parameters.withdrawObject]),
|
|
2509
|
+
padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
|
|
1582
2510
|
parameters.audit
|
|
1583
2511
|
);
|
|
1584
2512
|
}
|
|
2513
|
+
function confidentialEscrowFields2(input) {
|
|
2514
|
+
return {
|
|
2515
|
+
...input.escrowSend ? { escrowSend: input.escrowSend } : {},
|
|
2516
|
+
...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
|
|
2517
|
+
};
|
|
2518
|
+
}
|
|
1585
2519
|
async function buildTransferProofInputs(parameters) {
|
|
1586
2520
|
const changeStroops = validateSingleCoinTransferAmounts(
|
|
1587
2521
|
parameters.input.transferStroops,
|
|
1588
2522
|
parameters.noteStroops,
|
|
1589
2523
|
parameters.input.selfPrivateAddressStpl1ForChange
|
|
1590
2524
|
);
|
|
2525
|
+
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
2526
|
+
parameters.input.senderPrivKeyScalarHex
|
|
2527
|
+
);
|
|
1591
2528
|
const { witness, withdrawObject } = withdrawWitnessForCoin({
|
|
1592
2529
|
sdk: parameters.sdk,
|
|
1593
2530
|
coin: parameters.input.coin,
|
|
1594
2531
|
state: parameters.input.state,
|
|
1595
|
-
|
|
2532
|
+
ownerPubHex: parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
|
|
2533
|
+
parameters.input.senderPrivKeyScalarHex
|
|
2534
|
+
),
|
|
2535
|
+
privKeyScalar,
|
|
1596
2536
|
applicationId: parameters.applicationId
|
|
1597
2537
|
});
|
|
2538
|
+
const stampedWithdraw = stampWithdrawEscrowLimbs(
|
|
2539
|
+
withdrawObject,
|
|
2540
|
+
sweepWithdrawStamp(confidentialEscrowFields2(parameters.input))
|
|
2541
|
+
);
|
|
1598
2542
|
const { recipientSlot, deposits, changeCoin, publicInput } = await buildSenderTransferDepositsAndPublicInput({
|
|
1599
|
-
senderGAddress: parameters.input.senderGAddress,
|
|
1600
2543
|
senderPrivKeyScalarHex: parameters.input.senderPrivKeyScalarHex,
|
|
1601
2544
|
recipientPrivateAddressStpl1: parameters.input.recipientPrivateAddressStpl1,
|
|
1602
2545
|
transferStroops: parameters.input.transferStroops,
|
|
1603
2546
|
changeStroops,
|
|
1604
2547
|
selfPrivateAddressStpl1ForChange: parameters.input.selfPrivateAddressStpl1ForChange,
|
|
1605
2548
|
tokenAddress: parameters.input.tokenAddress,
|
|
1606
|
-
stateRoot: witness.stateRoot
|
|
2549
|
+
stateRoot: witness.stateRoot,
|
|
2550
|
+
...confidentialEscrowFields2(parameters.input)
|
|
1607
2551
|
});
|
|
1608
2552
|
return {
|
|
1609
2553
|
witness,
|
|
1610
|
-
withdrawObject,
|
|
2554
|
+
withdrawObject: stampedWithdraw,
|
|
1611
2555
|
recipientSlot,
|
|
1612
2556
|
deposits,
|
|
1613
2557
|
changeCoin,
|
|
@@ -1625,7 +2569,11 @@ async function prepareConfidentialTransferProof(parameters) {
|
|
|
1625
2569
|
input: parameters,
|
|
1626
2570
|
noteStroops
|
|
1627
2571
|
});
|
|
1628
|
-
const audit = buildTransferAuditParameters({
|
|
2572
|
+
const audit = buildTransferAuditParameters({
|
|
2573
|
+
poolService,
|
|
2574
|
+
applicationId,
|
|
2575
|
+
nAuditSlots: sdk.getLayout().nAuditSlots
|
|
2576
|
+
});
|
|
1629
2577
|
const proof = await proveTransaction({
|
|
1630
2578
|
sdk,
|
|
1631
2579
|
publicInput,
|
|
@@ -1636,6 +2584,7 @@ async function prepareConfidentialTransferProof(parameters) {
|
|
|
1636
2584
|
return {
|
|
1637
2585
|
...proof,
|
|
1638
2586
|
applicationIdsPlaintext: buildSingleTransferApplicationIds(
|
|
2587
|
+
sdk,
|
|
1639
2588
|
applicationId,
|
|
1640
2589
|
changeCoin
|
|
1641
2590
|
),
|
|
@@ -1767,12 +2716,25 @@ async function readLeafEphemeralHex(parameters) {
|
|
|
1767
2716
|
return { xHex, yHex };
|
|
1768
2717
|
}
|
|
1769
2718
|
|
|
2719
|
+
// src/transact/encoding/fr-decimal-to-bytes.ts
|
|
2720
|
+
var BN254_SCALAR_MOD = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
2721
|
+
var FIELD_BYTE_LENGTH2 = 32;
|
|
2722
|
+
var BYTE_MASK = 0xffn;
|
|
2723
|
+
var BITS_PER_BYTE = 8n;
|
|
2724
|
+
function frDecimalToPaddedBytes32(decimal) {
|
|
2725
|
+
let value = BigInt(decimal.trim());
|
|
2726
|
+
value = (value % BN254_SCALAR_MOD + BN254_SCALAR_MOD) % BN254_SCALAR_MOD;
|
|
2727
|
+
const bytes = Buffer.alloc(FIELD_BYTE_LENGTH2);
|
|
2728
|
+
for (let index = FIELD_BYTE_LENGTH2 - 1; index >= 0; index -= 1) {
|
|
2729
|
+
bytes[index] = Number(value & BYTE_MASK);
|
|
2730
|
+
value >>= BITS_PER_BYTE;
|
|
2731
|
+
}
|
|
2732
|
+
return bytes;
|
|
2733
|
+
}
|
|
2734
|
+
|
|
1770
2735
|
// src/state/foundation/paths.ts
|
|
1771
2736
|
var STELLAR_STATE_PATHS = {
|
|
1772
2737
|
privateRecords: "$.privateRecords",
|
|
1773
|
-
pendingClaimsItems: "$.pendingClaims.items",
|
|
1774
|
-
pendingClaimsPagination: "$.pendingClaims.pagination",
|
|
1775
|
-
pendingClaimsCountByOwner: "$.pendingClaims.countByOwner",
|
|
1776
2738
|
registryPrivateAddresses: "$.registry.privateAddresses",
|
|
1777
2739
|
registryRegisteredAddresses: "$.registry.registeredAddresses",
|
|
1778
2740
|
registryLookups: "$.registry.lookups",
|
|
@@ -1792,25 +2754,6 @@ var STELLAR_STATE_PATHS = {
|
|
|
1792
2754
|
|
|
1793
2755
|
// src/state/schemas/shared.ts
|
|
1794
2756
|
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
2757
|
var paginationSchema = z.object({
|
|
1815
2758
|
total: z.number().int().nonnegative(),
|
|
1816
2759
|
page: z.number().int().positive(),
|
|
@@ -1980,26 +2923,6 @@ function normalizePublicBalancesFromEntries(value, owner) {
|
|
|
1980
2923
|
}).filter((balance) => balance !== void 0);
|
|
1981
2924
|
}
|
|
1982
2925
|
|
|
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
2926
|
// src/state/read/normalize/deliveries.ts
|
|
2004
2927
|
function normalizeIncomingDeliveries(value) {
|
|
2005
2928
|
const entries = typeof value === "object" && value !== null && !Array.isArray(value) ? Object.values(value) : value;
|
|
@@ -2122,8 +3045,7 @@ import { registerArrayFilterItemSchema } from "@arcanetech/privacy-sdk-core/stat
|
|
|
2122
3045
|
|
|
2123
3046
|
// src/state/filters/ops.ts
|
|
2124
3047
|
var stellarArrayFilterSchemaKeys = {
|
|
2125
|
-
privateRecord: "privateRecord"
|
|
2126
|
-
pendingClaim: "pendingClaim"
|
|
3048
|
+
privateRecord: "privateRecord"
|
|
2127
3049
|
};
|
|
2128
3050
|
function rejectPrivateRecordsByIds(ids) {
|
|
2129
3051
|
return {
|
|
@@ -2149,56 +3071,6 @@ function rejectConsumedPrivateRecords() {
|
|
|
2149
3071
|
}
|
|
2150
3072
|
};
|
|
2151
3073
|
}
|
|
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
3074
|
|
|
2203
3075
|
// src/state/filters/register-schemas.ts
|
|
2204
3076
|
var registered = false;
|
|
@@ -2210,24 +3082,12 @@ function registerStellarArrayFilterSchemas() {
|
|
|
2210
3082
|
stellarArrayFilterSchemaKeys.privateRecord,
|
|
2211
3083
|
privateRecordSchema
|
|
2212
3084
|
);
|
|
2213
|
-
registerArrayFilterItemSchema(
|
|
2214
|
-
stellarArrayFilterSchemaKeys.pendingClaim,
|
|
2215
|
-
pendingClaimSchema
|
|
2216
|
-
);
|
|
2217
3085
|
registered = true;
|
|
2218
3086
|
}
|
|
2219
3087
|
|
|
2220
3088
|
// src/state/bridge/call-types.ts
|
|
2221
3089
|
import "@arcanetech/privacy-sdk-core/state";
|
|
2222
3090
|
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
3091
|
readStellarAddressRegistered: "readStellarAddressRegistered",
|
|
2232
3092
|
readCachedPrivateAddress: "readCachedPrivateAddress",
|
|
2233
3093
|
readRegistryLookup: "readRegistryLookup",
|
|
@@ -2454,194 +3314,10 @@ var stellarBalancesStateDefinitions = [
|
|
|
2454
3314
|
}
|
|
2455
3315
|
];
|
|
2456
3316
|
|
|
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
3317
|
// src/state/schemas/claims/deliveries.ts
|
|
2642
|
-
import { z as
|
|
2643
|
-
var readIncomingDeliveriesSchema =
|
|
2644
|
-
type:
|
|
3318
|
+
import { z as z5 } from "zod";
|
|
3319
|
+
var readIncomingDeliveriesSchema = z5.object({
|
|
3320
|
+
type: z5.literal(stellarStateCallTypes.readIncomingDeliveries)
|
|
2645
3321
|
}).transform(({ type }) => ({
|
|
2646
3322
|
type,
|
|
2647
3323
|
operations: [
|
|
@@ -2651,9 +3327,9 @@ var readIncomingDeliveriesSchema = z7.object({
|
|
|
2651
3327
|
}
|
|
2652
3328
|
]
|
|
2653
3329
|
}));
|
|
2654
|
-
var upsertIncomingDeliveriesSchema =
|
|
2655
|
-
type:
|
|
2656
|
-
deliveries:
|
|
3330
|
+
var upsertIncomingDeliveriesSchema = z5.object({
|
|
3331
|
+
type: z5.literal(stellarStateCallTypes.upsertIncomingDeliveries),
|
|
3332
|
+
deliveries: z5.array(incomingDeliverySchema)
|
|
2657
3333
|
}).transform(({ type, deliveries }) => ({
|
|
2658
3334
|
type,
|
|
2659
3335
|
operations: deliveries.map((delivery) => ({
|
|
@@ -2663,10 +3339,10 @@ var upsertIncomingDeliveriesSchema = z7.object({
|
|
|
2663
3339
|
value: delivery
|
|
2664
3340
|
}))
|
|
2665
3341
|
}));
|
|
2666
|
-
var readDeliverySyncStateSchema =
|
|
2667
|
-
type:
|
|
2668
|
-
privateAddress:
|
|
2669
|
-
asset:
|
|
3342
|
+
var readDeliverySyncStateSchema = z5.object({
|
|
3343
|
+
type: z5.literal(stellarStateCallTypes.readDeliverySyncState),
|
|
3344
|
+
privateAddress: z5.string().min(1),
|
|
3345
|
+
asset: z5.string().min(1)
|
|
2670
3346
|
}).transform(({ type, privateAddress, asset }) => ({
|
|
2671
3347
|
type,
|
|
2672
3348
|
operations: [
|
|
@@ -2677,8 +3353,8 @@ var readDeliverySyncStateSchema = z7.object({
|
|
|
2677
3353
|
}
|
|
2678
3354
|
]
|
|
2679
3355
|
}));
|
|
2680
|
-
var setDeliverySyncStateSchema =
|
|
2681
|
-
type:
|
|
3356
|
+
var setDeliverySyncStateSchema = z5.object({
|
|
3357
|
+
type: z5.literal(stellarStateCallTypes.setDeliverySyncState),
|
|
2682
3358
|
syncState: deliverySyncStateSchema
|
|
2683
3359
|
}).transform(({ type, syncState }) => ({
|
|
2684
3360
|
type,
|
|
@@ -2717,10 +3393,10 @@ var stellarDeliveriesStateDefinitions = [
|
|
|
2717
3393
|
];
|
|
2718
3394
|
|
|
2719
3395
|
// src/state/schemas/pool/merkle.ts
|
|
2720
|
-
import { z as
|
|
2721
|
-
var readPoolMerkleStateSchema =
|
|
2722
|
-
type:
|
|
2723
|
-
poolContract:
|
|
3396
|
+
import { z as z6 } from "zod";
|
|
3397
|
+
var readPoolMerkleStateSchema = z6.object({
|
|
3398
|
+
type: z6.literal(stellarStateCallTypes.readPoolMerkleState),
|
|
3399
|
+
poolContract: z6.string().min(1)
|
|
2724
3400
|
}).transform(({ type, poolContract }) => ({
|
|
2725
3401
|
type,
|
|
2726
3402
|
operations: [
|
|
@@ -2731,8 +3407,8 @@ var readPoolMerkleStateSchema = z8.object({
|
|
|
2731
3407
|
}
|
|
2732
3408
|
]
|
|
2733
3409
|
}));
|
|
2734
|
-
var setPoolMerkleStateSchema =
|
|
2735
|
-
type:
|
|
3410
|
+
var setPoolMerkleStateSchema = z6.object({
|
|
3411
|
+
type: z6.literal(stellarStateCallTypes.setPoolMerkleState),
|
|
2736
3412
|
state: poolMerkleStateSchema
|
|
2737
3413
|
}).transform(({ type, state }) => ({
|
|
2738
3414
|
type,
|
|
@@ -2745,10 +3421,10 @@ var setPoolMerkleStateSchema = z8.object({
|
|
|
2745
3421
|
}
|
|
2746
3422
|
]
|
|
2747
3423
|
}));
|
|
2748
|
-
var readLeafEphemeralSchema =
|
|
2749
|
-
type:
|
|
2750
|
-
poolContract:
|
|
2751
|
-
leafIndex:
|
|
3424
|
+
var readLeafEphemeralSchema = z6.object({
|
|
3425
|
+
type: z6.literal(stellarStateCallTypes.readLeafEphemeral),
|
|
3426
|
+
poolContract: z6.string().min(1),
|
|
3427
|
+
leafIndex: z6.number().int().nonnegative()
|
|
2752
3428
|
}).transform(({ type, poolContract, leafIndex }) => ({
|
|
2753
3429
|
type,
|
|
2754
3430
|
operations: [
|
|
@@ -2759,8 +3435,8 @@ var readLeafEphemeralSchema = z8.object({
|
|
|
2759
3435
|
}
|
|
2760
3436
|
]
|
|
2761
3437
|
}));
|
|
2762
|
-
var setLeafEphemeralSchema =
|
|
2763
|
-
type:
|
|
3438
|
+
var setLeafEphemeralSchema = z6.object({
|
|
3439
|
+
type: z6.literal(stellarStateCallTypes.setLeafEphemeral),
|
|
2764
3440
|
ephemeral: leafEphemeralSchema
|
|
2765
3441
|
}).transform(({ type, ephemeral }) => ({
|
|
2766
3442
|
type,
|
|
@@ -2799,9 +3475,9 @@ var stellarPoolStateDefinitions = [
|
|
|
2799
3475
|
];
|
|
2800
3476
|
|
|
2801
3477
|
// src/state/schemas/records/private.ts
|
|
2802
|
-
import { z as
|
|
2803
|
-
var listPrivateRecordsSchema =
|
|
2804
|
-
type:
|
|
3478
|
+
import { z as z7 } from "zod";
|
|
3479
|
+
var listPrivateRecordsSchema = z7.object({
|
|
3480
|
+
type: z7.literal(stellarStateCallTypes.listPrivateRecords)
|
|
2805
3481
|
}).transform(({ type }) => ({
|
|
2806
3482
|
type,
|
|
2807
3483
|
operations: [
|
|
@@ -2811,9 +3487,9 @@ var listPrivateRecordsSchema = z9.object({
|
|
|
2811
3487
|
}
|
|
2812
3488
|
]
|
|
2813
3489
|
}));
|
|
2814
|
-
var savePrivateRecordsSchema =
|
|
2815
|
-
type:
|
|
2816
|
-
records:
|
|
3490
|
+
var savePrivateRecordsSchema = z7.object({
|
|
3491
|
+
type: z7.literal(stellarStateCallTypes.savePrivateRecords),
|
|
3492
|
+
records: z7.array(privateRecordSchema)
|
|
2817
3493
|
}).transform(({ type, records }) => ({
|
|
2818
3494
|
type,
|
|
2819
3495
|
operations: [
|
|
@@ -2824,9 +3500,9 @@ var savePrivateRecordsSchema = z9.object({
|
|
|
2824
3500
|
}
|
|
2825
3501
|
]
|
|
2826
3502
|
}));
|
|
2827
|
-
var replacePrivateRecordsSchema =
|
|
2828
|
-
type:
|
|
2829
|
-
records:
|
|
3503
|
+
var replacePrivateRecordsSchema = z7.object({
|
|
3504
|
+
type: z7.literal(stellarStateCallTypes.replacePrivateRecords),
|
|
3505
|
+
records: z7.array(privateRecordSchema)
|
|
2830
3506
|
}).transform(({ type, records }) => ({
|
|
2831
3507
|
type,
|
|
2832
3508
|
operations: [
|
|
@@ -2841,18 +3517,18 @@ var replacePrivateRecordsSchema = z9.object({
|
|
|
2841
3517
|
}
|
|
2842
3518
|
]
|
|
2843
3519
|
}));
|
|
2844
|
-
var pruneConsumedPrivateRecordsSchema =
|
|
2845
|
-
type:
|
|
3520
|
+
var pruneConsumedPrivateRecordsSchema = z7.object({
|
|
3521
|
+
type: z7.literal(stellarStateCallTypes.pruneConsumedPrivateRecords)
|
|
2846
3522
|
}).transform(({ type }) => ({
|
|
2847
3523
|
type,
|
|
2848
3524
|
operations: [rejectConsumedPrivateRecords()]
|
|
2849
3525
|
}));
|
|
2850
3526
|
|
|
2851
3527
|
// src/state/schemas/records/transactions.ts
|
|
2852
|
-
import { z as
|
|
2853
|
-
var upsertPrivateRecordsSchema =
|
|
2854
|
-
type:
|
|
2855
|
-
records:
|
|
3528
|
+
import { z as z8 } from "zod";
|
|
3529
|
+
var upsertPrivateRecordsSchema = z8.object({
|
|
3530
|
+
type: z8.literal(stellarStateCallTypes.upsertPrivateRecords),
|
|
3531
|
+
records: z8.array(privateRecordSchema)
|
|
2856
3532
|
}).transform(({ type, records }) => ({
|
|
2857
3533
|
type,
|
|
2858
3534
|
operations: [
|
|
@@ -2864,9 +3540,9 @@ var upsertPrivateRecordsSchema = z10.object({
|
|
|
2864
3540
|
}
|
|
2865
3541
|
]
|
|
2866
3542
|
}));
|
|
2867
|
-
var readTransactionStatusSchema =
|
|
2868
|
-
type:
|
|
2869
|
-
txHash:
|
|
3543
|
+
var readTransactionStatusSchema = z8.object({
|
|
3544
|
+
type: z8.literal(stellarStateCallTypes.readTransactionStatus),
|
|
3545
|
+
txHash: z8.string().min(1)
|
|
2870
3546
|
}).transform(({ type, txHash }) => ({
|
|
2871
3547
|
type,
|
|
2872
3548
|
operations: [
|
|
@@ -2877,8 +3553,8 @@ var readTransactionStatusSchema = z10.object({
|
|
|
2877
3553
|
}
|
|
2878
3554
|
]
|
|
2879
3555
|
}));
|
|
2880
|
-
var setTransactionStatusSchema =
|
|
2881
|
-
type:
|
|
3556
|
+
var setTransactionStatusSchema = z8.object({
|
|
3557
|
+
type: z8.literal(stellarStateCallTypes.setTransactionStatus),
|
|
2882
3558
|
status: transactionStatusSchema
|
|
2883
3559
|
}).transform(({ type, status }) => ({
|
|
2884
3560
|
type,
|
|
@@ -2891,9 +3567,9 @@ var setTransactionStatusSchema = z10.object({
|
|
|
2891
3567
|
}
|
|
2892
3568
|
]
|
|
2893
3569
|
}));
|
|
2894
|
-
var clearTransactionStatusSchema =
|
|
2895
|
-
type:
|
|
2896
|
-
txHash:
|
|
3570
|
+
var clearTransactionStatusSchema = z8.object({
|
|
3571
|
+
type: z8.literal(stellarStateCallTypes.clearTransactionStatus),
|
|
3572
|
+
txHash: z8.string().min(1)
|
|
2897
3573
|
}).transform(({ type, txHash }) => ({
|
|
2898
3574
|
type,
|
|
2899
3575
|
operations: [
|
|
@@ -2935,10 +3611,10 @@ var stellarRecordsStateDefinitions = [
|
|
|
2935
3611
|
];
|
|
2936
3612
|
|
|
2937
3613
|
// src/state/schemas/registry/lookup.ts
|
|
2938
|
-
import { z as
|
|
2939
|
-
var readStellarAddressRegisteredSchema =
|
|
2940
|
-
type:
|
|
2941
|
-
address:
|
|
3614
|
+
import { z as z9 } from "zod";
|
|
3615
|
+
var readStellarAddressRegisteredSchema = z9.object({
|
|
3616
|
+
type: z9.literal(stellarStateCallTypes.readStellarAddressRegistered),
|
|
3617
|
+
address: z9.string().min(1)
|
|
2942
3618
|
}).transform(({ type, address }) => ({
|
|
2943
3619
|
type,
|
|
2944
3620
|
operations: [
|
|
@@ -2949,9 +3625,9 @@ var readStellarAddressRegisteredSchema = z11.object({
|
|
|
2949
3625
|
}
|
|
2950
3626
|
]
|
|
2951
3627
|
}));
|
|
2952
|
-
var readCachedPrivateAddressSchema =
|
|
2953
|
-
type:
|
|
2954
|
-
address:
|
|
3628
|
+
var readCachedPrivateAddressSchema = z9.object({
|
|
3629
|
+
type: z9.literal(stellarStateCallTypes.readCachedPrivateAddress),
|
|
3630
|
+
address: z9.string().min(1)
|
|
2955
3631
|
}).transform(({ type, address }) => ({
|
|
2956
3632
|
type,
|
|
2957
3633
|
operations: [
|
|
@@ -2962,11 +3638,11 @@ var readCachedPrivateAddressSchema = z11.object({
|
|
|
2962
3638
|
}
|
|
2963
3639
|
]
|
|
2964
3640
|
}));
|
|
2965
|
-
var saveRegisteredPrivateAddressSchema =
|
|
2966
|
-
type:
|
|
2967
|
-
address:
|
|
2968
|
-
privateAddress:
|
|
2969
|
-
registered:
|
|
3641
|
+
var saveRegisteredPrivateAddressSchema = z9.object({
|
|
3642
|
+
type: z9.literal(stellarStateCallTypes.saveRegisteredPrivateAddress),
|
|
3643
|
+
address: z9.string().min(1),
|
|
3644
|
+
privateAddress: z9.string().min(1),
|
|
3645
|
+
registered: z9.boolean()
|
|
2970
3646
|
}).transform(({ type, address, privateAddress, registered: registered2 }) => {
|
|
2971
3647
|
const lookup = registryLookupSchema.parse({
|
|
2972
3648
|
owner: address,
|
|
@@ -2998,9 +3674,9 @@ var saveRegisteredPrivateAddressSchema = z11.object({
|
|
|
2998
3674
|
]
|
|
2999
3675
|
};
|
|
3000
3676
|
});
|
|
3001
|
-
var invalidateRegisteredAddressSchema =
|
|
3002
|
-
type:
|
|
3003
|
-
address:
|
|
3677
|
+
var invalidateRegisteredAddressSchema = z9.object({
|
|
3678
|
+
type: z9.literal(stellarStateCallTypes.invalidateRegisteredAddress),
|
|
3679
|
+
address: z9.string().min(1)
|
|
3004
3680
|
}).transform(({ type, address }) => ({
|
|
3005
3681
|
type,
|
|
3006
3682
|
operations: [
|
|
@@ -3021,9 +3697,9 @@ var invalidateRegisteredAddressSchema = z11.object({
|
|
|
3021
3697
|
}
|
|
3022
3698
|
]
|
|
3023
3699
|
}));
|
|
3024
|
-
var readRegistryLookupSchema =
|
|
3025
|
-
type:
|
|
3026
|
-
address:
|
|
3700
|
+
var readRegistryLookupSchema = z9.object({
|
|
3701
|
+
type: z9.literal(stellarStateCallTypes.readRegistryLookup),
|
|
3702
|
+
address: z9.string().min(1)
|
|
3027
3703
|
}).transform(({ type, address }) => ({
|
|
3028
3704
|
type,
|
|
3029
3705
|
operations: [
|
|
@@ -3034,8 +3710,8 @@ var readRegistryLookupSchema = z11.object({
|
|
|
3034
3710
|
}
|
|
3035
3711
|
]
|
|
3036
3712
|
}));
|
|
3037
|
-
var saveRegistryLookupSchema =
|
|
3038
|
-
type:
|
|
3713
|
+
var saveRegistryLookupSchema = z9.object({
|
|
3714
|
+
type: z9.literal(stellarStateCallTypes.saveRegistryLookup),
|
|
3039
3715
|
lookup: registryLookupSchema
|
|
3040
3716
|
}).transform(({ type, lookup }) => {
|
|
3041
3717
|
const operations = [
|
|
@@ -3071,9 +3747,9 @@ var saveRegistryLookupSchema = z11.object({
|
|
|
3071
3747
|
}
|
|
3072
3748
|
return { type, operations };
|
|
3073
3749
|
});
|
|
3074
|
-
var invalidateRegistryLookupSchema =
|
|
3075
|
-
type:
|
|
3076
|
-
address:
|
|
3750
|
+
var invalidateRegistryLookupSchema = z9.object({
|
|
3751
|
+
type: z9.literal(stellarStateCallTypes.invalidateRegistryLookup),
|
|
3752
|
+
address: z9.string().min(1)
|
|
3077
3753
|
}).transform(({ type, address }) => ({
|
|
3078
3754
|
type,
|
|
3079
3755
|
operations: [
|
|
@@ -3154,9 +3830,9 @@ var stellarTransactionStateDefinitions = [
|
|
|
3154
3830
|
];
|
|
3155
3831
|
|
|
3156
3832
|
// src/state/schemas/wallet/scalar.ts
|
|
3157
|
-
import { z as
|
|
3158
|
-
var saveWalletPrivateAddressScalarSchema =
|
|
3159
|
-
type:
|
|
3833
|
+
import { z as z10 } from "zod";
|
|
3834
|
+
var saveWalletPrivateAddressScalarSchema = z10.object({
|
|
3835
|
+
type: z10.literal(stellarStateCallTypes.saveWalletPrivateAddressScalar),
|
|
3160
3836
|
scalar: walletPrivateAddressScalarSchema
|
|
3161
3837
|
}).transform(({ type, scalar }) => ({
|
|
3162
3838
|
type,
|
|
@@ -3169,10 +3845,10 @@ var saveWalletPrivateAddressScalarSchema = z12.object({
|
|
|
3169
3845
|
}
|
|
3170
3846
|
]
|
|
3171
3847
|
}));
|
|
3172
|
-
var readWalletPrivateAddressScalarSchema =
|
|
3173
|
-
type:
|
|
3174
|
-
owner:
|
|
3175
|
-
nonce:
|
|
3848
|
+
var readWalletPrivateAddressScalarSchema = z10.object({
|
|
3849
|
+
type: z10.literal(stellarStateCallTypes.readWalletPrivateAddressScalar),
|
|
3850
|
+
owner: z10.string().min(1),
|
|
3851
|
+
nonce: z10.string().min(1)
|
|
3176
3852
|
}).transform(({ type, owner, nonce }) => ({
|
|
3177
3853
|
type,
|
|
3178
3854
|
operations: [
|
|
@@ -3185,9 +3861,9 @@ var readWalletPrivateAddressScalarSchema = z12.object({
|
|
|
3185
3861
|
}));
|
|
3186
3862
|
|
|
3187
3863
|
// src/state/schemas/wallet/private-address.ts
|
|
3188
|
-
import { z as
|
|
3189
|
-
var saveWalletPrivateAddressRecordSchema =
|
|
3190
|
-
type:
|
|
3864
|
+
import { z as z11 } from "zod";
|
|
3865
|
+
var saveWalletPrivateAddressRecordSchema = z11.object({
|
|
3866
|
+
type: z11.literal(stellarStateCallTypes.saveWalletPrivateAddressRecord),
|
|
3191
3867
|
record: walletPrivateAddressRecordSchema
|
|
3192
3868
|
}).transform(({ type, record }) => ({
|
|
3193
3869
|
type,
|
|
@@ -3200,10 +3876,10 @@ var saveWalletPrivateAddressRecordSchema = z13.object({
|
|
|
3200
3876
|
}
|
|
3201
3877
|
]
|
|
3202
3878
|
}));
|
|
3203
|
-
var readWalletPrivateAddressRecordSchema =
|
|
3204
|
-
type:
|
|
3205
|
-
owner:
|
|
3206
|
-
nonce:
|
|
3879
|
+
var readWalletPrivateAddressRecordSchema = z11.object({
|
|
3880
|
+
type: z11.literal(stellarStateCallTypes.readWalletPrivateAddressRecord),
|
|
3881
|
+
owner: z11.string().min(1),
|
|
3882
|
+
nonce: z11.string().min(1)
|
|
3207
3883
|
}).transform(({ type, owner, nonce }) => ({
|
|
3208
3884
|
type,
|
|
3209
3885
|
operations: [
|
|
@@ -3214,10 +3890,10 @@ var readWalletPrivateAddressRecordSchema = z13.object({
|
|
|
3214
3890
|
}
|
|
3215
3891
|
]
|
|
3216
3892
|
}));
|
|
3217
|
-
var setWalletDefaultPrivateAddressNonceSchema =
|
|
3218
|
-
type:
|
|
3219
|
-
owner:
|
|
3220
|
-
nonce:
|
|
3893
|
+
var setWalletDefaultPrivateAddressNonceSchema = z11.object({
|
|
3894
|
+
type: z11.literal(stellarStateCallTypes.setWalletDefaultPrivateAddressNonce),
|
|
3895
|
+
owner: z11.string().min(1),
|
|
3896
|
+
nonce: z11.string().min(1)
|
|
3221
3897
|
}).transform(({ type, owner, nonce }) => ({
|
|
3222
3898
|
type,
|
|
3223
3899
|
operations: [
|
|
@@ -3229,9 +3905,9 @@ var setWalletDefaultPrivateAddressNonceSchema = z13.object({
|
|
|
3229
3905
|
}
|
|
3230
3906
|
]
|
|
3231
3907
|
}));
|
|
3232
|
-
var readWalletDefaultPrivateAddressNonceSchema =
|
|
3233
|
-
type:
|
|
3234
|
-
owner:
|
|
3908
|
+
var readWalletDefaultPrivateAddressNonceSchema = z11.object({
|
|
3909
|
+
type: z11.literal(stellarStateCallTypes.readWalletDefaultPrivateAddressNonce),
|
|
3910
|
+
owner: z11.string().min(1)
|
|
3235
3911
|
}).transform(({ type, owner }) => ({
|
|
3236
3912
|
type,
|
|
3237
3913
|
operations: [
|
|
@@ -3242,10 +3918,10 @@ var readWalletDefaultPrivateAddressNonceSchema = z13.object({
|
|
|
3242
3918
|
}
|
|
3243
3919
|
]
|
|
3244
3920
|
}));
|
|
3245
|
-
var deleteWalletPrivateAddressScalarSchema =
|
|
3246
|
-
type:
|
|
3247
|
-
owner:
|
|
3248
|
-
nonce:
|
|
3921
|
+
var deleteWalletPrivateAddressScalarSchema = z11.object({
|
|
3922
|
+
type: z11.literal(stellarStateCallTypes.deleteWalletPrivateAddressScalar),
|
|
3923
|
+
owner: z11.string().min(1),
|
|
3924
|
+
nonce: z11.string().min(1)
|
|
3249
3925
|
}).transform(({ type, owner, nonce }) => ({
|
|
3250
3926
|
type,
|
|
3251
3927
|
operations: [
|
|
@@ -3299,7 +3975,6 @@ var stellarWalletStateDefinitions = [
|
|
|
3299
3975
|
// src/state/definitions/index.ts
|
|
3300
3976
|
registerStellarArrayFilterSchemas();
|
|
3301
3977
|
var stellarStateDefinitions = [
|
|
3302
|
-
...stellarClaimsStateDefinitions,
|
|
3303
3978
|
...stellarRegistryStateDefinitions,
|
|
3304
3979
|
...stellarAssetsStateDefinitions,
|
|
3305
3980
|
...stellarBalancesStateDefinitions,
|
|
@@ -3423,112 +4098,10 @@ function createAssetsCatalogMethods(context) {
|
|
|
3423
4098
|
}
|
|
3424
4099
|
|
|
3425
4100
|
// 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) {
|
|
4101
|
+
function createAssetsService(context) {
|
|
3529
4102
|
return {
|
|
3530
|
-
...
|
|
3531
|
-
...
|
|
4103
|
+
...createAssetsCatalogMethods(context),
|
|
4104
|
+
...createPublicBalanceMethods(context)
|
|
3532
4105
|
};
|
|
3533
4106
|
}
|
|
3534
4107
|
|
|
@@ -4057,7 +4630,6 @@ function composeStellarStateService(adapter) {
|
|
|
4057
4630
|
...createWalletAddressService(base),
|
|
4058
4631
|
...createPoolMerkleService(base),
|
|
4059
4632
|
...createPoolEphemeralService(base),
|
|
4060
|
-
...createClaimsService(base),
|
|
4061
4633
|
...createDeliveriesService(base),
|
|
4062
4634
|
...createRecordsService(base)
|
|
4063
4635
|
};
|
|
@@ -4122,42 +4694,1030 @@ function attachPoolStatePorts(transactEnvironment, state) {
|
|
|
4122
4694
|
resolveSenderPrivKeyScalarFromState: createSenderScalarStateResolver(state)
|
|
4123
4695
|
};
|
|
4124
4696
|
}
|
|
4697
|
+
|
|
4698
|
+
// src/transact/encoding/ephemeral-key.ts
|
|
4699
|
+
var HEX_64_RE = /^[\da-f]{64}$/iu;
|
|
4700
|
+
function normalizeCoordinate(value) {
|
|
4701
|
+
const hex = value.trim().replace(/^0x/iu, "").toLowerCase();
|
|
4702
|
+
if (!HEX_64_RE.test(hex)) {
|
|
4703
|
+
throw new Error("Ephemeral key coordinate must be a 32-byte hex string.");
|
|
4704
|
+
}
|
|
4705
|
+
return hex;
|
|
4706
|
+
}
|
|
4707
|
+
function serializeEphemeralKeyString(point) {
|
|
4708
|
+
return `${normalizeCoordinate(point.xHex)}:${normalizeCoordinate(point.yHex)}`;
|
|
4709
|
+
}
|
|
4710
|
+
|
|
4711
|
+
// src/transact/private-address/record-coin.ts
|
|
4712
|
+
function requireCoinNoteFromRecord(record) {
|
|
4713
|
+
if (!record.coinNote) {
|
|
4714
|
+
throw new Error(`Private record ${record.id} is missing coin note data.`);
|
|
4715
|
+
}
|
|
4716
|
+
return record.coinNote;
|
|
4717
|
+
}
|
|
4718
|
+
function findCommitmentLeafIndex(commitments, commitment) {
|
|
4719
|
+
return commitments.indexOf(commitment);
|
|
4720
|
+
}
|
|
4721
|
+
|
|
4722
|
+
// src/transact/engine/prepare/shared.ts
|
|
4723
|
+
async function resolveTokenContractId2(environment, assetId) {
|
|
4724
|
+
if (environment.resolveTokenContractId) {
|
|
4725
|
+
return environment.resolveTokenContractId(assetId);
|
|
4726
|
+
}
|
|
4727
|
+
throw new Error(`Token contract is not configured for asset ${assetId}.`);
|
|
4728
|
+
}
|
|
4729
|
+
async function resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
|
|
4730
|
+
const cached = await readSenderPrivKeyScalarHex(
|
|
4731
|
+
environment,
|
|
4732
|
+
privateAddressStpl1,
|
|
4733
|
+
owner
|
|
4734
|
+
);
|
|
4735
|
+
if (cached) {
|
|
4736
|
+
return cached;
|
|
4737
|
+
}
|
|
4738
|
+
if (environment.ensureSenderPrivKeyScalarHex) {
|
|
4739
|
+
return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
|
|
4740
|
+
}
|
|
4741
|
+
if (!environment.resolveSenderPrivKeyScalarHex) {
|
|
4742
|
+
throw new Error("Sender private key scalar resolver is not configured.");
|
|
4743
|
+
}
|
|
4744
|
+
return environment.resolveSenderPrivKeyScalarHex(privateAddressStpl1);
|
|
4745
|
+
}
|
|
4746
|
+
async function readSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
|
|
4747
|
+
if (owner && environment.resolveSenderPrivKeyScalarFromState) {
|
|
4748
|
+
const fromState = await environment.resolveSenderPrivKeyScalarFromState({
|
|
4749
|
+
owner,
|
|
4750
|
+
privateAddressStpl1
|
|
4751
|
+
});
|
|
4752
|
+
if (fromState?.trim()) {
|
|
4753
|
+
return fromState.trim();
|
|
4754
|
+
}
|
|
4755
|
+
}
|
|
4756
|
+
if (environment.readSenderPrivKeyScalarHex) {
|
|
4757
|
+
const cached = await environment.readSenderPrivKeyScalarHex(privateAddressStpl1);
|
|
4758
|
+
if (cached?.trim()) {
|
|
4759
|
+
return cached.trim();
|
|
4760
|
+
}
|
|
4761
|
+
}
|
|
4762
|
+
return void 0;
|
|
4763
|
+
}
|
|
4764
|
+
async function ensureSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner) {
|
|
4765
|
+
const cached = await readSenderPrivKeyScalarHex(
|
|
4766
|
+
environment,
|
|
4767
|
+
privateAddressStpl1,
|
|
4768
|
+
owner
|
|
4769
|
+
);
|
|
4770
|
+
if (cached) {
|
|
4771
|
+
return cached;
|
|
4772
|
+
}
|
|
4773
|
+
if (environment.ensureSenderPrivKeyScalarHex) {
|
|
4774
|
+
return environment.ensureSenderPrivKeyScalarHex(privateAddressStpl1);
|
|
4775
|
+
}
|
|
4776
|
+
return resolveSenderPrivKeyScalarHex(environment, privateAddressStpl1, owner);
|
|
4777
|
+
}
|
|
4778
|
+
async function loadMerkleState(environment, walletPublicKey) {
|
|
4779
|
+
const merged = await fetchAndMergeMerkleState({
|
|
4780
|
+
poolContractId: environment.network.poolContract,
|
|
4781
|
+
walletPublicKey,
|
|
4782
|
+
transactEnvironment: environment,
|
|
4783
|
+
...environment.poolMerkleState ? { poolMerkleState: environment.poolMerkleState } : {}
|
|
4784
|
+
});
|
|
4785
|
+
return { commitments: merged.commitments };
|
|
4786
|
+
}
|
|
4787
|
+
|
|
4788
|
+
// src/transact/escrow/require-escrow-spend-scalar.ts
|
|
4789
|
+
function isEscrowSweepSpend(artifacts) {
|
|
4790
|
+
return artifacts?.spendSource === "escrow" && artifacts.escrowSend !== true;
|
|
4791
|
+
}
|
|
4792
|
+
function requireEscrowSpendScalarHex(artifacts) {
|
|
4793
|
+
if (!isEscrowSweepSpend(artifacts)) {
|
|
4794
|
+
throw new Error("Escrow sweep requires spendSource escrow.");
|
|
4795
|
+
}
|
|
4796
|
+
const hex = artifacts?.escrowSpendScalarHex?.trim();
|
|
4797
|
+
if (!hex) {
|
|
4798
|
+
throw new Error("Escrow sweep requires the reconstructed note owner scalar.");
|
|
4799
|
+
}
|
|
4800
|
+
return hex;
|
|
4801
|
+
}
|
|
4802
|
+
function nullifierCheckSpendScalarHex(artifacts) {
|
|
4803
|
+
if (!isEscrowSweepSpend(artifacts)) {
|
|
4804
|
+
return void 0;
|
|
4805
|
+
}
|
|
4806
|
+
return requireEscrowSpendScalarHex(artifacts);
|
|
4807
|
+
}
|
|
4808
|
+
|
|
4809
|
+
// src/transact/transfer-source/resolve.ts
|
|
4810
|
+
function readTransferFromPrivateAddress(from) {
|
|
4811
|
+
return from.trim();
|
|
4812
|
+
}
|
|
4813
|
+
|
|
4814
|
+
// src/transact/transfer-source/verify-private-records.ts
|
|
4815
|
+
import { executionError, insufficientStateError as insufficientStateError2 } from "@arcanetech/privacy-sdk-core";
|
|
4816
|
+
|
|
4817
|
+
// src/contracts/pool/pool-domain-service.ts
|
|
4818
|
+
import { Buffer as Buffer14 } from "buffer";
|
|
4819
|
+
function hexToBuffer(hex) {
|
|
4820
|
+
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
4821
|
+
return Buffer14.from(clean, "hex");
|
|
4822
|
+
}
|
|
4823
|
+
async function readNullifierConsumedOnChain(input) {
|
|
4824
|
+
const client = input.contractContext.createPoolClient({
|
|
4825
|
+
contractId: input.poolContractId,
|
|
4826
|
+
walletPublicKey: input.walletPublicKey,
|
|
4827
|
+
networkPassphrase: input.contractContext.network.networkPassphrase,
|
|
4828
|
+
sorobanRpcUrl: input.contractContext.network.rpcUrl
|
|
4829
|
+
});
|
|
4830
|
+
const read = await client.is_nulifier_hash_consumed({
|
|
4831
|
+
hash: hexToBuffer(input.nullifierHashHex)
|
|
4832
|
+
});
|
|
4833
|
+
return read.result;
|
|
4834
|
+
}
|
|
4835
|
+
|
|
4836
|
+
// src/transact/transfer-source/verify-private-records.ts
|
|
4837
|
+
async function resolveNullifierSpendScalarHex(input) {
|
|
4838
|
+
const stamped = input.spendScalarHex?.trim();
|
|
4839
|
+
if (stamped) {
|
|
4840
|
+
return stamped;
|
|
4841
|
+
}
|
|
4842
|
+
const privateAddress = input.record.privateAddress?.trim();
|
|
4843
|
+
if (!privateAddress) {
|
|
4844
|
+
throw executionError(
|
|
4845
|
+
"Private record is missing a private address; cannot derive the owner-bound spend scalar.",
|
|
4846
|
+
"validation",
|
|
4847
|
+
{
|
|
4848
|
+
reason: "private_record_missing_private_address",
|
|
4849
|
+
recordId: input.record.id
|
|
4850
|
+
}
|
|
4851
|
+
);
|
|
4852
|
+
}
|
|
4853
|
+
return ensureSenderPrivKeyScalarHex(
|
|
4854
|
+
input.environment,
|
|
4855
|
+
privateAddress,
|
|
4856
|
+
input.walletPublicKey
|
|
4857
|
+
);
|
|
4858
|
+
}
|
|
4859
|
+
async function readPrivateRecordNullifierSpendStatus(input) {
|
|
4860
|
+
const coin = requireCoinNoteFromRecord(input.record);
|
|
4861
|
+
const scalarHex = await resolveNullifierSpendScalarHex(input);
|
|
4862
|
+
const nullifierHashHex = await getPrivacyPoolService().calculateNullifierHash(
|
|
4863
|
+
coin.nullifier,
|
|
4864
|
+
privKeyScalarDecimalFromRecipientScalarHex(scalarHex)
|
|
4865
|
+
);
|
|
4866
|
+
const contractContext = requireContractContext(input.environment);
|
|
4867
|
+
const poolContractId = input.poolContractId?.trim() || contractContext.network.poolContract;
|
|
4868
|
+
const spent = await readNullifierConsumedOnChain({
|
|
4869
|
+
contractContext,
|
|
4870
|
+
poolContractId,
|
|
4871
|
+
walletPublicKey: input.walletPublicKey.trim(),
|
|
4872
|
+
nullifierHashHex
|
|
4873
|
+
});
|
|
4874
|
+
return { spent, nullifierHashHex };
|
|
4875
|
+
}
|
|
4876
|
+
async function verifyPrivateRecordsNullifiersBeforeExecute(input) {
|
|
4877
|
+
for (const record of input.records) {
|
|
4878
|
+
const status = await readPrivateRecordNullifierSpendStatus({
|
|
4879
|
+
record,
|
|
4880
|
+
environment: input.environment,
|
|
4881
|
+
walletPublicKey: input.walletPublicKey,
|
|
4882
|
+
...input.poolContractId ? { poolContractId: input.poolContractId } : {},
|
|
4883
|
+
...input.spendScalarHex ? { spendScalarHex: input.spendScalarHex } : {}
|
|
4884
|
+
});
|
|
4885
|
+
if (status.spent) {
|
|
4886
|
+
throw executionError(
|
|
4887
|
+
"Private input note nullifier was already spent on-chain.",
|
|
4888
|
+
"validation",
|
|
4889
|
+
{
|
|
4890
|
+
reason: "private_record_nullifier_spent",
|
|
4891
|
+
recordId: record.id,
|
|
4892
|
+
nullifierHashHex: status.nullifierHashHex
|
|
4893
|
+
}
|
|
4894
|
+
);
|
|
4895
|
+
}
|
|
4896
|
+
}
|
|
4897
|
+
}
|
|
4898
|
+
|
|
4899
|
+
// src/transact/engine/spend-proof-context.ts
|
|
4900
|
+
async function resolveSenderPrivKeyScalarHex2(input) {
|
|
4901
|
+
if (isEscrowSweepSpend(input.prepared.transactArtifacts)) {
|
|
4902
|
+
return requireEscrowSpendScalarHex(input.prepared.transactArtifacts);
|
|
4903
|
+
}
|
|
4904
|
+
if (input.prepared.kind !== "transfer" && input.prepared.kind !== "withdraw") {
|
|
4905
|
+
throw new Error("Spend execution requires a transfer or withdraw intent.");
|
|
4906
|
+
}
|
|
4907
|
+
return ensureSenderPrivKeyScalarHex(
|
|
4908
|
+
input.environment,
|
|
4909
|
+
readTransferFromPrivateAddress(input.prepared.intent.from),
|
|
4910
|
+
input.walletPublicKey
|
|
4911
|
+
);
|
|
4912
|
+
}
|
|
4913
|
+
async function buildSpendProofContextAtExecute(input) {
|
|
4914
|
+
const [primaryRecord] = input.prepared.consumedRecords;
|
|
4915
|
+
if (!primaryRecord) {
|
|
4916
|
+
throw new Error("Spend execution requires at least one private record.");
|
|
4917
|
+
}
|
|
4918
|
+
const walletPublicKey = primaryRecord.owner.trim();
|
|
4919
|
+
if (!walletPublicKey) {
|
|
4920
|
+
throw new Error("Spend execution record owner is missing.");
|
|
4921
|
+
}
|
|
4922
|
+
const senderPrivKeyScalarHex = await resolveSenderPrivKeyScalarHex2({
|
|
4923
|
+
prepared: input.prepared,
|
|
4924
|
+
environment: input.environment,
|
|
4925
|
+
walletPublicKey
|
|
4926
|
+
});
|
|
4927
|
+
const tokenAddress = await resolveTokenContractId2(
|
|
4928
|
+
input.environment,
|
|
4929
|
+
input.prepared.intent.asset
|
|
4930
|
+
);
|
|
4931
|
+
const coin = requireCoinNoteFromRecord(primaryRecord);
|
|
4932
|
+
const { commitments } = await loadMerkleState(input.environment, walletPublicKey);
|
|
4933
|
+
const leafIndex = findCommitmentLeafIndex(commitments, coin.commitment);
|
|
4934
|
+
if (leafIndex < 0) {
|
|
4935
|
+
throw new Error("Coin commitment not found in on-chain Merkle state.");
|
|
4936
|
+
}
|
|
4937
|
+
const ephemeral = await readLeafEphemeralHex({
|
|
4938
|
+
poolContractId: input.environment.network.poolContract,
|
|
4939
|
+
walletPublicKey,
|
|
4940
|
+
leafIndex,
|
|
4941
|
+
transactEnvironment: input.environment,
|
|
4942
|
+
...input.environment.leafEphemeral ? { leafEphemeral: input.environment.leafEphemeral } : {}
|
|
4943
|
+
});
|
|
4944
|
+
return {
|
|
4945
|
+
walletPublicKey,
|
|
4946
|
+
tokenAddress,
|
|
4947
|
+
coin,
|
|
4948
|
+
commitments,
|
|
4949
|
+
ephemeral,
|
|
4950
|
+
senderPrivKeyScalarHex,
|
|
4951
|
+
recipientPrivateAddressStpl1: input.recipientPrivateAddressStpl1
|
|
4952
|
+
};
|
|
4953
|
+
}
|
|
4954
|
+
async function readCoinEphemeralForRecord(input) {
|
|
4955
|
+
const coin = requireCoinNoteFromRecord(input.record);
|
|
4956
|
+
const leafIndex = findCommitmentLeafIndex(input.commitments, coin.commitment);
|
|
4957
|
+
if (leafIndex < 0) {
|
|
4958
|
+
throw new Error("Coin commitment not found in on-chain Merkle state.");
|
|
4959
|
+
}
|
|
4960
|
+
const ephemeral = await readLeafEphemeralHex({
|
|
4961
|
+
poolContractId: input.environment.network.poolContract,
|
|
4962
|
+
walletPublicKey: input.walletPublicKey,
|
|
4963
|
+
leafIndex,
|
|
4964
|
+
transactEnvironment: input.environment,
|
|
4965
|
+
...input.environment.leafEphemeral ? { leafEphemeral: input.environment.leafEphemeral } : {}
|
|
4966
|
+
});
|
|
4967
|
+
return { coin, ephemeral };
|
|
4968
|
+
}
|
|
4969
|
+
|
|
4970
|
+
// src/transact/engine/prepare/transfer-helpers.ts
|
|
4971
|
+
import { StrKey as StrKey8 } from "@stellar/stellar-sdk";
|
|
4972
|
+
function isStellarAccountRecipient(prepared) {
|
|
4973
|
+
return prepared.kind === "transfer" && StrKey8.isValidEd25519PublicKey(prepared.intent.to.trim());
|
|
4974
|
+
}
|
|
4975
|
+
async function resolveTransferRecipientForExecute(prepared, environment, walletPublicKey) {
|
|
4976
|
+
if (!isStellarAccountRecipient(prepared)) {
|
|
4977
|
+
return {
|
|
4978
|
+
recipientPrivateAddressStpl1: prepared.intent.to.trim()
|
|
4979
|
+
};
|
|
4980
|
+
}
|
|
4981
|
+
if (!environment.resolveTransferRecipientAtExecute) {
|
|
4982
|
+
throw new Error("Transfer recipient resolver is not configured.");
|
|
4983
|
+
}
|
|
4984
|
+
return environment.resolveTransferRecipientAtExecute({
|
|
4985
|
+
recipientStellarAddress: prepared.intent.to.trim(),
|
|
4986
|
+
walletPublicKey
|
|
4987
|
+
});
|
|
4988
|
+
}
|
|
4989
|
+
|
|
4990
|
+
// src/transact/engine/transfer-proof-at-execute.ts
|
|
4991
|
+
function readChangeRecipient(input, changeStroops) {
|
|
4992
|
+
if (changeStroops <= 0n || input.prepared.kind !== "transfer") {
|
|
4993
|
+
return void 0;
|
|
4994
|
+
}
|
|
4995
|
+
const from = input.prepared.intent.from;
|
|
4996
|
+
return readTransferFromPrivateAddress(from);
|
|
4997
|
+
}
|
|
4998
|
+
function proofEscrowFields(input) {
|
|
4999
|
+
return {
|
|
5000
|
+
...input.escrowSend ? { escrowSend: input.escrowSend } : {},
|
|
5001
|
+
...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
|
|
5002
|
+
};
|
|
5003
|
+
}
|
|
5004
|
+
async function buildSingleTransferProofAtExecute(input) {
|
|
5005
|
+
const context = await buildSpendProofContextAtExecute(input);
|
|
5006
|
+
const changeStroops = BigInt(context.coin.value) - input.prepared.intent.amount;
|
|
5007
|
+
const proof = await prepareConfidentialTransferProof({
|
|
5008
|
+
coin: context.coin,
|
|
5009
|
+
state: { commitments: context.commitments },
|
|
5010
|
+
senderPrivKeyScalarHex: context.senderPrivKeyScalarHex,
|
|
5011
|
+
depositorEphemeralKey: serializeEphemeralKeyString({
|
|
5012
|
+
xHex: context.ephemeral.xHex,
|
|
5013
|
+
yHex: context.ephemeral.yHex
|
|
5014
|
+
}),
|
|
5015
|
+
transferStroops: input.prepared.intent.amount,
|
|
5016
|
+
recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
|
|
5017
|
+
selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
|
|
5018
|
+
tokenAddress: context.tokenAddress,
|
|
5019
|
+
...proofEscrowFields(input)
|
|
5020
|
+
});
|
|
5021
|
+
return { context, proof };
|
|
5022
|
+
}
|
|
5023
|
+
async function buildDualTransferProofAtExecute(input) {
|
|
5024
|
+
const [primaryRecord, secondaryRecord] = input.prepared.consumedRecords;
|
|
5025
|
+
if (!primaryRecord || !secondaryRecord) {
|
|
5026
|
+
throw new Error("Dual transfer execution requires two private input records.");
|
|
5027
|
+
}
|
|
5028
|
+
const context = await buildSpendProofContextAtExecute(input);
|
|
5029
|
+
const secondary = await readCoinEphemeralForRecord({
|
|
5030
|
+
record: secondaryRecord,
|
|
5031
|
+
environment: input.environment,
|
|
5032
|
+
walletPublicKey: context.walletPublicKey,
|
|
5033
|
+
commitments: context.commitments
|
|
5034
|
+
});
|
|
5035
|
+
const totalNotes = BigInt(context.coin.value) + BigInt(secondary.coin.value);
|
|
5036
|
+
const changeStroops = totalNotes - input.prepared.intent.amount;
|
|
5037
|
+
const proof = await prepareConfidentialTransferProofDual({
|
|
5038
|
+
coinA: context.coin,
|
|
5039
|
+
coinB: secondary.coin,
|
|
5040
|
+
state: { commitments: context.commitments },
|
|
5041
|
+
senderPrivKeyScalarHex: context.senderPrivKeyScalarHex,
|
|
5042
|
+
ephemeralAKey: serializeEphemeralKeyString({
|
|
5043
|
+
xHex: context.ephemeral.xHex,
|
|
5044
|
+
yHex: context.ephemeral.yHex
|
|
5045
|
+
}),
|
|
5046
|
+
ephemeralBKey: serializeEphemeralKeyString({
|
|
5047
|
+
xHex: secondary.ephemeral.xHex,
|
|
5048
|
+
yHex: secondary.ephemeral.yHex
|
|
5049
|
+
}),
|
|
5050
|
+
transferStroops: input.prepared.intent.amount,
|
|
5051
|
+
recipientPrivateAddressStpl1: context.recipientPrivateAddressStpl1,
|
|
5052
|
+
selfPrivateAddressStpl1ForChange: readChangeRecipient(input, changeStroops),
|
|
5053
|
+
tokenAddress: context.tokenAddress,
|
|
5054
|
+
...proofEscrowFields(input)
|
|
5055
|
+
});
|
|
5056
|
+
return { context, proof };
|
|
5057
|
+
}
|
|
5058
|
+
async function buildTransferProofAtExecute(input) {
|
|
5059
|
+
const recordCount = input.prepared.consumedRecords.length;
|
|
5060
|
+
if (recordCount === 1) {
|
|
5061
|
+
return buildSingleTransferProofAtExecute(input);
|
|
5062
|
+
}
|
|
5063
|
+
if (recordCount === 2) {
|
|
5064
|
+
return buildDualTransferProofAtExecute(input);
|
|
5065
|
+
}
|
|
5066
|
+
throw new Error("Confidential transfer execution supports at most two input notes.");
|
|
5067
|
+
}
|
|
5068
|
+
|
|
5069
|
+
// src/transact/engine/transfer-finalize.ts
|
|
5070
|
+
function stampEscrowOutputRecords(input) {
|
|
5071
|
+
if (input.escrowSendPrivateAddress) {
|
|
5072
|
+
const [recipientRecord, ...rest] = input.prepared.outputRecords;
|
|
5073
|
+
if (recipientRecord) {
|
|
5074
|
+
input.prepared.outputRecords = [
|
|
5075
|
+
{
|
|
5076
|
+
...recipientRecord,
|
|
5077
|
+
privateAddress: input.escrowSendPrivateAddress
|
|
5078
|
+
},
|
|
5079
|
+
...rest
|
|
5080
|
+
];
|
|
5081
|
+
}
|
|
5082
|
+
}
|
|
5083
|
+
seedEscrowSweepOutputsFromProof({
|
|
5084
|
+
prepared: input.prepared,
|
|
5085
|
+
proof: input.proof,
|
|
5086
|
+
walletPublicKey: input.walletPublicKey
|
|
5087
|
+
});
|
|
5088
|
+
enrichTransferOutputRecords(input.prepared, input.proof);
|
|
5089
|
+
}
|
|
5090
|
+
function seedEscrowSweepOutputsFromProof(input) {
|
|
5091
|
+
if (input.prepared.transactArtifacts?.spendSource !== "escrow" || input.prepared.outputRecords.length > 0) {
|
|
5092
|
+
return;
|
|
5093
|
+
}
|
|
5094
|
+
input.prepared.outputRecords = [
|
|
5095
|
+
{
|
|
5096
|
+
id: input.proof.recipientCoin.commitment_hex,
|
|
5097
|
+
owner: input.walletPublicKey,
|
|
5098
|
+
privateAddress: input.prepared.intent.to,
|
|
5099
|
+
asset: input.prepared.intent.asset,
|
|
5100
|
+
amount: input.prepared.intent.amount,
|
|
5101
|
+
consumed: false
|
|
5102
|
+
}
|
|
5103
|
+
];
|
|
5104
|
+
}
|
|
5105
|
+
function enrichTransferOutputRecords(prepared, proof) {
|
|
5106
|
+
if (prepared.outputRecords.length === 0) {
|
|
5107
|
+
return;
|
|
5108
|
+
}
|
|
5109
|
+
const generatedOutputCoins = [
|
|
5110
|
+
proof.recipientCoin,
|
|
5111
|
+
...proof.changeCoin ? [proof.changeCoin] : []
|
|
5112
|
+
];
|
|
5113
|
+
prepared.outputRecords = prepared.outputRecords.map((record, index) => {
|
|
5114
|
+
const generatedCoin = generatedOutputCoins.at(index);
|
|
5115
|
+
if (!generatedCoin) {
|
|
5116
|
+
return record;
|
|
5117
|
+
}
|
|
5118
|
+
return {
|
|
5119
|
+
...record,
|
|
5120
|
+
id: generatedCoin.commitment_hex,
|
|
5121
|
+
commitmentHex: generatedCoin.commitment_hex,
|
|
5122
|
+
coinNote: generatedCoin.coin,
|
|
5123
|
+
depositScalarHex: generatedCoin.depositScalarHex,
|
|
5124
|
+
precommitementHex: generatedCoin.precommitementHex
|
|
5125
|
+
};
|
|
5126
|
+
});
|
|
5127
|
+
}
|
|
5128
|
+
function escrowSpendArtifacts(input) {
|
|
5129
|
+
if (input.escrowSend) {
|
|
5130
|
+
return {
|
|
5131
|
+
escrowSend: true,
|
|
5132
|
+
spendSource: "escrow",
|
|
5133
|
+
...input.escrowRecipient ? { escrowRecipient: input.escrowRecipient } : {}
|
|
5134
|
+
};
|
|
5135
|
+
}
|
|
5136
|
+
if (input.preparedSpendSource === "escrow") {
|
|
5137
|
+
return {
|
|
5138
|
+
spendSource: "escrow",
|
|
5139
|
+
...input.escrowRecipient ? { escrowRecipient: input.escrowRecipient } : {},
|
|
5140
|
+
...input.escrowSpendScalarHex ? { escrowSpendScalarHex: input.escrowSpendScalarHex } : {},
|
|
5141
|
+
...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
|
|
5142
|
+
};
|
|
5143
|
+
}
|
|
5144
|
+
return {};
|
|
5145
|
+
}
|
|
5146
|
+
function buildTransferFinalizeArtifacts(input) {
|
|
5147
|
+
return {
|
|
5148
|
+
proofHex: input.proof.proof_hex,
|
|
5149
|
+
publicHex: input.proof.public_hex,
|
|
5150
|
+
...ciphertextArtifactsFromProof(input.proof),
|
|
5151
|
+
applicationIdsPlaintext: input.proof.applicationIdsPlaintext,
|
|
5152
|
+
tokenAddress: input.context.tokenAddress,
|
|
5153
|
+
walletPublicKey: input.context.walletPublicKey,
|
|
5154
|
+
executeFinalizeRequired: false,
|
|
5155
|
+
...escrowSpendArtifacts(input)
|
|
5156
|
+
};
|
|
5157
|
+
}
|
|
5158
|
+
async function runTransferFinalizeSteps(input) {
|
|
5159
|
+
const recipient = await resolveTransferRecipientForExecute(
|
|
5160
|
+
input.prepared,
|
|
5161
|
+
input.environment,
|
|
5162
|
+
input.walletPublicKey
|
|
5163
|
+
);
|
|
5164
|
+
const spendScalarHex = nullifierCheckSpendScalarHex(input.prepared.transactArtifacts);
|
|
5165
|
+
await verifyPrivateRecordsNullifiersBeforeExecute({
|
|
5166
|
+
records: input.prepared.consumedRecords,
|
|
5167
|
+
environment: input.environment,
|
|
5168
|
+
walletPublicKey: input.walletPublicKey,
|
|
5169
|
+
...spendScalarHex ? { spendScalarHex } : {}
|
|
5170
|
+
});
|
|
5171
|
+
const { context, proof } = await buildTransferProofAtExecute({
|
|
5172
|
+
prepared: input.prepared,
|
|
5173
|
+
environment: input.environment,
|
|
5174
|
+
recipientPrivateAddressStpl1: recipient.recipientPrivateAddressStpl1,
|
|
5175
|
+
...recipient.escrowSend ? { escrowSend: recipient.escrowSend } : {},
|
|
5176
|
+
...input.prepared.transactArtifacts?.escrowClaimantLimbs ? {
|
|
5177
|
+
escrowClaimantLimbs: input.prepared.transactArtifacts.escrowClaimantLimbs
|
|
5178
|
+
} : {}
|
|
5179
|
+
});
|
|
5180
|
+
stampEscrowOutputRecords({
|
|
5181
|
+
prepared: input.prepared,
|
|
5182
|
+
proof,
|
|
5183
|
+
walletPublicKey: input.walletPublicKey,
|
|
5184
|
+
...recipient.escrowSend ? { escrowSendPrivateAddress: recipient.recipientPrivateAddressStpl1 } : {}
|
|
5185
|
+
});
|
|
5186
|
+
return buildTransferFinalizeArtifacts({
|
|
5187
|
+
proof,
|
|
5188
|
+
context,
|
|
5189
|
+
...sweepFinalizeStamp(input.prepared, recipient)
|
|
5190
|
+
});
|
|
5191
|
+
}
|
|
5192
|
+
function sweepArtifactStamp(artifacts) {
|
|
5193
|
+
return {
|
|
5194
|
+
...artifacts?.escrowSpendScalarHex ? { escrowSpendScalarHex: artifacts.escrowSpendScalarHex } : {},
|
|
5195
|
+
...artifacts?.spendSource ? { preparedSpendSource: artifacts.spendSource } : {},
|
|
5196
|
+
...artifacts?.escrowClaimantLimbs ? { escrowClaimantLimbs: artifacts.escrowClaimantLimbs } : {}
|
|
5197
|
+
};
|
|
5198
|
+
}
|
|
5199
|
+
function sweepFinalizeStamp(prepared, recipient) {
|
|
5200
|
+
const artifacts = prepared.transactArtifacts;
|
|
5201
|
+
const fromSend = recipient.escrowSend?.recipientStellarAddress?.trim();
|
|
5202
|
+
const escrowRecipient = fromSend || artifacts?.escrowRecipient?.trim();
|
|
5203
|
+
return {
|
|
5204
|
+
...recipient.escrowSend ? { escrowSend: true } : {},
|
|
5205
|
+
...escrowRecipient ? { escrowRecipient } : {},
|
|
5206
|
+
...sweepArtifactStamp(artifacts)
|
|
5207
|
+
};
|
|
5208
|
+
}
|
|
5209
|
+
async function finalizeTransferAtExecute(prepared, environment) {
|
|
5210
|
+
const [primaryRecord] = prepared.consumedRecords;
|
|
5211
|
+
if (!primaryRecord?.owner.trim()) {
|
|
5212
|
+
throw new Error("Transfer execution record owner is missing.");
|
|
5213
|
+
}
|
|
5214
|
+
const walletPublicKey = primaryRecord.owner.trim();
|
|
5215
|
+
return runTransferFinalizeSteps({ prepared, environment, walletPublicKey });
|
|
5216
|
+
}
|
|
5217
|
+
|
|
5218
|
+
// src/transact/engine/execute.ts
|
|
5219
|
+
function enrichWithdrawOutputRecords(prepared, proof) {
|
|
5220
|
+
if (!proof.changeCoin || prepared.outputRecords.length === 0) {
|
|
5221
|
+
return;
|
|
5222
|
+
}
|
|
5223
|
+
const changeCoin = proof.changeCoin;
|
|
5224
|
+
prepared.outputRecords = prepared.outputRecords.map((record) => ({
|
|
5225
|
+
...record,
|
|
5226
|
+
id: changeCoin.commitment_hex,
|
|
5227
|
+
commitmentHex: changeCoin.commitment_hex,
|
|
5228
|
+
coinNote: changeCoin.coin,
|
|
5229
|
+
depositScalarHex: changeCoin.depositScalarHex,
|
|
5230
|
+
precommitementHex: changeCoin.precommitementHex
|
|
5231
|
+
}));
|
|
5232
|
+
}
|
|
5233
|
+
function buildWithdrawFinalizeArtifacts(proof, context) {
|
|
5234
|
+
return {
|
|
5235
|
+
proofHex: proof.proof_hex,
|
|
5236
|
+
publicHex: proof.public_hex,
|
|
5237
|
+
...ciphertextArtifactsFromProof(proof),
|
|
5238
|
+
applicationIdsPlaintext: proof.applicationIdsPlaintext,
|
|
5239
|
+
tokenAddress: context.tokenAddress,
|
|
5240
|
+
walletPublicKey: context.walletPublicKey,
|
|
5241
|
+
executeFinalizeRequired: false
|
|
5242
|
+
};
|
|
5243
|
+
}
|
|
5244
|
+
async function finalizeSingleWithdrawAtExecute(prepared, environment, poolService, withdrawFrom) {
|
|
5245
|
+
const context = await buildSpendProofContextAtExecute({
|
|
5246
|
+
prepared,
|
|
5247
|
+
environment,
|
|
5248
|
+
recipientPrivateAddressStpl1: withdrawFrom
|
|
5249
|
+
});
|
|
5250
|
+
const changeStroops = BigInt(context.coin.value) - prepared.intent.amount;
|
|
5251
|
+
const proof = await poolService.prepareWithdrawTransactProof({
|
|
5252
|
+
coin: context.coin,
|
|
5253
|
+
state: { commitments: context.commitments },
|
|
5254
|
+
destinationStellarAddress: prepared.intent.to,
|
|
5255
|
+
privKeyScalarHex: context.senderPrivKeyScalarHex,
|
|
5256
|
+
depositorEphemeralKey: serializeEphemeralKeyString({
|
|
5257
|
+
xHex: context.ephemeral.xHex,
|
|
5258
|
+
yHex: context.ephemeral.yHex
|
|
5259
|
+
}),
|
|
5260
|
+
withdrawAmountStroops: prepared.intent.amount,
|
|
5261
|
+
changePrivateAddressStpl1: changeStroops > 0n ? withdrawFrom : void 0,
|
|
5262
|
+
tokenAddress: context.tokenAddress
|
|
5263
|
+
});
|
|
5264
|
+
enrichWithdrawOutputRecords(prepared, proof);
|
|
5265
|
+
return buildWithdrawFinalizeArtifacts(proof, context);
|
|
5266
|
+
}
|
|
5267
|
+
async function finalizeDualWithdrawAtExecute(prepared, environment, poolService, withdrawFrom) {
|
|
5268
|
+
const [, secondaryRecord] = prepared.consumedRecords;
|
|
5269
|
+
if (!secondaryRecord) {
|
|
5270
|
+
throw new Error("Dual withdraw execution requires two private input records.");
|
|
5271
|
+
}
|
|
5272
|
+
const context = await buildSpendProofContextAtExecute({
|
|
5273
|
+
prepared,
|
|
5274
|
+
environment,
|
|
5275
|
+
recipientPrivateAddressStpl1: withdrawFrom
|
|
5276
|
+
});
|
|
5277
|
+
const secondary = await readCoinEphemeralForRecord({
|
|
5278
|
+
record: secondaryRecord,
|
|
5279
|
+
environment,
|
|
5280
|
+
walletPublicKey: context.walletPublicKey,
|
|
5281
|
+
commitments: context.commitments
|
|
5282
|
+
});
|
|
5283
|
+
const totalNotes = BigInt(context.coin.value) + BigInt(secondary.coin.value);
|
|
5284
|
+
const changeStroops = totalNotes - prepared.intent.amount;
|
|
5285
|
+
const proof = await poolService.prepareWithdrawTransactProofDual({
|
|
5286
|
+
coinA: context.coin,
|
|
5287
|
+
coinB: secondary.coin,
|
|
5288
|
+
state: { commitments: context.commitments },
|
|
5289
|
+
destinationStellarAddress: prepared.intent.to,
|
|
5290
|
+
privKeyScalarHex: context.senderPrivKeyScalarHex,
|
|
5291
|
+
depositorEphemeralAKey: serializeEphemeralKeyString({
|
|
5292
|
+
xHex: context.ephemeral.xHex,
|
|
5293
|
+
yHex: context.ephemeral.yHex
|
|
5294
|
+
}),
|
|
5295
|
+
depositorEphemeralBKey: serializeEphemeralKeyString({
|
|
5296
|
+
xHex: secondary.ephemeral.xHex,
|
|
5297
|
+
yHex: secondary.ephemeral.yHex
|
|
5298
|
+
}),
|
|
5299
|
+
withdrawAmountStroops: prepared.intent.amount,
|
|
5300
|
+
changePrivateAddressStpl1: changeStroops > 0n ? withdrawFrom : void 0,
|
|
5301
|
+
tokenAddress: context.tokenAddress
|
|
5302
|
+
});
|
|
5303
|
+
enrichWithdrawOutputRecords(prepared, proof);
|
|
5304
|
+
return buildWithdrawFinalizeArtifacts(proof, context);
|
|
5305
|
+
}
|
|
5306
|
+
async function finalizeWithdrawAtExecute(prepared, environment, poolService) {
|
|
5307
|
+
if (prepared.kind !== "withdraw") {
|
|
5308
|
+
throw new Error("Withdraw finalize requires a withdraw operation.");
|
|
5309
|
+
}
|
|
5310
|
+
const withdrawIntent = prepared.intent;
|
|
5311
|
+
const withdrawFrom = withdrawIntent.from;
|
|
5312
|
+
const recordCount = prepared.consumedRecords.length;
|
|
5313
|
+
if (recordCount === 1) {
|
|
5314
|
+
return finalizeSingleWithdrawAtExecute(
|
|
5315
|
+
prepared,
|
|
5316
|
+
environment,
|
|
5317
|
+
poolService,
|
|
5318
|
+
withdrawFrom
|
|
5319
|
+
);
|
|
5320
|
+
}
|
|
5321
|
+
if (recordCount === 2) {
|
|
5322
|
+
return finalizeDualWithdrawAtExecute(
|
|
5323
|
+
prepared,
|
|
5324
|
+
environment,
|
|
5325
|
+
poolService,
|
|
5326
|
+
withdrawFrom
|
|
5327
|
+
);
|
|
5328
|
+
}
|
|
5329
|
+
throw new Error("Confidential withdraw execution supports at most two input notes.");
|
|
5330
|
+
}
|
|
5331
|
+
async function finalizeSpendOperationAtExecute(prepared, environment, poolService) {
|
|
5332
|
+
if (prepared.kind !== "transfer" && prepared.kind !== "withdraw") {
|
|
5333
|
+
return prepared;
|
|
5334
|
+
}
|
|
5335
|
+
if (prepared.transactArtifacts?.proofHex) {
|
|
5336
|
+
return prepared;
|
|
5337
|
+
}
|
|
5338
|
+
const artifacts = prepared.kind === "transfer" ? await finalizeTransferAtExecute(prepared, environment) : await finalizeWithdrawAtExecute(prepared, environment, poolService);
|
|
5339
|
+
return {
|
|
5340
|
+
...prepared,
|
|
5341
|
+
transactArtifacts: {
|
|
5342
|
+
...prepared.transactArtifacts,
|
|
5343
|
+
...artifacts
|
|
5344
|
+
}
|
|
5345
|
+
};
|
|
5346
|
+
}
|
|
5347
|
+
|
|
5348
|
+
// src/transact/relay/constants.ts
|
|
5349
|
+
var RELAY_TRANSACT_PACKAGE_VERSION_V1 = 1;
|
|
5350
|
+
var RELAY_TRANSACT_SUPPORTED_SIGNAL_COUNT = 93;
|
|
5351
|
+
var RELAY_TRANSACT_FIELD_BYTES = 32;
|
|
5352
|
+
var RELAY_TRANSACT_SIGNAL_PREFIX_BYTES = 4;
|
|
5353
|
+
var RELAY_SIGNAL_INDEX_NULLIFIER_0 = 0;
|
|
5354
|
+
var RELAY_SIGNAL_INDEX_NULLIFIER_1 = 1;
|
|
5355
|
+
var RELAY_SIGNAL_INDEX_STATE_ROOT = 82;
|
|
5356
|
+
var RELAY_SIGNAL_INDEX_WITHDRAW_ADDRESS_HI = 83;
|
|
5357
|
+
var RELAY_SIGNAL_INDEX_WITHDRAW_ADDRESS_LO = 84;
|
|
5358
|
+
var RELAY_SIGNAL_INDEX_ESCROW_RECIPIENT_HI = 85;
|
|
5359
|
+
var RELAY_SIGNAL_INDEX_ESCROW_RECIPIENT_LO = 86;
|
|
5360
|
+
var RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL_ASSET_HI = 87;
|
|
5361
|
+
var RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL_ASSET_LO = 88;
|
|
5362
|
+
var RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT_ASSET_HI = 89;
|
|
5363
|
+
var RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT_ASSET_LO = 90;
|
|
5364
|
+
var RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT = 91;
|
|
5365
|
+
var RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL = 92;
|
|
5366
|
+
|
|
5367
|
+
// src/transact/relay/signals.ts
|
|
5368
|
+
import { Buffer as Buffer15 } from "buffer";
|
|
5369
|
+
|
|
5370
|
+
// src/transact/relay/layout-profile.ts
|
|
5371
|
+
var FIELD_BYTES = 32;
|
|
5372
|
+
var PREFIX_BYTES = 4;
|
|
5373
|
+
var LEGACY_PUBLIC_INPUT_PREFIX_LEN = 5;
|
|
5374
|
+
var V2_PUBLIC_INPUT_PREFIX_LEN = 7;
|
|
5375
|
+
var EPHEMERAL_COORDINATE_COUNT = 2;
|
|
5376
|
+
var STANDARD_SHAPE = {
|
|
5377
|
+
nIns: 2,
|
|
5378
|
+
nOuts: 2,
|
|
5379
|
+
publicNInputs: 1,
|
|
5380
|
+
publicNOutputs: 1,
|
|
5381
|
+
nAuditSlots: 4,
|
|
5382
|
+
noteAuditLen: 12,
|
|
5383
|
+
noteOutputLen: 6
|
|
5384
|
+
};
|
|
5385
|
+
var SIX_BY_SIX_SHAPE = {
|
|
5386
|
+
nIns: 6,
|
|
5387
|
+
nOuts: 6,
|
|
5388
|
+
publicNInputs: 1,
|
|
5389
|
+
publicNOutputs: 1,
|
|
5390
|
+
nAuditSlots: 12,
|
|
5391
|
+
noteAuditLen: 12,
|
|
5392
|
+
noteOutputLen: 6
|
|
5393
|
+
};
|
|
5394
|
+
function profileFromShape(nonce, shape, publicInputPrefixLength, ciphertextsInPublicSignals) {
|
|
5395
|
+
const auditOffset = shape.nIns + shape.nOuts + shape.nOuts * EPHEMERAL_COORDINATE_COUNT;
|
|
5396
|
+
const outputNoteOffset = ciphertextsInPublicSignals ? auditOffset + shape.nAuditSlots * EPHEMERAL_COORDINATE_COUNT + shape.nAuditSlots * shape.noteAuditLen + shape.nAuditSlots : auditOffset + EPHEMERAL_COORDINATE_COUNT + shape.nAuditSlots;
|
|
5397
|
+
const publicOutputsLength = ciphertextsInPublicSignals ? outputNoteOffset + shape.nOuts * shape.noteOutputLen + shape.nOuts : outputNoteOffset + shape.nOuts;
|
|
5398
|
+
const signalCount = publicOutputsLength + publicInputPrefixLength + EPHEMERAL_COORDINATE_COUNT * shape.publicNInputs + EPHEMERAL_COORDINATE_COUNT * shape.publicNOutputs + shape.publicNInputs + shape.publicNOutputs;
|
|
5399
|
+
const stateRoot = publicOutputsLength;
|
|
5400
|
+
return {
|
|
5401
|
+
nonce,
|
|
5402
|
+
signalCount,
|
|
5403
|
+
fieldBytes: FIELD_BYTES,
|
|
5404
|
+
prefixBytes: PREFIX_BYTES,
|
|
5405
|
+
indices: {
|
|
5406
|
+
nullifier0: 0,
|
|
5407
|
+
nullifier1: 1,
|
|
5408
|
+
stateRoot,
|
|
5409
|
+
withdrawAddressHi: stateRoot + 1,
|
|
5410
|
+
withdrawAddressLo: stateRoot + 2,
|
|
5411
|
+
escrowRecipientHi: stateRoot + 3,
|
|
5412
|
+
escrowRecipientLo: stateRoot + 4,
|
|
5413
|
+
publicWithdrawalAssetHi: stateRoot + publicInputPrefixLength,
|
|
5414
|
+
publicWithdrawalAssetLo: stateRoot + publicInputPrefixLength + 1,
|
|
5415
|
+
publicDepositAssetHi: stateRoot + publicInputPrefixLength + 2,
|
|
5416
|
+
publicDepositAssetLo: stateRoot + publicInputPrefixLength + 3,
|
|
5417
|
+
publicDeposit: stateRoot + publicInputPrefixLength + 4,
|
|
5418
|
+
publicWithdrawal: stateRoot + publicInputPrefixLength + 5
|
|
5419
|
+
}
|
|
5420
|
+
};
|
|
5421
|
+
}
|
|
5422
|
+
function relayLayoutProfileForNonce(nonce) {
|
|
5423
|
+
if (nonce === STANDARD_ZK_CONFIG_NONCE) {
|
|
5424
|
+
return profileFromShape(
|
|
5425
|
+
nonce,
|
|
5426
|
+
STANDARD_SHAPE,
|
|
5427
|
+
LEGACY_PUBLIC_INPUT_PREFIX_LEN,
|
|
5428
|
+
true
|
|
5429
|
+
);
|
|
5430
|
+
}
|
|
5431
|
+
if (nonce === COMMITMENT_V2_ZK_NONCE) {
|
|
5432
|
+
return profileFromShape(nonce, STANDARD_SHAPE, V2_PUBLIC_INPUT_PREFIX_LEN, true);
|
|
5433
|
+
}
|
|
5434
|
+
if (nonce === BINDING_ZK_NONCE) {
|
|
5435
|
+
return profileFromShape(nonce, STANDARD_SHAPE, V2_PUBLIC_INPUT_PREFIX_LEN, false);
|
|
5436
|
+
}
|
|
5437
|
+
if (nonce === SIX_BY_SIX_ZK_NONCE) {
|
|
5438
|
+
return profileFromShape(nonce, SIX_BY_SIX_SHAPE, V2_PUBLIC_INPUT_PREFIX_LEN, true);
|
|
5439
|
+
}
|
|
5440
|
+
if (nonce === SIX_BY_SIX_BINDING_ZK_NONCE) {
|
|
5441
|
+
return profileFromShape(nonce, SIX_BY_SIX_SHAPE, V2_PUBLIC_INPUT_PREFIX_LEN, false);
|
|
5442
|
+
}
|
|
5443
|
+
throw new Error(`Unknown ZK config nonce ${nonce.toString()}`);
|
|
5444
|
+
}
|
|
5445
|
+
|
|
5446
|
+
// src/transact/relay/signals.ts
|
|
5447
|
+
function decodePublicSignalBytes(publicSignals) {
|
|
5448
|
+
return Buffer15.from(publicSignals.replace(/^0x/iu, ""), "hex");
|
|
5449
|
+
}
|
|
5450
|
+
function hasSupportedLengthPrefix(bytes, signalCount) {
|
|
5451
|
+
const expected = RELAY_TRANSACT_SIGNAL_PREFIX_BYTES + signalCount * RELAY_TRANSACT_FIELD_BYTES;
|
|
5452
|
+
if (bytes.length !== expected) {
|
|
5453
|
+
return false;
|
|
5454
|
+
}
|
|
5455
|
+
return bytes.readUInt32BE(0) === signalCount;
|
|
5456
|
+
}
|
|
5457
|
+
function assertSupportedPublicSignals(publicSignals, zkConfigNonce = DEFAULT_ZK_CONFIG_NONCE) {
|
|
5458
|
+
const profile = relayLayoutProfileForNonce(zkConfigNonce);
|
|
5459
|
+
const bytes = decodePublicSignalBytes(publicSignals);
|
|
5460
|
+
const supportedBytes = profile.signalCount * RELAY_TRANSACT_FIELD_BYTES;
|
|
5461
|
+
if (bytes.length === supportedBytes || hasSupportedLengthPrefix(bytes, profile.signalCount)) {
|
|
5462
|
+
return;
|
|
5463
|
+
}
|
|
5464
|
+
throw new Error(
|
|
5465
|
+
`Relay Transact Package V1 requires exactly ${String(profile.signalCount)} packed public signals.`
|
|
5466
|
+
);
|
|
5467
|
+
}
|
|
5468
|
+
function sliceSupportedPublicSignalFields(publicSignals, zkConfigNonce = DEFAULT_ZK_CONFIG_NONCE) {
|
|
5469
|
+
assertSupportedPublicSignals(publicSignals, zkConfigNonce);
|
|
5470
|
+
const profile = relayLayoutProfileForNonce(zkConfigNonce);
|
|
5471
|
+
const bytes = decodePublicSignalBytes(publicSignals);
|
|
5472
|
+
const body = hasSupportedLengthPrefix(bytes, profile.signalCount) ? bytes.subarray(RELAY_TRANSACT_SIGNAL_PREFIX_BYTES) : bytes;
|
|
5473
|
+
return Array.from(
|
|
5474
|
+
{ length: profile.signalCount },
|
|
5475
|
+
(_unused, index) => Buffer15.from(
|
|
5476
|
+
body.subarray(
|
|
5477
|
+
index * RELAY_TRANSACT_FIELD_BYTES,
|
|
5478
|
+
(index + 1) * RELAY_TRANSACT_FIELD_BYTES
|
|
5479
|
+
)
|
|
5480
|
+
)
|
|
5481
|
+
);
|
|
5482
|
+
}
|
|
5483
|
+
|
|
5484
|
+
// src/transact/relay/prepare.ts
|
|
5485
|
+
function normalizeHex(value) {
|
|
5486
|
+
return value.replace(/^0x/iu, "").toLowerCase();
|
|
5487
|
+
}
|
|
5488
|
+
function prepareRelayTransactPackage(input) {
|
|
5489
|
+
const zkConfigNonce = input.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
|
|
5490
|
+
assertSupportedPublicSignals(input.publicSignals, zkConfigNonce);
|
|
5491
|
+
const prepared = {
|
|
5492
|
+
version: RELAY_TRANSACT_PACKAGE_VERSION_V1,
|
|
5493
|
+
poolSelector: input.poolSelector,
|
|
5494
|
+
zkConfigNonce,
|
|
5495
|
+
proofBytes: normalizeHex(input.proofBytes),
|
|
5496
|
+
publicSignals: normalizeHex(input.publicSignals),
|
|
5497
|
+
applicationIdHints: input.applicationIdHints
|
|
5498
|
+
};
|
|
5499
|
+
if (input.ciphertextBytes) {
|
|
5500
|
+
prepared.ciphertextBytes = normalizeHex(input.ciphertextBytes);
|
|
5501
|
+
}
|
|
5502
|
+
if (input.outputNoteEphemeralScalars) {
|
|
5503
|
+
prepared.outputNoteEphemeralScalars = [...input.outputNoteEphemeralScalars];
|
|
5504
|
+
}
|
|
5505
|
+
if (input.escrowAuthorization) {
|
|
5506
|
+
prepared.escrowAuthorization = input.escrowAuthorization;
|
|
5507
|
+
}
|
|
5508
|
+
if (input.keyVersionHints) {
|
|
5509
|
+
prepared.keyVersionHints = input.keyVersionHints;
|
|
5510
|
+
}
|
|
5511
|
+
return prepared;
|
|
5512
|
+
}
|
|
5513
|
+
|
|
5514
|
+
// src/transact/relay/from-prepared.ts
|
|
5515
|
+
function requirePreparedArtifacts(prepared) {
|
|
5516
|
+
const artifacts = prepared.transactArtifacts;
|
|
5517
|
+
if (!artifacts?.proofHex || !artifacts.publicHex || !artifacts.applicationIdsPlaintext) {
|
|
5518
|
+
throw new Error("Prepared operation is missing transact artifacts.");
|
|
5519
|
+
}
|
|
5520
|
+
return {
|
|
5521
|
+
proofBytes: artifacts.proofHex,
|
|
5522
|
+
publicSignals: artifacts.publicHex,
|
|
5523
|
+
applicationIdHints: artifacts.applicationIdsPlaintext,
|
|
5524
|
+
...artifacts.ciphertextHex ? { ciphertextBytes: artifacts.ciphertextHex } : {},
|
|
5525
|
+
...artifacts.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: artifacts.outputNoteEphemeralScalars } : {},
|
|
5526
|
+
...artifacts.escrowAuthorization ? { escrowAuthorization: artifacts.escrowAuthorization } : {}
|
|
5527
|
+
};
|
|
5528
|
+
}
|
|
5529
|
+
function prepareRelayTransactPackageFromPrepared(input) {
|
|
5530
|
+
return prepareRelayTransactPackage({
|
|
5531
|
+
poolSelector: input.poolSelector,
|
|
5532
|
+
...requirePreparedArtifacts(input.prepared),
|
|
5533
|
+
...input.zkConfigNonce === void 0 ? {} : { zkConfigNonce: input.zkConfigNonce },
|
|
5534
|
+
...input.keyVersionHints ? { keyVersionHints: input.keyVersionHints } : {}
|
|
5535
|
+
});
|
|
5536
|
+
}
|
|
5537
|
+
|
|
5538
|
+
// src/transact/relay/profile.ts
|
|
5539
|
+
function fieldAt(fields, index) {
|
|
5540
|
+
const field = fields.find((_unused, offset) => offset === index);
|
|
5541
|
+
if (!field) {
|
|
5542
|
+
throw new Error(`Missing packed public signal at index ${String(index)}.`);
|
|
5543
|
+
}
|
|
5544
|
+
return field;
|
|
5545
|
+
}
|
|
5546
|
+
function fieldHex2(fields, index) {
|
|
5547
|
+
return fieldAt(fields, index).toString("hex");
|
|
5548
|
+
}
|
|
5549
|
+
function fieldAmount(fields, index) {
|
|
5550
|
+
return BigInt(`0x${fieldAt(fields, index).toString("hex")}`).toString();
|
|
5551
|
+
}
|
|
5552
|
+
function readRelayTransactSupportedProfile(prepared) {
|
|
5553
|
+
const layout = relayLayoutProfileForNonce(prepared.zkConfigNonce);
|
|
5554
|
+
const fields = sliceSupportedPublicSignalFields(
|
|
5555
|
+
prepared.publicSignals,
|
|
5556
|
+
prepared.zkConfigNonce
|
|
5557
|
+
);
|
|
5558
|
+
const { indices } = layout;
|
|
5559
|
+
return {
|
|
5560
|
+
orderedNullifiers: [
|
|
5561
|
+
fieldHex2(fields, indices.nullifier0),
|
|
5562
|
+
fieldHex2(fields, indices.nullifier1)
|
|
5563
|
+
],
|
|
5564
|
+
publicLegContext: {
|
|
5565
|
+
stateRoot: fieldHex2(fields, indices.stateRoot),
|
|
5566
|
+
withdrawAddressHi: fieldHex2(fields, indices.withdrawAddressHi),
|
|
5567
|
+
withdrawAddressLo: fieldHex2(fields, indices.withdrawAddressLo),
|
|
5568
|
+
escrowRecipientHi: fieldHex2(fields, indices.escrowRecipientHi),
|
|
5569
|
+
escrowRecipientLo: fieldHex2(fields, indices.escrowRecipientLo),
|
|
5570
|
+
publicWithdrawalAssetHi: fieldHex2(fields, indices.publicWithdrawalAssetHi),
|
|
5571
|
+
publicWithdrawalAssetLo: fieldHex2(fields, indices.publicWithdrawalAssetLo),
|
|
5572
|
+
publicDepositAssetHi: fieldHex2(fields, indices.publicDepositAssetHi),
|
|
5573
|
+
publicDepositAssetLo: fieldHex2(fields, indices.publicDepositAssetLo),
|
|
5574
|
+
publicDepositAmount: fieldAmount(fields, indices.publicDeposit),
|
|
5575
|
+
publicWithdrawalAmount: fieldAmount(fields, indices.publicWithdrawal)
|
|
5576
|
+
}
|
|
5577
|
+
};
|
|
5578
|
+
}
|
|
5579
|
+
|
|
5580
|
+
// src/transact/relay/required-submission-method.ts
|
|
5581
|
+
var ZERO_PUBLIC_DEPOSIT = 0n;
|
|
5582
|
+
var SUBMISSION_METHOD = {
|
|
5583
|
+
direct: "direct",
|
|
5584
|
+
relay: "relay"
|
|
5585
|
+
};
|
|
5586
|
+
var ESCROW_SUBMISSION_REFUSAL = {
|
|
5587
|
+
positivePublicDeposit: "escrow_positive_public_deposit"
|
|
5588
|
+
};
|
|
5589
|
+
var EscrowSubmissionRefusedError = class extends Error {
|
|
5590
|
+
reason;
|
|
5591
|
+
constructor(reason) {
|
|
5592
|
+
super(reason);
|
|
5593
|
+
this.name = "EscrowSubmissionRefusedError";
|
|
5594
|
+
this.reason = reason;
|
|
5595
|
+
}
|
|
5596
|
+
};
|
|
5597
|
+
function isEscrowPreparedOperation(prepared) {
|
|
5598
|
+
return prepared.transactArtifacts?.escrowSend === true || prepared.transactArtifacts?.spendSource === "escrow";
|
|
5599
|
+
}
|
|
5600
|
+
function publicDepositAmountFromPrepared(prepared, zkConfigNonce) {
|
|
5601
|
+
const publicHex = prepared.transactArtifacts?.publicHex;
|
|
5602
|
+
if (!publicHex) {
|
|
5603
|
+
return void 0;
|
|
5604
|
+
}
|
|
5605
|
+
const layout = relayLayoutProfileForNonce(zkConfigNonce);
|
|
5606
|
+
const fields = sliceSupportedPublicSignalFields(publicHex, zkConfigNonce);
|
|
5607
|
+
const field = fields.find(
|
|
5608
|
+
(_unused, offset) => offset === layout.indices.publicDeposit
|
|
5609
|
+
);
|
|
5610
|
+
if (!field) {
|
|
5611
|
+
throw new Error(
|
|
5612
|
+
`Missing packed public signal at index ${String(layout.indices.publicDeposit)}.`
|
|
5613
|
+
);
|
|
5614
|
+
}
|
|
5615
|
+
return BigInt(`0x${field.toString("hex")}`);
|
|
5616
|
+
}
|
|
5617
|
+
function evaluateRequiredSubmissionMethod(prepared, zkConfigNonce = DEFAULT_ZK_CONFIG_NONCE) {
|
|
5618
|
+
const publicDepositAmount = publicDepositAmountFromPrepared(prepared, zkConfigNonce);
|
|
5619
|
+
if (isEscrowPreparedOperation(prepared)) {
|
|
5620
|
+
if (publicDepositAmount !== void 0 && publicDepositAmount > ZERO_PUBLIC_DEPOSIT) {
|
|
5621
|
+
return { refused: ESCROW_SUBMISSION_REFUSAL.positivePublicDeposit };
|
|
5622
|
+
}
|
|
5623
|
+
if (prepared.transactArtifacts?.escrowSend === true) {
|
|
5624
|
+
return { method: SUBMISSION_METHOD.relay };
|
|
5625
|
+
}
|
|
5626
|
+
return { method: SUBMISSION_METHOD.direct };
|
|
5627
|
+
}
|
|
5628
|
+
if (publicDepositAmount === void 0) {
|
|
5629
|
+
throw new Error("Prepared operation is missing transact artifacts.");
|
|
5630
|
+
}
|
|
5631
|
+
return {
|
|
5632
|
+
method: publicDepositAmount > ZERO_PUBLIC_DEPOSIT ? SUBMISSION_METHOD.direct : SUBMISSION_METHOD.relay
|
|
5633
|
+
};
|
|
5634
|
+
}
|
|
5635
|
+
function requiredSubmissionMethod(prepared, zkConfigNonce = DEFAULT_ZK_CONFIG_NONCE) {
|
|
5636
|
+
const result = evaluateRequiredSubmissionMethod(prepared, zkConfigNonce);
|
|
5637
|
+
if ("refused" in result) {
|
|
5638
|
+
throw new EscrowSubmissionRefusedError(result.refused);
|
|
5639
|
+
}
|
|
5640
|
+
return result.method;
|
|
5641
|
+
}
|
|
4125
5642
|
export {
|
|
5643
|
+
BundledZkCircuit2 as BundledZkCircuit,
|
|
5644
|
+
COMMITMENT_V2_ZK_NONCE,
|
|
4126
5645
|
DEFAULT_STEALTH_SIGN_NONCE as DEFAULT_PRIVATE_ADDRESS_SIGN_NONCE,
|
|
5646
|
+
DEFAULT_STELLAR_ZK_CIRCUITS,
|
|
5647
|
+
DEFAULT_ZK_CONFIG_NONCE,
|
|
5648
|
+
ESCROW_SUBMISSION_REFUSAL,
|
|
5649
|
+
EscrowSubmissionRefusedError,
|
|
4127
5650
|
KytInspectError,
|
|
4128
5651
|
MIN_CONFIDENTIAL_TRANSFER_STROOPS,
|
|
5652
|
+
OWNER_BOUND_NOTE_SCHEMA_VERSION,
|
|
4129
5653
|
PrivacyPoolService,
|
|
5654
|
+
RELAY_SIGNAL_INDEX_ESCROW_RECIPIENT_HI,
|
|
5655
|
+
RELAY_SIGNAL_INDEX_ESCROW_RECIPIENT_LO,
|
|
5656
|
+
RELAY_SIGNAL_INDEX_NULLIFIER_0,
|
|
5657
|
+
RELAY_SIGNAL_INDEX_NULLIFIER_1,
|
|
5658
|
+
RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT,
|
|
5659
|
+
RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT_ASSET_HI,
|
|
5660
|
+
RELAY_SIGNAL_INDEX_PUBLIC_DEPOSIT_ASSET_LO,
|
|
5661
|
+
RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL,
|
|
5662
|
+
RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL_ASSET_HI,
|
|
5663
|
+
RELAY_SIGNAL_INDEX_PUBLIC_WITHDRAWAL_ASSET_LO,
|
|
5664
|
+
RELAY_SIGNAL_INDEX_STATE_ROOT,
|
|
5665
|
+
RELAY_SIGNAL_INDEX_WITHDRAW_ADDRESS_HI,
|
|
5666
|
+
RELAY_SIGNAL_INDEX_WITHDRAW_ADDRESS_LO,
|
|
5667
|
+
RELAY_TRANSACT_FIELD_BYTES,
|
|
5668
|
+
RELAY_TRANSACT_PACKAGE_VERSION_V1,
|
|
5669
|
+
RELAY_TRANSACT_SIGNAL_PREFIX_BYTES,
|
|
5670
|
+
RELAY_TRANSACT_SUPPORTED_SIGNAL_COUNT,
|
|
5671
|
+
SIX_BY_SIX_ZK_NONCE,
|
|
5672
|
+
STANDARD_ZK_CONFIG_NONCE,
|
|
5673
|
+
SUBMISSION_METHOD,
|
|
4130
5674
|
ZERO_STROOPS,
|
|
5675
|
+
assertEscrowSweepClaimant,
|
|
4131
5676
|
assetLegToTokenAddress,
|
|
5677
|
+
attachEscrowAuthorization,
|
|
4132
5678
|
attachPoolStatePorts,
|
|
4133
|
-
|
|
5679
|
+
buildBlindedRecipientTagChallengeMessage,
|
|
4134
5680
|
buildPoolTransactionAuditParameters,
|
|
4135
5681
|
buildPrivateAddressSignMessage,
|
|
4136
|
-
buildTransferOnboardingAtExecute,
|
|
4137
5682
|
configurePrivacyPoolService,
|
|
4138
5683
|
createPrivacyPoolService,
|
|
4139
5684
|
decodePrivateAddress,
|
|
5685
|
+
deriveEscrowRecipientFromStellarAddress,
|
|
4140
5686
|
encodePrivateAddress,
|
|
4141
5687
|
encodePrivateAddressFromHexCoordinates,
|
|
5688
|
+
evaluateRequiredSubmissionMethod,
|
|
4142
5689
|
fetchAndMergeMerkleState,
|
|
5690
|
+
fetchEscrowOutputNoteEvents,
|
|
5691
|
+
finalizeSpendOperationAtExecute,
|
|
4143
5692
|
frDecimalToPaddedBytes32,
|
|
4144
5693
|
generateRandomDepositScalarHex,
|
|
4145
5694
|
generateTemporaryRecipientPrivateAddress,
|
|
4146
5695
|
getPrivacyPoolService,
|
|
5696
|
+
isEscrowPreparedOperation,
|
|
4147
5697
|
loadDefaultStellarBrowserAssets,
|
|
4148
5698
|
loadStellarBrowserAssets,
|
|
5699
|
+
optionalZkArtifactBaseUrl,
|
|
4149
5700
|
parseAuditPublicKeyFromEnvHex,
|
|
4150
5701
|
parseKytReasonCode,
|
|
4151
5702
|
prepareConfidentialTransferProof,
|
|
4152
5703
|
prepareConfidentialTransferProofDual,
|
|
5704
|
+
prepareEscrowSweepOperation,
|
|
5705
|
+
prepareRelayTransactPackage,
|
|
5706
|
+
prepareRelayTransactPackageFromPrepared,
|
|
4153
5707
|
privateAddressSdk,
|
|
4154
5708
|
readLeafEphemeralHex,
|
|
5709
|
+
readRelayTransactSupportedProfile,
|
|
4155
5710
|
recipientPublicKeysDecimalFromPrivateAddress,
|
|
5711
|
+
reconstructEscrowNote,
|
|
4156
5712
|
requestKytPassageForPoolInteraction,
|
|
5713
|
+
requiredSubmissionMethod,
|
|
4157
5714
|
resolvePoolApplicationId,
|
|
5715
|
+
resolveZkConfigNonce,
|
|
4158
5716
|
runTtlPreflight,
|
|
5717
|
+
spendScalarHexFromStellarSignature,
|
|
4159
5718
|
submitSorobanConfidentialTransfer,
|
|
4160
5719
|
submitSorobanDeposit,
|
|
4161
|
-
tokenAddressToAssetLeg
|
|
5720
|
+
tokenAddressToAssetLeg,
|
|
5721
|
+
unsignedEscrowAuthorizationForSweep
|
|
4162
5722
|
};
|
|
4163
5723
|
//# sourceMappingURL=index.js.map
|