@arcanetech/privacy-sdk-stellar 0.3.0 → 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 +306 -159
- package/dist/index.js +2295 -1804
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +49 -118
- package/dist/node.js +1260 -1568
- 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 +362 -61
- package/dist/transact/index.js +2371 -940
- package/dist/transact/index.js.map +1 -1
- package/generated/contract/README.md +4 -4
- package/generated/contract/dist/index.d.ts +231 -256
- package/generated/contract/dist/index.js +71 -57
- package/generated/contract/package.json +1 -1
- package/generated/contract/src/index.ts +211 -242
- 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 +2 -2
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,143 +1032,473 @@ 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
|
-
|
|
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;
|
|
1010
1502
|
decisionId;
|
|
1011
1503
|
detailAddress;
|
|
1012
1504
|
constructor(parameters) {
|
|
@@ -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
|
})
|
|
@@ -1155,15 +1635,9 @@ async function registerKytPassage(parameters) {
|
|
|
1155
1635
|
await waitForKytRegistration({ server, hash: result.hash });
|
|
1156
1636
|
}
|
|
1157
1637
|
|
|
1158
|
-
// src/transact/environment/zk-config-nonce.ts
|
|
1159
|
-
var DEFAULT_ZK_CONFIG_NONCE = 0n;
|
|
1160
|
-
function resolveZkConfigNonce(transactEnvironment) {
|
|
1161
|
-
return transactEnvironment.zkConfigNonce ?? DEFAULT_ZK_CONFIG_NONCE;
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
1638
|
// src/transact/kyt/passage/inspect.ts
|
|
1165
|
-
function
|
|
1166
|
-
return
|
|
1639
|
+
function buildApplicationIdHints2(applicationId, nAuditSlots) {
|
|
1640
|
+
return uniformApplicationIdHints(applicationId, nAuditSlots);
|
|
1167
1641
|
}
|
|
1168
1642
|
function buildNonce() {
|
|
1169
1643
|
return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}`;
|
|
@@ -1191,37 +1665,61 @@ function throwKytInspectRejected(body) {
|
|
|
1191
1665
|
...parsed.address ? { detailAddress: parsed.address } : {}
|
|
1192
1666
|
});
|
|
1193
1667
|
}
|
|
1194
|
-
|
|
1195
|
-
const
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
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) {
|
|
1201
1676
|
const response = await fetch(
|
|
1202
1677
|
`${input.transactEnvironment.kyt.apiBaseUrl}/kyt/passages/inspect`,
|
|
1203
1678
|
{
|
|
1204
1679
|
method: "POST",
|
|
1205
|
-
headers:
|
|
1680
|
+
headers: inspectRequestHeaders(
|
|
1681
|
+
input.transactEnvironment.kyt.inspectAuthorization
|
|
1682
|
+
),
|
|
1206
1683
|
body: JSON.stringify(
|
|
1207
1684
|
{
|
|
1208
1685
|
owner: input.owner,
|
|
1209
1686
|
poolContract: input.poolContract,
|
|
1210
|
-
kytRegistry,
|
|
1687
|
+
kytRegistry: input.transactEnvironment.kyt.kytPassageRegistryContract,
|
|
1211
1688
|
proofBytes: input.proofHex,
|
|
1212
|
-
publicSignalsBytes:
|
|
1689
|
+
publicSignalsBytes: zeroBindingTagsInPublicSignals(
|
|
1690
|
+
input.publicHex,
|
|
1691
|
+
zkConfigNonce
|
|
1692
|
+
).toString("hex"),
|
|
1213
1693
|
applicationIdsPlaintext,
|
|
1214
1694
|
decryptedAuditSlots: input.decryptedAuditSlots,
|
|
1215
|
-
onboarding: input.onboarding,
|
|
1216
1695
|
nonce: buildNonce(),
|
|
1217
|
-
zkConfigNonce
|
|
1218
|
-
currentLedger
|
|
1696
|
+
zkConfigNonce,
|
|
1697
|
+
currentLedger,
|
|
1698
|
+
...input.ciphertextHex ? { ciphertextBytes: input.ciphertextHex } : {},
|
|
1699
|
+
...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {}
|
|
1219
1700
|
},
|
|
1220
1701
|
kytJsonReplacer
|
|
1221
1702
|
)
|
|
1222
1703
|
}
|
|
1223
1704
|
);
|
|
1224
|
-
|
|
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
|
+
);
|
|
1225
1723
|
if (body.status !== "approved") {
|
|
1226
1724
|
throwKytInspectRejected(body);
|
|
1227
1725
|
}
|
|
@@ -1237,6 +1735,216 @@ async function requestKytPassageForPoolInteraction(input) {
|
|
|
1237
1735
|
return body;
|
|
1238
1736
|
}
|
|
1239
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
|
+
|
|
1240
1948
|
// src/transact/submit/ttl-preflight.ts
|
|
1241
1949
|
function getNested(source, path) {
|
|
1242
1950
|
let cursor = source;
|
|
@@ -1283,12 +1991,12 @@ async function runTtlPreflight(assembledTransaction) {
|
|
|
1283
1991
|
|
|
1284
1992
|
// src/transact/submit/zk-config-ttl.ts
|
|
1285
1993
|
import {
|
|
1286
|
-
Address,
|
|
1994
|
+
Address as Address4,
|
|
1287
1995
|
Operation as Operation2,
|
|
1288
1996
|
SorobanDataBuilder,
|
|
1289
|
-
TransactionBuilder as
|
|
1290
|
-
rpc as
|
|
1291
|
-
xdr as
|
|
1997
|
+
TransactionBuilder as TransactionBuilder3,
|
|
1998
|
+
rpc as rpc5,
|
|
1999
|
+
xdr as xdr5
|
|
1292
2000
|
} from "@stellar/stellar-sdk";
|
|
1293
2001
|
var ZK_CONFIG_TTL_THRESHOLD_LEDGERS = 1e5;
|
|
1294
2002
|
var ZK_CONFIG_TTL_EXTEND_TO_LEDGERS = 5e5;
|
|
@@ -1312,15 +2020,15 @@ async function waitForExtendFootprintTtlConfirmation(parameters) {
|
|
|
1312
2020
|
throw new Error("ZK config TTL extension was not confirmed in time");
|
|
1313
2021
|
}
|
|
1314
2022
|
function zkConfigLedgerKey(contractId, nonce) {
|
|
1315
|
-
const configKeyScValue =
|
|
1316
|
-
|
|
1317
|
-
|
|
2023
|
+
const configKeyScValue = xdr5.ScVal.scvVec([
|
|
2024
|
+
xdr5.ScVal.scvSymbol("Config"),
|
|
2025
|
+
xdr5.ScVal.scvU64(xdr5.Uint64.fromString(nonce.toString()))
|
|
1318
2026
|
]);
|
|
1319
|
-
return
|
|
1320
|
-
new
|
|
1321
|
-
contract: new
|
|
2027
|
+
return xdr5.LedgerKey.contractData(
|
|
2028
|
+
new xdr5.LedgerKeyContractData({
|
|
2029
|
+
contract: new Address4(contractId).toScAddress(),
|
|
1322
2030
|
key: configKeyScValue,
|
|
1323
|
-
durability:
|
|
2031
|
+
durability: xdr5.ContractDataDurability.persistent()
|
|
1324
2032
|
})
|
|
1325
2033
|
);
|
|
1326
2034
|
}
|
|
@@ -1338,7 +2046,7 @@ async function needsTtlExtension(parameters) {
|
|
|
1338
2046
|
}
|
|
1339
2047
|
async function submitExtendFootprintTtlTransaction(parameters) {
|
|
1340
2048
|
const sourceAccount = await parameters.server.getAccount(parameters.sourcePublicKey);
|
|
1341
|
-
const transaction = new
|
|
2049
|
+
const transaction = new TransactionBuilder3(sourceAccount, {
|
|
1342
2050
|
fee: EXTEND_TTL_FEE_STROOPS,
|
|
1343
2051
|
networkPassphrase: parameters.networkPassphrase
|
|
1344
2052
|
}).addOperation(
|
|
@@ -1352,7 +2060,7 @@ async function submitExtendFootprintTtlTransaction(parameters) {
|
|
|
1352
2060
|
networkPassphrase: parameters.networkPassphrase,
|
|
1353
2061
|
address: parameters.sourcePublicKey
|
|
1354
2062
|
});
|
|
1355
|
-
const signedTransaction =
|
|
2063
|
+
const signedTransaction = TransactionBuilder3.fromXDR(
|
|
1356
2064
|
signedTxXdr,
|
|
1357
2065
|
parameters.networkPassphrase
|
|
1358
2066
|
);
|
|
@@ -1370,7 +2078,7 @@ async function extendZkConfigTtlIfNeeded(parameters) {
|
|
|
1370
2078
|
if (!parameters.signTransaction) {
|
|
1371
2079
|
return;
|
|
1372
2080
|
}
|
|
1373
|
-
const server = new
|
|
2081
|
+
const server = new rpc5.Server(parameters.sorobanRpcUrl, { allowHttp: true });
|
|
1374
2082
|
const ledgerKey = zkConfigLedgerKey(parameters.contractId, parameters.nonce);
|
|
1375
2083
|
if (!await needsTtlExtension({ server, ledgerKey })) {
|
|
1376
2084
|
return;
|
|
@@ -1400,7 +2108,10 @@ async function submitPoolTransact(parameters) {
|
|
|
1400
2108
|
nonce: parameters.nonce,
|
|
1401
2109
|
proof_bytes: Buffer11.from(parameters.proofHex.replace(/^0x/iu, ""), "hex"),
|
|
1402
2110
|
pub_signals_bytes: Buffer11.from(parameters.publicHex.replace(/^0x/iu, ""), "hex"),
|
|
1403
|
-
|
|
2111
|
+
ciphertext_bytes: Buffer11.from(
|
|
2112
|
+
(parameters.ciphertextHex ?? "").replace(/^0x/iu, ""),
|
|
2113
|
+
"hex"
|
|
2114
|
+
),
|
|
1404
2115
|
kyt_authorization: {
|
|
1405
2116
|
expiration_ledger: parameters.approval.expiresAtLedger,
|
|
1406
2117
|
signature: approvalSignatureToBytes(parameters.approval.signature)
|
|
@@ -1425,19 +2136,21 @@ async function submitSorobanDeposit(input) {
|
|
|
1425
2136
|
});
|
|
1426
2137
|
const merkleTx = await poolClient.get_merkle_root();
|
|
1427
2138
|
const merkleRootBuffer = merkleTx.result;
|
|
1428
|
-
const
|
|
2139
|
+
const proof = await input.privacyPoolService.prepareDepositTransactProof({
|
|
1429
2140
|
privateAddressStpl1: input.privateAddressStpl1,
|
|
1430
2141
|
coin: input.coin,
|
|
1431
2142
|
depositScalarHex: input.depositScalarHex,
|
|
1432
2143
|
merkleRootBytes: merkleRootBuffer,
|
|
1433
2144
|
tokenAddress: input.tokenAddress
|
|
1434
2145
|
});
|
|
2146
|
+
const ciphertext = ciphertextArtifactsFromProof(proof);
|
|
1435
2147
|
const approval = await requestKytPassageForPoolInteraction({
|
|
1436
2148
|
owner: input.walletPublicKey,
|
|
1437
2149
|
poolContract: input.contractId,
|
|
1438
|
-
proofHex: proof_hex,
|
|
1439
|
-
publicHex: public_hex,
|
|
1440
|
-
applicationIdsPlaintext,
|
|
2150
|
+
proofHex: proof.proof_hex,
|
|
2151
|
+
publicHex: proof.public_hex,
|
|
2152
|
+
applicationIdsPlaintext: proof.applicationIdsPlaintext,
|
|
2153
|
+
...ciphertext,
|
|
1441
2154
|
networkPassphrase: input.networkPassphrase,
|
|
1442
2155
|
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
1443
2156
|
transactEnvironment: input.transactEnvironment
|
|
@@ -1447,8 +2160,9 @@ async function submitSorobanDeposit(input) {
|
|
|
1447
2160
|
contractId: input.contractId,
|
|
1448
2161
|
from: input.walletPublicKey,
|
|
1449
2162
|
nonce: resolveZkConfigNonce(input.transactEnvironment),
|
|
1450
|
-
proofHex: proof_hex,
|
|
1451
|
-
publicHex: public_hex,
|
|
2163
|
+
proofHex: proof.proof_hex,
|
|
2164
|
+
publicHex: proof.public_hex,
|
|
2165
|
+
...ciphertext,
|
|
1452
2166
|
approval,
|
|
1453
2167
|
networkPassphrase: input.networkPassphrase,
|
|
1454
2168
|
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
@@ -1469,7 +2183,8 @@ async function submitSorobanConfidentialTransfer(input) {
|
|
|
1469
2183
|
poolContract: input.contractId,
|
|
1470
2184
|
proofHex: input.proofHex,
|
|
1471
2185
|
publicHex: input.publicHex,
|
|
1472
|
-
...input.
|
|
2186
|
+
...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
|
|
2187
|
+
...input.outputNoteEphemeralScalars ? { outputNoteEphemeralScalars: input.outputNoteEphemeralScalars } : {},
|
|
1473
2188
|
...input.applicationIdsPlaintext ? { applicationIdsPlaintext: input.applicationIdsPlaintext } : {},
|
|
1474
2189
|
networkPassphrase: input.networkPassphrase,
|
|
1475
2190
|
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
@@ -1482,7 +2197,7 @@ async function submitSorobanConfidentialTransfer(input) {
|
|
|
1482
2197
|
nonce: resolveZkConfigNonce(input.transactEnvironment),
|
|
1483
2198
|
proofHex: input.proofHex,
|
|
1484
2199
|
publicHex: input.publicHex,
|
|
1485
|
-
...input.
|
|
2200
|
+
...input.ciphertextHex ? { ciphertextHex: input.ciphertextHex } : {},
|
|
1486
2201
|
approval,
|
|
1487
2202
|
networkPassphrase: input.networkPassphrase,
|
|
1488
2203
|
sorobanRpcUrl: input.sorobanRpcUrl,
|
|
@@ -1490,14 +2205,19 @@ async function submitSorobanConfidentialTransfer(input) {
|
|
|
1490
2205
|
});
|
|
1491
2206
|
}
|
|
1492
2207
|
|
|
1493
|
-
// src/transact/
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
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"];
|
|
1501
2221
|
}
|
|
1502
2222
|
async function buildChangeDepositPair(parameters) {
|
|
1503
2223
|
const changeSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
|
|
@@ -1516,24 +2236,24 @@ async function buildChangeDepositPair(parameters) {
|
|
|
1516
2236
|
};
|
|
1517
2237
|
}
|
|
1518
2238
|
async function buildRecipientAndOptionalChangeDeposits(parameters) {
|
|
2239
|
+
const escrow = {
|
|
2240
|
+
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
2241
|
+
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
2242
|
+
};
|
|
1519
2243
|
const recipientPrivateAddress = parameters.recipientPrivateAddressStpl1.trim();
|
|
1520
2244
|
const recipientSlot = await getPrivacyPoolService().buildAlignedDepositSlot({
|
|
1521
2245
|
privateAddressStpl1: recipientPrivateAddress,
|
|
1522
2246
|
amountStroops: parameters.transferStroops,
|
|
1523
|
-
tokenAddress: parameters.tokenAddress
|
|
2247
|
+
tokenAddress: parameters.tokenAddress,
|
|
2248
|
+
...escrowOutputFields(escrow)
|
|
1524
2249
|
});
|
|
1525
2250
|
if (parameters.changeStroops <= ZERO_STROOPS) {
|
|
1526
2251
|
return {
|
|
1527
2252
|
recipientSlot,
|
|
1528
|
-
deposits:
|
|
1529
|
-
recipientPrivateAddress,
|
|
1530
|
-
parameters.tokenAddress,
|
|
1531
|
-
recipientSlot.deposit
|
|
1532
|
-
)
|
|
2253
|
+
deposits: paddingDepositPair(recipientSlot.deposit)
|
|
1533
2254
|
};
|
|
1534
2255
|
}
|
|
1535
2256
|
const changeResult = await buildChangeDepositPair({
|
|
1536
|
-
recipientPrivateAddressStpl1: recipientPrivateAddress,
|
|
1537
2257
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1538
2258
|
changeStroops: parameters.changeStroops,
|
|
1539
2259
|
tokenAddress: parameters.tokenAddress,
|
|
@@ -1555,20 +2275,61 @@ function generatedOutputCoinFromSlot(slot) {
|
|
|
1555
2275
|
precommitementHex: slot.precommitementHex
|
|
1556
2276
|
};
|
|
1557
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
|
+
}
|
|
1558
2317
|
async function buildTransferDepositsAndPublicInput(parameters) {
|
|
1559
2318
|
const { recipientSlot, deposits, changeCoin } = await buildRecipientAndOptionalChangeDeposits({
|
|
1560
2319
|
recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
|
|
1561
2320
|
transferStroops: parameters.transferStroops,
|
|
1562
2321
|
changeStroops: parameters.changeStroops,
|
|
1563
2322
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1564
|
-
tokenAddress: parameters.tokenAddress
|
|
2323
|
+
tokenAddress: parameters.tokenAddress,
|
|
2324
|
+
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
2325
|
+
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
1565
2326
|
});
|
|
1566
2327
|
const publicInput = withTokenAddressPublicInputs(
|
|
1567
2328
|
{
|
|
1568
2329
|
stateRoot: parameters.stateRoot,
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
2330
|
+
privKeyScalar: parameters.privKeyScalar,
|
|
2331
|
+
...publicEscrowRecipientLimbs(parameters),
|
|
2332
|
+
...sweepOutputOwnerFields(parameters)
|
|
1572
2333
|
},
|
|
1573
2334
|
parameters.tokenAddress
|
|
1574
2335
|
);
|
|
@@ -1580,10 +2341,6 @@ async function buildTransferDepositsAndPublicInput(parameters) {
|
|
|
1580
2341
|
};
|
|
1581
2342
|
}
|
|
1582
2343
|
async function buildSenderTransferDepositsAndPublicInput(parameters) {
|
|
1583
|
-
const { hi, lo, privKeyScalar } = senderWithdrawFrAndScalar({
|
|
1584
|
-
senderGAddress: parameters.senderGAddress,
|
|
1585
|
-
senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex
|
|
1586
|
-
});
|
|
1587
2344
|
return buildTransferDepositsAndPublicInput({
|
|
1588
2345
|
recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
|
|
1589
2346
|
transferStroops: parameters.transferStroops,
|
|
@@ -1591,31 +2348,55 @@ async function buildSenderTransferDepositsAndPublicInput(parameters) {
|
|
|
1591
2348
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1592
2349
|
tokenAddress: parameters.tokenAddress,
|
|
1593
2350
|
stateRoot: parameters.stateRoot,
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
2351
|
+
privKeyScalar: privKeyScalarDecimalFromRecipientScalarHex(
|
|
2352
|
+
parameters.senderPrivKeyScalarHex
|
|
2353
|
+
),
|
|
2354
|
+
...parameters.escrowSend ? { escrowSend: parameters.escrowSend } : {},
|
|
2355
|
+
...parameters.escrowClaimantLimbs ? { escrowClaimantLimbs: parameters.escrowClaimantLimbs } : {}
|
|
1597
2356
|
});
|
|
1598
2357
|
}
|
|
1599
2358
|
|
|
1600
2359
|
// src/transact/proofs/confidential/dual.ts
|
|
1601
|
-
function
|
|
1602
|
-
return
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
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
|
+
});
|
|
1608
2385
|
}
|
|
1609
2386
|
async function proveDualConfidentialTransfer(parameters) {
|
|
1610
2387
|
const audit = buildPoolTransactionAuditParameters({
|
|
1611
2388
|
applicationId: parameters.applicationId,
|
|
2389
|
+
nAuditSlots: parameters.sdk.getLayout().nAuditSlots,
|
|
1612
2390
|
...parameters.auditPublicKey ? { auditPublicKey: parameters.auditPublicKey } : {}
|
|
1613
2391
|
});
|
|
1614
2392
|
return parameters.sdk.proveTransaction(
|
|
1615
2393
|
parameters.publicInput,
|
|
1616
|
-
buildZeroPublicLegs(),
|
|
1617
|
-
|
|
1618
|
-
|
|
2394
|
+
padPublicLegsToLayout(parameters.sdk, buildZeroPublicLegs()),
|
|
2395
|
+
padWithdrawSlotsToLayout(parameters.sdk, [
|
|
2396
|
+
parameters.legA.withdrawObject,
|
|
2397
|
+
parameters.legB.withdrawObject
|
|
2398
|
+
]),
|
|
2399
|
+
padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
|
|
1619
2400
|
audit
|
|
1620
2401
|
);
|
|
1621
2402
|
}
|
|
@@ -1629,24 +2410,33 @@ async function buildDualTransferProofContext(parameters, applicationId, sdk) {
|
|
|
1629
2410
|
changeStroops,
|
|
1630
2411
|
parameters.selfPrivateAddressStpl1ForChange
|
|
1631
2412
|
);
|
|
1632
|
-
const
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
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
|
+
);
|
|
1641
2431
|
const transferInputs = await buildSenderTransferDepositsAndPublicInput({
|
|
1642
|
-
senderGAddress: parameters.senderGAddress,
|
|
1643
2432
|
senderPrivKeyScalarHex: parameters.senderPrivKeyScalarHex,
|
|
1644
2433
|
recipientPrivateAddressStpl1: parameters.recipientPrivateAddressStpl1,
|
|
1645
2434
|
transferStroops: parameters.transferStroops,
|
|
1646
2435
|
changeStroops,
|
|
1647
2436
|
selfPrivateAddressStpl1ForChange: parameters.selfPrivateAddressStpl1ForChange,
|
|
1648
2437
|
tokenAddress: parameters.tokenAddress,
|
|
1649
|
-
stateRoot: legA.witness.stateRoot
|
|
2438
|
+
stateRoot: legA.witness.stateRoot,
|
|
2439
|
+
...confidentialEscrowFields(parameters)
|
|
1650
2440
|
});
|
|
1651
2441
|
return { legA, legB, applicationId, ...transferInputs };
|
|
1652
2442
|
}
|
|
@@ -1674,7 +2464,11 @@ async function prepareConfidentialTransferProofDual(parameters) {
|
|
|
1674
2464
|
}));
|
|
1675
2465
|
return {
|
|
1676
2466
|
...proof,
|
|
1677
|
-
applicationIdsPlaintext: buildDualTransferApplicationIds(
|
|
2467
|
+
applicationIdsPlaintext: buildDualTransferApplicationIds(
|
|
2468
|
+
sdk,
|
|
2469
|
+
applicationId,
|
|
2470
|
+
changeCoin
|
|
2471
|
+
),
|
|
1678
2472
|
recipientCoin: generatedOutputCoinFromSlot(recipientSlot),
|
|
1679
2473
|
...changeCoin ? { changeCoin } : {}
|
|
1680
2474
|
};
|
|
@@ -1692,51 +2486,72 @@ function validateSingleCoinTransferAmounts(transferStroops, noteStroops, selfPri
|
|
|
1692
2486
|
requireChangeRecipientWhenPartial(changeStroops, selfPrivateAddressStpl1ForChange);
|
|
1693
2487
|
return changeStroops;
|
|
1694
2488
|
}
|
|
1695
|
-
function buildSingleTransferApplicationIds(applicationId, changeCoin) {
|
|
1696
|
-
return
|
|
2489
|
+
function buildSingleTransferApplicationIds(sdk, applicationId, changeCoin) {
|
|
2490
|
+
return buildApplicationIdHints({
|
|
2491
|
+
sdk,
|
|
2492
|
+
inputIds: [applicationId],
|
|
2493
|
+
outputIds: [applicationId, changeCoin ? applicationId : "0"]
|
|
2494
|
+
});
|
|
1697
2495
|
}
|
|
1698
2496
|
function buildTransferAuditParameters(parameters) {
|
|
1699
2497
|
const auditPublicKey = parameters.poolService.getAuditPublicKey();
|
|
1700
2498
|
return buildPoolTransactionAuditParameters({
|
|
1701
2499
|
applicationId: parameters.applicationId,
|
|
2500
|
+
nAuditSlots: parameters.nAuditSlots,
|
|
1702
2501
|
...auditPublicKey ? { auditPublicKey } : {}
|
|
1703
2502
|
});
|
|
1704
2503
|
}
|
|
1705
2504
|
async function proveTransaction(parameters) {
|
|
1706
2505
|
return parameters.sdk.proveTransaction(
|
|
1707
2506
|
parameters.publicInput,
|
|
1708
|
-
buildZeroPublicLegs(),
|
|
1709
|
-
[parameters.withdrawObject
|
|
1710
|
-
parameters.deposits,
|
|
2507
|
+
padPublicLegsToLayout(parameters.sdk, buildZeroPublicLegs()),
|
|
2508
|
+
padWithdrawSlotsToLayout(parameters.sdk, [parameters.withdrawObject]),
|
|
2509
|
+
padDepositSlotsToLayout(parameters.sdk, parameters.deposits),
|
|
1711
2510
|
parameters.audit
|
|
1712
2511
|
);
|
|
1713
2512
|
}
|
|
2513
|
+
function confidentialEscrowFields2(input) {
|
|
2514
|
+
return {
|
|
2515
|
+
...input.escrowSend ? { escrowSend: input.escrowSend } : {},
|
|
2516
|
+
...input.escrowClaimantLimbs ? { escrowClaimantLimbs: input.escrowClaimantLimbs } : {}
|
|
2517
|
+
};
|
|
2518
|
+
}
|
|
1714
2519
|
async function buildTransferProofInputs(parameters) {
|
|
1715
2520
|
const changeStroops = validateSingleCoinTransferAmounts(
|
|
1716
2521
|
parameters.input.transferStroops,
|
|
1717
2522
|
parameters.noteStroops,
|
|
1718
2523
|
parameters.input.selfPrivateAddressStpl1ForChange
|
|
1719
2524
|
);
|
|
2525
|
+
const privKeyScalar = privKeyScalarDecimalFromRecipientScalarHex(
|
|
2526
|
+
parameters.input.senderPrivKeyScalarHex
|
|
2527
|
+
);
|
|
1720
2528
|
const { witness, withdrawObject } = withdrawWitnessForCoin({
|
|
1721
2529
|
sdk: parameters.sdk,
|
|
1722
2530
|
coin: parameters.input.coin,
|
|
1723
2531
|
state: parameters.input.state,
|
|
1724
|
-
|
|
2532
|
+
ownerPubHex: parameters.sdk.ecdhEphemeralPublicKeyFromScalarHex(
|
|
2533
|
+
parameters.input.senderPrivKeyScalarHex
|
|
2534
|
+
),
|
|
2535
|
+
privKeyScalar,
|
|
1725
2536
|
applicationId: parameters.applicationId
|
|
1726
2537
|
});
|
|
2538
|
+
const stampedWithdraw = stampWithdrawEscrowLimbs(
|
|
2539
|
+
withdrawObject,
|
|
2540
|
+
sweepWithdrawStamp(confidentialEscrowFields2(parameters.input))
|
|
2541
|
+
);
|
|
1727
2542
|
const { recipientSlot, deposits, changeCoin, publicInput } = await buildSenderTransferDepositsAndPublicInput({
|
|
1728
|
-
senderGAddress: parameters.input.senderGAddress,
|
|
1729
2543
|
senderPrivKeyScalarHex: parameters.input.senderPrivKeyScalarHex,
|
|
1730
2544
|
recipientPrivateAddressStpl1: parameters.input.recipientPrivateAddressStpl1,
|
|
1731
2545
|
transferStroops: parameters.input.transferStroops,
|
|
1732
2546
|
changeStroops,
|
|
1733
2547
|
selfPrivateAddressStpl1ForChange: parameters.input.selfPrivateAddressStpl1ForChange,
|
|
1734
2548
|
tokenAddress: parameters.input.tokenAddress,
|
|
1735
|
-
stateRoot: witness.stateRoot
|
|
2549
|
+
stateRoot: witness.stateRoot,
|
|
2550
|
+
...confidentialEscrowFields2(parameters.input)
|
|
1736
2551
|
});
|
|
1737
2552
|
return {
|
|
1738
2553
|
witness,
|
|
1739
|
-
withdrawObject,
|
|
2554
|
+
withdrawObject: stampedWithdraw,
|
|
1740
2555
|
recipientSlot,
|
|
1741
2556
|
deposits,
|
|
1742
2557
|
changeCoin,
|
|
@@ -1754,7 +2569,11 @@ async function prepareConfidentialTransferProof(parameters) {
|
|
|
1754
2569
|
input: parameters,
|
|
1755
2570
|
noteStroops
|
|
1756
2571
|
});
|
|
1757
|
-
const audit = buildTransferAuditParameters({
|
|
2572
|
+
const audit = buildTransferAuditParameters({
|
|
2573
|
+
poolService,
|
|
2574
|
+
applicationId,
|
|
2575
|
+
nAuditSlots: sdk.getLayout().nAuditSlots
|
|
2576
|
+
});
|
|
1758
2577
|
const proof = await proveTransaction({
|
|
1759
2578
|
sdk,
|
|
1760
2579
|
publicInput,
|
|
@@ -1765,6 +2584,7 @@ async function prepareConfidentialTransferProof(parameters) {
|
|
|
1765
2584
|
return {
|
|
1766
2585
|
...proof,
|
|
1767
2586
|
applicationIdsPlaintext: buildSingleTransferApplicationIds(
|
|
2587
|
+
sdk,
|
|
1768
2588
|
applicationId,
|
|
1769
2589
|
changeCoin
|
|
1770
2590
|
),
|
|
@@ -1896,12 +2716,25 @@ async function readLeafEphemeralHex(parameters) {
|
|
|
1896
2716
|
return { xHex, yHex };
|
|
1897
2717
|
}
|
|
1898
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
|
+
|
|
1899
2735
|
// src/state/foundation/paths.ts
|
|
1900
2736
|
var STELLAR_STATE_PATHS = {
|
|
1901
2737
|
privateRecords: "$.privateRecords",
|
|
1902
|
-
pendingClaimsItems: "$.pendingClaims.items",
|
|
1903
|
-
pendingClaimsPagination: "$.pendingClaims.pagination",
|
|
1904
|
-
pendingClaimsCountByOwner: "$.pendingClaims.countByOwner",
|
|
1905
2738
|
registryPrivateAddresses: "$.registry.privateAddresses",
|
|
1906
2739
|
registryRegisteredAddresses: "$.registry.registeredAddresses",
|
|
1907
2740
|
registryLookups: "$.registry.lookups",
|
|
@@ -1921,25 +2754,6 @@ var STELLAR_STATE_PATHS = {
|
|
|
1921
2754
|
|
|
1922
2755
|
// src/state/schemas/shared.ts
|
|
1923
2756
|
import { z } from "zod";
|
|
1924
|
-
var pendingClaimSchema = z.object({
|
|
1925
|
-
id: z.string().min(1),
|
|
1926
|
-
owner: z.string().min(1),
|
|
1927
|
-
asset: z.string().min(1),
|
|
1928
|
-
amount: z.coerce.bigint(),
|
|
1929
|
-
createdAt: z.string().min(1),
|
|
1930
|
-
poolTxId: z.string().optional(),
|
|
1931
|
-
commitmentHex: z.string().optional(),
|
|
1932
|
-
nullifierHex: z.string().optional(),
|
|
1933
|
-
futureNullifierHashHex: z.string().optional(),
|
|
1934
|
-
assetHiHex: z.string().optional(),
|
|
1935
|
-
assetLoHex: z.string().optional(),
|
|
1936
|
-
nullifierFieldHex: z.string().optional(),
|
|
1937
|
-
secretHex: z.string().optional(),
|
|
1938
|
-
tempPublicKeyXHex: z.string().optional(),
|
|
1939
|
-
tempPublicKeyYHex: z.string().optional(),
|
|
1940
|
-
encryptedRecoveryBase64: z.string().optional(),
|
|
1941
|
-
createdAtLedger: z.number().int().optional()
|
|
1942
|
-
});
|
|
1943
2757
|
var paginationSchema = z.object({
|
|
1944
2758
|
total: z.number().int().nonnegative(),
|
|
1945
2759
|
page: z.number().int().positive(),
|
|
@@ -2109,26 +2923,6 @@ function normalizePublicBalancesFromEntries(value, owner) {
|
|
|
2109
2923
|
}).filter((balance) => balance !== void 0);
|
|
2110
2924
|
}
|
|
2111
2925
|
|
|
2112
|
-
// src/state/read/normalize/claims.ts
|
|
2113
|
-
function normalizePendingClaimsState(value) {
|
|
2114
|
-
if (typeof value !== "object" || value === null) {
|
|
2115
|
-
return { items: [] };
|
|
2116
|
-
}
|
|
2117
|
-
const record = value;
|
|
2118
|
-
const items = Array.isArray(record.items) ? record.items.flatMap((item) => {
|
|
2119
|
-
const parsed = pendingClaimSchema.safeParse(item);
|
|
2120
|
-
return parsed.success ? [withoutUndefinedFields(parsed.data)] : [];
|
|
2121
|
-
}) : [];
|
|
2122
|
-
const paginationResult = paginationSchema.safeParse(record.pagination);
|
|
2123
|
-
if (paginationResult.success) {
|
|
2124
|
-
return { items, pagination: paginationResult.data };
|
|
2125
|
-
}
|
|
2126
|
-
return { items };
|
|
2127
|
-
}
|
|
2128
|
-
function normalizePendingClaimsCount(value) {
|
|
2129
|
-
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
2130
|
-
}
|
|
2131
|
-
|
|
2132
2926
|
// src/state/read/normalize/deliveries.ts
|
|
2133
2927
|
function normalizeIncomingDeliveries(value) {
|
|
2134
2928
|
const entries = typeof value === "object" && value !== null && !Array.isArray(value) ? Object.values(value) : value;
|
|
@@ -2251,8 +3045,7 @@ import { registerArrayFilterItemSchema } from "@arcanetech/privacy-sdk-core/stat
|
|
|
2251
3045
|
|
|
2252
3046
|
// src/state/filters/ops.ts
|
|
2253
3047
|
var stellarArrayFilterSchemaKeys = {
|
|
2254
|
-
privateRecord: "privateRecord"
|
|
2255
|
-
pendingClaim: "pendingClaim"
|
|
3048
|
+
privateRecord: "privateRecord"
|
|
2256
3049
|
};
|
|
2257
3050
|
function rejectPrivateRecordsByIds(ids) {
|
|
2258
3051
|
return {
|
|
@@ -2278,56 +3071,6 @@ function rejectConsumedPrivateRecords() {
|
|
|
2278
3071
|
}
|
|
2279
3072
|
};
|
|
2280
3073
|
}
|
|
2281
|
-
function rejectPendingClaimsByOwner(owner) {
|
|
2282
|
-
return {
|
|
2283
|
-
opType: "arrayFilter",
|
|
2284
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2285
|
-
itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
|
|
2286
|
-
rejectWhen: {
|
|
2287
|
-
op: "fieldEquals",
|
|
2288
|
-
field: "owner",
|
|
2289
|
-
value: owner
|
|
2290
|
-
}
|
|
2291
|
-
};
|
|
2292
|
-
}
|
|
2293
|
-
function rejectPendingClaimsByIds(ids) {
|
|
2294
|
-
return {
|
|
2295
|
-
opType: "arrayFilter",
|
|
2296
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2297
|
-
itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
|
|
2298
|
-
rejectWhen: {
|
|
2299
|
-
op: "fieldIn",
|
|
2300
|
-
field: "id",
|
|
2301
|
-
values: ids
|
|
2302
|
-
}
|
|
2303
|
-
};
|
|
2304
|
-
}
|
|
2305
|
-
function rejectPendingClaimsByOwnerAndAsset(input) {
|
|
2306
|
-
const matches = [];
|
|
2307
|
-
if (input.owner !== void 0) {
|
|
2308
|
-
matches.push({
|
|
2309
|
-
op: "fieldEquals",
|
|
2310
|
-
field: "owner",
|
|
2311
|
-
value: input.owner
|
|
2312
|
-
});
|
|
2313
|
-
}
|
|
2314
|
-
if (input.asset !== void 0) {
|
|
2315
|
-
matches.push({
|
|
2316
|
-
op: "fieldEquals",
|
|
2317
|
-
field: "asset",
|
|
2318
|
-
value: input.asset
|
|
2319
|
-
});
|
|
2320
|
-
}
|
|
2321
|
-
return {
|
|
2322
|
-
opType: "arrayFilter",
|
|
2323
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2324
|
-
itemSchemaKey: stellarArrayFilterSchemaKeys.pendingClaim,
|
|
2325
|
-
rejectWhen: {
|
|
2326
|
-
op: "and",
|
|
2327
|
-
matches
|
|
2328
|
-
}
|
|
2329
|
-
};
|
|
2330
|
-
}
|
|
2331
3074
|
|
|
2332
3075
|
// src/state/filters/register-schemas.ts
|
|
2333
3076
|
var registered = false;
|
|
@@ -2339,24 +3082,12 @@ function registerStellarArrayFilterSchemas() {
|
|
|
2339
3082
|
stellarArrayFilterSchemaKeys.privateRecord,
|
|
2340
3083
|
privateRecordSchema
|
|
2341
3084
|
);
|
|
2342
|
-
registerArrayFilterItemSchema(
|
|
2343
|
-
stellarArrayFilterSchemaKeys.pendingClaim,
|
|
2344
|
-
pendingClaimSchema
|
|
2345
|
-
);
|
|
2346
3085
|
registered = true;
|
|
2347
3086
|
}
|
|
2348
3087
|
|
|
2349
3088
|
// src/state/bridge/call-types.ts
|
|
2350
3089
|
import "@arcanetech/privacy-sdk-core/state";
|
|
2351
3090
|
var stellarStateCallTypes = {
|
|
2352
|
-
pendingClaims: "pendingClaims",
|
|
2353
|
-
clearPendingClaims: "clearPendingClaims",
|
|
2354
|
-
readPendingClaims: "readPendingClaims",
|
|
2355
|
-
replacePendingClaimsPage: "replacePendingClaimsPage",
|
|
2356
|
-
upsertPendingClaims: "upsertPendingClaims",
|
|
2357
|
-
removePendingClaims: "removePendingClaims",
|
|
2358
|
-
setPendingClaimsCount: "setPendingClaimsCount",
|
|
2359
|
-
readPendingClaimsCount: "readPendingClaimsCount",
|
|
2360
3091
|
readStellarAddressRegistered: "readStellarAddressRegistered",
|
|
2361
3092
|
readCachedPrivateAddress: "readCachedPrivateAddress",
|
|
2362
3093
|
readRegistryLookup: "readRegistryLookup",
|
|
@@ -2583,194 +3314,10 @@ var stellarBalancesStateDefinitions = [
|
|
|
2583
3314
|
}
|
|
2584
3315
|
];
|
|
2585
3316
|
|
|
2586
|
-
// src/state/schemas/claims/write.ts
|
|
2587
|
-
import { z as z5 } from "zod";
|
|
2588
|
-
var pendingClaimsWriteSchema = z5.object({
|
|
2589
|
-
type: z5.literal(stellarStateCallTypes.pendingClaims),
|
|
2590
|
-
claims: z5.array(pendingClaimSchema),
|
|
2591
|
-
paginationInfo: paginationSchema
|
|
2592
|
-
}).transform(({ type, claims, paginationInfo }) => ({
|
|
2593
|
-
type,
|
|
2594
|
-
operations: [
|
|
2595
|
-
{
|
|
2596
|
-
opType: "arrayPush",
|
|
2597
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2598
|
-
items: claims
|
|
2599
|
-
},
|
|
2600
|
-
{
|
|
2601
|
-
opType: "primitiveSet",
|
|
2602
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsPagination,
|
|
2603
|
-
value: paginationInfo
|
|
2604
|
-
}
|
|
2605
|
-
]
|
|
2606
|
-
}));
|
|
2607
|
-
var clearPendingClaimsSchema = z5.object({
|
|
2608
|
-
type: z5.literal(stellarStateCallTypes.clearPendingClaims),
|
|
2609
|
-
owner: z5.string().optional(),
|
|
2610
|
-
asset: z5.string().optional()
|
|
2611
|
-
}).transform(({ type, owner, asset }) => {
|
|
2612
|
-
if (owner === void 0 && asset === void 0) {
|
|
2613
|
-
return {
|
|
2614
|
-
type,
|
|
2615
|
-
operations: [
|
|
2616
|
-
{
|
|
2617
|
-
opType: "arrayClean",
|
|
2618
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems
|
|
2619
|
-
}
|
|
2620
|
-
]
|
|
2621
|
-
};
|
|
2622
|
-
}
|
|
2623
|
-
return {
|
|
2624
|
-
type,
|
|
2625
|
-
operations: [rejectPendingClaimsByOwnerAndAsset({ owner, asset })]
|
|
2626
|
-
};
|
|
2627
|
-
});
|
|
2628
|
-
var readPendingClaimsSchema = z5.object({
|
|
2629
|
-
type: z5.literal(stellarStateCallTypes.readPendingClaims)
|
|
2630
|
-
}).transform(({ type }) => ({
|
|
2631
|
-
type,
|
|
2632
|
-
operations: [
|
|
2633
|
-
{
|
|
2634
|
-
opType: "primitiveGet",
|
|
2635
|
-
jsonPath: "$.pendingClaims"
|
|
2636
|
-
}
|
|
2637
|
-
]
|
|
2638
|
-
}));
|
|
2639
|
-
|
|
2640
|
-
// src/state/schemas/claims/page.ts
|
|
2641
|
-
import { z as z6 } from "zod";
|
|
2642
|
-
var pendingClaimBridgeItemSchema = pendingClaimSchema;
|
|
2643
|
-
var replacePendingClaimsPageSchema = z6.object({
|
|
2644
|
-
type: z6.literal(stellarStateCallTypes.replacePendingClaimsPage),
|
|
2645
|
-
owner: z6.string().min(1),
|
|
2646
|
-
claims: z6.array(pendingClaimBridgeItemSchema),
|
|
2647
|
-
paginationInfo: z6.object({
|
|
2648
|
-
total: z6.number().int().nonnegative(),
|
|
2649
|
-
page: z6.number().int().positive(),
|
|
2650
|
-
pageSize: z6.number().int().positive(),
|
|
2651
|
-
hasMore: z6.boolean()
|
|
2652
|
-
}),
|
|
2653
|
-
count: z6.number().int().nonnegative().optional()
|
|
2654
|
-
}).transform(({ type, owner, claims, paginationInfo, count }) => ({
|
|
2655
|
-
type,
|
|
2656
|
-
operations: [
|
|
2657
|
-
rejectPendingClaimsByOwner(owner),
|
|
2658
|
-
{
|
|
2659
|
-
opType: "arrayPush",
|
|
2660
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2661
|
-
items: claims
|
|
2662
|
-
},
|
|
2663
|
-
{
|
|
2664
|
-
opType: "primitiveSet",
|
|
2665
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsPagination,
|
|
2666
|
-
value: paginationInfo
|
|
2667
|
-
},
|
|
2668
|
-
{
|
|
2669
|
-
opType: "recordSet",
|
|
2670
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
|
|
2671
|
-
key: owner,
|
|
2672
|
-
value: count ?? paginationInfo.total
|
|
2673
|
-
}
|
|
2674
|
-
]
|
|
2675
|
-
}));
|
|
2676
|
-
var upsertPendingClaimsSchema = z6.object({
|
|
2677
|
-
type: z6.literal(stellarStateCallTypes.upsertPendingClaims),
|
|
2678
|
-
claims: z6.array(pendingClaimBridgeItemSchema)
|
|
2679
|
-
}).transform(({ type, claims }) => ({
|
|
2680
|
-
type,
|
|
2681
|
-
operations: [
|
|
2682
|
-
rejectPendingClaimsByIds(claims.map((claim) => claim.id)),
|
|
2683
|
-
{
|
|
2684
|
-
opType: "arrayPush",
|
|
2685
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsItems,
|
|
2686
|
-
items: claims
|
|
2687
|
-
}
|
|
2688
|
-
]
|
|
2689
|
-
}));
|
|
2690
|
-
var removePendingClaimsSchema = z6.object({
|
|
2691
|
-
type: z6.literal(stellarStateCallTypes.removePendingClaims),
|
|
2692
|
-
ids: z6.array(z6.string().min(1))
|
|
2693
|
-
}).transform(({ type, ids }) => ({
|
|
2694
|
-
type,
|
|
2695
|
-
operations: [rejectPendingClaimsByIds(ids)]
|
|
2696
|
-
}));
|
|
2697
|
-
var readPendingClaimsCountSchema = z6.object({
|
|
2698
|
-
type: z6.literal(stellarStateCallTypes.readPendingClaimsCount),
|
|
2699
|
-
owner: z6.string().min(1)
|
|
2700
|
-
}).transform(({ type, owner }) => ({
|
|
2701
|
-
type,
|
|
2702
|
-
operations: [
|
|
2703
|
-
{
|
|
2704
|
-
opType: "recordGet",
|
|
2705
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
|
|
2706
|
-
key: owner
|
|
2707
|
-
}
|
|
2708
|
-
]
|
|
2709
|
-
}));
|
|
2710
|
-
var setPendingClaimsCountSchema = z6.object({
|
|
2711
|
-
type: z6.literal(stellarStateCallTypes.setPendingClaimsCount),
|
|
2712
|
-
owner: z6.string().min(1),
|
|
2713
|
-
count: z6.number().int().nonnegative()
|
|
2714
|
-
}).transform(({ type, owner, count }) => ({
|
|
2715
|
-
type,
|
|
2716
|
-
operations: [
|
|
2717
|
-
{
|
|
2718
|
-
opType: "recordSet",
|
|
2719
|
-
jsonPath: STELLAR_STATE_PATHS.pendingClaimsCountByOwner,
|
|
2720
|
-
key: owner,
|
|
2721
|
-
value: count
|
|
2722
|
-
}
|
|
2723
|
-
]
|
|
2724
|
-
}));
|
|
2725
|
-
|
|
2726
|
-
// src/state/definitions/claims.ts
|
|
2727
|
-
var stellarClaimsStateDefinitions = [
|
|
2728
|
-
{
|
|
2729
|
-
type: stellarStateCallTypes.pendingClaims,
|
|
2730
|
-
mode: "write",
|
|
2731
|
-
schema: pendingClaimsWriteSchema
|
|
2732
|
-
},
|
|
2733
|
-
{
|
|
2734
|
-
type: stellarStateCallTypes.clearPendingClaims,
|
|
2735
|
-
mode: "write",
|
|
2736
|
-
schema: clearPendingClaimsSchema
|
|
2737
|
-
},
|
|
2738
|
-
{
|
|
2739
|
-
type: stellarStateCallTypes.readPendingClaims,
|
|
2740
|
-
mode: "read",
|
|
2741
|
-
schema: readPendingClaimsSchema
|
|
2742
|
-
},
|
|
2743
|
-
{
|
|
2744
|
-
type: stellarStateCallTypes.replacePendingClaimsPage,
|
|
2745
|
-
mode: "write",
|
|
2746
|
-
schema: replacePendingClaimsPageSchema
|
|
2747
|
-
},
|
|
2748
|
-
{
|
|
2749
|
-
type: stellarStateCallTypes.upsertPendingClaims,
|
|
2750
|
-
mode: "write",
|
|
2751
|
-
schema: upsertPendingClaimsSchema
|
|
2752
|
-
},
|
|
2753
|
-
{
|
|
2754
|
-
type: stellarStateCallTypes.removePendingClaims,
|
|
2755
|
-
mode: "write",
|
|
2756
|
-
schema: removePendingClaimsSchema
|
|
2757
|
-
},
|
|
2758
|
-
{
|
|
2759
|
-
type: stellarStateCallTypes.readPendingClaimsCount,
|
|
2760
|
-
mode: "read",
|
|
2761
|
-
schema: readPendingClaimsCountSchema
|
|
2762
|
-
},
|
|
2763
|
-
{
|
|
2764
|
-
type: stellarStateCallTypes.setPendingClaimsCount,
|
|
2765
|
-
mode: "write",
|
|
2766
|
-
schema: setPendingClaimsCountSchema
|
|
2767
|
-
}
|
|
2768
|
-
];
|
|
2769
|
-
|
|
2770
3317
|
// src/state/schemas/claims/deliveries.ts
|
|
2771
|
-
import { z as
|
|
2772
|
-
var readIncomingDeliveriesSchema =
|
|
2773
|
-
type:
|
|
3318
|
+
import { z as z5 } from "zod";
|
|
3319
|
+
var readIncomingDeliveriesSchema = z5.object({
|
|
3320
|
+
type: z5.literal(stellarStateCallTypes.readIncomingDeliveries)
|
|
2774
3321
|
}).transform(({ type }) => ({
|
|
2775
3322
|
type,
|
|
2776
3323
|
operations: [
|
|
@@ -2780,9 +3327,9 @@ var readIncomingDeliveriesSchema = z7.object({
|
|
|
2780
3327
|
}
|
|
2781
3328
|
]
|
|
2782
3329
|
}));
|
|
2783
|
-
var upsertIncomingDeliveriesSchema =
|
|
2784
|
-
type:
|
|
2785
|
-
deliveries:
|
|
3330
|
+
var upsertIncomingDeliveriesSchema = z5.object({
|
|
3331
|
+
type: z5.literal(stellarStateCallTypes.upsertIncomingDeliveries),
|
|
3332
|
+
deliveries: z5.array(incomingDeliverySchema)
|
|
2786
3333
|
}).transform(({ type, deliveries }) => ({
|
|
2787
3334
|
type,
|
|
2788
3335
|
operations: deliveries.map((delivery) => ({
|
|
@@ -2792,10 +3339,10 @@ var upsertIncomingDeliveriesSchema = z7.object({
|
|
|
2792
3339
|
value: delivery
|
|
2793
3340
|
}))
|
|
2794
3341
|
}));
|
|
2795
|
-
var readDeliverySyncStateSchema =
|
|
2796
|
-
type:
|
|
2797
|
-
privateAddress:
|
|
2798
|
-
asset:
|
|
3342
|
+
var readDeliverySyncStateSchema = z5.object({
|
|
3343
|
+
type: z5.literal(stellarStateCallTypes.readDeliverySyncState),
|
|
3344
|
+
privateAddress: z5.string().min(1),
|
|
3345
|
+
asset: z5.string().min(1)
|
|
2799
3346
|
}).transform(({ type, privateAddress, asset }) => ({
|
|
2800
3347
|
type,
|
|
2801
3348
|
operations: [
|
|
@@ -2806,8 +3353,8 @@ var readDeliverySyncStateSchema = z7.object({
|
|
|
2806
3353
|
}
|
|
2807
3354
|
]
|
|
2808
3355
|
}));
|
|
2809
|
-
var setDeliverySyncStateSchema =
|
|
2810
|
-
type:
|
|
3356
|
+
var setDeliverySyncStateSchema = z5.object({
|
|
3357
|
+
type: z5.literal(stellarStateCallTypes.setDeliverySyncState),
|
|
2811
3358
|
syncState: deliverySyncStateSchema
|
|
2812
3359
|
}).transform(({ type, syncState }) => ({
|
|
2813
3360
|
type,
|
|
@@ -2846,10 +3393,10 @@ var stellarDeliveriesStateDefinitions = [
|
|
|
2846
3393
|
];
|
|
2847
3394
|
|
|
2848
3395
|
// src/state/schemas/pool/merkle.ts
|
|
2849
|
-
import { z as
|
|
2850
|
-
var readPoolMerkleStateSchema =
|
|
2851
|
-
type:
|
|
2852
|
-
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)
|
|
2853
3400
|
}).transform(({ type, poolContract }) => ({
|
|
2854
3401
|
type,
|
|
2855
3402
|
operations: [
|
|
@@ -2860,8 +3407,8 @@ var readPoolMerkleStateSchema = z8.object({
|
|
|
2860
3407
|
}
|
|
2861
3408
|
]
|
|
2862
3409
|
}));
|
|
2863
|
-
var setPoolMerkleStateSchema =
|
|
2864
|
-
type:
|
|
3410
|
+
var setPoolMerkleStateSchema = z6.object({
|
|
3411
|
+
type: z6.literal(stellarStateCallTypes.setPoolMerkleState),
|
|
2865
3412
|
state: poolMerkleStateSchema
|
|
2866
3413
|
}).transform(({ type, state }) => ({
|
|
2867
3414
|
type,
|
|
@@ -2874,10 +3421,10 @@ var setPoolMerkleStateSchema = z8.object({
|
|
|
2874
3421
|
}
|
|
2875
3422
|
]
|
|
2876
3423
|
}));
|
|
2877
|
-
var readLeafEphemeralSchema =
|
|
2878
|
-
type:
|
|
2879
|
-
poolContract:
|
|
2880
|
-
leafIndex:
|
|
3424
|
+
var readLeafEphemeralSchema = z6.object({
|
|
3425
|
+
type: z6.literal(stellarStateCallTypes.readLeafEphemeral),
|
|
3426
|
+
poolContract: z6.string().min(1),
|
|
3427
|
+
leafIndex: z6.number().int().nonnegative()
|
|
2881
3428
|
}).transform(({ type, poolContract, leafIndex }) => ({
|
|
2882
3429
|
type,
|
|
2883
3430
|
operations: [
|
|
@@ -2888,8 +3435,8 @@ var readLeafEphemeralSchema = z8.object({
|
|
|
2888
3435
|
}
|
|
2889
3436
|
]
|
|
2890
3437
|
}));
|
|
2891
|
-
var setLeafEphemeralSchema =
|
|
2892
|
-
type:
|
|
3438
|
+
var setLeafEphemeralSchema = z6.object({
|
|
3439
|
+
type: z6.literal(stellarStateCallTypes.setLeafEphemeral),
|
|
2893
3440
|
ephemeral: leafEphemeralSchema
|
|
2894
3441
|
}).transform(({ type, ephemeral }) => ({
|
|
2895
3442
|
type,
|
|
@@ -2928,9 +3475,9 @@ var stellarPoolStateDefinitions = [
|
|
|
2928
3475
|
];
|
|
2929
3476
|
|
|
2930
3477
|
// src/state/schemas/records/private.ts
|
|
2931
|
-
import { z as
|
|
2932
|
-
var listPrivateRecordsSchema =
|
|
2933
|
-
type:
|
|
3478
|
+
import { z as z7 } from "zod";
|
|
3479
|
+
var listPrivateRecordsSchema = z7.object({
|
|
3480
|
+
type: z7.literal(stellarStateCallTypes.listPrivateRecords)
|
|
2934
3481
|
}).transform(({ type }) => ({
|
|
2935
3482
|
type,
|
|
2936
3483
|
operations: [
|
|
@@ -2940,9 +3487,9 @@ var listPrivateRecordsSchema = z9.object({
|
|
|
2940
3487
|
}
|
|
2941
3488
|
]
|
|
2942
3489
|
}));
|
|
2943
|
-
var savePrivateRecordsSchema =
|
|
2944
|
-
type:
|
|
2945
|
-
records:
|
|
3490
|
+
var savePrivateRecordsSchema = z7.object({
|
|
3491
|
+
type: z7.literal(stellarStateCallTypes.savePrivateRecords),
|
|
3492
|
+
records: z7.array(privateRecordSchema)
|
|
2946
3493
|
}).transform(({ type, records }) => ({
|
|
2947
3494
|
type,
|
|
2948
3495
|
operations: [
|
|
@@ -2953,9 +3500,9 @@ var savePrivateRecordsSchema = z9.object({
|
|
|
2953
3500
|
}
|
|
2954
3501
|
]
|
|
2955
3502
|
}));
|
|
2956
|
-
var replacePrivateRecordsSchema =
|
|
2957
|
-
type:
|
|
2958
|
-
records:
|
|
3503
|
+
var replacePrivateRecordsSchema = z7.object({
|
|
3504
|
+
type: z7.literal(stellarStateCallTypes.replacePrivateRecords),
|
|
3505
|
+
records: z7.array(privateRecordSchema)
|
|
2959
3506
|
}).transform(({ type, records }) => ({
|
|
2960
3507
|
type,
|
|
2961
3508
|
operations: [
|
|
@@ -2970,18 +3517,18 @@ var replacePrivateRecordsSchema = z9.object({
|
|
|
2970
3517
|
}
|
|
2971
3518
|
]
|
|
2972
3519
|
}));
|
|
2973
|
-
var pruneConsumedPrivateRecordsSchema =
|
|
2974
|
-
type:
|
|
3520
|
+
var pruneConsumedPrivateRecordsSchema = z7.object({
|
|
3521
|
+
type: z7.literal(stellarStateCallTypes.pruneConsumedPrivateRecords)
|
|
2975
3522
|
}).transform(({ type }) => ({
|
|
2976
3523
|
type,
|
|
2977
3524
|
operations: [rejectConsumedPrivateRecords()]
|
|
2978
3525
|
}));
|
|
2979
3526
|
|
|
2980
3527
|
// src/state/schemas/records/transactions.ts
|
|
2981
|
-
import { z as
|
|
2982
|
-
var upsertPrivateRecordsSchema =
|
|
2983
|
-
type:
|
|
2984
|
-
records:
|
|
3528
|
+
import { z as z8 } from "zod";
|
|
3529
|
+
var upsertPrivateRecordsSchema = z8.object({
|
|
3530
|
+
type: z8.literal(stellarStateCallTypes.upsertPrivateRecords),
|
|
3531
|
+
records: z8.array(privateRecordSchema)
|
|
2985
3532
|
}).transform(({ type, records }) => ({
|
|
2986
3533
|
type,
|
|
2987
3534
|
operations: [
|
|
@@ -2993,9 +3540,9 @@ var upsertPrivateRecordsSchema = z10.object({
|
|
|
2993
3540
|
}
|
|
2994
3541
|
]
|
|
2995
3542
|
}));
|
|
2996
|
-
var readTransactionStatusSchema =
|
|
2997
|
-
type:
|
|
2998
|
-
txHash:
|
|
3543
|
+
var readTransactionStatusSchema = z8.object({
|
|
3544
|
+
type: z8.literal(stellarStateCallTypes.readTransactionStatus),
|
|
3545
|
+
txHash: z8.string().min(1)
|
|
2999
3546
|
}).transform(({ type, txHash }) => ({
|
|
3000
3547
|
type,
|
|
3001
3548
|
operations: [
|
|
@@ -3006,8 +3553,8 @@ var readTransactionStatusSchema = z10.object({
|
|
|
3006
3553
|
}
|
|
3007
3554
|
]
|
|
3008
3555
|
}));
|
|
3009
|
-
var setTransactionStatusSchema =
|
|
3010
|
-
type:
|
|
3556
|
+
var setTransactionStatusSchema = z8.object({
|
|
3557
|
+
type: z8.literal(stellarStateCallTypes.setTransactionStatus),
|
|
3011
3558
|
status: transactionStatusSchema
|
|
3012
3559
|
}).transform(({ type, status }) => ({
|
|
3013
3560
|
type,
|
|
@@ -3020,9 +3567,9 @@ var setTransactionStatusSchema = z10.object({
|
|
|
3020
3567
|
}
|
|
3021
3568
|
]
|
|
3022
3569
|
}));
|
|
3023
|
-
var clearTransactionStatusSchema =
|
|
3024
|
-
type:
|
|
3025
|
-
txHash:
|
|
3570
|
+
var clearTransactionStatusSchema = z8.object({
|
|
3571
|
+
type: z8.literal(stellarStateCallTypes.clearTransactionStatus),
|
|
3572
|
+
txHash: z8.string().min(1)
|
|
3026
3573
|
}).transform(({ type, txHash }) => ({
|
|
3027
3574
|
type,
|
|
3028
3575
|
operations: [
|
|
@@ -3064,10 +3611,10 @@ var stellarRecordsStateDefinitions = [
|
|
|
3064
3611
|
];
|
|
3065
3612
|
|
|
3066
3613
|
// src/state/schemas/registry/lookup.ts
|
|
3067
|
-
import { z as
|
|
3068
|
-
var readStellarAddressRegisteredSchema =
|
|
3069
|
-
type:
|
|
3070
|
-
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)
|
|
3071
3618
|
}).transform(({ type, address }) => ({
|
|
3072
3619
|
type,
|
|
3073
3620
|
operations: [
|
|
@@ -3078,9 +3625,9 @@ var readStellarAddressRegisteredSchema = z11.object({
|
|
|
3078
3625
|
}
|
|
3079
3626
|
]
|
|
3080
3627
|
}));
|
|
3081
|
-
var readCachedPrivateAddressSchema =
|
|
3082
|
-
type:
|
|
3083
|
-
address:
|
|
3628
|
+
var readCachedPrivateAddressSchema = z9.object({
|
|
3629
|
+
type: z9.literal(stellarStateCallTypes.readCachedPrivateAddress),
|
|
3630
|
+
address: z9.string().min(1)
|
|
3084
3631
|
}).transform(({ type, address }) => ({
|
|
3085
3632
|
type,
|
|
3086
3633
|
operations: [
|
|
@@ -3091,11 +3638,11 @@ var readCachedPrivateAddressSchema = z11.object({
|
|
|
3091
3638
|
}
|
|
3092
3639
|
]
|
|
3093
3640
|
}));
|
|
3094
|
-
var saveRegisteredPrivateAddressSchema =
|
|
3095
|
-
type:
|
|
3096
|
-
address:
|
|
3097
|
-
privateAddress:
|
|
3098
|
-
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()
|
|
3099
3646
|
}).transform(({ type, address, privateAddress, registered: registered2 }) => {
|
|
3100
3647
|
const lookup = registryLookupSchema.parse({
|
|
3101
3648
|
owner: address,
|
|
@@ -3127,9 +3674,9 @@ var saveRegisteredPrivateAddressSchema = z11.object({
|
|
|
3127
3674
|
]
|
|
3128
3675
|
};
|
|
3129
3676
|
});
|
|
3130
|
-
var invalidateRegisteredAddressSchema =
|
|
3131
|
-
type:
|
|
3132
|
-
address:
|
|
3677
|
+
var invalidateRegisteredAddressSchema = z9.object({
|
|
3678
|
+
type: z9.literal(stellarStateCallTypes.invalidateRegisteredAddress),
|
|
3679
|
+
address: z9.string().min(1)
|
|
3133
3680
|
}).transform(({ type, address }) => ({
|
|
3134
3681
|
type,
|
|
3135
3682
|
operations: [
|
|
@@ -3150,9 +3697,9 @@ var invalidateRegisteredAddressSchema = z11.object({
|
|
|
3150
3697
|
}
|
|
3151
3698
|
]
|
|
3152
3699
|
}));
|
|
3153
|
-
var readRegistryLookupSchema =
|
|
3154
|
-
type:
|
|
3155
|
-
address:
|
|
3700
|
+
var readRegistryLookupSchema = z9.object({
|
|
3701
|
+
type: z9.literal(stellarStateCallTypes.readRegistryLookup),
|
|
3702
|
+
address: z9.string().min(1)
|
|
3156
3703
|
}).transform(({ type, address }) => ({
|
|
3157
3704
|
type,
|
|
3158
3705
|
operations: [
|
|
@@ -3163,8 +3710,8 @@ var readRegistryLookupSchema = z11.object({
|
|
|
3163
3710
|
}
|
|
3164
3711
|
]
|
|
3165
3712
|
}));
|
|
3166
|
-
var saveRegistryLookupSchema =
|
|
3167
|
-
type:
|
|
3713
|
+
var saveRegistryLookupSchema = z9.object({
|
|
3714
|
+
type: z9.literal(stellarStateCallTypes.saveRegistryLookup),
|
|
3168
3715
|
lookup: registryLookupSchema
|
|
3169
3716
|
}).transform(({ type, lookup }) => {
|
|
3170
3717
|
const operations = [
|
|
@@ -3200,9 +3747,9 @@ var saveRegistryLookupSchema = z11.object({
|
|
|
3200
3747
|
}
|
|
3201
3748
|
return { type, operations };
|
|
3202
3749
|
});
|
|
3203
|
-
var invalidateRegistryLookupSchema =
|
|
3204
|
-
type:
|
|
3205
|
-
address:
|
|
3750
|
+
var invalidateRegistryLookupSchema = z9.object({
|
|
3751
|
+
type: z9.literal(stellarStateCallTypes.invalidateRegistryLookup),
|
|
3752
|
+
address: z9.string().min(1)
|
|
3206
3753
|
}).transform(({ type, address }) => ({
|
|
3207
3754
|
type,
|
|
3208
3755
|
operations: [
|
|
@@ -3283,9 +3830,9 @@ var stellarTransactionStateDefinitions = [
|
|
|
3283
3830
|
];
|
|
3284
3831
|
|
|
3285
3832
|
// src/state/schemas/wallet/scalar.ts
|
|
3286
|
-
import { z as
|
|
3287
|
-
var saveWalletPrivateAddressScalarSchema =
|
|
3288
|
-
type:
|
|
3833
|
+
import { z as z10 } from "zod";
|
|
3834
|
+
var saveWalletPrivateAddressScalarSchema = z10.object({
|
|
3835
|
+
type: z10.literal(stellarStateCallTypes.saveWalletPrivateAddressScalar),
|
|
3289
3836
|
scalar: walletPrivateAddressScalarSchema
|
|
3290
3837
|
}).transform(({ type, scalar }) => ({
|
|
3291
3838
|
type,
|
|
@@ -3298,10 +3845,10 @@ var saveWalletPrivateAddressScalarSchema = z12.object({
|
|
|
3298
3845
|
}
|
|
3299
3846
|
]
|
|
3300
3847
|
}));
|
|
3301
|
-
var readWalletPrivateAddressScalarSchema =
|
|
3302
|
-
type:
|
|
3303
|
-
owner:
|
|
3304
|
-
nonce:
|
|
3848
|
+
var readWalletPrivateAddressScalarSchema = z10.object({
|
|
3849
|
+
type: z10.literal(stellarStateCallTypes.readWalletPrivateAddressScalar),
|
|
3850
|
+
owner: z10.string().min(1),
|
|
3851
|
+
nonce: z10.string().min(1)
|
|
3305
3852
|
}).transform(({ type, owner, nonce }) => ({
|
|
3306
3853
|
type,
|
|
3307
3854
|
operations: [
|
|
@@ -3314,9 +3861,9 @@ var readWalletPrivateAddressScalarSchema = z12.object({
|
|
|
3314
3861
|
}));
|
|
3315
3862
|
|
|
3316
3863
|
// src/state/schemas/wallet/private-address.ts
|
|
3317
|
-
import { z as
|
|
3318
|
-
var saveWalletPrivateAddressRecordSchema =
|
|
3319
|
-
type:
|
|
3864
|
+
import { z as z11 } from "zod";
|
|
3865
|
+
var saveWalletPrivateAddressRecordSchema = z11.object({
|
|
3866
|
+
type: z11.literal(stellarStateCallTypes.saveWalletPrivateAddressRecord),
|
|
3320
3867
|
record: walletPrivateAddressRecordSchema
|
|
3321
3868
|
}).transform(({ type, record }) => ({
|
|
3322
3869
|
type,
|
|
@@ -3329,10 +3876,10 @@ var saveWalletPrivateAddressRecordSchema = z13.object({
|
|
|
3329
3876
|
}
|
|
3330
3877
|
]
|
|
3331
3878
|
}));
|
|
3332
|
-
var readWalletPrivateAddressRecordSchema =
|
|
3333
|
-
type:
|
|
3334
|
-
owner:
|
|
3335
|
-
nonce:
|
|
3879
|
+
var readWalletPrivateAddressRecordSchema = z11.object({
|
|
3880
|
+
type: z11.literal(stellarStateCallTypes.readWalletPrivateAddressRecord),
|
|
3881
|
+
owner: z11.string().min(1),
|
|
3882
|
+
nonce: z11.string().min(1)
|
|
3336
3883
|
}).transform(({ type, owner, nonce }) => ({
|
|
3337
3884
|
type,
|
|
3338
3885
|
operations: [
|
|
@@ -3343,10 +3890,10 @@ var readWalletPrivateAddressRecordSchema = z13.object({
|
|
|
3343
3890
|
}
|
|
3344
3891
|
]
|
|
3345
3892
|
}));
|
|
3346
|
-
var setWalletDefaultPrivateAddressNonceSchema =
|
|
3347
|
-
type:
|
|
3348
|
-
owner:
|
|
3349
|
-
nonce:
|
|
3893
|
+
var setWalletDefaultPrivateAddressNonceSchema = z11.object({
|
|
3894
|
+
type: z11.literal(stellarStateCallTypes.setWalletDefaultPrivateAddressNonce),
|
|
3895
|
+
owner: z11.string().min(1),
|
|
3896
|
+
nonce: z11.string().min(1)
|
|
3350
3897
|
}).transform(({ type, owner, nonce }) => ({
|
|
3351
3898
|
type,
|
|
3352
3899
|
operations: [
|
|
@@ -3358,9 +3905,9 @@ var setWalletDefaultPrivateAddressNonceSchema = z13.object({
|
|
|
3358
3905
|
}
|
|
3359
3906
|
]
|
|
3360
3907
|
}));
|
|
3361
|
-
var readWalletDefaultPrivateAddressNonceSchema =
|
|
3362
|
-
type:
|
|
3363
|
-
owner:
|
|
3908
|
+
var readWalletDefaultPrivateAddressNonceSchema = z11.object({
|
|
3909
|
+
type: z11.literal(stellarStateCallTypes.readWalletDefaultPrivateAddressNonce),
|
|
3910
|
+
owner: z11.string().min(1)
|
|
3364
3911
|
}).transform(({ type, owner }) => ({
|
|
3365
3912
|
type,
|
|
3366
3913
|
operations: [
|
|
@@ -3371,10 +3918,10 @@ var readWalletDefaultPrivateAddressNonceSchema = z13.object({
|
|
|
3371
3918
|
}
|
|
3372
3919
|
]
|
|
3373
3920
|
}));
|
|
3374
|
-
var deleteWalletPrivateAddressScalarSchema =
|
|
3375
|
-
type:
|
|
3376
|
-
owner:
|
|
3377
|
-
nonce:
|
|
3921
|
+
var deleteWalletPrivateAddressScalarSchema = z11.object({
|
|
3922
|
+
type: z11.literal(stellarStateCallTypes.deleteWalletPrivateAddressScalar),
|
|
3923
|
+
owner: z11.string().min(1),
|
|
3924
|
+
nonce: z11.string().min(1)
|
|
3378
3925
|
}).transform(({ type, owner, nonce }) => ({
|
|
3379
3926
|
type,
|
|
3380
3927
|
operations: [
|
|
@@ -3428,7 +3975,6 @@ var stellarWalletStateDefinitions = [
|
|
|
3428
3975
|
// src/state/definitions/index.ts
|
|
3429
3976
|
registerStellarArrayFilterSchemas();
|
|
3430
3977
|
var stellarStateDefinitions = [
|
|
3431
|
-
...stellarClaimsStateDefinitions,
|
|
3432
3978
|
...stellarRegistryStateDefinitions,
|
|
3433
3979
|
...stellarAssetsStateDefinitions,
|
|
3434
3980
|
...stellarBalancesStateDefinitions,
|
|
@@ -3552,112 +4098,10 @@ function createAssetsCatalogMethods(context) {
|
|
|
3552
4098
|
}
|
|
3553
4099
|
|
|
3554
4100
|
// src/state/service/assets/index.ts
|
|
3555
|
-
function createAssetsService(context) {
|
|
3556
|
-
return {
|
|
3557
|
-
...createAssetsCatalogMethods(context),
|
|
3558
|
-
...createPublicBalanceMethods(context)
|
|
3559
|
-
};
|
|
3560
|
-
}
|
|
3561
|
-
|
|
3562
|
-
// src/state/service/claims/read-methods.ts
|
|
3563
|
-
function createClaimsReadMethods(context) {
|
|
3564
|
-
const { bridge } = context;
|
|
3565
|
-
async function getPendingClaims(filter = {}) {
|
|
3566
|
-
const value = await bridge.read({
|
|
3567
|
-
type: stellarStateCallTypes.readPendingClaims
|
|
3568
|
-
});
|
|
3569
|
-
const state = normalizePendingClaimsState(value);
|
|
3570
|
-
const items = state.items.filter((claim) => {
|
|
3571
|
-
if (filter.owner !== void 0 && claim.owner !== filter.owner) {
|
|
3572
|
-
return false;
|
|
3573
|
-
}
|
|
3574
|
-
if (filter.asset !== void 0 && claim.asset !== filter.asset) {
|
|
3575
|
-
return false;
|
|
3576
|
-
}
|
|
3577
|
-
return true;
|
|
3578
|
-
});
|
|
3579
|
-
if (state.pagination !== void 0) {
|
|
3580
|
-
return { items, pagination: state.pagination };
|
|
3581
|
-
}
|
|
3582
|
-
return { items };
|
|
3583
|
-
}
|
|
3584
|
-
return {
|
|
3585
|
-
getPendingClaims,
|
|
3586
|
-
async getPendingClaimsCount(owner) {
|
|
3587
|
-
const value = await bridge.read({
|
|
3588
|
-
type: stellarStateCallTypes.readPendingClaimsCount,
|
|
3589
|
-
owner
|
|
3590
|
-
});
|
|
3591
|
-
const count = normalizePendingClaimsCount(value);
|
|
3592
|
-
if (count !== void 0) {
|
|
3593
|
-
return count;
|
|
3594
|
-
}
|
|
3595
|
-
const claims = await getPendingClaims({ owner });
|
|
3596
|
-
return claims.items.length;
|
|
3597
|
-
}
|
|
3598
|
-
};
|
|
3599
|
-
}
|
|
3600
|
-
|
|
3601
|
-
// src/state/service/claims/write-methods.ts
|
|
3602
|
-
function appendPendingClaims(bridge, claims, paginationInfo) {
|
|
3603
|
-
return bridge.write({
|
|
3604
|
-
type: stellarStateCallTypes.pendingClaims,
|
|
3605
|
-
claims,
|
|
3606
|
-
paginationInfo
|
|
3607
|
-
});
|
|
3608
|
-
}
|
|
3609
|
-
function replacePendingClaimsPage(bridge, input) {
|
|
3610
|
-
return bridge.write({
|
|
3611
|
-
type: stellarStateCallTypes.replacePendingClaimsPage,
|
|
3612
|
-
owner: input.owner,
|
|
3613
|
-
claims: input.claims,
|
|
3614
|
-
paginationInfo: input.paginationInfo,
|
|
3615
|
-
...input.count === void 0 ? {} : { count: input.count }
|
|
3616
|
-
});
|
|
3617
|
-
}
|
|
3618
|
-
function upsertPendingClaims(bridge, claims) {
|
|
3619
|
-
return bridge.write({
|
|
3620
|
-
type: stellarStateCallTypes.upsertPendingClaims,
|
|
3621
|
-
claims
|
|
3622
|
-
});
|
|
3623
|
-
}
|
|
3624
|
-
function removePendingClaims(bridge, ids) {
|
|
3625
|
-
return bridge.write({
|
|
3626
|
-
type: stellarStateCallTypes.removePendingClaims,
|
|
3627
|
-
ids
|
|
3628
|
-
});
|
|
3629
|
-
}
|
|
3630
|
-
function clearPendingClaims(bridge, input = {}) {
|
|
3631
|
-
return bridge.write({
|
|
3632
|
-
type: stellarStateCallTypes.clearPendingClaims,
|
|
3633
|
-
...input.owner === void 0 ? {} : { owner: input.owner },
|
|
3634
|
-
...input.asset === void 0 ? {} : { asset: input.asset }
|
|
3635
|
-
});
|
|
3636
|
-
}
|
|
3637
|
-
function setPendingClaimsCount(bridge, owner, count) {
|
|
3638
|
-
return bridge.write({
|
|
3639
|
-
type: stellarStateCallTypes.setPendingClaimsCount,
|
|
3640
|
-
owner,
|
|
3641
|
-
count
|
|
3642
|
-
});
|
|
3643
|
-
}
|
|
3644
|
-
function createClaimsWriteMethods(context) {
|
|
3645
|
-
const { bridge } = context;
|
|
3646
|
-
return {
|
|
3647
|
-
appendPendingClaims: (claims, paginationInfo) => appendPendingClaims(bridge, claims, paginationInfo),
|
|
3648
|
-
replacePendingClaimsPage: (input) => replacePendingClaimsPage(bridge, input),
|
|
3649
|
-
upsertPendingClaims: (claims) => upsertPendingClaims(bridge, claims),
|
|
3650
|
-
removePendingClaims: (ids) => removePendingClaims(bridge, ids),
|
|
3651
|
-
clearPendingClaims: (input = {}) => clearPendingClaims(bridge, input),
|
|
3652
|
-
setPendingClaimsCount: (owner, count) => setPendingClaimsCount(bridge, owner, count)
|
|
3653
|
-
};
|
|
3654
|
-
}
|
|
3655
|
-
|
|
3656
|
-
// src/state/service/claims/index.ts
|
|
3657
|
-
function createClaimsService(context) {
|
|
4101
|
+
function createAssetsService(context) {
|
|
3658
4102
|
return {
|
|
3659
|
-
...
|
|
3660
|
-
...
|
|
4103
|
+
...createAssetsCatalogMethods(context),
|
|
4104
|
+
...createPublicBalanceMethods(context)
|
|
3661
4105
|
};
|
|
3662
4106
|
}
|
|
3663
4107
|
|
|
@@ -4186,7 +4630,6 @@ function composeStellarStateService(adapter) {
|
|
|
4186
4630
|
...createWalletAddressService(base),
|
|
4187
4631
|
...createPoolMerkleService(base),
|
|
4188
4632
|
...createPoolEphemeralService(base),
|
|
4189
|
-
...createClaimsService(base),
|
|
4190
4633
|
...createDeliveriesService(base),
|
|
4191
4634
|
...createRecordsService(base)
|
|
4192
4635
|
};
|
|
@@ -4251,42 +4694,1030 @@ function attachPoolStatePorts(transactEnvironment, state) {
|
|
|
4251
4694
|
resolveSenderPrivKeyScalarFromState: createSenderScalarStateResolver(state)
|
|
4252
4695
|
};
|
|
4253
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
|
+
}
|
|
4254
5642
|
export {
|
|
5643
|
+
BundledZkCircuit2 as BundledZkCircuit,
|
|
5644
|
+
COMMITMENT_V2_ZK_NONCE,
|
|
4255
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,
|
|
4256
5650
|
KytInspectError,
|
|
4257
5651
|
MIN_CONFIDENTIAL_TRANSFER_STROOPS,
|
|
5652
|
+
OWNER_BOUND_NOTE_SCHEMA_VERSION,
|
|
4258
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,
|
|
4259
5674
|
ZERO_STROOPS,
|
|
5675
|
+
assertEscrowSweepClaimant,
|
|
4260
5676
|
assetLegToTokenAddress,
|
|
5677
|
+
attachEscrowAuthorization,
|
|
4261
5678
|
attachPoolStatePorts,
|
|
4262
|
-
|
|
5679
|
+
buildBlindedRecipientTagChallengeMessage,
|
|
4263
5680
|
buildPoolTransactionAuditParameters,
|
|
4264
5681
|
buildPrivateAddressSignMessage,
|
|
4265
|
-
buildTransferOnboardingAtExecute,
|
|
4266
5682
|
configurePrivacyPoolService,
|
|
4267
5683
|
createPrivacyPoolService,
|
|
4268
5684
|
decodePrivateAddress,
|
|
5685
|
+
deriveEscrowRecipientFromStellarAddress,
|
|
4269
5686
|
encodePrivateAddress,
|
|
4270
5687
|
encodePrivateAddressFromHexCoordinates,
|
|
5688
|
+
evaluateRequiredSubmissionMethod,
|
|
4271
5689
|
fetchAndMergeMerkleState,
|
|
5690
|
+
fetchEscrowOutputNoteEvents,
|
|
5691
|
+
finalizeSpendOperationAtExecute,
|
|
4272
5692
|
frDecimalToPaddedBytes32,
|
|
4273
5693
|
generateRandomDepositScalarHex,
|
|
4274
5694
|
generateTemporaryRecipientPrivateAddress,
|
|
4275
5695
|
getPrivacyPoolService,
|
|
5696
|
+
isEscrowPreparedOperation,
|
|
4276
5697
|
loadDefaultStellarBrowserAssets,
|
|
4277
5698
|
loadStellarBrowserAssets,
|
|
5699
|
+
optionalZkArtifactBaseUrl,
|
|
4278
5700
|
parseAuditPublicKeyFromEnvHex,
|
|
4279
5701
|
parseKytReasonCode,
|
|
4280
5702
|
prepareConfidentialTransferProof,
|
|
4281
5703
|
prepareConfidentialTransferProofDual,
|
|
5704
|
+
prepareEscrowSweepOperation,
|
|
5705
|
+
prepareRelayTransactPackage,
|
|
5706
|
+
prepareRelayTransactPackageFromPrepared,
|
|
4282
5707
|
privateAddressSdk,
|
|
4283
5708
|
readLeafEphemeralHex,
|
|
5709
|
+
readRelayTransactSupportedProfile,
|
|
4284
5710
|
recipientPublicKeysDecimalFromPrivateAddress,
|
|
5711
|
+
reconstructEscrowNote,
|
|
4285
5712
|
requestKytPassageForPoolInteraction,
|
|
5713
|
+
requiredSubmissionMethod,
|
|
4286
5714
|
resolvePoolApplicationId,
|
|
5715
|
+
resolveZkConfigNonce,
|
|
4287
5716
|
runTtlPreflight,
|
|
5717
|
+
spendScalarHexFromStellarSignature,
|
|
4288
5718
|
submitSorobanConfidentialTransfer,
|
|
4289
5719
|
submitSorobanDeposit,
|
|
4290
|
-
tokenAddressToAssetLeg
|
|
5720
|
+
tokenAddressToAssetLeg,
|
|
5721
|
+
unsignedEscrowAuthorizationForSweep
|
|
4291
5722
|
};
|
|
4292
5723
|
//# sourceMappingURL=index.js.map
|