@atumlabs/payment-gateway-client 2.2.0 → 3.0.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/CHANGELOG.md +108 -0
- package/LICENSE +202 -83
- package/NOTICE +2 -0
- package/README.md +547 -46
- package/THIRD-PARTY-NOTICES.txt +7 -1
- package/dist/cli/approve-permit2.d.ts +1 -0
- package/dist/cli/approve-permit2.js +7325 -0
- package/dist/cli/payment-status.js +2307 -261
- package/dist/cli/quote-status.js +2305 -259
- package/dist/cli/request-quote.js +2333 -266
- package/dist/cli/send-payment.js +3079 -360
- package/dist/index.d.ts +926 -1701
- package/dist/index.js +3470 -492
- package/dist/sender-auth-verify-C-Q-zvAO.d.ts +2013 -0
- package/dist/signing.d.ts +223 -0
- package/dist/signing.js +7219 -0
- package/docs/idempotency.md +97 -40
- package/docs/signing.md +218 -0
- package/package.json +48 -14
- package/signing.d.ts +2 -0
- package/signing.js +11 -0
package/dist/cli/send-payment.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/*
|
|
3
|
-
* Copyright
|
|
4
|
-
*
|
|
5
|
-
* Access and use are governed by the LICENSE file distributed with this package.
|
|
6
|
-
* Do not remove, alter, or obscure this notice.
|
|
3
|
+
* Copyright 2026 Atum Labs, Inc.
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
7
5
|
*/
|
|
8
6
|
"use strict";
|
|
9
7
|
var __create = Object.create;
|
|
@@ -12,11 +10,20 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
12
10
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
11
|
var __getProtoOf = Object.getPrototypeOf;
|
|
14
12
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
15
|
-
var __esm = (fn, res) => function __init() {
|
|
16
|
-
|
|
13
|
+
var __esm = (fn, res, err) => function __init() {
|
|
14
|
+
if (err) throw err[0];
|
|
15
|
+
try {
|
|
16
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
17
|
+
} catch (e) {
|
|
18
|
+
throw err = [e], e;
|
|
19
|
+
}
|
|
17
20
|
};
|
|
18
21
|
var __commonJS = (cb, mod) => function __require() {
|
|
19
|
-
|
|
22
|
+
try {
|
|
23
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
24
|
+
} catch (e) {
|
|
25
|
+
throw mod = 0, e;
|
|
26
|
+
}
|
|
20
27
|
};
|
|
21
28
|
var __export = (target, all) => {
|
|
22
29
|
for (var name in all)
|
|
@@ -89,7 +96,7 @@ var require_tron_address = __commonJS({
|
|
|
89
96
|
hexAddress = base58ToHex2(address);
|
|
90
97
|
}
|
|
91
98
|
hexAddress = hexAddress.replace(/^0x/, "");
|
|
92
|
-
if (hexAddress.startsWith(TVM_MAINNET_PREFIX)) {
|
|
99
|
+
if (hexAddress.length === 42 && hexAddress.startsWith(TVM_MAINNET_PREFIX)) {
|
|
93
100
|
hexAddress = hexAddress.substring(2);
|
|
94
101
|
}
|
|
95
102
|
if (hexAddress.length !== 40) {
|
|
@@ -103,14 +110,62 @@ var require_tron_address = __commonJS({
|
|
|
103
110
|
}
|
|
104
111
|
});
|
|
105
112
|
|
|
113
|
+
// ../contracts/tvm/escrow-encoding/typescript/dist/witness-values.js
|
|
114
|
+
var require_witness_values = __commonJS({
|
|
115
|
+
"../contracts/tvm/escrow-encoding/typescript/dist/witness-values.js"(exports2) {
|
|
116
|
+
"use strict";
|
|
117
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
118
|
+
exports2.normalizeBytes32 = normalizeBytes32;
|
|
119
|
+
exports2.normalizeUint256 = normalizeUint256;
|
|
120
|
+
exports2.maskedChainIdToHex = maskedChainIdToHex;
|
|
121
|
+
var ethers_1 = require("ethers");
|
|
122
|
+
var chain_id_1 = require_chain_id();
|
|
123
|
+
function normalizeBytes32(label, value) {
|
|
124
|
+
let bytes;
|
|
125
|
+
try {
|
|
126
|
+
bytes = (0, ethers_1.getBytes)(value);
|
|
127
|
+
} catch {
|
|
128
|
+
throw new Error(`${label} must be 0x-prefixed hex (32 bytes), got ${JSON.stringify(value)}`);
|
|
129
|
+
}
|
|
130
|
+
if (bytes.length !== 32) {
|
|
131
|
+
throw new Error(`${label} must be exactly 32 bytes, got ${bytes.length}`);
|
|
132
|
+
}
|
|
133
|
+
return (0, ethers_1.hexlify)(bytes);
|
|
134
|
+
}
|
|
135
|
+
function normalizeUint256(label, value) {
|
|
136
|
+
let n;
|
|
137
|
+
try {
|
|
138
|
+
n = BigInt(value);
|
|
139
|
+
} catch {
|
|
140
|
+
throw new Error(`${label} must be an integer (bigint or decimal string), got ${JSON.stringify(value)}`);
|
|
141
|
+
}
|
|
142
|
+
if (n < 0n) {
|
|
143
|
+
throw new Error(`${label} must be non-negative (uint256), got ${n.toString()}`);
|
|
144
|
+
}
|
|
145
|
+
return n.toString();
|
|
146
|
+
}
|
|
147
|
+
function maskedChainIdToHex(chainId) {
|
|
148
|
+
if (!Number.isSafeInteger(chainId) || chainId < 0) {
|
|
149
|
+
throw new Error(`chainId must be a non-negative safe integer, got ${chainId}`);
|
|
150
|
+
}
|
|
151
|
+
return `0x${(0, chain_id_1.maskChainId)(chainId).toString(16)}`;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
106
156
|
// ../contracts/tvm/escrow-encoding/typescript/dist/reserve-encoder.js
|
|
107
157
|
var require_reserve_encoder = __commonJS({
|
|
108
158
|
"../contracts/tvm/escrow-encoding/typescript/dist/reserve-encoder.js"(exports2) {
|
|
109
159
|
"use strict";
|
|
110
160
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
161
|
+
exports2.RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE = void 0;
|
|
111
162
|
exports2.computeReserveDigest = computeReserveDigest;
|
|
163
|
+
exports2.buildTvmReserveTypedDataWithQuoteSource = buildTvmReserveTypedDataWithQuoteSource;
|
|
164
|
+
exports2.computeTvmReserveDigestWithQuoteSource = computeTvmReserveDigestWithQuoteSource;
|
|
112
165
|
var ethers_1 = require("ethers");
|
|
113
166
|
var chain_id_1 = require_chain_id();
|
|
167
|
+
var tron_address_1 = require_tron_address();
|
|
168
|
+
var witness_values_1 = require_witness_values();
|
|
114
169
|
var RESERVE_WITNESS_TYPES = {
|
|
115
170
|
ReserveWitness: [
|
|
116
171
|
{ name: "paymentId", type: "bytes32" },
|
|
@@ -129,6 +184,36 @@ var require_reserve_encoder = __commonJS({
|
|
|
129
184
|
settler: input.settler
|
|
130
185
|
});
|
|
131
186
|
}
|
|
187
|
+
exports2.RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE = {
|
|
188
|
+
ReserveWitness: [
|
|
189
|
+
{ name: "depositId", type: "bytes32" },
|
|
190
|
+
{ name: "quoteHash", type: "bytes32" },
|
|
191
|
+
{ name: "settler", type: "address" },
|
|
192
|
+
{ name: "sourceAmount", type: "uint256" }
|
|
193
|
+
]
|
|
194
|
+
};
|
|
195
|
+
function buildTvmReserveTypedDataWithQuoteSource(input) {
|
|
196
|
+
return {
|
|
197
|
+
types: exports2.RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE,
|
|
198
|
+
primaryType: "ReserveWitness",
|
|
199
|
+
domain: {
|
|
200
|
+
name: "Escrow",
|
|
201
|
+
version: "3",
|
|
202
|
+
chainId: (0, witness_values_1.maskedChainIdToHex)(input.chainId),
|
|
203
|
+
verifyingContract: (0, tron_address_1.normalizeAddress)(input.escrowContract)
|
|
204
|
+
},
|
|
205
|
+
message: {
|
|
206
|
+
depositId: (0, witness_values_1.normalizeBytes32)("depositId", input.depositId),
|
|
207
|
+
quoteHash: (0, witness_values_1.normalizeBytes32)("quoteHash", input.quoteHash),
|
|
208
|
+
settler: (0, tron_address_1.normalizeAddress)(input.settler),
|
|
209
|
+
sourceAmount: (0, witness_values_1.normalizeUint256)("sourceAmount", input.sourceAmount)
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
function computeTvmReserveDigestWithQuoteSource(input) {
|
|
214
|
+
const prehash = buildTvmReserveTypedDataWithQuoteSource(input);
|
|
215
|
+
return ethers_1.TypedDataEncoder.hash(prehash.domain, prehash.types, prehash.message);
|
|
216
|
+
}
|
|
132
217
|
}
|
|
133
218
|
});
|
|
134
219
|
|
|
@@ -155,11 +240,14 @@ var require_deposit_encoder = __commonJS({
|
|
|
155
240
|
"../contracts/tvm/escrow-encoding/typescript/dist/deposit-encoder.js"(exports2) {
|
|
156
241
|
"use strict";
|
|
157
242
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
243
|
+
exports2.MAX_DESTINATION_BYTES = exports2.PERMIT_WITNESS_TYPES_WITH_DESTINATION = void 0;
|
|
158
244
|
exports2.createTvmPermitWitnessTransferFromPrehash = createTvmPermitWitnessTransferFromPrehash2;
|
|
159
245
|
exports2.hashTvmPermitWitnessTransferFrom = hashTvmPermitWitnessTransferFrom2;
|
|
246
|
+
exports2.createTvmPermitWitnessTransferFromPrehashWithDestination = createTvmPermitWitnessTransferFromPrehashWithDestination;
|
|
160
247
|
var ethers_1 = require("ethers");
|
|
161
248
|
var chain_id_1 = require_chain_id();
|
|
162
249
|
var tron_address_1 = require_tron_address();
|
|
250
|
+
var witness_values_1 = require_witness_values();
|
|
163
251
|
var PERMIT_WITNESS_TYPES_V2 = {
|
|
164
252
|
PermitWitnessTransferFrom: [
|
|
165
253
|
{ name: "permitted", type: "TokenPermissions" },
|
|
@@ -205,6 +293,180 @@ var require_deposit_encoder = __commonJS({
|
|
|
205
293
|
function hashTvmPermitWitnessTransferFrom2(prehash) {
|
|
206
294
|
return ethers_1.TypedDataEncoder.hash(prehash.domain, prehash.types, prehash.message);
|
|
207
295
|
}
|
|
296
|
+
exports2.PERMIT_WITNESS_TYPES_WITH_DESTINATION = {
|
|
297
|
+
PermitWitnessTransferFrom: [
|
|
298
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
299
|
+
{ name: "spender", type: "address" },
|
|
300
|
+
{ name: "nonce", type: "uint256" },
|
|
301
|
+
{ name: "deadline", type: "uint256" },
|
|
302
|
+
{ name: "witness", type: "DepositWitness" }
|
|
303
|
+
],
|
|
304
|
+
TokenPermissions: [
|
|
305
|
+
{ name: "token", type: "address" },
|
|
306
|
+
{ name: "amount", type: "uint256" }
|
|
307
|
+
],
|
|
308
|
+
DepositWitness: [
|
|
309
|
+
{ name: "depositRequestHash", type: "bytes32" },
|
|
310
|
+
{ name: "destination", type: "string" },
|
|
311
|
+
{ name: "reserver", type: "address" },
|
|
312
|
+
{ name: "releaser", type: "address" }
|
|
313
|
+
]
|
|
314
|
+
};
|
|
315
|
+
exports2.MAX_DESTINATION_BYTES = 256;
|
|
316
|
+
function assertDestinationWithinBounds(destination) {
|
|
317
|
+
if (destination === "") {
|
|
318
|
+
throw new Error('destination is empty: the escrow reverts DestinationCannotBeEmpty, and because keccak256("") is a valid bytes32 this would otherwise sign a commitment to no destination at all');
|
|
319
|
+
}
|
|
320
|
+
const byteLength = (0, ethers_1.toUtf8Bytes)(destination).length;
|
|
321
|
+
if (byteLength > exports2.MAX_DESTINATION_BYTES) {
|
|
322
|
+
throw new Error(`destination is ${byteLength} bytes, over the escrow's MAX_DESTINATION_BYTES of ${exports2.MAX_DESTINATION_BYTES}: the contract reverts DestinationTooLong, so this digest could never be redeemed`);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function createTvmPermitWitnessTransferFromPrehashWithDestination(params) {
|
|
326
|
+
assertDestinationWithinBounds(params.destination);
|
|
327
|
+
return {
|
|
328
|
+
types: exports2.PERMIT_WITNESS_TYPES_WITH_DESTINATION,
|
|
329
|
+
primaryType: "PermitWitnessTransferFrom",
|
|
330
|
+
domain: {
|
|
331
|
+
name: "Permit2",
|
|
332
|
+
chainId: (0, witness_values_1.maskedChainIdToHex)(params.chainId),
|
|
333
|
+
verifyingContract: (0, tron_address_1.normalizeAddress)(params.permit2Address)
|
|
334
|
+
},
|
|
335
|
+
message: {
|
|
336
|
+
permitted: {
|
|
337
|
+
token: (0, tron_address_1.normalizeAddress)(params.tokenAddress),
|
|
338
|
+
amount: (0, witness_values_1.normalizeUint256)("amount", params.amount)
|
|
339
|
+
},
|
|
340
|
+
spender: (0, tron_address_1.normalizeAddress)(params.spenderAddress),
|
|
341
|
+
nonce: (0, witness_values_1.normalizeUint256)("nonce", params.nonce),
|
|
342
|
+
deadline: (0, witness_values_1.normalizeUint256)("deadline", params.deadline),
|
|
343
|
+
witness: {
|
|
344
|
+
depositRequestHash: (0, witness_values_1.normalizeBytes32)("depositRequestHash", params.depositRequestHash),
|
|
345
|
+
destination: params.destination,
|
|
346
|
+
reserver: (0, tron_address_1.normalizeAddress)(params.reserverAddress),
|
|
347
|
+
releaser: (0, tron_address_1.normalizeAddress)(params.releaserAddress)
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// ../contracts/tvm/escrow-encoding/typescript/dist/release-encoder.js
|
|
356
|
+
var require_release_encoder = __commonJS({
|
|
357
|
+
"../contracts/tvm/escrow-encoding/typescript/dist/release-encoder.js"(exports2) {
|
|
358
|
+
"use strict";
|
|
359
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
360
|
+
exports2.RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH = void 0;
|
|
361
|
+
exports2.buildTvmReleaseTypedDataWithQuoteHash = buildTvmReleaseTypedDataWithQuoteHash;
|
|
362
|
+
exports2.computeTvmReleaseDigestWithQuoteHash = computeTvmReleaseDigestWithQuoteHash;
|
|
363
|
+
var ethers_1 = require("ethers");
|
|
364
|
+
var tron_address_1 = require_tron_address();
|
|
365
|
+
var witness_values_1 = require_witness_values();
|
|
366
|
+
exports2.RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH = {
|
|
367
|
+
ReleaseWitness: [
|
|
368
|
+
{ name: "depositId", type: "bytes32" },
|
|
369
|
+
{ name: "quoteHash", type: "bytes32" },
|
|
370
|
+
{ name: "depositRequestHash", type: "bytes32" },
|
|
371
|
+
{ name: "destinationHash", type: "bytes32" },
|
|
372
|
+
{ name: "depositor", type: "address" },
|
|
373
|
+
{ name: "token", type: "address" },
|
|
374
|
+
{ name: "amount", type: "uint256" },
|
|
375
|
+
{ name: "feeAmount", type: "uint256" },
|
|
376
|
+
{ name: "reserver", type: "address" },
|
|
377
|
+
{ name: "releaser", type: "address" },
|
|
378
|
+
{ name: "settler", type: "address" }
|
|
379
|
+
]
|
|
380
|
+
};
|
|
381
|
+
function buildTvmReleaseTypedDataWithQuoteHash(input) {
|
|
382
|
+
const w = input.witness;
|
|
383
|
+
return {
|
|
384
|
+
types: exports2.RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH,
|
|
385
|
+
primaryType: "ReleaseWitness",
|
|
386
|
+
domain: {
|
|
387
|
+
name: "Escrow",
|
|
388
|
+
version: "3",
|
|
389
|
+
chainId: (0, witness_values_1.maskedChainIdToHex)(input.chainId),
|
|
390
|
+
verifyingContract: (0, tron_address_1.normalizeAddress)(input.escrowContract)
|
|
391
|
+
},
|
|
392
|
+
message: {
|
|
393
|
+
depositId: (0, witness_values_1.normalizeBytes32)("depositId", w.depositId),
|
|
394
|
+
quoteHash: (0, witness_values_1.normalizeBytes32)("quoteHash", w.quoteHash),
|
|
395
|
+
depositRequestHash: (0, witness_values_1.normalizeBytes32)("depositRequestHash", w.depositRequestHash),
|
|
396
|
+
destinationHash: (0, witness_values_1.normalizeBytes32)("destinationHash", w.destinationHash),
|
|
397
|
+
depositor: (0, tron_address_1.normalizeAddress)(w.depositor),
|
|
398
|
+
token: (0, tron_address_1.normalizeAddress)(w.token),
|
|
399
|
+
amount: (0, witness_values_1.normalizeUint256)("amount", w.amount),
|
|
400
|
+
feeAmount: (0, witness_values_1.normalizeUint256)("feeAmount", w.feeAmount),
|
|
401
|
+
reserver: (0, tron_address_1.normalizeAddress)(w.reserver),
|
|
402
|
+
releaser: (0, tron_address_1.normalizeAddress)(w.releaser),
|
|
403
|
+
settler: (0, tron_address_1.normalizeAddress)(w.settler)
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
function computeTvmReleaseDigestWithQuoteHash(input) {
|
|
408
|
+
const prehash = buildTvmReleaseTypedDataWithQuoteHash(input);
|
|
409
|
+
return ethers_1.TypedDataEncoder.hash(prehash.domain, prehash.types, prehash.message);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
// ../contracts/tvm/escrow-encoding/typescript/dist/refund-encoder.js
|
|
415
|
+
var require_refund_encoder = __commonJS({
|
|
416
|
+
"../contracts/tvm/escrow-encoding/typescript/dist/refund-encoder.js"(exports2) {
|
|
417
|
+
"use strict";
|
|
418
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
419
|
+
exports2.REFUND_WITNESS_TYPES_WITH_QUOTE_HASH = void 0;
|
|
420
|
+
exports2.buildTvmRefundTypedDataWithQuoteHash = buildTvmRefundTypedDataWithQuoteHash;
|
|
421
|
+
exports2.computeTvmRefundDigestWithQuoteHash = computeTvmRefundDigestWithQuoteHash;
|
|
422
|
+
var ethers_1 = require("ethers");
|
|
423
|
+
var tron_address_1 = require_tron_address();
|
|
424
|
+
var witness_values_1 = require_witness_values();
|
|
425
|
+
exports2.REFUND_WITNESS_TYPES_WITH_QUOTE_HASH = {
|
|
426
|
+
RefundWitness: [
|
|
427
|
+
{ name: "depositId", type: "bytes32" },
|
|
428
|
+
{ name: "quoteHash", type: "bytes32" },
|
|
429
|
+
{ name: "depositRequestHash", type: "bytes32" },
|
|
430
|
+
{ name: "destinationHash", type: "bytes32" },
|
|
431
|
+
{ name: "depositor", type: "address" },
|
|
432
|
+
{ name: "token", type: "address" },
|
|
433
|
+
{ name: "amount", type: "uint256" },
|
|
434
|
+
{ name: "feeAmount", type: "uint256" },
|
|
435
|
+
{ name: "reserver", type: "address" },
|
|
436
|
+
{ name: "releaser", type: "address" },
|
|
437
|
+
{ name: "settler", type: "address" }
|
|
438
|
+
]
|
|
439
|
+
};
|
|
440
|
+
function buildTvmRefundTypedDataWithQuoteHash(input) {
|
|
441
|
+
const w = input.witness;
|
|
442
|
+
return {
|
|
443
|
+
types: exports2.REFUND_WITNESS_TYPES_WITH_QUOTE_HASH,
|
|
444
|
+
primaryType: "RefundWitness",
|
|
445
|
+
domain: {
|
|
446
|
+
name: "Escrow",
|
|
447
|
+
version: "3",
|
|
448
|
+
chainId: (0, witness_values_1.maskedChainIdToHex)(input.chainId),
|
|
449
|
+
verifyingContract: (0, tron_address_1.normalizeAddress)(input.escrowContract)
|
|
450
|
+
},
|
|
451
|
+
message: {
|
|
452
|
+
depositId: (0, witness_values_1.normalizeBytes32)("depositId", w.depositId),
|
|
453
|
+
quoteHash: (0, witness_values_1.normalizeBytes32)("quoteHash", w.quoteHash),
|
|
454
|
+
depositRequestHash: (0, witness_values_1.normalizeBytes32)("depositRequestHash", w.depositRequestHash),
|
|
455
|
+
destinationHash: (0, witness_values_1.normalizeBytes32)("destinationHash", w.destinationHash),
|
|
456
|
+
depositor: (0, tron_address_1.normalizeAddress)(w.depositor),
|
|
457
|
+
token: (0, tron_address_1.normalizeAddress)(w.token),
|
|
458
|
+
amount: (0, witness_values_1.normalizeUint256)("amount", w.amount),
|
|
459
|
+
feeAmount: (0, witness_values_1.normalizeUint256)("feeAmount", w.feeAmount),
|
|
460
|
+
reserver: (0, tron_address_1.normalizeAddress)(w.reserver),
|
|
461
|
+
releaser: (0, tron_address_1.normalizeAddress)(w.releaser),
|
|
462
|
+
settler: (0, tron_address_1.normalizeAddress)(w.settler)
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
function computeTvmRefundDigestWithQuoteHash(input) {
|
|
467
|
+
const prehash = buildTvmRefundTypedDataWithQuoteHash(input);
|
|
468
|
+
return ethers_1.TypedDataEncoder.hash(prehash.domain, prehash.types, prehash.message);
|
|
469
|
+
}
|
|
208
470
|
}
|
|
209
471
|
});
|
|
210
472
|
|
|
@@ -213,7 +475,7 @@ var require_dist = __commonJS({
|
|
|
213
475
|
"../contracts/tvm/escrow-encoding/typescript/dist/index.js"(exports2) {
|
|
214
476
|
"use strict";
|
|
215
477
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
216
|
-
exports2.hashTvmPermitWitnessTransferFrom = exports2.createTvmPermitWitnessTransferFromPrehash = exports2.computePaymentId = exports2.computeReserveDigest = exports2.normalizeAddress = exports2.base58ToHex = exports2.maskChainId = void 0;
|
|
478
|
+
exports2.MAX_DESTINATION_BYTES = exports2.createTvmPermitWitnessTransferFromPrehashWithDestination = exports2.PERMIT_WITNESS_TYPES_WITH_DESTINATION = exports2.computeTvmRefundDigestWithQuoteHash = exports2.buildTvmRefundTypedDataWithQuoteHash = exports2.REFUND_WITNESS_TYPES_WITH_QUOTE_HASH = exports2.computeTvmReleaseDigestWithQuoteHash = exports2.buildTvmReleaseTypedDataWithQuoteHash = exports2.RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH = exports2.computeTvmReserveDigestWithQuoteSource = exports2.buildTvmReserveTypedDataWithQuoteSource = exports2.RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE = exports2.hashTvmPermitWitnessTransferFrom = exports2.createTvmPermitWitnessTransferFromPrehash = exports2.computePaymentId = exports2.computeReserveDigest = exports2.normalizeAddress = exports2.base58ToHex = exports2.maskChainId = void 0;
|
|
217
479
|
var chain_id_1 = require_chain_id();
|
|
218
480
|
Object.defineProperty(exports2, "maskChainId", { enumerable: true, get: function() {
|
|
219
481
|
return chain_id_1.maskChainId;
|
|
@@ -240,6 +502,222 @@ var require_dist = __commonJS({
|
|
|
240
502
|
Object.defineProperty(exports2, "hashTvmPermitWitnessTransferFrom", { enumerable: true, get: function() {
|
|
241
503
|
return deposit_encoder_1.hashTvmPermitWitnessTransferFrom;
|
|
242
504
|
} });
|
|
505
|
+
var reserve_encoder_2 = require_reserve_encoder();
|
|
506
|
+
Object.defineProperty(exports2, "RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE", { enumerable: true, get: function() {
|
|
507
|
+
return reserve_encoder_2.RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE;
|
|
508
|
+
} });
|
|
509
|
+
Object.defineProperty(exports2, "buildTvmReserveTypedDataWithQuoteSource", { enumerable: true, get: function() {
|
|
510
|
+
return reserve_encoder_2.buildTvmReserveTypedDataWithQuoteSource;
|
|
511
|
+
} });
|
|
512
|
+
Object.defineProperty(exports2, "computeTvmReserveDigestWithQuoteSource", { enumerable: true, get: function() {
|
|
513
|
+
return reserve_encoder_2.computeTvmReserveDigestWithQuoteSource;
|
|
514
|
+
} });
|
|
515
|
+
var release_encoder_1 = require_release_encoder();
|
|
516
|
+
Object.defineProperty(exports2, "RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH", { enumerable: true, get: function() {
|
|
517
|
+
return release_encoder_1.RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH;
|
|
518
|
+
} });
|
|
519
|
+
Object.defineProperty(exports2, "buildTvmReleaseTypedDataWithQuoteHash", { enumerable: true, get: function() {
|
|
520
|
+
return release_encoder_1.buildTvmReleaseTypedDataWithQuoteHash;
|
|
521
|
+
} });
|
|
522
|
+
Object.defineProperty(exports2, "computeTvmReleaseDigestWithQuoteHash", { enumerable: true, get: function() {
|
|
523
|
+
return release_encoder_1.computeTvmReleaseDigestWithQuoteHash;
|
|
524
|
+
} });
|
|
525
|
+
var refund_encoder_1 = require_refund_encoder();
|
|
526
|
+
Object.defineProperty(exports2, "REFUND_WITNESS_TYPES_WITH_QUOTE_HASH", { enumerable: true, get: function() {
|
|
527
|
+
return refund_encoder_1.REFUND_WITNESS_TYPES_WITH_QUOTE_HASH;
|
|
528
|
+
} });
|
|
529
|
+
Object.defineProperty(exports2, "buildTvmRefundTypedDataWithQuoteHash", { enumerable: true, get: function() {
|
|
530
|
+
return refund_encoder_1.buildTvmRefundTypedDataWithQuoteHash;
|
|
531
|
+
} });
|
|
532
|
+
Object.defineProperty(exports2, "computeTvmRefundDigestWithQuoteHash", { enumerable: true, get: function() {
|
|
533
|
+
return refund_encoder_1.computeTvmRefundDigestWithQuoteHash;
|
|
534
|
+
} });
|
|
535
|
+
var deposit_encoder_2 = require_deposit_encoder();
|
|
536
|
+
Object.defineProperty(exports2, "PERMIT_WITNESS_TYPES_WITH_DESTINATION", { enumerable: true, get: function() {
|
|
537
|
+
return deposit_encoder_2.PERMIT_WITNESS_TYPES_WITH_DESTINATION;
|
|
538
|
+
} });
|
|
539
|
+
Object.defineProperty(exports2, "createTvmPermitWitnessTransferFromPrehashWithDestination", { enumerable: true, get: function() {
|
|
540
|
+
return deposit_encoder_2.createTvmPermitWitnessTransferFromPrehashWithDestination;
|
|
541
|
+
} });
|
|
542
|
+
Object.defineProperty(exports2, "MAX_DESTINATION_BYTES", { enumerable: true, get: function() {
|
|
543
|
+
return deposit_encoder_2.MAX_DESTINATION_BYTES;
|
|
544
|
+
} });
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
// ../schemas/declarations/common/chain-address/typescript/dist/index.js
|
|
549
|
+
var require_dist2 = __commonJS({
|
|
550
|
+
"../schemas/declarations/common/chain-address/typescript/dist/index.js"(exports2) {
|
|
551
|
+
"use strict";
|
|
552
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
553
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
554
|
+
};
|
|
555
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
556
|
+
exports2.InvalidAccountError = exports2.REASONS = exports2.NAMESPACE_SOLANA = exports2.NAMESPACE_TRON = exports2.NAMESPACE_EIP155 = void 0;
|
|
557
|
+
exports2.supportedNamespaces = supportedNamespaces;
|
|
558
|
+
exports2.parse = parse;
|
|
559
|
+
exports2.validate = validate;
|
|
560
|
+
exports2.checkAccount = checkAccount;
|
|
561
|
+
var bs58_1 = __importDefault(require("bs58"));
|
|
562
|
+
var ethers_1 = require("ethers");
|
|
563
|
+
var tvm_escrow_encoding_1 = require_dist();
|
|
564
|
+
exports2.NAMESPACE_EIP155 = "eip155";
|
|
565
|
+
exports2.NAMESPACE_TRON = "tron";
|
|
566
|
+
exports2.NAMESPACE_SOLANA = "solana";
|
|
567
|
+
exports2.REASONS = [
|
|
568
|
+
"EMPTY",
|
|
569
|
+
"SURROUNDING_WHITESPACE",
|
|
570
|
+
"UNSUPPORTED_NAMESPACE",
|
|
571
|
+
"UNPARSEABLE",
|
|
572
|
+
"ZERO"
|
|
573
|
+
];
|
|
574
|
+
var InvalidAccountError2 = class extends Error {
|
|
575
|
+
reason;
|
|
576
|
+
network;
|
|
577
|
+
account;
|
|
578
|
+
detail;
|
|
579
|
+
constructor(reason, network, account, detail = "") {
|
|
580
|
+
super(messageFor(reason, network, detail));
|
|
581
|
+
this.name = "InvalidAccountError";
|
|
582
|
+
this.reason = reason;
|
|
583
|
+
this.network = network;
|
|
584
|
+
this.account = account;
|
|
585
|
+
this.detail = detail;
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
exports2.InvalidAccountError = InvalidAccountError2;
|
|
589
|
+
function messageFor(reason, network, detail) {
|
|
590
|
+
switch (reason) {
|
|
591
|
+
case "EMPTY":
|
|
592
|
+
return "account is required and cannot be empty";
|
|
593
|
+
case "SURROUNDING_WHITESPACE":
|
|
594
|
+
return "account must not contain leading or trailing whitespace";
|
|
595
|
+
case "UNSUPPORTED_NAMESPACE":
|
|
596
|
+
return `no address rules are known for chain ${network}`;
|
|
597
|
+
case "ZERO":
|
|
598
|
+
return `account is the zero address on ${network}, which cannot receive a payout`;
|
|
599
|
+
default:
|
|
600
|
+
return `account is not a valid address for ${network}`;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
function supportedNamespaces() {
|
|
604
|
+
return [exports2.NAMESPACE_EIP155, exports2.NAMESPACE_SOLANA, exports2.NAMESPACE_TRON];
|
|
605
|
+
}
|
|
606
|
+
function trimSurrounding(value) {
|
|
607
|
+
return value.replace(/^[\s\u0085]+|[\s\u0085]+$/gu, "");
|
|
608
|
+
}
|
|
609
|
+
function parse(network, account) {
|
|
610
|
+
if (trimSurrounding(account) === "") {
|
|
611
|
+
throw new InvalidAccountError2("EMPTY", network, account);
|
|
612
|
+
}
|
|
613
|
+
if (account !== trimSurrounding(account)) {
|
|
614
|
+
throw new InvalidAccountError2("SURROUNDING_WHITESPACE", network, account);
|
|
615
|
+
}
|
|
616
|
+
const separator = network.indexOf(":");
|
|
617
|
+
if (separator <= 0) {
|
|
618
|
+
throw new InvalidAccountError2("UNSUPPORTED_NAMESPACE", network, account);
|
|
619
|
+
}
|
|
620
|
+
const namespace = network.slice(0, separator);
|
|
621
|
+
let bytes;
|
|
622
|
+
try {
|
|
623
|
+
switch (namespace) {
|
|
624
|
+
case exports2.NAMESPACE_EIP155:
|
|
625
|
+
bytes = parseEvm(account);
|
|
626
|
+
break;
|
|
627
|
+
case exports2.NAMESPACE_TRON:
|
|
628
|
+
bytes = parseTron(account);
|
|
629
|
+
break;
|
|
630
|
+
case exports2.NAMESPACE_SOLANA:
|
|
631
|
+
bytes = parseSolana(account);
|
|
632
|
+
break;
|
|
633
|
+
default:
|
|
634
|
+
throw new InvalidAccountError2("UNSUPPORTED_NAMESPACE", network, account);
|
|
635
|
+
}
|
|
636
|
+
} catch (error) {
|
|
637
|
+
if (error instanceof InvalidAccountError2)
|
|
638
|
+
throw error;
|
|
639
|
+
throw new InvalidAccountError2("UNPARSEABLE", network, account, error.message);
|
|
640
|
+
}
|
|
641
|
+
return { namespace, bytes };
|
|
642
|
+
}
|
|
643
|
+
function validate(network, account) {
|
|
644
|
+
const parsed = parse(network, account);
|
|
645
|
+
if (isZero(parsed.bytes)) {
|
|
646
|
+
throw new InvalidAccountError2("ZERO", network, account);
|
|
647
|
+
}
|
|
648
|
+
return parsed;
|
|
649
|
+
}
|
|
650
|
+
function checkAccount(network, account) {
|
|
651
|
+
try {
|
|
652
|
+
validate(network, account);
|
|
653
|
+
return null;
|
|
654
|
+
} catch (error) {
|
|
655
|
+
if (error instanceof InvalidAccountError2)
|
|
656
|
+
return error;
|
|
657
|
+
throw error;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
function isZero(bytes) {
|
|
661
|
+
return bytes.length > 0 && bytes.every((one) => one === 0);
|
|
662
|
+
}
|
|
663
|
+
var HEX_40 = /^(0[xX])?[0-9a-fA-F]{40}$/;
|
|
664
|
+
function parseEvm(account) {
|
|
665
|
+
if (!HEX_40.test(account)) {
|
|
666
|
+
throw new Error("expected 40 hex characters, optionally 0x-prefixed");
|
|
667
|
+
}
|
|
668
|
+
const body = account.replace(/^0[xX]/, "");
|
|
669
|
+
const lower = body.toLowerCase();
|
|
670
|
+
if (body !== lower && body !== body.toUpperCase()) {
|
|
671
|
+
if ((0, ethers_1.getAddress)(`0x${lower}`) !== account) {
|
|
672
|
+
throw new Error("mixed-case address fails its EIP-55 checksum");
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
return hexToBytes2(lower);
|
|
676
|
+
}
|
|
677
|
+
function parseTron(account) {
|
|
678
|
+
let hexBody;
|
|
679
|
+
if (account.startsWith("T") && account.length === 34) {
|
|
680
|
+
try {
|
|
681
|
+
hexBody = (0, tvm_escrow_encoding_1.base58ToHex)(account);
|
|
682
|
+
} catch (error) {
|
|
683
|
+
throw new Error(`base58 address failed its checksum: ${error.message}`);
|
|
684
|
+
}
|
|
685
|
+
} else if (account.toLowerCase().startsWith("0x41") && account.length === 44) {
|
|
686
|
+
hexBody = account.slice(2);
|
|
687
|
+
} else if (HEX_40.test(account)) {
|
|
688
|
+
return parseEvm(account);
|
|
689
|
+
} else {
|
|
690
|
+
throw new Error("expected a T-prefixed base58 address or 40 hex characters");
|
|
691
|
+
}
|
|
692
|
+
hexBody = hexBody.startsWith("41") ? hexBody.slice(2) : hexBody;
|
|
693
|
+
if (hexBody.length !== 40) {
|
|
694
|
+
throw new Error(`expected 40 hex characters after conversion, got ${hexBody.length}`);
|
|
695
|
+
}
|
|
696
|
+
return hexToBytes2(hexBody);
|
|
697
|
+
}
|
|
698
|
+
function parseSolana(account) {
|
|
699
|
+
let decoded;
|
|
700
|
+
try {
|
|
701
|
+
decoded = bs58_1.default.decode(account);
|
|
702
|
+
} catch {
|
|
703
|
+
throw new Error("expected a 32-byte base58 public key");
|
|
704
|
+
}
|
|
705
|
+
if (decoded.length !== 32) {
|
|
706
|
+
throw new Error(`expected a 32-byte base58 public key, got ${decoded.length} bytes`);
|
|
707
|
+
}
|
|
708
|
+
return decoded;
|
|
709
|
+
}
|
|
710
|
+
var HEX_BODY = /^[0-9a-fA-F]*$/;
|
|
711
|
+
function hexToBytes2(hex) {
|
|
712
|
+
if (hex.length % 2 !== 0 || !HEX_BODY.test(hex)) {
|
|
713
|
+
throw new Error("expected hex characters");
|
|
714
|
+
}
|
|
715
|
+
const out = new Uint8Array(hex.length / 2);
|
|
716
|
+
for (let i = 0; i < out.length; i += 1) {
|
|
717
|
+
out[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
718
|
+
}
|
|
719
|
+
return out;
|
|
720
|
+
}
|
|
243
721
|
}
|
|
244
722
|
});
|
|
245
723
|
|
|
@@ -251,12 +729,96 @@ var require_types = __commonJS({
|
|
|
251
729
|
}
|
|
252
730
|
});
|
|
253
731
|
|
|
732
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/destination.js
|
|
733
|
+
var require_destination = __commonJS({
|
|
734
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/destination.js"(exports2) {
|
|
735
|
+
"use strict";
|
|
736
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
737
|
+
exports2.DESTINATION_COMMITMENT_WITNESS_VERSION = exports2.MAX_DESTINATION_BYTES = void 0;
|
|
738
|
+
exports2.usesDestinationCommitment = usesDestinationCommitment;
|
|
739
|
+
exports2.deriveDepositRequestHash = deriveDepositRequestHash;
|
|
740
|
+
exports2.buildEscrowDestination = buildEscrowDestination;
|
|
741
|
+
var ethers_1 = require("ethers");
|
|
742
|
+
exports2.MAX_DESTINATION_BYTES = 256;
|
|
743
|
+
var NAMESPACE_EIP155 = "eip155";
|
|
744
|
+
exports2.DESTINATION_COMMITMENT_WITNESS_VERSION = 4;
|
|
745
|
+
function usesDestinationCommitment(depositWitnessVersion) {
|
|
746
|
+
return depositWitnessVersion === void 0 || depositWitnessVersion >= exports2.DESTINATION_COMMITMENT_WITNESS_VERSION;
|
|
747
|
+
}
|
|
748
|
+
function deriveDepositRequestHash(requestId) {
|
|
749
|
+
if (requestId === "") {
|
|
750
|
+
throw new Error('sender_auth: cannot derive deposit_request_hash: request_id is empty, and keccak256("") is a perfectly valid non-zero bytes32, so this would silently commit every empty-id deposit to the same hash instead of failing');
|
|
751
|
+
}
|
|
752
|
+
return (0, ethers_1.keccak256)((0, ethers_1.toUtf8Bytes)(requestId));
|
|
753
|
+
}
|
|
754
|
+
function buildEscrowDestination(assetIdentifier, account) {
|
|
755
|
+
if (assetIdentifier === "") {
|
|
756
|
+
throw new Error("sender_auth: destination asset_identifier is empty");
|
|
757
|
+
}
|
|
758
|
+
if (account === "") {
|
|
759
|
+
throw new Error("sender_auth: destination account is empty");
|
|
760
|
+
}
|
|
761
|
+
if (assetIdentifier.includes("@") || account.includes("@")) {
|
|
762
|
+
throw new Error(`sender_auth: destination asset_identifier (${JSON.stringify(assetIdentifier)}) and account (${JSON.stringify(account)}) must not contain '@': it is the separator between them in the committed destination grammar`);
|
|
763
|
+
}
|
|
764
|
+
const namespace = caip2Namespace(assetIdentifier);
|
|
765
|
+
let asset = assetIdentifier;
|
|
766
|
+
let acct = account;
|
|
767
|
+
if (namespace === NAMESPACE_EIP155) {
|
|
768
|
+
asset = asset.toLowerCase();
|
|
769
|
+
acct = acct.toLowerCase();
|
|
770
|
+
}
|
|
771
|
+
const destination = `${asset}@${acct}`;
|
|
772
|
+
const byteLength = (0, ethers_1.toUtf8Bytes)(destination).length;
|
|
773
|
+
if (byteLength > exports2.MAX_DESTINATION_BYTES) {
|
|
774
|
+
throw new Error(`sender_auth: composed destination is ${byteLength} bytes, over the escrow's MAX_DESTINATION_BYTES of ${exports2.MAX_DESTINATION_BYTES}: the contract reverts DestinationTooLong, so this deposit could never be redeemed`);
|
|
775
|
+
}
|
|
776
|
+
return destination;
|
|
777
|
+
}
|
|
778
|
+
function caip2Namespace(assetIdentifier) {
|
|
779
|
+
const slash = assetIdentifier.indexOf("/");
|
|
780
|
+
const chainPart = slash === -1 ? "" : assetIdentifier.slice(0, slash);
|
|
781
|
+
const assetPart = slash === -1 ? "" : assetIdentifier.slice(slash + 1);
|
|
782
|
+
if (slash === -1 || chainPart === "" || assetPart === "") {
|
|
783
|
+
const looksLegacy = !assetIdentifier.includes("/") && countChar(assetIdentifier, ":") === 2;
|
|
784
|
+
const hint = looksLegacy ? " (this looks like the deprecated `<chain>:<ref>:<asset>` form; migrate it to `<chain>:<ref>/<asset-namespace>:<asset-reference>`)" : "";
|
|
785
|
+
throw new Error(`sender_auth: destination asset_identifier ${JSON.stringify(assetIdentifier)} is not CAIP-19: expected <caip2-chain-id>/<asset-namespace>:<asset-reference>${hint}`);
|
|
786
|
+
}
|
|
787
|
+
const assetColon = assetPart.indexOf(":");
|
|
788
|
+
if (assetColon <= 0 || assetColon === assetPart.length - 1) {
|
|
789
|
+
throw new Error(`sender_auth: destination asset_identifier ${JSON.stringify(assetIdentifier)} has a malformed asset part ${JSON.stringify(assetPart)}: expected <asset-namespace>:<asset-reference>`);
|
|
790
|
+
}
|
|
791
|
+
const assetNamespace = assetPart.slice(0, assetColon);
|
|
792
|
+
if (assetNamespace !== assetNamespace.toLowerCase()) {
|
|
793
|
+
throw new Error(`sender_auth: destination asset_identifier ${JSON.stringify(assetIdentifier)} has a non-canonical asset namespace ${JSON.stringify(assetNamespace)}: the ratified grammar requires it lowercase (${JSON.stringify(assetNamespace.toLowerCase())}). It is rejected rather than normalised because the destination commitment is over these exact bytes`);
|
|
794
|
+
}
|
|
795
|
+
const chainColon = chainPart.indexOf(":");
|
|
796
|
+
if (chainColon <= 0 || chainColon === chainPart.length - 1) {
|
|
797
|
+
throw new Error(`sender_auth: destination asset_identifier ${JSON.stringify(assetIdentifier)} has a malformed chain part ${JSON.stringify(chainPart)}: expected <namespace>:<reference>`);
|
|
798
|
+
}
|
|
799
|
+
const namespace = chainPart.slice(0, chainColon);
|
|
800
|
+
if (namespace !== namespace.toLowerCase()) {
|
|
801
|
+
throw new Error(`sender_auth: destination asset_identifier ${JSON.stringify(assetIdentifier)} has a non-canonical chain namespace ${JSON.stringify(namespace)}: the ratified grammar requires it lowercase (${JSON.stringify(namespace.toLowerCase())}). It is rejected rather than normalised because the destination commitment is over these exact bytes`);
|
|
802
|
+
}
|
|
803
|
+
return namespace;
|
|
804
|
+
}
|
|
805
|
+
function countChar(s, c) {
|
|
806
|
+
let n = 0;
|
|
807
|
+
for (const ch of s) {
|
|
808
|
+
if (ch === c)
|
|
809
|
+
n++;
|
|
810
|
+
}
|
|
811
|
+
return n;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
});
|
|
815
|
+
|
|
254
816
|
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/utils.js
|
|
255
817
|
var require_utils = __commonJS({
|
|
256
818
|
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/utils.js"(exports2) {
|
|
257
819
|
"use strict";
|
|
258
820
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
259
|
-
exports2.REQUEST_ID_DOMAIN = exports2.SOLANA_REPLAY_SLOTS = exports2.PERMIT_NONCE_DOMAIN = exports2.REPLAY_HORIZON_SECS = void 0;
|
|
821
|
+
exports2.REQUEST_ID_DOMAIN = exports2.SOLANA_REPLAY_BUCKETS = exports2.SOLANA_REPLAY_SLOTS = exports2.PERMIT_NONCE_DOMAIN = exports2.REPLAY_HORIZON_SECS = void 0;
|
|
260
822
|
exports2.resolvePermitDeadline = resolvePermitDeadline;
|
|
261
823
|
exports2.generatePermitNonce = generatePermitNonce;
|
|
262
824
|
exports2.resolvePermitNonce = resolvePermitNonce;
|
|
@@ -264,6 +826,7 @@ var require_utils = __commonJS({
|
|
|
264
826
|
exports2.deterministicPermitNonce = deterministicPermitNonce2;
|
|
265
827
|
exports2.deterministicSolanaNonce = deterministicSolanaNonce2;
|
|
266
828
|
exports2.deterministicRequestId = deterministicRequestId;
|
|
829
|
+
exports2.parseSourceAsset = parseSourceAsset;
|
|
267
830
|
exports2.sameAddress = sameAddress;
|
|
268
831
|
exports2.assertKeyMatchesSender = assertKeyMatchesSender2;
|
|
269
832
|
exports2.assertToken = assertToken;
|
|
@@ -272,8 +835,11 @@ var require_utils = __commonJS({
|
|
|
272
835
|
exports2.assertSpender = assertSpender;
|
|
273
836
|
exports2.assertWitnessRoles = assertWitnessRoles;
|
|
274
837
|
exports2.assertRolePairComplete = assertRolePairComplete;
|
|
838
|
+
exports2.assertDestination = assertDestination;
|
|
839
|
+
exports2.assertDepositRequestHash = assertDepositRequestHash;
|
|
275
840
|
exports2.nowSec = nowSec;
|
|
276
841
|
var ethers_1 = require("ethers");
|
|
842
|
+
var destination_js_1 = require_destination();
|
|
277
843
|
exports2.REPLAY_HORIZON_SECS = 128;
|
|
278
844
|
function resolvePermitDeadline(deadline) {
|
|
279
845
|
return BigInt(deadline);
|
|
@@ -288,7 +854,7 @@ var require_utils = __commonJS({
|
|
|
288
854
|
}
|
|
289
855
|
exports2.PERMIT_NONCE_DOMAIN = "atum-permit:v1:";
|
|
290
856
|
exports2.SOLANA_REPLAY_SLOTS = 235n;
|
|
291
|
-
|
|
857
|
+
exports2.SOLANA_REPLAY_BUCKETS = 256n;
|
|
292
858
|
function canonicalDepositor(depositor) {
|
|
293
859
|
const lower = depositor.toLowerCase();
|
|
294
860
|
return lower.startsWith("0x") ? lower : depositor;
|
|
@@ -305,7 +871,7 @@ var require_utils = __commonJS({
|
|
|
305
871
|
function deterministicSolanaNonce2(params) {
|
|
306
872
|
const seed = permitNonceSeed(params.requestId, params.depositor);
|
|
307
873
|
const slot = seed % exports2.SOLANA_REPLAY_SLOTS;
|
|
308
|
-
const bucket = (seed >> 8n) %
|
|
874
|
+
const bucket = (seed >> 8n) % exports2.SOLANA_REPLAY_BUCKETS;
|
|
309
875
|
return bucket << 32n | slot;
|
|
310
876
|
}
|
|
311
877
|
exports2.REQUEST_ID_DOMAIN = "atum-request:v1:";
|
|
@@ -322,6 +888,17 @@ var require_utils = __commonJS({
|
|
|
322
888
|
const digest = (0, ethers_1.keccak256)((0, ethers_1.toUtf8Bytes)(`${exports2.REQUEST_ID_DOMAIN}${params.anchor}:${canonicalDepositor(params.account)}`));
|
|
323
889
|
return `${params.prefix}${digest.slice(2, 26)}`;
|
|
324
890
|
}
|
|
891
|
+
function parseSourceAsset(assetIdentifier) {
|
|
892
|
+
const parts = typeof assetIdentifier === "string" ? assetIdentifier.split("/") : [];
|
|
893
|
+
const nsParts = parts[1]?.split(":");
|
|
894
|
+
if (parts.length === 3 && parts[0] && parts[1] && parts[2]) {
|
|
895
|
+
throw new Error(`sender_auth: source asset ${JSON.stringify(assetIdentifier)} names a token id, which a deposit cannot bind`);
|
|
896
|
+
}
|
|
897
|
+
if (parts.length !== 2 || !parts[0] || !nsParts || nsParts.length !== 2 || !nsParts[0] || !nsParts[1]) {
|
|
898
|
+
throw new Error(`sender_auth: invalid source asset ${JSON.stringify(assetIdentifier)}`);
|
|
899
|
+
}
|
|
900
|
+
return { network: parts[0], asset: nsParts[1] };
|
|
901
|
+
}
|
|
325
902
|
function sameAddress(a, b) {
|
|
326
903
|
if (a.startsWith("0x") && b.startsWith("0x")) {
|
|
327
904
|
return a.toLowerCase() === b.toLowerCase();
|
|
@@ -363,6 +940,17 @@ var require_utils = __commonJS({
|
|
|
363
940
|
throw new Error("sender_auth: reserver and releaser must be supplied together");
|
|
364
941
|
}
|
|
365
942
|
}
|
|
943
|
+
function assertDestination(signed, expected) {
|
|
944
|
+
if (signed !== expected) {
|
|
945
|
+
throw new Error(`sender_auth: signed deposit destination ${JSON.stringify(signed)} does not match the expected destination ${JSON.stringify(expected)} \u2014 the escrow stores only keccak256(bytes(destination)) and cannot tell a formatting disagreement from a wrong payee, so a deposit signed against this destination could be neither released nor refunded`);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
function assertDepositRequestHash(signedHex, expectedRequestId) {
|
|
949
|
+
const expected = (0, destination_js_1.deriveDepositRequestHash)(expectedRequestId);
|
|
950
|
+
if (signedHex.toLowerCase() !== expected.toLowerCase()) {
|
|
951
|
+
throw new Error(`sender_auth: signed deposit_request_hash ${signedHex} is not keccak256(request_id) for request_id ${JSON.stringify(expectedRequestId)} (expected ${expected}): the deposit authorizes a different payment request`);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
366
954
|
function nowSec() {
|
|
367
955
|
return Math.floor(Date.now() / 1e3);
|
|
368
956
|
}
|
|
@@ -374,7 +962,7 @@ var require_chain_id2 = __commonJS({
|
|
|
374
962
|
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/chain-id.js"(exports2) {
|
|
375
963
|
"use strict";
|
|
376
964
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
377
|
-
exports2.TRON_PERMIT2_FALLBACKS = exports2.TRON_CHAIN_IDS = void 0;
|
|
965
|
+
exports2.TRON_PERMIT2_FALLBACKS = exports2.TRON_CHAIN_IDS = exports2.MAX_EVM_CHAIN_ID = void 0;
|
|
378
966
|
exports2.namespaceOf = namespaceOf;
|
|
379
967
|
exports2.evmChainId = evmChainId;
|
|
380
968
|
exports2.tronNumericChainId = tronNumericChainId;
|
|
@@ -383,21 +971,30 @@ var require_chain_id2 = __commonJS({
|
|
|
383
971
|
function namespaceOf(network) {
|
|
384
972
|
return network.split(":")[0];
|
|
385
973
|
}
|
|
974
|
+
exports2.MAX_EVM_CHAIN_ID = Number.MAX_SAFE_INTEGER;
|
|
386
975
|
function evmChainId(network) {
|
|
387
976
|
const match = /^eip155:([0-9]+)$/.exec(network);
|
|
388
977
|
if (!match) {
|
|
389
978
|
throw new Error(`sender_auth: expected an eip155 network, got ${network}`);
|
|
390
979
|
}
|
|
391
|
-
|
|
980
|
+
const chainId = Number(match[1]);
|
|
981
|
+
if (chainId > exports2.MAX_EVM_CHAIN_ID) {
|
|
982
|
+
throw new Error(`sender_auth: eip155 chain id ${match[1]} exceeds the EIP-2294 maximum (${exports2.MAX_EVM_CHAIN_ID})`);
|
|
983
|
+
}
|
|
984
|
+
return chainId;
|
|
392
985
|
}
|
|
393
986
|
exports2.TRON_CHAIN_IDS = {
|
|
394
987
|
mainnet: 728126428,
|
|
395
988
|
shasta: 2494104990
|
|
396
989
|
};
|
|
397
990
|
function tronNumericChainId(network) {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
991
|
+
if (namespaceOf(network) !== "tron") {
|
|
992
|
+
throw new Error(`sender_auth: expected a tron network, got ${network}`);
|
|
993
|
+
}
|
|
994
|
+
const segments = network.split(":");
|
|
995
|
+
const cluster = segments.length === 2 ? segments[1] : void 0;
|
|
996
|
+
const id = cluster !== void 0 && Object.hasOwn(exports2.TRON_CHAIN_IDS, cluster) ? exports2.TRON_CHAIN_IDS[cluster] : void 0;
|
|
997
|
+
if (typeof id !== "number") {
|
|
401
998
|
throw new Error(`sender_auth: unsupported Tron network '${network}'`);
|
|
402
999
|
}
|
|
403
1000
|
return id;
|
|
@@ -407,8 +1004,8 @@ var require_chain_id2 = __commonJS({
|
|
|
407
1004
|
"tron:shasta": "TPUqJPASUn1zLvbLBgRZ5pBYrx7WSe5ahp"
|
|
408
1005
|
};
|
|
409
1006
|
function resolveTronPermit2(network) {
|
|
410
|
-
const resolved = exports2.TRON_PERMIT2_FALLBACKS[network];
|
|
411
|
-
if (
|
|
1007
|
+
const resolved = Object.hasOwn(exports2.TRON_PERMIT2_FALLBACKS, network) ? exports2.TRON_PERMIT2_FALLBACKS[network] : void 0;
|
|
1008
|
+
if (typeof resolved !== "string" || resolved === "") {
|
|
412
1009
|
throw new Error(`sender_auth: no Permit2 address known for Tron network '${network}'`);
|
|
413
1010
|
}
|
|
414
1011
|
return resolved;
|
|
@@ -464,7 +1061,7 @@ var require_permit_types = __commonJS({
|
|
|
464
1061
|
"../contracts/evm/escrow-encoding/typescript/dist/permit-types.js"(exports2) {
|
|
465
1062
|
"use strict";
|
|
466
1063
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
467
|
-
exports2.REFUND_WITNESS_TYPES = exports2.RELEASE_WITNESS_TYPES = exports2.RESERVE_WITNESS_TYPES = exports2.PERMIT_WITNESS_TYPES_V2 = exports2.PERMIT_WITNESS_TYPES = void 0;
|
|
1064
|
+
exports2.REFUND_WITNESS_TYPES_WITH_QUOTE_HASH = exports2.RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH = exports2.RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE = exports2.PERMIT_WITNESS_TYPES_WITH_DESTINATION = exports2.REFUND_WITNESS_TYPES = exports2.RELEASE_WITNESS_TYPES = exports2.RESERVE_WITNESS_TYPES = exports2.PERMIT_WITNESS_TYPES_V2 = exports2.PERMIT_WITNESS_TYPES = void 0;
|
|
468
1065
|
exports2.createPermit2Domain = createPermit2Domain;
|
|
469
1066
|
exports2.createEscrowDomain = createEscrowDomain;
|
|
470
1067
|
exports2.PERMIT_WITNESS_TYPES = {
|
|
@@ -547,6 +1144,63 @@ var require_permit_types = __commonJS({
|
|
|
547
1144
|
{ name: "settler", type: "address" }
|
|
548
1145
|
]
|
|
549
1146
|
};
|
|
1147
|
+
exports2.PERMIT_WITNESS_TYPES_WITH_DESTINATION = {
|
|
1148
|
+
PermitWitnessTransferFrom: [
|
|
1149
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
1150
|
+
{ name: "spender", type: "address" },
|
|
1151
|
+
{ name: "nonce", type: "uint256" },
|
|
1152
|
+
{ name: "deadline", type: "uint256" },
|
|
1153
|
+
{ name: "witness", type: "DepositWitness" }
|
|
1154
|
+
],
|
|
1155
|
+
TokenPermissions: [
|
|
1156
|
+
{ name: "token", type: "address" },
|
|
1157
|
+
{ name: "amount", type: "uint256" }
|
|
1158
|
+
],
|
|
1159
|
+
DepositWitness: [
|
|
1160
|
+
{ name: "depositRequestHash", type: "bytes32" },
|
|
1161
|
+
{ name: "destination", type: "string" },
|
|
1162
|
+
{ name: "reserver", type: "address" },
|
|
1163
|
+
{ name: "releaser", type: "address" }
|
|
1164
|
+
]
|
|
1165
|
+
};
|
|
1166
|
+
exports2.RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE = {
|
|
1167
|
+
ReserveWitness: [
|
|
1168
|
+
{ name: "depositId", type: "bytes32" },
|
|
1169
|
+
{ name: "quoteHash", type: "bytes32" },
|
|
1170
|
+
{ name: "settler", type: "address" },
|
|
1171
|
+
{ name: "sourceAmount", type: "uint256" }
|
|
1172
|
+
]
|
|
1173
|
+
};
|
|
1174
|
+
exports2.RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH = {
|
|
1175
|
+
ReleaseWitness: [
|
|
1176
|
+
{ name: "depositId", type: "bytes32" },
|
|
1177
|
+
{ name: "quoteHash", type: "bytes32" },
|
|
1178
|
+
{ name: "depositRequestHash", type: "bytes32" },
|
|
1179
|
+
{ name: "destinationHash", type: "bytes32" },
|
|
1180
|
+
{ name: "depositor", type: "address" },
|
|
1181
|
+
{ name: "token", type: "address" },
|
|
1182
|
+
{ name: "amount", type: "uint256" },
|
|
1183
|
+
{ name: "feeAmount", type: "uint256" },
|
|
1184
|
+
{ name: "reserver", type: "address" },
|
|
1185
|
+
{ name: "releaser", type: "address" },
|
|
1186
|
+
{ name: "settler", type: "address" }
|
|
1187
|
+
]
|
|
1188
|
+
};
|
|
1189
|
+
exports2.REFUND_WITNESS_TYPES_WITH_QUOTE_HASH = {
|
|
1190
|
+
RefundWitness: [
|
|
1191
|
+
{ name: "depositId", type: "bytes32" },
|
|
1192
|
+
{ name: "quoteHash", type: "bytes32" },
|
|
1193
|
+
{ name: "depositRequestHash", type: "bytes32" },
|
|
1194
|
+
{ name: "destinationHash", type: "bytes32" },
|
|
1195
|
+
{ name: "depositor", type: "address" },
|
|
1196
|
+
{ name: "token", type: "address" },
|
|
1197
|
+
{ name: "amount", type: "uint256" },
|
|
1198
|
+
{ name: "feeAmount", type: "uint256" },
|
|
1199
|
+
{ name: "reserver", type: "address" },
|
|
1200
|
+
{ name: "releaser", type: "address" },
|
|
1201
|
+
{ name: "settler", type: "address" }
|
|
1202
|
+
]
|
|
1203
|
+
};
|
|
550
1204
|
}
|
|
551
1205
|
});
|
|
552
1206
|
|
|
@@ -673,6 +1327,8 @@ var require_escrow_abi = __commonJS({
|
|
|
673
1327
|
name: "depositWitness",
|
|
674
1328
|
type: "tuple",
|
|
675
1329
|
components: [
|
|
1330
|
+
{ name: "depositRequestHash", type: "bytes32" },
|
|
1331
|
+
{ name: "destination", type: "string" },
|
|
676
1332
|
{ name: "reserver", type: "address" },
|
|
677
1333
|
{ name: "releaser", type: "address" }
|
|
678
1334
|
]
|
|
@@ -682,15 +1338,17 @@ var require_escrow_abi = __commonJS({
|
|
|
682
1338
|
name: "reserveWitness",
|
|
683
1339
|
type: "tuple",
|
|
684
1340
|
components: [
|
|
685
|
-
{ name: "
|
|
686
|
-
{ name: "
|
|
1341
|
+
{ name: "depositId", type: "bytes32" },
|
|
1342
|
+
{ name: "quoteHash", type: "bytes32" },
|
|
1343
|
+
{ name: "settler", type: "address" },
|
|
1344
|
+
{ name: "sourceAmount", type: "uint256" }
|
|
687
1345
|
]
|
|
688
1346
|
},
|
|
689
1347
|
{ name: "reserveSignature", type: "bytes" }
|
|
690
1348
|
]
|
|
691
1349
|
}
|
|
692
1350
|
],
|
|
693
|
-
outputs: [{ name: "
|
|
1351
|
+
outputs: [{ name: "depositId", type: "bytes32" }],
|
|
694
1352
|
stateMutability: "nonpayable"
|
|
695
1353
|
},
|
|
696
1354
|
{
|
|
@@ -705,7 +1363,10 @@ var require_escrow_abi = __commonJS({
|
|
|
705
1363
|
name: "refundWitness",
|
|
706
1364
|
type: "tuple",
|
|
707
1365
|
components: [
|
|
708
|
-
{ name: "
|
|
1366
|
+
{ name: "depositId", type: "bytes32" },
|
|
1367
|
+
{ name: "quoteHash", type: "bytes32" },
|
|
1368
|
+
{ name: "depositRequestHash", type: "bytes32" },
|
|
1369
|
+
{ name: "destinationHash", type: "bytes32" },
|
|
709
1370
|
{ name: "depositor", type: "address" },
|
|
710
1371
|
{ name: "token", type: "address" },
|
|
711
1372
|
{ name: "amount", type: "uint256" },
|
|
@@ -725,7 +1386,7 @@ var require_escrow_abi = __commonJS({
|
|
|
725
1386
|
{
|
|
726
1387
|
type: "function",
|
|
727
1388
|
name: "getDepositHash",
|
|
728
|
-
inputs: [{ name: "
|
|
1389
|
+
inputs: [{ name: "depositId", type: "bytes32" }],
|
|
729
1390
|
outputs: [{ name: "", type: "bytes32" }],
|
|
730
1391
|
stateMutability: "view"
|
|
731
1392
|
},
|
|
@@ -741,14 +1402,67 @@ var require_escrow_abi = __commonJS({
|
|
|
741
1402
|
}
|
|
742
1403
|
});
|
|
743
1404
|
|
|
1405
|
+
// ../contracts/evm/escrow-encoding/typescript/dist/witness-values.js
|
|
1406
|
+
var require_witness_values2 = __commonJS({
|
|
1407
|
+
"../contracts/evm/escrow-encoding/typescript/dist/witness-values.js"(exports2) {
|
|
1408
|
+
"use strict";
|
|
1409
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1410
|
+
exports2.normalizeBytes32 = normalizeBytes32;
|
|
1411
|
+
exports2.normalizeAddressField = normalizeAddressField;
|
|
1412
|
+
exports2.normalizeUint256 = normalizeUint256;
|
|
1413
|
+
exports2.chainIdToHex = chainIdToHex;
|
|
1414
|
+
var ethers_1 = require("ethers");
|
|
1415
|
+
function normalizeBytes32(label, value) {
|
|
1416
|
+
let bytes;
|
|
1417
|
+
try {
|
|
1418
|
+
bytes = (0, ethers_1.getBytes)(value);
|
|
1419
|
+
} catch {
|
|
1420
|
+
throw new Error(`${label} must be 0x-prefixed hex (32 bytes), got ${JSON.stringify(value)}`);
|
|
1421
|
+
}
|
|
1422
|
+
if (bytes.length !== 32) {
|
|
1423
|
+
throw new Error(`${label} must be exactly 32 bytes, got ${bytes.length}`);
|
|
1424
|
+
}
|
|
1425
|
+
return (0, ethers_1.hexlify)(bytes);
|
|
1426
|
+
}
|
|
1427
|
+
function normalizeAddressField(label, value) {
|
|
1428
|
+
try {
|
|
1429
|
+
return (0, ethers_1.getAddress)(value);
|
|
1430
|
+
} catch {
|
|
1431
|
+
throw new Error(`${label} must be a 20-byte hex address, got ${JSON.stringify(value)}`);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
function normalizeUint256(label, value) {
|
|
1435
|
+
let n;
|
|
1436
|
+
try {
|
|
1437
|
+
n = BigInt(value);
|
|
1438
|
+
} catch {
|
|
1439
|
+
throw new Error(`${label} must be an integer (bigint or decimal string), got ${JSON.stringify(value)}`);
|
|
1440
|
+
}
|
|
1441
|
+
if (n < 0n) {
|
|
1442
|
+
throw new Error(`${label} must be non-negative (uint256), got ${n.toString()}`);
|
|
1443
|
+
}
|
|
1444
|
+
return n.toString();
|
|
1445
|
+
}
|
|
1446
|
+
function chainIdToHex(chainId) {
|
|
1447
|
+
if (!Number.isSafeInteger(chainId) || chainId < 0) {
|
|
1448
|
+
throw new Error(`chainId must be a non-negative safe integer, got ${chainId}`);
|
|
1449
|
+
}
|
|
1450
|
+
return `0x${chainId.toString(16)}`;
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
});
|
|
1454
|
+
|
|
744
1455
|
// ../contracts/evm/escrow-encoding/typescript/dist/reserve-encoder.js
|
|
745
1456
|
var require_reserve_encoder2 = __commonJS({
|
|
746
1457
|
"../contracts/evm/escrow-encoding/typescript/dist/reserve-encoder.js"(exports2) {
|
|
747
1458
|
"use strict";
|
|
748
1459
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
749
1460
|
exports2.computeReserveDigest = computeReserveDigest;
|
|
1461
|
+
exports2.buildReserveTypedDataWithQuoteSource = buildReserveTypedDataWithQuoteSource;
|
|
1462
|
+
exports2.computeReserveDigestWithQuoteSource = computeReserveDigestWithQuoteSource;
|
|
750
1463
|
var ethers_1 = require("ethers");
|
|
751
1464
|
var permit_types_1 = require_permit_types();
|
|
1465
|
+
var witness_values_1 = require_witness_values2();
|
|
752
1466
|
function computeReserveDigest(input) {
|
|
753
1467
|
const domain = (0, permit_types_1.createEscrowDomain)(input.chainId, input.escrowContract);
|
|
754
1468
|
return ethers_1.TypedDataEncoder.hash(domain, permit_types_1.RESERVE_WITNESS_TYPES, {
|
|
@@ -756,6 +1470,114 @@ var require_reserve_encoder2 = __commonJS({
|
|
|
756
1470
|
settler: input.settler
|
|
757
1471
|
});
|
|
758
1472
|
}
|
|
1473
|
+
function buildReserveTypedDataWithQuoteSource(input) {
|
|
1474
|
+
return {
|
|
1475
|
+
types: permit_types_1.RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE,
|
|
1476
|
+
primaryType: "ReserveWitness",
|
|
1477
|
+
domain: {
|
|
1478
|
+
name: "Escrow",
|
|
1479
|
+
version: "3",
|
|
1480
|
+
chainId: (0, witness_values_1.chainIdToHex)(input.chainId),
|
|
1481
|
+
verifyingContract: (0, witness_values_1.normalizeAddressField)("escrowContract", input.escrowContract)
|
|
1482
|
+
},
|
|
1483
|
+
message: {
|
|
1484
|
+
depositId: (0, witness_values_1.normalizeBytes32)("depositId", input.depositId),
|
|
1485
|
+
quoteHash: (0, witness_values_1.normalizeBytes32)("quoteHash", input.quoteHash),
|
|
1486
|
+
settler: (0, witness_values_1.normalizeAddressField)("settler", input.settler),
|
|
1487
|
+
sourceAmount: (0, witness_values_1.normalizeUint256)("sourceAmount", input.sourceAmount)
|
|
1488
|
+
}
|
|
1489
|
+
};
|
|
1490
|
+
}
|
|
1491
|
+
function computeReserveDigestWithQuoteSource(input) {
|
|
1492
|
+
const prehash = buildReserveTypedDataWithQuoteSource(input);
|
|
1493
|
+
return ethers_1.TypedDataEncoder.hash(prehash.domain, prehash.types, prehash.message);
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
});
|
|
1497
|
+
|
|
1498
|
+
// ../contracts/evm/escrow-encoding/typescript/dist/release-encoder.js
|
|
1499
|
+
var require_release_encoder2 = __commonJS({
|
|
1500
|
+
"../contracts/evm/escrow-encoding/typescript/dist/release-encoder.js"(exports2) {
|
|
1501
|
+
"use strict";
|
|
1502
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1503
|
+
exports2.buildReleaseTypedDataWithQuoteHash = buildReleaseTypedDataWithQuoteHash;
|
|
1504
|
+
exports2.computeReleaseDigestWithQuoteHash = computeReleaseDigestWithQuoteHash;
|
|
1505
|
+
var ethers_1 = require("ethers");
|
|
1506
|
+
var permit_types_1 = require_permit_types();
|
|
1507
|
+
var witness_values_1 = require_witness_values2();
|
|
1508
|
+
function buildReleaseTypedDataWithQuoteHash(input) {
|
|
1509
|
+
const w = input.witness;
|
|
1510
|
+
return {
|
|
1511
|
+
types: permit_types_1.RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH,
|
|
1512
|
+
primaryType: "ReleaseWitness",
|
|
1513
|
+
domain: {
|
|
1514
|
+
name: "Escrow",
|
|
1515
|
+
version: "3",
|
|
1516
|
+
chainId: (0, witness_values_1.chainIdToHex)(input.chainId),
|
|
1517
|
+
verifyingContract: (0, witness_values_1.normalizeAddressField)("escrowContract", input.escrowContract)
|
|
1518
|
+
},
|
|
1519
|
+
message: {
|
|
1520
|
+
depositId: (0, witness_values_1.normalizeBytes32)("depositId", w.depositId),
|
|
1521
|
+
quoteHash: (0, witness_values_1.normalizeBytes32)("quoteHash", w.quoteHash),
|
|
1522
|
+
depositRequestHash: (0, witness_values_1.normalizeBytes32)("depositRequestHash", w.depositRequestHash),
|
|
1523
|
+
destinationHash: (0, witness_values_1.normalizeBytes32)("destinationHash", w.destinationHash),
|
|
1524
|
+
depositor: (0, witness_values_1.normalizeAddressField)("depositor", w.depositor),
|
|
1525
|
+
token: (0, witness_values_1.normalizeAddressField)("token", w.token),
|
|
1526
|
+
amount: (0, witness_values_1.normalizeUint256)("amount", w.amount),
|
|
1527
|
+
feeAmount: (0, witness_values_1.normalizeUint256)("feeAmount", w.feeAmount),
|
|
1528
|
+
reserver: (0, witness_values_1.normalizeAddressField)("reserver", w.reserver),
|
|
1529
|
+
releaser: (0, witness_values_1.normalizeAddressField)("releaser", w.releaser),
|
|
1530
|
+
settler: (0, witness_values_1.normalizeAddressField)("settler", w.settler)
|
|
1531
|
+
}
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
function computeReleaseDigestWithQuoteHash(input) {
|
|
1535
|
+
const prehash = buildReleaseTypedDataWithQuoteHash(input);
|
|
1536
|
+
return ethers_1.TypedDataEncoder.hash(prehash.domain, prehash.types, prehash.message);
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
});
|
|
1540
|
+
|
|
1541
|
+
// ../contracts/evm/escrow-encoding/typescript/dist/refund-encoder.js
|
|
1542
|
+
var require_refund_encoder2 = __commonJS({
|
|
1543
|
+
"../contracts/evm/escrow-encoding/typescript/dist/refund-encoder.js"(exports2) {
|
|
1544
|
+
"use strict";
|
|
1545
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1546
|
+
exports2.buildRefundTypedDataWithQuoteHash = buildRefundTypedDataWithQuoteHash;
|
|
1547
|
+
exports2.computeRefundDigestWithQuoteHash = computeRefundDigestWithQuoteHash;
|
|
1548
|
+
var ethers_1 = require("ethers");
|
|
1549
|
+
var permit_types_1 = require_permit_types();
|
|
1550
|
+
var witness_values_1 = require_witness_values2();
|
|
1551
|
+
function buildRefundTypedDataWithQuoteHash(input) {
|
|
1552
|
+
const w = input.witness;
|
|
1553
|
+
return {
|
|
1554
|
+
types: permit_types_1.REFUND_WITNESS_TYPES_WITH_QUOTE_HASH,
|
|
1555
|
+
primaryType: "RefundWitness",
|
|
1556
|
+
domain: {
|
|
1557
|
+
name: "Escrow",
|
|
1558
|
+
version: "3",
|
|
1559
|
+
chainId: (0, witness_values_1.chainIdToHex)(input.chainId),
|
|
1560
|
+
verifyingContract: (0, witness_values_1.normalizeAddressField)("escrowContract", input.escrowContract)
|
|
1561
|
+
},
|
|
1562
|
+
message: {
|
|
1563
|
+
depositId: (0, witness_values_1.normalizeBytes32)("depositId", w.depositId),
|
|
1564
|
+
quoteHash: (0, witness_values_1.normalizeBytes32)("quoteHash", w.quoteHash),
|
|
1565
|
+
depositRequestHash: (0, witness_values_1.normalizeBytes32)("depositRequestHash", w.depositRequestHash),
|
|
1566
|
+
destinationHash: (0, witness_values_1.normalizeBytes32)("destinationHash", w.destinationHash),
|
|
1567
|
+
depositor: (0, witness_values_1.normalizeAddressField)("depositor", w.depositor),
|
|
1568
|
+
token: (0, witness_values_1.normalizeAddressField)("token", w.token),
|
|
1569
|
+
amount: (0, witness_values_1.normalizeUint256)("amount", w.amount),
|
|
1570
|
+
feeAmount: (0, witness_values_1.normalizeUint256)("feeAmount", w.feeAmount),
|
|
1571
|
+
reserver: (0, witness_values_1.normalizeAddressField)("reserver", w.reserver),
|
|
1572
|
+
releaser: (0, witness_values_1.normalizeAddressField)("releaser", w.releaser),
|
|
1573
|
+
settler: (0, witness_values_1.normalizeAddressField)("settler", w.settler)
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
function computeRefundDigestWithQuoteHash(input) {
|
|
1578
|
+
const prehash = buildRefundTypedDataWithQuoteHash(input);
|
|
1579
|
+
return ethers_1.TypedDataEncoder.hash(prehash.domain, prehash.types, prehash.message);
|
|
1580
|
+
}
|
|
759
1581
|
}
|
|
760
1582
|
});
|
|
761
1583
|
|
|
@@ -764,11 +1586,13 @@ var require_deposit_encoder2 = __commonJS({
|
|
|
764
1586
|
"../contracts/evm/escrow-encoding/typescript/dist/deposit-encoder.js"(exports2) {
|
|
765
1587
|
"use strict";
|
|
766
1588
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
767
|
-
exports2.PERMIT2_CONTRACT_ADDRESS = void 0;
|
|
1589
|
+
exports2.MAX_DESTINATION_BYTES = exports2.PERMIT2_CONTRACT_ADDRESS = void 0;
|
|
768
1590
|
exports2.createPermitWitnessTransferFromPrehash = createPermitWitnessTransferFromPrehash2;
|
|
769
1591
|
exports2.hashPermitWitnessTransferFrom = hashPermitWitnessTransferFrom2;
|
|
1592
|
+
exports2.createPermitWitnessTransferFromPrehashWithDestination = createPermitWitnessTransferFromPrehashWithDestination;
|
|
770
1593
|
var ethers_1 = require("ethers");
|
|
771
1594
|
var permit_types_1 = require_permit_types();
|
|
1595
|
+
var witness_values_1 = require_witness_values2();
|
|
772
1596
|
exports2.PERMIT2_CONTRACT_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
773
1597
|
function createPermitWitnessTransferFromPrehash2(params) {
|
|
774
1598
|
return {
|
|
@@ -797,15 +1621,52 @@ var require_deposit_encoder2 = __commonJS({
|
|
|
797
1621
|
function hashPermitWitnessTransferFrom2(prehash) {
|
|
798
1622
|
return ethers_1.TypedDataEncoder.hash(prehash.domain, prehash.types, prehash.message);
|
|
799
1623
|
}
|
|
1624
|
+
exports2.MAX_DESTINATION_BYTES = 256;
|
|
1625
|
+
function assertDestinationWithinBounds(destination) {
|
|
1626
|
+
if (destination === "") {
|
|
1627
|
+
throw new Error('destination is empty: the escrow reverts DestinationCannotBeEmpty, and because keccak256("") is a valid bytes32 this would otherwise sign a commitment to no destination at all');
|
|
1628
|
+
}
|
|
1629
|
+
const byteLength = (0, ethers_1.toUtf8Bytes)(destination).length;
|
|
1630
|
+
if (byteLength > exports2.MAX_DESTINATION_BYTES) {
|
|
1631
|
+
throw new Error(`destination is ${byteLength} bytes, over the escrow's MAX_DESTINATION_BYTES of ${exports2.MAX_DESTINATION_BYTES}: the contract reverts DestinationTooLong, so this digest could never be redeemed`);
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
function createPermitWitnessTransferFromPrehashWithDestination(params) {
|
|
1635
|
+
assertDestinationWithinBounds(params.destination);
|
|
1636
|
+
return {
|
|
1637
|
+
types: permit_types_1.PERMIT_WITNESS_TYPES_WITH_DESTINATION,
|
|
1638
|
+
primaryType: "PermitWitnessTransferFrom",
|
|
1639
|
+
domain: {
|
|
1640
|
+
name: "Permit2",
|
|
1641
|
+
chainId: (0, witness_values_1.chainIdToHex)(params.chainId),
|
|
1642
|
+
verifyingContract: (0, witness_values_1.normalizeAddressField)("verifyingContract", params.verifyingContract)
|
|
1643
|
+
},
|
|
1644
|
+
message: {
|
|
1645
|
+
permitted: {
|
|
1646
|
+
token: (0, witness_values_1.normalizeAddressField)("token", params.token),
|
|
1647
|
+
amount: (0, witness_values_1.normalizeUint256)("amount", params.amount)
|
|
1648
|
+
},
|
|
1649
|
+
spender: (0, witness_values_1.normalizeAddressField)("spender", params.spender),
|
|
1650
|
+
nonce: (0, witness_values_1.normalizeUint256)("nonce", params.nonce),
|
|
1651
|
+
deadline: (0, witness_values_1.normalizeUint256)("deadline", params.deadline),
|
|
1652
|
+
witness: {
|
|
1653
|
+
depositRequestHash: (0, witness_values_1.normalizeBytes32)("depositRequestHash", params.depositRequestHash),
|
|
1654
|
+
destination: params.destination,
|
|
1655
|
+
reserver: (0, witness_values_1.normalizeAddressField)("reserver", params.reserver),
|
|
1656
|
+
releaser: (0, witness_values_1.normalizeAddressField)("releaser", params.releaser)
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
};
|
|
1660
|
+
}
|
|
800
1661
|
}
|
|
801
1662
|
});
|
|
802
1663
|
|
|
803
1664
|
// ../contracts/evm/escrow-encoding/typescript/dist/index.js
|
|
804
|
-
var
|
|
1665
|
+
var require_dist3 = __commonJS({
|
|
805
1666
|
"../contracts/evm/escrow-encoding/typescript/dist/index.js"(exports2) {
|
|
806
1667
|
"use strict";
|
|
807
1668
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
808
|
-
exports2.PERMIT2_CONTRACT_ADDRESS = exports2.hashPermitWitnessTransferFrom = exports2.createPermitWitnessTransferFromPrehash = exports2.computeReserveDigest = exports2.ESCROW_V3_ABI_JSON = exports2.ESCROW_V2_ABI_JSON = exports2.ESCROW_ABI_JSON = exports2.ESCROW_ABI = exports2.REFUND_WITNESS_TYPES = exports2.RELEASE_WITNESS_TYPES = exports2.RESERVE_WITNESS_TYPES = exports2.createEscrowDomain = exports2.createPermit2Domain = exports2.PERMIT_WITNESS_TYPES_V2 = exports2.PERMIT_WITNESS_TYPES = exports2.generateNonce = exports2.computePaymentIdV2 = exports2.computePaymentId = void 0;
|
|
1669
|
+
exports2.MAX_DESTINATION_BYTES = exports2.createPermitWitnessTransferFromPrehashWithDestination = exports2.PERMIT2_CONTRACT_ADDRESS = exports2.hashPermitWitnessTransferFrom = exports2.createPermitWitnessTransferFromPrehash = exports2.computeRefundDigestWithQuoteHash = exports2.buildRefundTypedDataWithQuoteHash = exports2.computeReleaseDigestWithQuoteHash = exports2.buildReleaseTypedDataWithQuoteHash = exports2.computeReserveDigestWithQuoteSource = exports2.buildReserveTypedDataWithQuoteSource = exports2.computeReserveDigest = exports2.ESCROW_V3_ABI_JSON = exports2.ESCROW_V2_ABI_JSON = exports2.ESCROW_ABI_JSON = exports2.ESCROW_ABI = exports2.REFUND_WITNESS_TYPES_WITH_QUOTE_HASH = exports2.RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH = exports2.RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE = exports2.PERMIT_WITNESS_TYPES_WITH_DESTINATION = exports2.REFUND_WITNESS_TYPES = exports2.RELEASE_WITNESS_TYPES = exports2.RESERVE_WITNESS_TYPES = exports2.createEscrowDomain = exports2.createPermit2Domain = exports2.PERMIT_WITNESS_TYPES_V2 = exports2.PERMIT_WITNESS_TYPES = exports2.generateNonce = exports2.computePaymentIdV2 = exports2.computePaymentId = void 0;
|
|
809
1670
|
var payment_id_1 = require_payment_id2();
|
|
810
1671
|
Object.defineProperty(exports2, "computePaymentId", { enumerable: true, get: function() {
|
|
811
1672
|
return payment_id_1.computePaymentId;
|
|
@@ -839,6 +1700,19 @@ var require_dist2 = __commonJS({
|
|
|
839
1700
|
Object.defineProperty(exports2, "REFUND_WITNESS_TYPES", { enumerable: true, get: function() {
|
|
840
1701
|
return permit_types_1.REFUND_WITNESS_TYPES;
|
|
841
1702
|
} });
|
|
1703
|
+
var permit_types_2 = require_permit_types();
|
|
1704
|
+
Object.defineProperty(exports2, "PERMIT_WITNESS_TYPES_WITH_DESTINATION", { enumerable: true, get: function() {
|
|
1705
|
+
return permit_types_2.PERMIT_WITNESS_TYPES_WITH_DESTINATION;
|
|
1706
|
+
} });
|
|
1707
|
+
Object.defineProperty(exports2, "RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE", { enumerable: true, get: function() {
|
|
1708
|
+
return permit_types_2.RESERVE_WITNESS_TYPES_WITH_QUOTE_SOURCE;
|
|
1709
|
+
} });
|
|
1710
|
+
Object.defineProperty(exports2, "RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH", { enumerable: true, get: function() {
|
|
1711
|
+
return permit_types_2.RELEASE_WITNESS_TYPES_WITH_QUOTE_HASH;
|
|
1712
|
+
} });
|
|
1713
|
+
Object.defineProperty(exports2, "REFUND_WITNESS_TYPES_WITH_QUOTE_HASH", { enumerable: true, get: function() {
|
|
1714
|
+
return permit_types_2.REFUND_WITNESS_TYPES_WITH_QUOTE_HASH;
|
|
1715
|
+
} });
|
|
842
1716
|
var escrow_abi_1 = require_escrow_abi();
|
|
843
1717
|
Object.defineProperty(exports2, "ESCROW_ABI", { enumerable: true, get: function() {
|
|
844
1718
|
return escrow_abi_1.ESCROW_ABI;
|
|
@@ -852,9 +1726,30 @@ var require_dist2 = __commonJS({
|
|
|
852
1726
|
Object.defineProperty(exports2, "ESCROW_V3_ABI_JSON", { enumerable: true, get: function() {
|
|
853
1727
|
return escrow_abi_1.ESCROW_V3_ABI_JSON;
|
|
854
1728
|
} });
|
|
855
|
-
var reserve_encoder_1 = require_reserve_encoder2();
|
|
856
|
-
Object.defineProperty(exports2, "computeReserveDigest", { enumerable: true, get: function() {
|
|
857
|
-
return reserve_encoder_1.computeReserveDigest;
|
|
1729
|
+
var reserve_encoder_1 = require_reserve_encoder2();
|
|
1730
|
+
Object.defineProperty(exports2, "computeReserveDigest", { enumerable: true, get: function() {
|
|
1731
|
+
return reserve_encoder_1.computeReserveDigest;
|
|
1732
|
+
} });
|
|
1733
|
+
var reserve_encoder_2 = require_reserve_encoder2();
|
|
1734
|
+
Object.defineProperty(exports2, "buildReserveTypedDataWithQuoteSource", { enumerable: true, get: function() {
|
|
1735
|
+
return reserve_encoder_2.buildReserveTypedDataWithQuoteSource;
|
|
1736
|
+
} });
|
|
1737
|
+
Object.defineProperty(exports2, "computeReserveDigestWithQuoteSource", { enumerable: true, get: function() {
|
|
1738
|
+
return reserve_encoder_2.computeReserveDigestWithQuoteSource;
|
|
1739
|
+
} });
|
|
1740
|
+
var release_encoder_1 = require_release_encoder2();
|
|
1741
|
+
Object.defineProperty(exports2, "buildReleaseTypedDataWithQuoteHash", { enumerable: true, get: function() {
|
|
1742
|
+
return release_encoder_1.buildReleaseTypedDataWithQuoteHash;
|
|
1743
|
+
} });
|
|
1744
|
+
Object.defineProperty(exports2, "computeReleaseDigestWithQuoteHash", { enumerable: true, get: function() {
|
|
1745
|
+
return release_encoder_1.computeReleaseDigestWithQuoteHash;
|
|
1746
|
+
} });
|
|
1747
|
+
var refund_encoder_1 = require_refund_encoder2();
|
|
1748
|
+
Object.defineProperty(exports2, "buildRefundTypedDataWithQuoteHash", { enumerable: true, get: function() {
|
|
1749
|
+
return refund_encoder_1.buildRefundTypedDataWithQuoteHash;
|
|
1750
|
+
} });
|
|
1751
|
+
Object.defineProperty(exports2, "computeRefundDigestWithQuoteHash", { enumerable: true, get: function() {
|
|
1752
|
+
return refund_encoder_1.computeRefundDigestWithQuoteHash;
|
|
858
1753
|
} });
|
|
859
1754
|
var deposit_encoder_1 = require_deposit_encoder2();
|
|
860
1755
|
Object.defineProperty(exports2, "createPermitWitnessTransferFromPrehash", { enumerable: true, get: function() {
|
|
@@ -866,6 +1761,13 @@ var require_dist2 = __commonJS({
|
|
|
866
1761
|
Object.defineProperty(exports2, "PERMIT2_CONTRACT_ADDRESS", { enumerable: true, get: function() {
|
|
867
1762
|
return deposit_encoder_1.PERMIT2_CONTRACT_ADDRESS;
|
|
868
1763
|
} });
|
|
1764
|
+
var deposit_encoder_2 = require_deposit_encoder2();
|
|
1765
|
+
Object.defineProperty(exports2, "createPermitWitnessTransferFromPrehashWithDestination", { enumerable: true, get: function() {
|
|
1766
|
+
return deposit_encoder_2.createPermitWitnessTransferFromPrehashWithDestination;
|
|
1767
|
+
} });
|
|
1768
|
+
Object.defineProperty(exports2, "MAX_DESTINATION_BYTES", { enumerable: true, get: function() {
|
|
1769
|
+
return deposit_encoder_2.MAX_DESTINATION_BYTES;
|
|
1770
|
+
} });
|
|
869
1771
|
}
|
|
870
1772
|
});
|
|
871
1773
|
|
|
@@ -906,24 +1808,25 @@ var require_evm = __commonJS({
|
|
|
906
1808
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
907
1809
|
exports2.evmAdapter = void 0;
|
|
908
1810
|
var ethers_1 = require("ethers");
|
|
909
|
-
var evm_escrow_encoding_1 =
|
|
1811
|
+
var evm_escrow_encoding_1 = require_dist3();
|
|
910
1812
|
var utils_js_1 = require_utils();
|
|
1813
|
+
var destination_js_1 = require_destination();
|
|
911
1814
|
var errors_js_1 = require_errors();
|
|
912
1815
|
var chain_id_js_1 = require_chain_id2();
|
|
913
1816
|
exports2.evmAdapter = {
|
|
914
|
-
async buildAuthMessage({ sourceAsset, maxSourceAmount, sourceDefaults, deadline, nonce }) {
|
|
1817
|
+
async buildAuthMessage({ sourceAsset, maxSourceAmount, requestId, sourceDefaults, destinationAsset, destinationAccount, deadline, nonce }) {
|
|
915
1818
|
if (nonce === void 0) {
|
|
916
1819
|
throw new Error("sender_auth: buildAuthMessage requires an explicit nonce \u2014 derive it deterministically from a stable request id (e.g. an order id) so retries reproduce the same permit; pass generatePermitNonce() only for genuinely one-shot builds");
|
|
917
1820
|
}
|
|
918
1821
|
if (deadline === void 0) {
|
|
919
1822
|
throw new Error("sender_auth: buildAuthMessage requires an explicit permit deadline (absolute Unix seconds) \u2014 the low-level builder does not default it; derive it from the payment's fulfillment/settlement deadline in the calling layer (pgc/mppx)");
|
|
920
1823
|
}
|
|
921
|
-
const sourceChainId =
|
|
922
|
-
const chainIdNum =
|
|
923
|
-
const
|
|
924
|
-
const
|
|
1824
|
+
const { network: sourceChainId, asset: tokenAddress } = (0, utils_js_1.parseSourceAsset)(sourceAsset);
|
|
1825
|
+
const chainIdNum = (0, chain_id_js_1.evmChainId)(sourceChainId);
|
|
1826
|
+
const permit2Contract = sourceDefaults.permit2Contract ?? evm_escrow_encoding_1.PERMIT2_CONTRACT_ADDRESS;
|
|
1827
|
+
const basePermit = {
|
|
925
1828
|
chainId: chainIdNum,
|
|
926
|
-
verifyingContract:
|
|
1829
|
+
verifyingContract: permit2Contract,
|
|
927
1830
|
token: tokenAddress,
|
|
928
1831
|
amount: maxSourceAmount,
|
|
929
1832
|
spender: sourceDefaults.escrowContract,
|
|
@@ -932,7 +1835,21 @@ var require_evm = __commonJS({
|
|
|
932
1835
|
reserver: sourceDefaults.quoteSelector,
|
|
933
1836
|
releaser: sourceDefaults.fulfillmentVerifierAccount
|
|
934
1837
|
};
|
|
935
|
-
|
|
1838
|
+
if ((0, destination_js_1.usesDestinationCommitment)(sourceDefaults.depositWitnessVersion)) {
|
|
1839
|
+
const permitParams = {
|
|
1840
|
+
...basePermit,
|
|
1841
|
+
// The two escrow commitments. Composed here through the shared helpers rather than
|
|
1842
|
+
// accepted pre-built, so this producer and the release signer cannot disagree about
|
|
1843
|
+
// formatting — a disagreement the escrow cannot detect, because it stores only
|
|
1844
|
+
// keccak256(bytes(destination)).
|
|
1845
|
+
depositRequestHash: (0, destination_js_1.deriveDepositRequestHash)(requestId),
|
|
1846
|
+
destination: (0, destination_js_1.buildEscrowDestination)(destinationAsset, destinationAccount)
|
|
1847
|
+
};
|
|
1848
|
+
const messagePrehash2 = (0, evm_escrow_encoding_1.createPermitWitnessTransferFromPrehashWithDestination)(permitParams);
|
|
1849
|
+
const messageHash2 = (0, evm_escrow_encoding_1.hashPermitWitnessTransferFrom)(messagePrehash2);
|
|
1850
|
+
return { messageScheme: "EVM_PERMIT2", messageHash: messageHash2, messagePrehash: JSON.stringify(messagePrehash2) };
|
|
1851
|
+
}
|
|
1852
|
+
const messagePrehash = (0, evm_escrow_encoding_1.createPermitWitnessTransferFromPrehash)(basePermit);
|
|
936
1853
|
const messageHash = (0, evm_escrow_encoding_1.hashPermitWitnessTransferFrom)(messagePrehash);
|
|
937
1854
|
return { messageScheme: "EVM_PERMIT2", messageHash, messagePrehash: JSON.stringify(messagePrehash) };
|
|
938
1855
|
},
|
|
@@ -965,17 +1882,31 @@ var require_evm = __commonJS({
|
|
|
965
1882
|
let msg;
|
|
966
1883
|
try {
|
|
967
1884
|
msg = JSON.parse(signed.message_prehash).message;
|
|
968
|
-
|
|
1885
|
+
const base = {
|
|
969
1886
|
chainId: (0, chain_id_js_1.evmChainId)(source.network),
|
|
970
|
-
|
|
1887
|
+
// The same Permit2 buildAuthMessage signed against. Taken from the VERIFIER's
|
|
1888
|
+
// expectations, never from msg — the prehash is client-supplied, so reading the domain
|
|
1889
|
+
// out of it would let a caller nominate its own verifying contract and have the
|
|
1890
|
+
// signature check itself. Absent means canonical, matching the build side's default.
|
|
1891
|
+
verifyingContract: expected.permit2Contract ?? evm_escrow_encoding_1.PERMIT2_CONTRACT_ADDRESS,
|
|
971
1892
|
token: msg.permitted.token,
|
|
972
1893
|
amount: msg.permitted.amount,
|
|
973
1894
|
spender: msg.spender,
|
|
974
1895
|
nonce: BigInt(msg.nonce),
|
|
975
1896
|
deadline: BigInt(msg.deadline),
|
|
976
|
-
reserver: msg.witness
|
|
977
|
-
releaser: msg.witness
|
|
978
|
-
}
|
|
1897
|
+
reserver: msg.witness?.reserver,
|
|
1898
|
+
releaser: msg.witness?.releaser
|
|
1899
|
+
};
|
|
1900
|
+
const hasHash = typeof msg.witness?.depositRequestHash === "string";
|
|
1901
|
+
const hasDestination = typeof msg.witness?.destination === "string";
|
|
1902
|
+
if (hasHash !== hasDestination) {
|
|
1903
|
+
throw new Error("half-populated deposit witness");
|
|
1904
|
+
}
|
|
1905
|
+
canonical = hasHash ? (0, evm_escrow_encoding_1.createPermitWitnessTransferFromPrehashWithDestination)({
|
|
1906
|
+
...base,
|
|
1907
|
+
depositRequestHash: msg.witness.depositRequestHash,
|
|
1908
|
+
destination: msg.witness.destination
|
|
1909
|
+
}) : (0, evm_escrow_encoding_1.createPermitWitnessTransferFromPrehash)(base);
|
|
979
1910
|
} catch {
|
|
980
1911
|
throw new errors_js_1.MalformedPrehashError();
|
|
981
1912
|
}
|
|
@@ -999,6 +1930,12 @@ var require_evm = __commonJS({
|
|
|
999
1930
|
if (expected.reserver !== void 0 && expected.releaser !== void 0) {
|
|
1000
1931
|
(0, utils_js_1.assertWitnessRoles)(msg.witness.reserver, msg.witness.releaser, expected.reserver, expected.releaser, (a) => a);
|
|
1001
1932
|
}
|
|
1933
|
+
if (expected.destination !== void 0) {
|
|
1934
|
+
(0, utils_js_1.assertDestination)(msg.witness.destination, expected.destination);
|
|
1935
|
+
}
|
|
1936
|
+
if (expected.requestId !== void 0) {
|
|
1937
|
+
(0, utils_js_1.assertDepositRequestHash)(msg.witness.depositRequestHash, expected.requestId);
|
|
1938
|
+
}
|
|
1002
1939
|
return {
|
|
1003
1940
|
amount: msg.permitted.amount,
|
|
1004
1941
|
deadlineSec,
|
|
@@ -1009,7 +1946,11 @@ var require_evm = __commonJS({
|
|
|
1009
1946
|
deadlineSec,
|
|
1010
1947
|
reserver: msg.witness.reserver,
|
|
1011
1948
|
releaser: msg.witness.releaser,
|
|
1012
|
-
spender: msg.spender
|
|
1949
|
+
spender: msg.spender,
|
|
1950
|
+
// Surfaced whether or not the opt-in checks above ran, so a consumer binding these
|
|
1951
|
+
// downstream does not have to re-parse message_prehash and risk drifting from this parse.
|
|
1952
|
+
destination: msg.witness.destination,
|
|
1953
|
+
depositRequestHash: msg.witness.depositRequestHash
|
|
1013
1954
|
}
|
|
1014
1955
|
};
|
|
1015
1956
|
}
|
|
@@ -1028,18 +1969,18 @@ var require_tron = __commonJS({
|
|
|
1028
1969
|
var utils_js_1 = require_utils();
|
|
1029
1970
|
var errors_js_1 = require_errors();
|
|
1030
1971
|
var chain_id_js_1 = require_chain_id2();
|
|
1972
|
+
var destination_js_1 = require_destination();
|
|
1031
1973
|
exports2.tronAdapter = {
|
|
1032
|
-
async buildAuthMessage({ sourceAsset, maxSourceAmount, sourceDefaults, deadline, nonce }) {
|
|
1974
|
+
async buildAuthMessage({ sourceAsset, maxSourceAmount, requestId, sourceDefaults, destinationAsset, destinationAccount, deadline, nonce }) {
|
|
1033
1975
|
if (nonce === void 0) {
|
|
1034
1976
|
throw new Error("sender_auth: buildAuthMessage requires an explicit nonce \u2014 derive it deterministically from a stable request id (e.g. an order id) so retries reproduce the same permit; pass generatePermitNonce() only for genuinely one-shot builds");
|
|
1035
1977
|
}
|
|
1036
1978
|
if (deadline === void 0) {
|
|
1037
1979
|
throw new Error("sender_auth: buildAuthMessage requires an explicit permit deadline (absolute Unix seconds) \u2014 the low-level builder does not default it; derive it from the payment's fulfillment/settlement deadline in the calling layer (pgc/mppx)");
|
|
1038
1980
|
}
|
|
1039
|
-
const sourceChainId =
|
|
1040
|
-
const tokenAddress = sourceAsset.split("/")[1].split(":")[1];
|
|
1981
|
+
const { network: sourceChainId, asset: tokenAddress } = (0, utils_js_1.parseSourceAsset)(sourceAsset);
|
|
1041
1982
|
const permit2Address = sourceDefaults.permit2Contract ?? (0, chain_id_js_1.resolveTronPermit2)(sourceChainId);
|
|
1042
|
-
const
|
|
1983
|
+
const baseParams = {
|
|
1043
1984
|
chainId: (0, chain_id_js_1.tronNumericChainId)(sourceChainId),
|
|
1044
1985
|
permit2Address,
|
|
1045
1986
|
tokenAddress,
|
|
@@ -1050,7 +1991,21 @@ var require_tron = __commonJS({
|
|
|
1050
1991
|
reserverAddress: sourceDefaults.quoteSelector,
|
|
1051
1992
|
releaserAddress: sourceDefaults.fulfillmentVerifierAccount
|
|
1052
1993
|
};
|
|
1053
|
-
|
|
1994
|
+
if ((0, destination_js_1.usesDestinationCommitment)(sourceDefaults.depositWitnessVersion)) {
|
|
1995
|
+
const tvmParams = {
|
|
1996
|
+
...baseParams,
|
|
1997
|
+
// The two commitments, composed through the shared helpers rather than accepted
|
|
1998
|
+
// pre-built, so this producer and the Go release signer cannot disagree about
|
|
1999
|
+
// formatting — a disagreement the escrow cannot detect, because it stores only
|
|
2000
|
+
// keccak256(bytes(destination)).
|
|
2001
|
+
depositRequestHash: (0, destination_js_1.deriveDepositRequestHash)(requestId),
|
|
2002
|
+
destination: (0, destination_js_1.buildEscrowDestination)(destinationAsset, destinationAccount)
|
|
2003
|
+
};
|
|
2004
|
+
const messagePrehash2 = (0, tvm_escrow_encoding_1.createTvmPermitWitnessTransferFromPrehashWithDestination)(tvmParams);
|
|
2005
|
+
const messageHash2 = (0, tvm_escrow_encoding_1.hashTvmPermitWitnessTransferFrom)(messagePrehash2);
|
|
2006
|
+
return { messageScheme: "EVM_PERMIT2", messageHash: messageHash2, messagePrehash: JSON.stringify(messagePrehash2) };
|
|
2007
|
+
}
|
|
2008
|
+
const messagePrehash = (0, tvm_escrow_encoding_1.createTvmPermitWitnessTransferFromPrehash)(baseParams);
|
|
1054
2009
|
const messageHash = (0, tvm_escrow_encoding_1.hashTvmPermitWitnessTransferFrom)(messagePrehash);
|
|
1055
2010
|
return { messageScheme: "EVM_PERMIT2", messageHash, messagePrehash: JSON.stringify(messagePrehash) };
|
|
1056
2011
|
},
|
|
@@ -1085,17 +2040,31 @@ var require_tron = __commonJS({
|
|
|
1085
2040
|
let digest;
|
|
1086
2041
|
try {
|
|
1087
2042
|
msg = JSON.parse(signed.message_prehash).message;
|
|
1088
|
-
const
|
|
2043
|
+
const base = {
|
|
1089
2044
|
chainId: (0, chain_id_js_1.tronNumericChainId)(source.network),
|
|
1090
|
-
|
|
2045
|
+
// The same Permit2 buildAuthMessage signed against, taken from the VERIFIER's
|
|
2046
|
+
// expectations rather than from msg — the prehash is payer-supplied, so reading the
|
|
2047
|
+
// domain out of it would let a caller nominate its own verifying contract. Absent means
|
|
2048
|
+
// the pinned per-chain address, matching the build side's default.
|
|
2049
|
+
permit2Address: expected.permit2Contract ?? (0, chain_id_js_1.resolveTronPermit2)(source.network),
|
|
1091
2050
|
tokenAddress: msg.permitted.token,
|
|
1092
2051
|
amount: msg.permitted.amount,
|
|
1093
2052
|
spenderAddress: msg.spender,
|
|
1094
2053
|
nonce: BigInt(msg.nonce),
|
|
1095
2054
|
deadline: BigInt(msg.deadline),
|
|
1096
|
-
reserverAddress: msg.witness
|
|
1097
|
-
releaserAddress: msg.witness
|
|
1098
|
-
}
|
|
2055
|
+
reserverAddress: msg.witness?.reserver,
|
|
2056
|
+
releaserAddress: msg.witness?.releaser
|
|
2057
|
+
};
|
|
2058
|
+
const hasHash = typeof msg.witness?.depositRequestHash === "string";
|
|
2059
|
+
const hasDestination = typeof msg.witness?.destination === "string";
|
|
2060
|
+
if (hasHash !== hasDestination) {
|
|
2061
|
+
throw new Error("half-populated witness");
|
|
2062
|
+
}
|
|
2063
|
+
const canonical = hasHash ? (0, tvm_escrow_encoding_1.createTvmPermitWitnessTransferFromPrehashWithDestination)({
|
|
2064
|
+
...base,
|
|
2065
|
+
depositRequestHash: msg.witness.depositRequestHash,
|
|
2066
|
+
destination: msg.witness.destination
|
|
2067
|
+
}) : (0, tvm_escrow_encoding_1.createTvmPermitWitnessTransferFromPrehash)(base);
|
|
1099
2068
|
digest = (0, tvm_escrow_encoding_1.hashTvmPermitWitnessTransferFrom)(canonical);
|
|
1100
2069
|
} catch {
|
|
1101
2070
|
throw new errors_js_1.MalformedPrehashError();
|
|
@@ -1143,7 +2112,7 @@ var require_errors2 = __commonJS({
|
|
|
1143
2112
|
"../contracts/svm/escrow-encoding/typescript/dist/errors.js"(exports2) {
|
|
1144
2113
|
"use strict";
|
|
1145
2114
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1146
|
-
exports2.InvalidHexError = exports2.InvalidBase58Error = exports2.InvalidPubkeyLengthError = exports2.ZeroDepositHashError = exports2.ZeroRecipientError = exports2.ZeroReleaserError = exports2.ZeroReserverError = exports2.ZeroAmountError = exports2.ZeroMintError = exports2.ZeroDepositorError = exports2.
|
|
2115
|
+
exports2.InvalidEscrowDomainError = exports2.DestinationTooLongError = exports2.EmptyDestinationError = exports2.ZeroSourceAmountError = exports2.ZeroQuoteHashError = exports2.InvalidHexError = exports2.InvalidBase58Error = exports2.InvalidPubkeyLengthError = exports2.ZeroDepositHashError = exports2.ZeroRecipientError = exports2.ZeroReleaserError = exports2.ZeroReserverError = exports2.ZeroAmountError = exports2.ZeroMintError = exports2.ZeroDepositorError = exports2.ZeroDepositRequestHashError = exports2.EncodingError = void 0;
|
|
1147
2116
|
var EncodingError = class extends Error {
|
|
1148
2117
|
constructor(message) {
|
|
1149
2118
|
super(message);
|
|
@@ -1151,13 +2120,13 @@ var require_errors2 = __commonJS({
|
|
|
1151
2120
|
}
|
|
1152
2121
|
};
|
|
1153
2122
|
exports2.EncodingError = EncodingError;
|
|
1154
|
-
var
|
|
2123
|
+
var ZeroDepositRequestHashError = class extends EncodingError {
|
|
1155
2124
|
constructor() {
|
|
1156
|
-
super("
|
|
1157
|
-
this.name = "
|
|
2125
|
+
super("deposit request hash cannot be zero");
|
|
2126
|
+
this.name = "ZeroDepositRequestHashError";
|
|
1158
2127
|
}
|
|
1159
2128
|
};
|
|
1160
|
-
exports2.
|
|
2129
|
+
exports2.ZeroDepositRequestHashError = ZeroDepositRequestHashError;
|
|
1161
2130
|
var ZeroDepositorError = class extends EncodingError {
|
|
1162
2131
|
constructor() {
|
|
1163
2132
|
super("depositor cannot be zero");
|
|
@@ -1228,6 +2197,41 @@ var require_errors2 = __commonJS({
|
|
|
1228
2197
|
}
|
|
1229
2198
|
};
|
|
1230
2199
|
exports2.InvalidHexError = InvalidHexError;
|
|
2200
|
+
var ZeroQuoteHashError = class extends EncodingError {
|
|
2201
|
+
constructor() {
|
|
2202
|
+
super("quote hash cannot be zero");
|
|
2203
|
+
this.name = "ZeroQuoteHashError";
|
|
2204
|
+
}
|
|
2205
|
+
};
|
|
2206
|
+
exports2.ZeroQuoteHashError = ZeroQuoteHashError;
|
|
2207
|
+
var ZeroSourceAmountError = class extends EncodingError {
|
|
2208
|
+
constructor() {
|
|
2209
|
+
super("source amount cannot be zero");
|
|
2210
|
+
this.name = "ZeroSourceAmountError";
|
|
2211
|
+
}
|
|
2212
|
+
};
|
|
2213
|
+
exports2.ZeroSourceAmountError = ZeroSourceAmountError;
|
|
2214
|
+
var EmptyDestinationError = class extends EncodingError {
|
|
2215
|
+
constructor() {
|
|
2216
|
+
super("destination cannot be empty");
|
|
2217
|
+
this.name = "EmptyDestinationError";
|
|
2218
|
+
}
|
|
2219
|
+
};
|
|
2220
|
+
exports2.EmptyDestinationError = EmptyDestinationError;
|
|
2221
|
+
var DestinationTooLongError = class extends EncodingError {
|
|
2222
|
+
constructor() {
|
|
2223
|
+
super("destination exceeds the maximum length");
|
|
2224
|
+
this.name = "DestinationTooLongError";
|
|
2225
|
+
}
|
|
2226
|
+
};
|
|
2227
|
+
exports2.DestinationTooLongError = DestinationTooLongError;
|
|
2228
|
+
var InvalidEscrowDomainError = class extends EncodingError {
|
|
2229
|
+
constructor(message) {
|
|
2230
|
+
super(message);
|
|
2231
|
+
this.name = "InvalidEscrowDomainError";
|
|
2232
|
+
}
|
|
2233
|
+
};
|
|
2234
|
+
exports2.InvalidEscrowDomainError = InvalidEscrowDomainError;
|
|
1231
2235
|
}
|
|
1232
2236
|
});
|
|
1233
2237
|
|
|
@@ -1242,7 +2246,7 @@ var require_pubkey = __commonJS({
|
|
|
1242
2246
|
exports2.Pubkey = void 0;
|
|
1243
2247
|
var bs58_1 = __importDefault(require("bs58"));
|
|
1244
2248
|
var errors_1 = require_errors2();
|
|
1245
|
-
var
|
|
2249
|
+
var Pubkey = class _Pubkey {
|
|
1246
2250
|
constructor(data) {
|
|
1247
2251
|
if (data.length !== 32) {
|
|
1248
2252
|
throw new errors_1.InvalidPubkeyLengthError();
|
|
@@ -1335,7 +2339,7 @@ var require_pubkey = __commonJS({
|
|
|
1335
2339
|
return this.data.every((b, i) => b === other.data[i]);
|
|
1336
2340
|
}
|
|
1337
2341
|
};
|
|
1338
|
-
exports2.Pubkey =
|
|
2342
|
+
exports2.Pubkey = Pubkey;
|
|
1339
2343
|
}
|
|
1340
2344
|
});
|
|
1341
2345
|
|
|
@@ -1936,12 +2940,17 @@ var require_escrow_domain = __commonJS({
|
|
|
1936
2940
|
"use strict";
|
|
1937
2941
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1938
2942
|
exports2.escrowDomainPrefixBytes = escrowDomainPrefixBytes;
|
|
2943
|
+
exports2.newEscrowDomain = newEscrowDomain;
|
|
2944
|
+
var errors_1 = require_errors2();
|
|
1939
2945
|
function escrowDomainPrefixBytes(domain) {
|
|
1940
2946
|
if (domain.clusterId.length !== 32) {
|
|
1941
|
-
throw new
|
|
2947
|
+
throw new errors_1.InvalidEscrowDomainError(`EscrowDomain.clusterId must be 32 bytes, got ${domain.clusterId.length}`);
|
|
2948
|
+
}
|
|
2949
|
+
if (domain.programId.isZero()) {
|
|
2950
|
+
throw new errors_1.InvalidEscrowDomainError("EscrowDomain.programId cannot be zero");
|
|
1942
2951
|
}
|
|
1943
2952
|
if (!Number.isInteger(domain.signatureDomainVersion) || domain.signatureDomainVersion < 1 || domain.signatureDomainVersion > 255) {
|
|
1944
|
-
throw new
|
|
2953
|
+
throw new errors_1.InvalidEscrowDomainError(`EscrowDomain.signatureDomainVersion must be an integer in 1..=255, got ${domain.signatureDomainVersion}`);
|
|
1945
2954
|
}
|
|
1946
2955
|
return [
|
|
1947
2956
|
new TextEncoder().encode("escrow"),
|
|
@@ -1950,6 +2959,25 @@ var require_escrow_domain = __commonJS({
|
|
|
1950
2959
|
domain.programId.toBytes()
|
|
1951
2960
|
];
|
|
1952
2961
|
}
|
|
2962
|
+
function newEscrowDomain(clusterName, signatureDomainVersion, programId) {
|
|
2963
|
+
const trimmed = clusterName.trim();
|
|
2964
|
+
if (trimmed.length === 0) {
|
|
2965
|
+
throw new errors_1.InvalidEscrowDomainError("EscrowDomain cluster name cannot be empty");
|
|
2966
|
+
}
|
|
2967
|
+
const encoded = new TextEncoder().encode(trimmed);
|
|
2968
|
+
if (encoded.length > 32) {
|
|
2969
|
+
throw new errors_1.InvalidEscrowDomainError(`EscrowDomain cluster name "${trimmed}" exceeds 32 bytes`);
|
|
2970
|
+
}
|
|
2971
|
+
if (!Number.isInteger(signatureDomainVersion) || signatureDomainVersion < 1 || signatureDomainVersion > 255) {
|
|
2972
|
+
throw new errors_1.InvalidEscrowDomainError(`EscrowDomain.signatureDomainVersion must be an integer in 1..=255, got ${signatureDomainVersion}`);
|
|
2973
|
+
}
|
|
2974
|
+
if (programId.isZero()) {
|
|
2975
|
+
throw new errors_1.InvalidEscrowDomainError("EscrowDomain.programId cannot be zero");
|
|
2976
|
+
}
|
|
2977
|
+
const clusterId = new Uint8Array(32);
|
|
2978
|
+
clusterId.set(encoded);
|
|
2979
|
+
return { clusterId, signatureDomainVersion, programId };
|
|
2980
|
+
}
|
|
1953
2981
|
}
|
|
1954
2982
|
});
|
|
1955
2983
|
|
|
@@ -1958,13 +2986,36 @@ var require_deposit_encoder3 = __commonJS({
|
|
|
1958
2986
|
"../contracts/svm/escrow-encoding/typescript/dist/deposit-encoder.js"(exports2) {
|
|
1959
2987
|
"use strict";
|
|
1960
2988
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1961
|
-
exports2.
|
|
2989
|
+
exports2.MAX_DESTINATION_LEN = void 0;
|
|
2990
|
+
exports2.computeDepositHash = computeDepositHash;
|
|
2991
|
+
exports2.computeDestinationHash = computeDestinationHash;
|
|
2992
|
+
exports2.computeDepositHashV2 = computeDepositHashV2;
|
|
1962
2993
|
var encoding_utils_1 = require_encoding_utils();
|
|
1963
2994
|
var escrow_domain_1 = require_escrow_domain();
|
|
1964
2995
|
var errors_1 = require_errors2();
|
|
1965
|
-
function
|
|
1966
|
-
if (params.
|
|
1967
|
-
throw new errors_1.
|
|
2996
|
+
function computeDepositHash(params, domain) {
|
|
2997
|
+
if (params.depositRequestHash.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(params.depositRequestHash)) {
|
|
2998
|
+
throw new errors_1.ZeroDepositRequestHashError();
|
|
2999
|
+
}
|
|
3000
|
+
if (params.depositor.isZero())
|
|
3001
|
+
throw new errors_1.ZeroDepositorError();
|
|
3002
|
+
if (params.mint.isZero())
|
|
3003
|
+
throw new errors_1.ZeroMintError();
|
|
3004
|
+
if (params.amount === 0n)
|
|
3005
|
+
throw new errors_1.ZeroAmountError();
|
|
3006
|
+
if (params.reserver.isZero())
|
|
3007
|
+
throw new errors_1.ZeroReserverError();
|
|
3008
|
+
if (params.releaser.isZero())
|
|
3009
|
+
throw new errors_1.ZeroReleaserError();
|
|
3010
|
+
return (0, encoding_utils_1.keccak256)(...(0, escrow_domain_1.escrowDomainPrefixBytes)(domain), (0, encoding_utils_1.stringToBytes)("deposit"), params.depositRequestHash, params.depositor.toBytes(), params.mint.toBytes(), (0, encoding_utils_1.encodeU64LE)(params.amount), params.reserver.toBytes(), params.releaser.toBytes(), (0, encoding_utils_1.encodeU64LE)(params.nonce), (0, encoding_utils_1.encodeU64LE)(params.issuedAt), (0, encoding_utils_1.encodeU64LE)(params.deadline));
|
|
3011
|
+
}
|
|
3012
|
+
exports2.MAX_DESTINATION_LEN = 256;
|
|
3013
|
+
function computeDestinationHash(destination) {
|
|
3014
|
+
return (0, encoding_utils_1.keccak256)((0, encoding_utils_1.stringToBytes)(destination));
|
|
3015
|
+
}
|
|
3016
|
+
function computeDepositHashV2(params, destination, domain) {
|
|
3017
|
+
if (params.depositRequestHash.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(params.depositRequestHash)) {
|
|
3018
|
+
throw new errors_1.ZeroDepositRequestHashError();
|
|
1968
3019
|
}
|
|
1969
3020
|
if (params.depositor.isZero())
|
|
1970
3021
|
throw new errors_1.ZeroDepositorError();
|
|
@@ -1976,7 +3027,28 @@ var require_deposit_encoder3 = __commonJS({
|
|
|
1976
3027
|
throw new errors_1.ZeroReserverError();
|
|
1977
3028
|
if (params.releaser.isZero())
|
|
1978
3029
|
throw new errors_1.ZeroReleaserError();
|
|
1979
|
-
|
|
3030
|
+
if (destination.length === 0)
|
|
3031
|
+
throw new errors_1.EmptyDestinationError();
|
|
3032
|
+
if ((0, encoding_utils_1.stringToBytes)(destination).length > exports2.MAX_DESTINATION_LEN) {
|
|
3033
|
+
throw new errors_1.DestinationTooLongError();
|
|
3034
|
+
}
|
|
3035
|
+
return (0, encoding_utils_1.keccak256)(
|
|
3036
|
+
...(0, escrow_domain_1.escrowDomainPrefixBytes)(domain),
|
|
3037
|
+
(0, encoding_utils_1.stringToBytes)("deposit"),
|
|
3038
|
+
params.depositRequestHash,
|
|
3039
|
+
// Hash first: keccak256 concatenates without length prefixes, so injectivity depends on every
|
|
3040
|
+
// hashed field being fixed-width. Feeding the raw string would make it conditional on the
|
|
3041
|
+
// surrounding widths and diverge from the on-chain program, which hashes it too.
|
|
3042
|
+
computeDestinationHash(destination),
|
|
3043
|
+
params.depositor.toBytes(),
|
|
3044
|
+
params.mint.toBytes(),
|
|
3045
|
+
(0, encoding_utils_1.encodeU64LE)(params.amount),
|
|
3046
|
+
params.reserver.toBytes(),
|
|
3047
|
+
params.releaser.toBytes(),
|
|
3048
|
+
(0, encoding_utils_1.encodeU64LE)(params.nonce),
|
|
3049
|
+
(0, encoding_utils_1.encodeU64LE)(params.issuedAt),
|
|
3050
|
+
(0, encoding_utils_1.encodeU64LE)(params.deadline)
|
|
3051
|
+
);
|
|
1980
3052
|
}
|
|
1981
3053
|
}
|
|
1982
3054
|
});
|
|
@@ -1987,6 +3059,8 @@ var require_reserve_encoder3 = __commonJS({
|
|
|
1987
3059
|
"use strict";
|
|
1988
3060
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1989
3061
|
exports2.computeReserveHash = computeReserveHash;
|
|
3062
|
+
exports2.computeReserveHashV2 = computeReserveHashV2;
|
|
3063
|
+
exports2.computeReserveHashV3 = computeReserveHashV3;
|
|
1990
3064
|
var encoding_utils_1 = require_encoding_utils();
|
|
1991
3065
|
var escrow_domain_1 = require_escrow_domain();
|
|
1992
3066
|
var errors_1 = require_errors2();
|
|
@@ -1998,15 +3072,38 @@ var require_reserve_encoder3 = __commonJS({
|
|
|
1998
3072
|
throw new errors_1.ZeroRecipientError();
|
|
1999
3073
|
return (0, encoding_utils_1.keccak256)(...(0, escrow_domain_1.escrowDomainPrefixBytes)(domain), (0, encoding_utils_1.stringToBytes)("reserve"), params.recipient.toBytes(), params.depositHash);
|
|
2000
3074
|
}
|
|
3075
|
+
function computeReserveHashV2(params, quoteHash, domain) {
|
|
3076
|
+
if (params.depositHash.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(params.depositHash)) {
|
|
3077
|
+
throw new errors_1.ZeroDepositHashError();
|
|
3078
|
+
}
|
|
3079
|
+
if (params.recipient.isZero())
|
|
3080
|
+
throw new errors_1.ZeroRecipientError();
|
|
3081
|
+
if (quoteHash.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(quoteHash))
|
|
3082
|
+
throw new errors_1.ZeroQuoteHashError();
|
|
3083
|
+
return (0, encoding_utils_1.keccak256)(...(0, escrow_domain_1.escrowDomainPrefixBytes)(domain), (0, encoding_utils_1.stringToBytes)("reserve"), params.recipient.toBytes(), params.depositHash, quoteHash);
|
|
3084
|
+
}
|
|
3085
|
+
function computeReserveHashV3(params, quoteHash, sourceAmount, domain) {
|
|
3086
|
+
if (params.depositHash.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(params.depositHash)) {
|
|
3087
|
+
throw new errors_1.ZeroDepositHashError();
|
|
3088
|
+
}
|
|
3089
|
+
if (params.recipient.isZero())
|
|
3090
|
+
throw new errors_1.ZeroRecipientError();
|
|
3091
|
+
if (quoteHash.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(quoteHash))
|
|
3092
|
+
throw new errors_1.ZeroQuoteHashError();
|
|
3093
|
+
if (sourceAmount === 0n)
|
|
3094
|
+
throw new errors_1.ZeroSourceAmountError();
|
|
3095
|
+
return (0, encoding_utils_1.keccak256)(...(0, escrow_domain_1.escrowDomainPrefixBytes)(domain), (0, encoding_utils_1.stringToBytes)("reserve"), params.recipient.toBytes(), params.depositHash, quoteHash, (0, encoding_utils_1.encodeU64LE)(sourceAmount));
|
|
3096
|
+
}
|
|
2001
3097
|
}
|
|
2002
3098
|
});
|
|
2003
3099
|
|
|
2004
3100
|
// ../contracts/svm/escrow-encoding/typescript/dist/release-encoder.js
|
|
2005
|
-
var
|
|
3101
|
+
var require_release_encoder3 = __commonJS({
|
|
2006
3102
|
"../contracts/svm/escrow-encoding/typescript/dist/release-encoder.js"(exports2) {
|
|
2007
3103
|
"use strict";
|
|
2008
3104
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2009
3105
|
exports2.computeReleaseHash = computeReleaseHash;
|
|
3106
|
+
exports2.computeReleaseHashV2 = computeReleaseHashV2;
|
|
2010
3107
|
var encoding_utils_1 = require_encoding_utils();
|
|
2011
3108
|
var escrow_domain_1 = require_escrow_domain();
|
|
2012
3109
|
var errors_1 = require_errors2();
|
|
@@ -2016,15 +3113,22 @@ var require_release_encoder = __commonJS({
|
|
|
2016
3113
|
}
|
|
2017
3114
|
return (0, encoding_utils_1.keccak256)(...(0, escrow_domain_1.escrowDomainPrefixBytes)(domain), (0, encoding_utils_1.stringToBytes)("release"), params.depositHash);
|
|
2018
3115
|
}
|
|
3116
|
+
function computeReleaseHashV2(params, quoteHash, domain) {
|
|
3117
|
+
if (params.depositHash.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(params.depositHash)) {
|
|
3118
|
+
throw new errors_1.ZeroDepositHashError();
|
|
3119
|
+
}
|
|
3120
|
+
return (0, encoding_utils_1.keccak256)(...(0, escrow_domain_1.escrowDomainPrefixBytes)(domain), (0, encoding_utils_1.stringToBytes)("release"), params.depositHash, quoteHash);
|
|
3121
|
+
}
|
|
2019
3122
|
}
|
|
2020
3123
|
});
|
|
2021
3124
|
|
|
2022
3125
|
// ../contracts/svm/escrow-encoding/typescript/dist/refund-encoder.js
|
|
2023
|
-
var
|
|
3126
|
+
var require_refund_encoder3 = __commonJS({
|
|
2024
3127
|
"../contracts/svm/escrow-encoding/typescript/dist/refund-encoder.js"(exports2) {
|
|
2025
3128
|
"use strict";
|
|
2026
3129
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2027
3130
|
exports2.computeRefundHash = computeRefundHash;
|
|
3131
|
+
exports2.computeRefundHashV2 = computeRefundHashV2;
|
|
2028
3132
|
var encoding_utils_1 = require_encoding_utils();
|
|
2029
3133
|
var escrow_domain_1 = require_escrow_domain();
|
|
2030
3134
|
var errors_1 = require_errors2();
|
|
@@ -2034,6 +3138,12 @@ var require_refund_encoder = __commonJS({
|
|
|
2034
3138
|
}
|
|
2035
3139
|
return (0, encoding_utils_1.keccak256)(...(0, escrow_domain_1.escrowDomainPrefixBytes)(domain), (0, encoding_utils_1.stringToBytes)("refund"), params.depositHash);
|
|
2036
3140
|
}
|
|
3141
|
+
function computeRefundHashV2(params, quoteHash, domain) {
|
|
3142
|
+
if (params.depositHash.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(params.depositHash)) {
|
|
3143
|
+
throw new errors_1.ZeroDepositHashError();
|
|
3144
|
+
}
|
|
3145
|
+
return (0, encoding_utils_1.keccak256)(...(0, escrow_domain_1.escrowDomainPrefixBytes)(domain), (0, encoding_utils_1.stringToBytes)("refund"), params.depositHash, quoteHash);
|
|
3146
|
+
}
|
|
2037
3147
|
}
|
|
2038
3148
|
});
|
|
2039
3149
|
|
|
@@ -2042,16 +3152,16 @@ var require_nonce_generator2 = __commonJS({
|
|
|
2042
3152
|
"../contracts/svm/escrow-encoding/typescript/dist/nonce-generator.js"(exports2) {
|
|
2043
3153
|
"use strict";
|
|
2044
3154
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2045
|
-
exports2.MAX_VALID_SLOT = exports2.REPLAY_SLOTS = void 0;
|
|
3155
|
+
exports2.REPLAY_BUCKETS = exports2.MAX_VALID_SLOT = exports2.REPLAY_SLOTS = exports2.DEPOSIT_COMPUTE_UNIT_LIMIT = void 0;
|
|
2046
3156
|
exports2.generateNonce = generateNonce2;
|
|
2047
3157
|
var crypto_1 = require("crypto");
|
|
3158
|
+
exports2.DEPOSIT_COMPUTE_UNIT_LIMIT = 4e5;
|
|
2048
3159
|
exports2.REPLAY_SLOTS = 235;
|
|
2049
3160
|
exports2.MAX_VALID_SLOT = exports2.REPLAY_SLOTS - 1;
|
|
2050
|
-
|
|
3161
|
+
exports2.REPLAY_BUCKETS = 256;
|
|
2051
3162
|
var NONCE_BUCKET_SHIFT = 32n;
|
|
2052
3163
|
function generateNonce2() {
|
|
2053
|
-
const
|
|
2054
|
-
const bucketID = bucketBytes.readUInt32LE(0) & NONCE_BUCKET_MASK;
|
|
3164
|
+
const bucketID = (0, crypto_1.randomBytes)(4).readUInt32LE(0) % exports2.REPLAY_BUCKETS;
|
|
2055
3165
|
let slot;
|
|
2056
3166
|
do {
|
|
2057
3167
|
slot = (0, crypto_1.randomBytes)(1)[0];
|
|
@@ -2062,11 +3172,11 @@ var require_nonce_generator2 = __commonJS({
|
|
|
2062
3172
|
});
|
|
2063
3173
|
|
|
2064
3174
|
// ../contracts/svm/escrow-encoding/typescript/dist/index.js
|
|
2065
|
-
var
|
|
3175
|
+
var require_dist4 = __commonJS({
|
|
2066
3176
|
"../contracts/svm/escrow-encoding/typescript/dist/index.js"(exports2) {
|
|
2067
3177
|
"use strict";
|
|
2068
3178
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2069
|
-
exports2.MAX_VALID_SLOT = exports2.REPLAY_SLOTS = exports2.generateNonce = exports2.computeRefundHash = exports2.computeReleaseHash = exports2.computeReserveHash = exports2.computeDepositHash = exports2.InvalidHexError = exports2.InvalidBase58Error = exports2.InvalidPubkeyLengthError = exports2.ZeroDepositHashError = exports2.ZeroRecipientError = exports2.ZeroReleaserError = exports2.ZeroReserverError = exports2.ZeroAmountError = exports2.ZeroMintError = exports2.ZeroDepositorError = exports2.
|
|
3179
|
+
exports2.DEPOSIT_COMPUTE_UNIT_LIMIT = exports2.REPLAY_BUCKETS = exports2.MAX_VALID_SLOT = exports2.REPLAY_SLOTS = exports2.generateNonce = exports2.computeRefundHashV2 = exports2.computeRefundHash = exports2.computeReleaseHashV2 = exports2.computeReleaseHash = exports2.computeReserveHashV3 = exports2.computeReserveHashV2 = exports2.computeReserveHash = exports2.MAX_DESTINATION_LEN = exports2.computeDestinationHash = exports2.computeDepositHashV2 = exports2.computeDepositHash = exports2.InvalidHexError = exports2.InvalidBase58Error = exports2.InvalidPubkeyLengthError = exports2.InvalidEscrowDomainError = exports2.ZeroSourceAmountError = exports2.ZeroDepositHashError = exports2.ZeroRecipientError = exports2.ZeroReleaserError = exports2.ZeroReserverError = exports2.ZeroAmountError = exports2.ZeroMintError = exports2.ZeroDepositorError = exports2.DestinationTooLongError = exports2.EmptyDestinationError = exports2.ZeroQuoteHashError = exports2.ZeroDepositRequestHashError = exports2.EncodingError = exports2.newEscrowDomain = exports2.escrowDomainPrefixBytes = exports2.isZeroBytes32 = exports2.stringToBytes = exports2.keccak256 = exports2.encodeU64LE = exports2.Pubkey = void 0;
|
|
2070
3180
|
var pubkey_1 = require_pubkey();
|
|
2071
3181
|
Object.defineProperty(exports2, "Pubkey", { enumerable: true, get: function() {
|
|
2072
3182
|
return pubkey_1.Pubkey;
|
|
@@ -2088,12 +3198,24 @@ var require_dist3 = __commonJS({
|
|
|
2088
3198
|
Object.defineProperty(exports2, "escrowDomainPrefixBytes", { enumerable: true, get: function() {
|
|
2089
3199
|
return escrow_domain_1.escrowDomainPrefixBytes;
|
|
2090
3200
|
} });
|
|
3201
|
+
Object.defineProperty(exports2, "newEscrowDomain", { enumerable: true, get: function() {
|
|
3202
|
+
return escrow_domain_1.newEscrowDomain;
|
|
3203
|
+
} });
|
|
2091
3204
|
var errors_1 = require_errors2();
|
|
2092
3205
|
Object.defineProperty(exports2, "EncodingError", { enumerable: true, get: function() {
|
|
2093
3206
|
return errors_1.EncodingError;
|
|
2094
3207
|
} });
|
|
2095
|
-
Object.defineProperty(exports2, "
|
|
2096
|
-
return errors_1.
|
|
3208
|
+
Object.defineProperty(exports2, "ZeroDepositRequestHashError", { enumerable: true, get: function() {
|
|
3209
|
+
return errors_1.ZeroDepositRequestHashError;
|
|
3210
|
+
} });
|
|
3211
|
+
Object.defineProperty(exports2, "ZeroQuoteHashError", { enumerable: true, get: function() {
|
|
3212
|
+
return errors_1.ZeroQuoteHashError;
|
|
3213
|
+
} });
|
|
3214
|
+
Object.defineProperty(exports2, "EmptyDestinationError", { enumerable: true, get: function() {
|
|
3215
|
+
return errors_1.EmptyDestinationError;
|
|
3216
|
+
} });
|
|
3217
|
+
Object.defineProperty(exports2, "DestinationTooLongError", { enumerable: true, get: function() {
|
|
3218
|
+
return errors_1.DestinationTooLongError;
|
|
2097
3219
|
} });
|
|
2098
3220
|
Object.defineProperty(exports2, "ZeroDepositorError", { enumerable: true, get: function() {
|
|
2099
3221
|
return errors_1.ZeroDepositorError;
|
|
@@ -2116,6 +3238,12 @@ var require_dist3 = __commonJS({
|
|
|
2116
3238
|
Object.defineProperty(exports2, "ZeroDepositHashError", { enumerable: true, get: function() {
|
|
2117
3239
|
return errors_1.ZeroDepositHashError;
|
|
2118
3240
|
} });
|
|
3241
|
+
Object.defineProperty(exports2, "ZeroSourceAmountError", { enumerable: true, get: function() {
|
|
3242
|
+
return errors_1.ZeroSourceAmountError;
|
|
3243
|
+
} });
|
|
3244
|
+
Object.defineProperty(exports2, "InvalidEscrowDomainError", { enumerable: true, get: function() {
|
|
3245
|
+
return errors_1.InvalidEscrowDomainError;
|
|
3246
|
+
} });
|
|
2119
3247
|
Object.defineProperty(exports2, "InvalidPubkeyLengthError", { enumerable: true, get: function() {
|
|
2120
3248
|
return errors_1.InvalidPubkeyLengthError;
|
|
2121
3249
|
} });
|
|
@@ -2129,18 +3257,39 @@ var require_dist3 = __commonJS({
|
|
|
2129
3257
|
Object.defineProperty(exports2, "computeDepositHash", { enumerable: true, get: function() {
|
|
2130
3258
|
return deposit_encoder_1.computeDepositHash;
|
|
2131
3259
|
} });
|
|
3260
|
+
Object.defineProperty(exports2, "computeDepositHashV2", { enumerable: true, get: function() {
|
|
3261
|
+
return deposit_encoder_1.computeDepositHashV2;
|
|
3262
|
+
} });
|
|
3263
|
+
Object.defineProperty(exports2, "computeDestinationHash", { enumerable: true, get: function() {
|
|
3264
|
+
return deposit_encoder_1.computeDestinationHash;
|
|
3265
|
+
} });
|
|
3266
|
+
Object.defineProperty(exports2, "MAX_DESTINATION_LEN", { enumerable: true, get: function() {
|
|
3267
|
+
return deposit_encoder_1.MAX_DESTINATION_LEN;
|
|
3268
|
+
} });
|
|
2132
3269
|
var reserve_encoder_1 = require_reserve_encoder3();
|
|
2133
3270
|
Object.defineProperty(exports2, "computeReserveHash", { enumerable: true, get: function() {
|
|
2134
3271
|
return reserve_encoder_1.computeReserveHash;
|
|
2135
3272
|
} });
|
|
2136
|
-
|
|
3273
|
+
Object.defineProperty(exports2, "computeReserveHashV2", { enumerable: true, get: function() {
|
|
3274
|
+
return reserve_encoder_1.computeReserveHashV2;
|
|
3275
|
+
} });
|
|
3276
|
+
Object.defineProperty(exports2, "computeReserveHashV3", { enumerable: true, get: function() {
|
|
3277
|
+
return reserve_encoder_1.computeReserveHashV3;
|
|
3278
|
+
} });
|
|
3279
|
+
var release_encoder_1 = require_release_encoder3();
|
|
2137
3280
|
Object.defineProperty(exports2, "computeReleaseHash", { enumerable: true, get: function() {
|
|
2138
3281
|
return release_encoder_1.computeReleaseHash;
|
|
2139
3282
|
} });
|
|
2140
|
-
|
|
3283
|
+
Object.defineProperty(exports2, "computeReleaseHashV2", { enumerable: true, get: function() {
|
|
3284
|
+
return release_encoder_1.computeReleaseHashV2;
|
|
3285
|
+
} });
|
|
3286
|
+
var refund_encoder_1 = require_refund_encoder3();
|
|
2141
3287
|
Object.defineProperty(exports2, "computeRefundHash", { enumerable: true, get: function() {
|
|
2142
3288
|
return refund_encoder_1.computeRefundHash;
|
|
2143
3289
|
} });
|
|
3290
|
+
Object.defineProperty(exports2, "computeRefundHashV2", { enumerable: true, get: function() {
|
|
3291
|
+
return refund_encoder_1.computeRefundHashV2;
|
|
3292
|
+
} });
|
|
2144
3293
|
var nonce_generator_1 = require_nonce_generator2();
|
|
2145
3294
|
Object.defineProperty(exports2, "generateNonce", { enumerable: true, get: function() {
|
|
2146
3295
|
return nonce_generator_1.generateNonce;
|
|
@@ -2151,6 +3300,12 @@ var require_dist3 = __commonJS({
|
|
|
2151
3300
|
Object.defineProperty(exports2, "MAX_VALID_SLOT", { enumerable: true, get: function() {
|
|
2152
3301
|
return nonce_generator_1.MAX_VALID_SLOT;
|
|
2153
3302
|
} });
|
|
3303
|
+
Object.defineProperty(exports2, "REPLAY_BUCKETS", { enumerable: true, get: function() {
|
|
3304
|
+
return nonce_generator_1.REPLAY_BUCKETS;
|
|
3305
|
+
} });
|
|
3306
|
+
Object.defineProperty(exports2, "DEPOSIT_COMPUTE_UNIT_LIMIT", { enumerable: true, get: function() {
|
|
3307
|
+
return nonce_generator_1.DEPOSIT_COMPUTE_UNIT_LIMIT;
|
|
3308
|
+
} });
|
|
2154
3309
|
}
|
|
2155
3310
|
});
|
|
2156
3311
|
|
|
@@ -2166,7 +3321,8 @@ var require_solana = __commonJS({
|
|
|
2166
3321
|
var ethers_1 = require("ethers");
|
|
2167
3322
|
var tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
2168
3323
|
var bs58_1 = __importDefault(require("bs58"));
|
|
2169
|
-
var solana_escrow_encoding_1 =
|
|
3324
|
+
var solana_escrow_encoding_1 = require_dist4();
|
|
3325
|
+
var destination_js_1 = require_destination();
|
|
2170
3326
|
var utils_js_1 = require_utils();
|
|
2171
3327
|
var errors_js_1 = require_errors();
|
|
2172
3328
|
var chain_id_js_1 = require_chain_id2();
|
|
@@ -2176,7 +3332,8 @@ var require_solana = __commonJS({
|
|
|
2176
3332
|
}
|
|
2177
3333
|
function hashDeposit(prehash, domain) {
|
|
2178
3334
|
return (0, ethers_1.hexlify)((0, solana_escrow_encoding_1.computeDepositHash)({
|
|
2179
|
-
|
|
3335
|
+
// The encoder field was renamed for cross-VM parity; the prehash WIRE key stays payment_id.
|
|
3336
|
+
depositRequestHash: (0, ethers_1.getBytes)(prehash.payment_id),
|
|
2180
3337
|
depositor: solana_escrow_encoding_1.Pubkey.fromBase58(prehash.depositor),
|
|
2181
3338
|
mint: solana_escrow_encoding_1.Pubkey.fromBase58(prehash.mint),
|
|
2182
3339
|
amount: BigInt(prehash.amount),
|
|
@@ -2187,6 +3344,26 @@ var require_solana = __commonJS({
|
|
|
2187
3344
|
deadline: BigInt(prehash.deadline)
|
|
2188
3345
|
}, domain));
|
|
2189
3346
|
}
|
|
3347
|
+
var SVM_DESTINATION_COMMITMENT_VERSION = 4;
|
|
3348
|
+
function hashDepositV2(prehash, domain) {
|
|
3349
|
+
return (0, ethers_1.hexlify)((0, solana_escrow_encoding_1.computeDepositHashV2)(
|
|
3350
|
+
{
|
|
3351
|
+
depositRequestHash: (0, ethers_1.getBytes)(prehash.deposit_request_hash),
|
|
3352
|
+
depositor: solana_escrow_encoding_1.Pubkey.fromBase58(prehash.depositor),
|
|
3353
|
+
mint: solana_escrow_encoding_1.Pubkey.fromBase58(prehash.mint),
|
|
3354
|
+
amount: BigInt(prehash.amount),
|
|
3355
|
+
reserver: solana_escrow_encoding_1.Pubkey.fromBase58(prehash.reserver),
|
|
3356
|
+
releaser: solana_escrow_encoding_1.Pubkey.fromBase58(prehash.releaser),
|
|
3357
|
+
nonce: BigInt(prehash.nonce),
|
|
3358
|
+
issuedAt: BigInt(prehash.issued_at),
|
|
3359
|
+
deadline: BigInt(prehash.deadline)
|
|
3360
|
+
},
|
|
3361
|
+
// Plaintext, NOT pre-hashed: the encoder hashes it, and hashing an already-hashed
|
|
3362
|
+
// destination yields a well-formed commitment no on-chain state can satisfy.
|
|
3363
|
+
prehash.destination,
|
|
3364
|
+
domain
|
|
3365
|
+
));
|
|
3366
|
+
}
|
|
2190
3367
|
function domainFrom(defaults) {
|
|
2191
3368
|
if (!defaults.escrowContract) {
|
|
2192
3369
|
throw new Error("sender_auth: Solana source requires escrowContract (escrow program id) for the deposit-hash domain");
|
|
@@ -2201,12 +3378,11 @@ var require_solana = __commonJS({
|
|
|
2201
3378
|
};
|
|
2202
3379
|
}
|
|
2203
3380
|
exports2.solanaAdapter = {
|
|
2204
|
-
async buildAuthMessage({ sourceAsset, depositor, maxSourceAmount, requestId, sourceDefaults, nonce, solanaClockReader }) {
|
|
3381
|
+
async buildAuthMessage({ sourceAsset, depositor, maxSourceAmount, requestId, sourceDefaults, destinationAsset, destinationAccount, nonce, solanaClockReader }) {
|
|
2205
3382
|
if (!requestId) {
|
|
2206
3383
|
throw new Error("sender_auth: request_id is required");
|
|
2207
3384
|
}
|
|
2208
|
-
const sourceChainId =
|
|
2209
|
-
const tokenMint = sourceAsset.split("/")[1].split(":")[1];
|
|
3385
|
+
const { network: sourceChainId, asset: tokenMint } = (0, utils_js_1.parseSourceAsset)(sourceAsset);
|
|
2210
3386
|
const depositNonce = nonce !== void 0 ? BigInt(nonce) : (0, solana_escrow_encoding_1.generateNonce)();
|
|
2211
3387
|
if (nonce !== void 0) {
|
|
2212
3388
|
if (depositNonce < 0n || depositNonce >= 1n << 64n) {
|
|
@@ -2219,8 +3395,8 @@ var require_solana = __commonJS({
|
|
|
2219
3395
|
const issuedAt = solanaClockReader ? await solanaClockReader(sourceChainId) : BigInt(Math.floor(Date.now() / 1e3));
|
|
2220
3396
|
const deadline = issuedAt + BigInt(utils_js_1.REPLAY_HORIZON_SECS - 8);
|
|
2221
3397
|
const paymentId = generateSolanaPaymentIdV3(requestId);
|
|
2222
|
-
const
|
|
2223
|
-
|
|
3398
|
+
const domain = domainFrom(sourceDefaults);
|
|
3399
|
+
const common = {
|
|
2224
3400
|
depositor,
|
|
2225
3401
|
mint: tokenMint,
|
|
2226
3402
|
amount: BigInt(maxSourceAmount).toString(),
|
|
@@ -2230,7 +3406,20 @@ var require_solana = __commonJS({
|
|
|
2230
3406
|
issued_at: issuedAt.toString(),
|
|
2231
3407
|
deadline: deadline.toString()
|
|
2232
3408
|
};
|
|
2233
|
-
|
|
3409
|
+
if (domain.signatureDomainVersion >= SVM_DESTINATION_COMMITMENT_VERSION) {
|
|
3410
|
+
const prehashV2 = {
|
|
3411
|
+
deposit_request_hash: paymentId,
|
|
3412
|
+
destination: (0, destination_js_1.buildEscrowDestination)(destinationAsset, destinationAccount),
|
|
3413
|
+
...common
|
|
3414
|
+
};
|
|
3415
|
+
return {
|
|
3416
|
+
messageScheme: "SOLANA",
|
|
3417
|
+
messageHash: hashDepositV2(prehashV2, domain),
|
|
3418
|
+
messagePrehash: JSON.stringify(prehashV2)
|
|
3419
|
+
};
|
|
3420
|
+
}
|
|
3421
|
+
const prehash = { payment_id: paymentId, ...common };
|
|
3422
|
+
const depositHash = hashDeposit(prehash, domain);
|
|
2234
3423
|
return { messageScheme: "SOLANA", messageHash: depositHash, messagePrehash: JSON.stringify(prehash) };
|
|
2235
3424
|
},
|
|
2236
3425
|
async sign(signedMessage, privateKey) {
|
|
@@ -2276,8 +3465,18 @@ var require_solana = __commonJS({
|
|
|
2276
3465
|
let prehash;
|
|
2277
3466
|
let canonicalHash;
|
|
2278
3467
|
try {
|
|
2279
|
-
|
|
2280
|
-
|
|
3468
|
+
const domain = domainFrom(expected);
|
|
3469
|
+
if (domain.signatureDomainVersion >= SVM_DESTINATION_COMMITMENT_VERSION) {
|
|
3470
|
+
const v2 = JSON.parse(signed.message_prehash);
|
|
3471
|
+
if (typeof v2.deposit_request_hash !== "string" || typeof v2.destination !== "string") {
|
|
3472
|
+
throw new Error("pre-widening V1 prehash on a destination-committing domain");
|
|
3473
|
+
}
|
|
3474
|
+
canonicalHash = hashDepositV2(v2, domain);
|
|
3475
|
+
prehash = { payment_id: v2.deposit_request_hash, ...v2 };
|
|
3476
|
+
} else {
|
|
3477
|
+
prehash = JSON.parse(signed.message_prehash);
|
|
3478
|
+
canonicalHash = hashDeposit(prehash, domain);
|
|
3479
|
+
}
|
|
2281
3480
|
} catch {
|
|
2282
3481
|
throw new errors_js_1.MalformedPrehashError();
|
|
2283
3482
|
}
|
|
@@ -2369,14 +3568,7 @@ var require_verify = __commonJS({
|
|
|
2369
3568
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2370
3569
|
exports2.verifyPaymentRequest = verifyPaymentRequest;
|
|
2371
3570
|
var index_js_1 = require_adapters();
|
|
2372
|
-
|
|
2373
|
-
const parts = assetIdentifier.split("/");
|
|
2374
|
-
const nsParts = parts[1]?.split(":");
|
|
2375
|
-
if (parts.length < 2 || !nsParts || nsParts.length < 2 || !nsParts[1]) {
|
|
2376
|
-
throw new Error(`sender_auth: invalid source asset "${assetIdentifier}"`);
|
|
2377
|
-
}
|
|
2378
|
-
return { network: parts[0], asset: nsParts[1] };
|
|
2379
|
-
}
|
|
3571
|
+
var utils_js_1 = require_utils();
|
|
2380
3572
|
function verifyPaymentRequest(request2, expected = {}) {
|
|
2381
3573
|
const senderAuth = request2.sender_auth;
|
|
2382
3574
|
if (!senderAuth?.signed_messages?.length) {
|
|
@@ -2385,7 +3577,7 @@ var require_verify = __commonJS({
|
|
|
2385
3577
|
if (!request2.source) {
|
|
2386
3578
|
throw new Error("sender_auth: request has no source");
|
|
2387
3579
|
}
|
|
2388
|
-
const requestSource = parseSourceAsset(request2.source.asset_identifier);
|
|
3580
|
+
const requestSource = (0, utils_js_1.parseSourceAsset)(request2.source.asset_identifier);
|
|
2389
3581
|
const { sourceAsset, network: networkOverride, maxSourceAmount: amountOverride, ...scheme } = expected;
|
|
2390
3582
|
const network = networkOverride ?? requestSource.network;
|
|
2391
3583
|
const asset = sourceAsset ?? requestSource.asset;
|
|
@@ -2420,7 +3612,7 @@ var require_signer = __commonJS({
|
|
|
2420
3612
|
});
|
|
2421
3613
|
|
|
2422
3614
|
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/index.js
|
|
2423
|
-
var
|
|
3615
|
+
var require_dist5 = __commonJS({
|
|
2424
3616
|
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/index.js"(exports2) {
|
|
2425
3617
|
"use strict";
|
|
2426
3618
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -2440,32 +3632,427 @@ var require_dist4 = __commonJS({
|
|
|
2440
3632
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
2441
3633
|
};
|
|
2442
3634
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2443
|
-
exports2.localKeySigner = exports2.SignerMismatchError = exports2.RecoveryFailedError = exports2.MalformedPrehashError = exports2.verifyPaymentRequest = exports2.getChainAdapter = void 0;
|
|
2444
|
-
__exportStar(require_types(), exports2);
|
|
2445
|
-
__exportStar(require_utils(), exports2);
|
|
2446
|
-
__exportStar(require_chain_id2(), exports2);
|
|
2447
|
-
var index_js_1 = require_adapters();
|
|
2448
|
-
Object.defineProperty(exports2, "getChainAdapter", { enumerable: true, get: function() {
|
|
2449
|
-
return index_js_1.getChainAdapter;
|
|
3635
|
+
exports2.localKeySigner = exports2.SignerMismatchError = exports2.RecoveryFailedError = exports2.MalformedPrehashError = exports2.verifyPaymentRequest = exports2.DESTINATION_COMMITMENT_WITNESS_VERSION = exports2.usesDestinationCommitment = exports2.MAX_DESTINATION_BYTES = exports2.deriveDepositRequestHash = exports2.buildEscrowDestination = exports2.getChainAdapter = void 0;
|
|
3636
|
+
__exportStar(require_types(), exports2);
|
|
3637
|
+
__exportStar(require_utils(), exports2);
|
|
3638
|
+
__exportStar(require_chain_id2(), exports2);
|
|
3639
|
+
var index_js_1 = require_adapters();
|
|
3640
|
+
Object.defineProperty(exports2, "getChainAdapter", { enumerable: true, get: function() {
|
|
3641
|
+
return index_js_1.getChainAdapter;
|
|
3642
|
+
} });
|
|
3643
|
+
var destination_js_1 = require_destination();
|
|
3644
|
+
Object.defineProperty(exports2, "buildEscrowDestination", { enumerable: true, get: function() {
|
|
3645
|
+
return destination_js_1.buildEscrowDestination;
|
|
3646
|
+
} });
|
|
3647
|
+
Object.defineProperty(exports2, "deriveDepositRequestHash", { enumerable: true, get: function() {
|
|
3648
|
+
return destination_js_1.deriveDepositRequestHash;
|
|
3649
|
+
} });
|
|
3650
|
+
Object.defineProperty(exports2, "MAX_DESTINATION_BYTES", { enumerable: true, get: function() {
|
|
3651
|
+
return destination_js_1.MAX_DESTINATION_BYTES;
|
|
3652
|
+
} });
|
|
3653
|
+
Object.defineProperty(exports2, "usesDestinationCommitment", { enumerable: true, get: function() {
|
|
3654
|
+
return destination_js_1.usesDestinationCommitment;
|
|
3655
|
+
} });
|
|
3656
|
+
Object.defineProperty(exports2, "DESTINATION_COMMITMENT_WITNESS_VERSION", { enumerable: true, get: function() {
|
|
3657
|
+
return destination_js_1.DESTINATION_COMMITMENT_WITNESS_VERSION;
|
|
3658
|
+
} });
|
|
3659
|
+
var verify_js_1 = require_verify();
|
|
3660
|
+
Object.defineProperty(exports2, "verifyPaymentRequest", { enumerable: true, get: function() {
|
|
3661
|
+
return verify_js_1.verifyPaymentRequest;
|
|
3662
|
+
} });
|
|
3663
|
+
var errors_js_1 = require_errors();
|
|
3664
|
+
Object.defineProperty(exports2, "MalformedPrehashError", { enumerable: true, get: function() {
|
|
3665
|
+
return errors_js_1.MalformedPrehashError;
|
|
3666
|
+
} });
|
|
3667
|
+
Object.defineProperty(exports2, "RecoveryFailedError", { enumerable: true, get: function() {
|
|
3668
|
+
return errors_js_1.RecoveryFailedError;
|
|
3669
|
+
} });
|
|
3670
|
+
Object.defineProperty(exports2, "SignerMismatchError", { enumerable: true, get: function() {
|
|
3671
|
+
return errors_js_1.SignerMismatchError;
|
|
3672
|
+
} });
|
|
3673
|
+
var signer_js_1 = require_signer();
|
|
3674
|
+
Object.defineProperty(exports2, "localKeySigner", { enumerable: true, get: function() {
|
|
3675
|
+
return signer_js_1.localKeySigner;
|
|
3676
|
+
} });
|
|
3677
|
+
}
|
|
3678
|
+
});
|
|
3679
|
+
|
|
3680
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/allowance.js
|
|
3681
|
+
var require_allowance = __commonJS({
|
|
3682
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/allowance.js"(exports2) {
|
|
3683
|
+
"use strict";
|
|
3684
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3685
|
+
exports2.UNLIMITED_APPROVAL_FLOOR = exports2.UNLIMITED_APPROVAL = void 0;
|
|
3686
|
+
exports2.isAllowanceSufficient = isAllowanceSufficient;
|
|
3687
|
+
exports2.effectiveRequirement = effectiveRequirement;
|
|
3688
|
+
exports2.resolveApprovalAmount = resolveApprovalAmount;
|
|
3689
|
+
var ethers_1 = require("ethers");
|
|
3690
|
+
exports2.UNLIMITED_APPROVAL = ethers_1.MaxUint256;
|
|
3691
|
+
exports2.UNLIMITED_APPROVAL_FLOOR = ethers_1.MaxUint256 / 2n;
|
|
3692
|
+
function isAllowanceSufficient(current, requiredAllowance) {
|
|
3693
|
+
return requiredAllowance !== void 0 ? current >= requiredAllowance : current >= exports2.UNLIMITED_APPROVAL_FLOOR;
|
|
3694
|
+
}
|
|
3695
|
+
function effectiveRequirement(requiredAllowance, approvalAmount) {
|
|
3696
|
+
return requiredAllowance ?? approvalAmount;
|
|
3697
|
+
}
|
|
3698
|
+
function resolveApprovalAmount(approvalAmount, requiredAllowance) {
|
|
3699
|
+
if (approvalAmount === void 0)
|
|
3700
|
+
return exports2.UNLIMITED_APPROVAL;
|
|
3701
|
+
if (approvalAmount <= 0n) {
|
|
3702
|
+
throw new Error(`token_approval: approvalAmount must be positive, got ${approvalAmount}`);
|
|
3703
|
+
}
|
|
3704
|
+
if (requiredAllowance !== void 0 && approvalAmount < requiredAllowance) {
|
|
3705
|
+
throw new Error(`token_approval: approvalAmount ${approvalAmount} is below requiredAllowance ${requiredAllowance}, so the approval would still fall short and every call would send another one`);
|
|
3706
|
+
}
|
|
3707
|
+
return approvalAmount;
|
|
3708
|
+
}
|
|
3709
|
+
}
|
|
3710
|
+
});
|
|
3711
|
+
|
|
3712
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/adapters/unconfirmed.js
|
|
3713
|
+
var require_unconfirmed = __commonJS({
|
|
3714
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/adapters/unconfirmed.js"(exports2) {
|
|
3715
|
+
"use strict";
|
|
3716
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3717
|
+
exports2.unconfirmed = unconfirmed;
|
|
3718
|
+
exports2.isUnconfirmed = isUnconfirmed2;
|
|
3719
|
+
function unconfirmed(message) {
|
|
3720
|
+
return Object.assign(new Error(message), { unconfirmed: true });
|
|
3721
|
+
}
|
|
3722
|
+
function isUnconfirmed2(error) {
|
|
3723
|
+
return error?.unconfirmed === true;
|
|
3724
|
+
}
|
|
3725
|
+
}
|
|
3726
|
+
});
|
|
3727
|
+
|
|
3728
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/adapters/evm.js
|
|
3729
|
+
var require_evm2 = __commonJS({
|
|
3730
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/adapters/evm.js"(exports2) {
|
|
3731
|
+
"use strict";
|
|
3732
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3733
|
+
exports2.evmAdapter = exports2.ERC20_ALLOWANCE_ABI = void 0;
|
|
3734
|
+
var ethers_1 = require("ethers");
|
|
3735
|
+
var evm_escrow_encoding_1 = require_dist3();
|
|
3736
|
+
var unconfirmed_js_1 = require_unconfirmed();
|
|
3737
|
+
exports2.ERC20_ALLOWANCE_ABI = [
|
|
3738
|
+
"function allowance(address owner, address spender) view returns (uint256)",
|
|
3739
|
+
"function approve(address spender, uint256 amount) returns (bool)"
|
|
3740
|
+
];
|
|
3741
|
+
var DEFAULT_CONFIRMATION_TIMEOUT_MS = 6e4;
|
|
3742
|
+
function requireSigner(params) {
|
|
3743
|
+
if (!params.signer) {
|
|
3744
|
+
throw new Error(`token_approval: approving on ${params.network} needs an ethers signer connected to that chain (params.signer)`);
|
|
3745
|
+
}
|
|
3746
|
+
return params.signer;
|
|
3747
|
+
}
|
|
3748
|
+
function erc20(params) {
|
|
3749
|
+
return new ethers_1.Contract(params.token, exports2.ERC20_ALLOWANCE_ABI, requireSigner(params));
|
|
3750
|
+
}
|
|
3751
|
+
async function send(params, call, purpose) {
|
|
3752
|
+
const tx = await call;
|
|
3753
|
+
params.onSubmitted?.(tx.hash, purpose);
|
|
3754
|
+
const timeoutMs = params.confirmation?.timeoutMs ?? DEFAULT_CONFIRMATION_TIMEOUT_MS;
|
|
3755
|
+
try {
|
|
3756
|
+
await tx.wait(1, timeoutMs);
|
|
3757
|
+
} catch (error) {
|
|
3758
|
+
if (isTimeout(error)) {
|
|
3759
|
+
throw (0, unconfirmed_js_1.unconfirmed)(`token_approval: the ${purpose === "reset" ? "allowance reset" : "approval"} ${tx.hash} was not confirmed within ${timeoutMs}ms. It may still confirm \u2014 check the transaction before approving again.`);
|
|
3760
|
+
}
|
|
3761
|
+
throw error;
|
|
3762
|
+
}
|
|
3763
|
+
return tx.hash;
|
|
3764
|
+
}
|
|
3765
|
+
function isTimeout(error) {
|
|
3766
|
+
return error?.code === "TIMEOUT";
|
|
3767
|
+
}
|
|
3768
|
+
exports2.evmAdapter = {
|
|
3769
|
+
applicable: true,
|
|
3770
|
+
resolveSpender(params) {
|
|
3771
|
+
return params.spender ?? evm_escrow_encoding_1.PERMIT2_CONTRACT_ADDRESS;
|
|
3772
|
+
},
|
|
3773
|
+
async senderAddress(params) {
|
|
3774
|
+
return await requireSigner(params).getAddress();
|
|
3775
|
+
},
|
|
3776
|
+
async readAllowance(params, spender) {
|
|
3777
|
+
return await erc20(params).allowance(params.owner, spender);
|
|
3778
|
+
},
|
|
3779
|
+
async approve(params, spender, amount, current) {
|
|
3780
|
+
const token = erc20(params);
|
|
3781
|
+
if (current !== 0n && await refusesOverwrite(params, token, spender, amount)) {
|
|
3782
|
+
const nonce = await requireSigner(params).getNonce("pending");
|
|
3783
|
+
const resetTxHash = await send(params, token.approve(spender, 0n, { nonce }), "reset");
|
|
3784
|
+
try {
|
|
3785
|
+
return {
|
|
3786
|
+
txHash: await send(params, token.approve(spender, amount, { nonce: nonce + 1 }), "approval"),
|
|
3787
|
+
resetTxHash
|
|
3788
|
+
};
|
|
3789
|
+
} catch (error) {
|
|
3790
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
3791
|
+
if ((0, unconfirmed_js_1.isUnconfirmed)(error)) {
|
|
3792
|
+
throw (0, unconfirmed_js_1.unconfirmed)(`token_approval: the allowance was reset to 0 in ${resetTxHash} and the new approval was broadcast but not confirmed (${detail}). If it lands the allowance is ${amount}; if it does not, it stays 0. Check that transaction before approving again.`);
|
|
3793
|
+
}
|
|
3794
|
+
throw new Error(`token_approval: the allowance was reset to 0 in ${resetTxHash}, but the new approval did not go through (${detail}). The allowance is currently 0 \u2014 re-run to finish.`);
|
|
3795
|
+
}
|
|
3796
|
+
}
|
|
3797
|
+
return { txHash: await send(params, token.approve(spender, amount), "approval") };
|
|
3798
|
+
}
|
|
3799
|
+
};
|
|
3800
|
+
async function refusesOverwrite(params, token, spender, amount) {
|
|
3801
|
+
const data = token.interface.encodeFunctionData("approve", [spender, amount]);
|
|
3802
|
+
try {
|
|
3803
|
+
await requireSigner(params).call({ to: params.token, data });
|
|
3804
|
+
return false;
|
|
3805
|
+
} catch (error) {
|
|
3806
|
+
if (isRevert(error))
|
|
3807
|
+
return true;
|
|
3808
|
+
throw error;
|
|
3809
|
+
}
|
|
3810
|
+
}
|
|
3811
|
+
function isRevert(error) {
|
|
3812
|
+
return error?.code === "CALL_EXCEPTION";
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
});
|
|
3816
|
+
|
|
3817
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/adapters/tron.js
|
|
3818
|
+
var require_tron2 = __commonJS({
|
|
3819
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/adapters/tron.js"(exports2) {
|
|
3820
|
+
"use strict";
|
|
3821
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3822
|
+
exports2.tronAdapter = exports2.TRC20_ALLOWANCE_ABI = void 0;
|
|
3823
|
+
var payment_request_sender_auth_1 = require_dist5();
|
|
3824
|
+
var unconfirmed_js_1 = require_unconfirmed();
|
|
3825
|
+
exports2.TRC20_ALLOWANCE_ABI = [
|
|
3826
|
+
{
|
|
3827
|
+
name: "allowance",
|
|
3828
|
+
type: "function",
|
|
3829
|
+
stateMutability: "View",
|
|
3830
|
+
inputs: [
|
|
3831
|
+
{ name: "owner", type: "address" },
|
|
3832
|
+
{ name: "spender", type: "address" }
|
|
3833
|
+
],
|
|
3834
|
+
outputs: [{ type: "uint256" }]
|
|
3835
|
+
},
|
|
3836
|
+
{
|
|
3837
|
+
name: "approve",
|
|
3838
|
+
type: "function",
|
|
3839
|
+
stateMutability: "Nonpayable",
|
|
3840
|
+
inputs: [
|
|
3841
|
+
{ name: "spender", type: "address" },
|
|
3842
|
+
{ name: "amount", type: "uint256" }
|
|
3843
|
+
],
|
|
3844
|
+
outputs: [{ type: "bool" }]
|
|
3845
|
+
}
|
|
3846
|
+
];
|
|
3847
|
+
var DEFAULT_FEE_LIMIT = 1e8;
|
|
3848
|
+
var DEFAULT_CONFIRMATION_TIMEOUT_MS = 6e4;
|
|
3849
|
+
var DEFAULT_POLL_INTERVAL_MS2 = 1500;
|
|
3850
|
+
function requireTronWeb(params) {
|
|
3851
|
+
if (!params.tronWeb) {
|
|
3852
|
+
throw new Error(`token_approval: approving on ${params.network} needs a TronWeb instance configured for that chain (params.tronWeb)`);
|
|
3853
|
+
}
|
|
3854
|
+
return params.tronWeb;
|
|
3855
|
+
}
|
|
3856
|
+
function token(params) {
|
|
3857
|
+
return requireTronWeb(params).contract(exports2.TRC20_ALLOWANCE_ABI, params.token);
|
|
3858
|
+
}
|
|
3859
|
+
var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
3860
|
+
async function waitForConfirmation(tronWeb, txId, options) {
|
|
3861
|
+
const timeoutMs = options?.timeoutMs ?? DEFAULT_CONFIRMATION_TIMEOUT_MS;
|
|
3862
|
+
const pollIntervalMs = options?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS2;
|
|
3863
|
+
const deadline = Date.now() + timeoutMs;
|
|
3864
|
+
for (; ; ) {
|
|
3865
|
+
let result;
|
|
3866
|
+
try {
|
|
3867
|
+
result = (await tronWeb.trx.getTransactionInfo(txId))?.receipt?.result;
|
|
3868
|
+
} catch {
|
|
3869
|
+
}
|
|
3870
|
+
if (result === "SUCCESS")
|
|
3871
|
+
return;
|
|
3872
|
+
if (result !== void 0) {
|
|
3873
|
+
throw new Error(`token_approval: Tron approval ${txId} failed on-chain (${result})`);
|
|
3874
|
+
}
|
|
3875
|
+
if (Date.now() >= deadline) {
|
|
3876
|
+
throw (0, unconfirmed_js_1.unconfirmed)(`token_approval: Tron approval ${txId} was not confirmed within ${timeoutMs}ms. It may still confirm \u2014 check the transaction before approving again.`);
|
|
3877
|
+
}
|
|
3878
|
+
await sleep(pollIntervalMs);
|
|
3879
|
+
}
|
|
3880
|
+
}
|
|
3881
|
+
async function send(params, contract, spender, amount, purpose) {
|
|
3882
|
+
const txId = await contract.approve(spender, amount.toString()).send({ feeLimit: params.confirmation?.feeLimit ?? DEFAULT_FEE_LIMIT });
|
|
3883
|
+
params.onSubmitted?.(txId, purpose);
|
|
3884
|
+
await waitForConfirmation(requireTronWeb(params), txId, params.confirmation);
|
|
3885
|
+
return txId;
|
|
3886
|
+
}
|
|
3887
|
+
exports2.tronAdapter = {
|
|
3888
|
+
applicable: true,
|
|
3889
|
+
resolveSpender(params) {
|
|
3890
|
+
return params.spender ?? (0, payment_request_sender_auth_1.resolveTronPermit2)(params.network);
|
|
3891
|
+
},
|
|
3892
|
+
async senderAddress(params) {
|
|
3893
|
+
return requireTronWeb(params).defaultAddress?.base58 || void 0;
|
|
3894
|
+
},
|
|
3895
|
+
async readAllowance(params, spender) {
|
|
3896
|
+
const raw = await token(params).allowance(params.owner, spender).call();
|
|
3897
|
+
return BigInt(String(raw));
|
|
3898
|
+
},
|
|
3899
|
+
async approve(params, spender, amount, current) {
|
|
3900
|
+
const contract = token(params);
|
|
3901
|
+
try {
|
|
3902
|
+
return { txHash: await send(params, contract, spender, amount, "approval") };
|
|
3903
|
+
} catch (error) {
|
|
3904
|
+
if (current === 0n || (0, unconfirmed_js_1.isUnconfirmed)(error))
|
|
3905
|
+
throw error;
|
|
3906
|
+
throw new Error(`token_approval: the approval on ${params.network} failed while an allowance of ${current} was already set (${error instanceof Error ? error.message : String(error)}). Some tokens refuse to replace a non-zero allowance in place: approve 0 first, then retry.`);
|
|
3907
|
+
}
|
|
3908
|
+
}
|
|
3909
|
+
};
|
|
3910
|
+
}
|
|
3911
|
+
});
|
|
3912
|
+
|
|
3913
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/adapters/solana.js
|
|
3914
|
+
var require_solana2 = __commonJS({
|
|
3915
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/adapters/solana.js"(exports2) {
|
|
3916
|
+
"use strict";
|
|
3917
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3918
|
+
exports2.solanaAdapter = void 0;
|
|
3919
|
+
exports2.solanaAdapter = {
|
|
3920
|
+
applicable: false,
|
|
3921
|
+
resolveSpender() {
|
|
3922
|
+
throw new Error("token_approval: Solana does not use a Permit2-style allowance");
|
|
3923
|
+
},
|
|
3924
|
+
async senderAddress() {
|
|
3925
|
+
throw new Error("token_approval: Solana does not use a Permit2-style allowance");
|
|
3926
|
+
},
|
|
3927
|
+
async readAllowance() {
|
|
3928
|
+
throw new Error("token_approval: Solana does not use a Permit2-style allowance");
|
|
3929
|
+
},
|
|
3930
|
+
async approve() {
|
|
3931
|
+
throw new Error("token_approval: Solana does not use a Permit2-style allowance");
|
|
3932
|
+
}
|
|
3933
|
+
};
|
|
3934
|
+
}
|
|
3935
|
+
});
|
|
3936
|
+
|
|
3937
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/adapters/index.js
|
|
3938
|
+
var require_adapters2 = __commonJS({
|
|
3939
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/adapters/index.js"(exports2) {
|
|
3940
|
+
"use strict";
|
|
3941
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3942
|
+
exports2.approvalAdapterFor = approvalAdapterFor;
|
|
3943
|
+
var payment_request_sender_auth_1 = require_dist5();
|
|
3944
|
+
var evm_js_1 = require_evm2();
|
|
3945
|
+
var tron_js_1 = require_tron2();
|
|
3946
|
+
var solana_js_1 = require_solana2();
|
|
3947
|
+
var ADAPTERS = {
|
|
3948
|
+
eip155: evm_js_1.evmAdapter,
|
|
3949
|
+
tron: tron_js_1.tronAdapter,
|
|
3950
|
+
solana: solana_js_1.solanaAdapter
|
|
3951
|
+
};
|
|
3952
|
+
function approvalAdapterFor(network) {
|
|
3953
|
+
const namespace = (0, payment_request_sender_auth_1.namespaceOf)(network);
|
|
3954
|
+
const adapter = Object.hasOwn(ADAPTERS, namespace) ? ADAPTERS[namespace] : void 0;
|
|
3955
|
+
if (!adapter) {
|
|
3956
|
+
throw new Error(`token_approval: no approval adapter for network '${network}'`);
|
|
3957
|
+
}
|
|
3958
|
+
return adapter;
|
|
3959
|
+
}
|
|
3960
|
+
}
|
|
3961
|
+
});
|
|
3962
|
+
|
|
3963
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/sender.js
|
|
3964
|
+
var require_sender = __commonJS({
|
|
3965
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/sender.js"(exports2) {
|
|
3966
|
+
"use strict";
|
|
3967
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3968
|
+
exports2.assertSenderIsOwner = assertSenderIsOwner;
|
|
3969
|
+
function assertSenderIsOwner(owner, sender) {
|
|
3970
|
+
if (sender === void 0 || sender.toLowerCase() === owner.toLowerCase())
|
|
3971
|
+
return;
|
|
3972
|
+
throw new Error(`token_approval: the approval would be sent by ${sender}, but the allowance is being granted for ${owner}. An approval only ever applies to the account that sends it, so this would approve ${sender} and leave ${owner} unable to pay. Pass a signer for ${owner}, or read the allowance for ${sender}.`);
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3975
|
+
});
|
|
3976
|
+
|
|
3977
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/index.js
|
|
3978
|
+
var require_dist6 = __commonJS({
|
|
3979
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/token-approval/dist/index.js"(exports2) {
|
|
3980
|
+
"use strict";
|
|
3981
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3982
|
+
exports2.approvalAdapterFor = exports2.isUnconfirmed = exports2.assertSenderIsOwner = exports2.resolveApprovalAmount = exports2.isAllowanceSufficient = exports2.effectiveRequirement = exports2.UNLIMITED_APPROVAL_FLOOR = exports2.UNLIMITED_APPROVAL = void 0;
|
|
3983
|
+
exports2.needsSourceApproval = needsSourceApproval2;
|
|
3984
|
+
exports2.ensureSourceApproval = ensureSourceApproval2;
|
|
3985
|
+
var allowance_js_1 = require_allowance();
|
|
3986
|
+
var index_js_1 = require_adapters2();
|
|
3987
|
+
var sender_js_1 = require_sender();
|
|
3988
|
+
var allowance_js_2 = require_allowance();
|
|
3989
|
+
Object.defineProperty(exports2, "UNLIMITED_APPROVAL", { enumerable: true, get: function() {
|
|
3990
|
+
return allowance_js_2.UNLIMITED_APPROVAL;
|
|
2450
3991
|
} });
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
return verify_js_1.verifyPaymentRequest;
|
|
3992
|
+
Object.defineProperty(exports2, "UNLIMITED_APPROVAL_FLOOR", { enumerable: true, get: function() {
|
|
3993
|
+
return allowance_js_2.UNLIMITED_APPROVAL_FLOOR;
|
|
2454
3994
|
} });
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
return errors_js_1.MalformedPrehashError;
|
|
3995
|
+
Object.defineProperty(exports2, "effectiveRequirement", { enumerable: true, get: function() {
|
|
3996
|
+
return allowance_js_2.effectiveRequirement;
|
|
2458
3997
|
} });
|
|
2459
|
-
Object.defineProperty(exports2, "
|
|
2460
|
-
return
|
|
3998
|
+
Object.defineProperty(exports2, "isAllowanceSufficient", { enumerable: true, get: function() {
|
|
3999
|
+
return allowance_js_2.isAllowanceSufficient;
|
|
2461
4000
|
} });
|
|
2462
|
-
Object.defineProperty(exports2, "
|
|
2463
|
-
return
|
|
4001
|
+
Object.defineProperty(exports2, "resolveApprovalAmount", { enumerable: true, get: function() {
|
|
4002
|
+
return allowance_js_2.resolveApprovalAmount;
|
|
2464
4003
|
} });
|
|
2465
|
-
var
|
|
2466
|
-
Object.defineProperty(exports2, "
|
|
2467
|
-
return
|
|
4004
|
+
var sender_js_2 = require_sender();
|
|
4005
|
+
Object.defineProperty(exports2, "assertSenderIsOwner", { enumerable: true, get: function() {
|
|
4006
|
+
return sender_js_2.assertSenderIsOwner;
|
|
4007
|
+
} });
|
|
4008
|
+
var unconfirmed_js_1 = require_unconfirmed();
|
|
4009
|
+
Object.defineProperty(exports2, "isUnconfirmed", { enumerable: true, get: function() {
|
|
4010
|
+
return unconfirmed_js_1.isUnconfirmed;
|
|
2468
4011
|
} });
|
|
4012
|
+
var index_js_2 = require_adapters2();
|
|
4013
|
+
Object.defineProperty(exports2, "approvalAdapterFor", { enumerable: true, get: function() {
|
|
4014
|
+
return index_js_2.approvalAdapterFor;
|
|
4015
|
+
} });
|
|
4016
|
+
async function needsSourceApproval2(params) {
|
|
4017
|
+
const adapter = (0, index_js_1.approvalAdapterFor)(params.network);
|
|
4018
|
+
if (!adapter.applicable)
|
|
4019
|
+
return false;
|
|
4020
|
+
const required = (0, allowance_js_1.effectiveRequirement)(params.requiredAllowance, params.approvalAmount);
|
|
4021
|
+
(0, allowance_js_1.resolveApprovalAmount)(params.approvalAmount, required);
|
|
4022
|
+
const spender = adapter.resolveSpender(params);
|
|
4023
|
+
const current = await adapter.readAllowance(params, spender);
|
|
4024
|
+
return !(0, allowance_js_1.isAllowanceSufficient)(current, required);
|
|
4025
|
+
}
|
|
4026
|
+
async function ensureSourceApproval2(params) {
|
|
4027
|
+
const adapter = (0, index_js_1.approvalAdapterFor)(params.network);
|
|
4028
|
+
if (!adapter.applicable)
|
|
4029
|
+
return { alreadySufficient: true };
|
|
4030
|
+
const required = (0, allowance_js_1.effectiveRequirement)(params.requiredAllowance, params.approvalAmount);
|
|
4031
|
+
const amount = (0, allowance_js_1.resolveApprovalAmount)(params.approvalAmount, required);
|
|
4032
|
+
const spender = adapter.resolveSpender(params);
|
|
4033
|
+
const current = await adapter.readAllowance(params, spender);
|
|
4034
|
+
if ((0, allowance_js_1.isAllowanceSufficient)(current, required)) {
|
|
4035
|
+
return { alreadySufficient: true };
|
|
4036
|
+
}
|
|
4037
|
+
(0, sender_js_1.assertSenderIsOwner)(params.owner, await adapter.senderAddress(params));
|
|
4038
|
+
return { alreadySufficient: false, ...await adapter.approve(params, spender, amount, current) };
|
|
4039
|
+
}
|
|
4040
|
+
}
|
|
4041
|
+
});
|
|
4042
|
+
|
|
4043
|
+
// src/signers/pinned-address.ts
|
|
4044
|
+
function requirePinnedSender(pinnedAddress) {
|
|
4045
|
+
if (pinnedAddress === null || pinnedAddress === void 0) return void 0;
|
|
4046
|
+
if (typeof pinnedAddress !== "string" || pinnedAddress.trim() === "") {
|
|
4047
|
+
throw new Error(
|
|
4048
|
+
"The sender address (pinnedAddress) must be a non-empty address. Pass the sender to check it against the signing wallet or key. SDK callers may omit pinnedAddress to skip that check."
|
|
4049
|
+
);
|
|
4050
|
+
}
|
|
4051
|
+
return pinnedAddress;
|
|
4052
|
+
}
|
|
4053
|
+
var init_pinned_address = __esm({
|
|
4054
|
+
"src/signers/pinned-address.ts"() {
|
|
4055
|
+
"use strict";
|
|
2469
4056
|
}
|
|
2470
4057
|
});
|
|
2471
4058
|
|
|
@@ -2566,7 +4153,7 @@ var require_policy = __commonJS({
|
|
|
2566
4153
|
});
|
|
2567
4154
|
|
|
2568
4155
|
// ../key-management/common/typescript/dist/index.js
|
|
2569
|
-
var
|
|
4156
|
+
var require_dist7 = __commonJS({
|
|
2570
4157
|
"../key-management/common/typescript/dist/index.js"(exports2) {
|
|
2571
4158
|
"use strict";
|
|
2572
4159
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -2708,7 +4295,7 @@ var require_client = __commonJS({
|
|
|
2708
4295
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2709
4296
|
exports2.TurnkeyClient = void 0;
|
|
2710
4297
|
var promises_1 = require("timers/promises");
|
|
2711
|
-
var km_core_1 =
|
|
4298
|
+
var km_core_1 = require_dist7();
|
|
2712
4299
|
var constants_1 = require_constants();
|
|
2713
4300
|
var logger_1 = require_logger();
|
|
2714
4301
|
var meter_1 = require_meter();
|
|
@@ -2860,7 +4447,8 @@ var require_client = __commonJS({
|
|
|
2860
4447
|
}
|
|
2861
4448
|
if (activity?.status !== "ACTIVITY_STATUS_COMPLETED") {
|
|
2862
4449
|
const failure = activity?.failure ?? {};
|
|
2863
|
-
|
|
4450
|
+
const fp = activity?.fingerprint ? ` fingerprint=${activity.fingerprint}` : "";
|
|
4451
|
+
throw (0, km_core_1.signerTerminal)(km_core_1.SignerErrorCode.TURNKEY_ACTIVITY_FAILED, `Turnkey ${ctx} activityId=${activity?.id ?? "?"} status=${activity?.status ?? "unknown"}${fp}; ${JSON.stringify(failure)}`);
|
|
2864
4452
|
}
|
|
2865
4453
|
if (activity.result == null) {
|
|
2866
4454
|
throw (0, km_core_1.signerTerminal)(km_core_1.SignerErrorCode.TURNKEY_BAD_RESPONSE, `Turnkey ${ctx} activityId=${activity.id} COMPLETED but result was missing`);
|
|
@@ -3087,7 +4675,7 @@ var require_signer_base = __commonJS({
|
|
|
3087
4675
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3088
4676
|
exports2.resolveTurnkeyAccountAddress = resolveTurnkeyAccountAddress;
|
|
3089
4677
|
var promises_1 = require("timers/promises");
|
|
3090
|
-
var km_core_1 =
|
|
4678
|
+
var km_core_1 = require_dist7();
|
|
3091
4679
|
var constants_1 = require_constants();
|
|
3092
4680
|
var DISCOVERY_BACKOFF_MS = constants_1.TURNKEY_RETRY_BACKOFF_MS;
|
|
3093
4681
|
async function resolveTurnkeyAccountAddress(deps, addressFormat) {
|
|
@@ -3146,7 +4734,7 @@ var require_secp256k1_helpers = __commonJS({
|
|
|
3146
4734
|
exports2.signSecp256k1TypedDataAndVerify = signSecp256k1TypedDataAndVerify;
|
|
3147
4735
|
exports2.bytesFromHexOrBytes = bytesFromHexOrBytes;
|
|
3148
4736
|
var ethers_1 = require("ethers");
|
|
3149
|
-
var km_core_1 =
|
|
4737
|
+
var km_core_1 = require_dist7();
|
|
3150
4738
|
var EIP712_HASH_FUNCTION = "HASH_FUNCTION_NOT_APPLICABLE";
|
|
3151
4739
|
async function signSecp256k1PreimageAndVerify(client, signWith, preimage, expectedEvmAddrLower) {
|
|
3152
4740
|
const preimageHex = (0, ethers_1.hexlify)(preimage).slice(2);
|
|
@@ -3193,13 +4781,13 @@ var require_secp256k1_helpers = __commonJS({
|
|
|
3193
4781
|
});
|
|
3194
4782
|
|
|
3195
4783
|
// ../key-management/providers/turnkey/typescript/dist/chains/evm.js
|
|
3196
|
-
var
|
|
4784
|
+
var require_evm3 = __commonJS({
|
|
3197
4785
|
"../key-management/providers/turnkey/typescript/dist/chains/evm.js"(exports2) {
|
|
3198
4786
|
"use strict";
|
|
3199
4787
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3200
4788
|
exports2.TurnkeyEvmSigner = void 0;
|
|
3201
4789
|
var ethers_1 = require("ethers");
|
|
3202
|
-
var km_core_1 =
|
|
4790
|
+
var km_core_1 = require_dist7();
|
|
3203
4791
|
var signer_base_1 = require_signer_base();
|
|
3204
4792
|
var secp256k1_helpers_1 = require_secp256k1_helpers();
|
|
3205
4793
|
var ADDRESS_FORMAT = "ADDRESS_FORMAT_ETHEREUM";
|
|
@@ -3315,7 +4903,7 @@ ${msgBytes.length}`);
|
|
|
3315
4903
|
});
|
|
3316
4904
|
|
|
3317
4905
|
// ../key-management/providers/turnkey/typescript/dist/chains/solana.js
|
|
3318
|
-
var
|
|
4906
|
+
var require_solana3 = __commonJS({
|
|
3319
4907
|
"../key-management/providers/turnkey/typescript/dist/chains/solana.js"(exports2) {
|
|
3320
4908
|
"use strict";
|
|
3321
4909
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -3363,7 +4951,7 @@ var require_solana2 = __commonJS({
|
|
|
3363
4951
|
exports2.encodePayload = encodePayload;
|
|
3364
4952
|
var web3_js_1 = require("@solana/web3.js");
|
|
3365
4953
|
var bs58_1 = __importDefault(require("bs58"));
|
|
3366
|
-
var km_core_1 =
|
|
4954
|
+
var km_core_1 = require_dist7();
|
|
3367
4955
|
var signer_base_1 = require_signer_base();
|
|
3368
4956
|
var ADDRESS_FORMAT = "ADDRESS_FORMAT_SOLANA";
|
|
3369
4957
|
var TurnkeySolanaSigner2 = class {
|
|
@@ -3456,7 +5044,7 @@ var require_solana2 = __commonJS({
|
|
|
3456
5044
|
});
|
|
3457
5045
|
|
|
3458
5046
|
// ../key-management/providers/turnkey/typescript/dist/chains/tron.js
|
|
3459
|
-
var
|
|
5047
|
+
var require_tron3 = __commonJS({
|
|
3460
5048
|
"../key-management/providers/turnkey/typescript/dist/chains/tron.js"(exports2) {
|
|
3461
5049
|
"use strict";
|
|
3462
5050
|
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
@@ -3468,7 +5056,7 @@ var require_tron2 = __commonJS({
|
|
|
3468
5056
|
var bs58_1 = __importDefault(require("bs58"));
|
|
3469
5057
|
var ethers_1 = require("ethers");
|
|
3470
5058
|
var node_crypto_1 = require("crypto");
|
|
3471
|
-
var km_core_1 =
|
|
5059
|
+
var km_core_1 = require_dist7();
|
|
3472
5060
|
var signer_base_1 = require_signer_base();
|
|
3473
5061
|
var secp256k1_helpers_1 = require_secp256k1_helpers();
|
|
3474
5062
|
var ADDRESS_FORMAT = "ADDRESS_FORMAT_TRON";
|
|
@@ -3690,6 +5278,200 @@ var require_users = __commonJS({
|
|
|
3690
5278
|
}
|
|
3691
5279
|
});
|
|
3692
5280
|
|
|
5281
|
+
// ../key-management/providers/turnkey/typescript/dist/admin/activities.js
|
|
5282
|
+
var require_activities = __commonJS({
|
|
5283
|
+
"../key-management/providers/turnkey/typescript/dist/admin/activities.js"(exports2) {
|
|
5284
|
+
"use strict";
|
|
5285
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
5286
|
+
exports2.getRootQuorum = getRootQuorum;
|
|
5287
|
+
exports2.getActivity = getActivity;
|
|
5288
|
+
exports2.listPendingActivities = listPendingActivities;
|
|
5289
|
+
exports2.approvedVoterIds = approvedVoterIds;
|
|
5290
|
+
exports2.approveActivity = approveActivity;
|
|
5291
|
+
async function getRootQuorum(client, organizationId) {
|
|
5292
|
+
const r = await client.query("/public/v1/query/get_organization", { organizationId });
|
|
5293
|
+
const q = r.organizationData?.rootQuorum;
|
|
5294
|
+
if (typeof q?.threshold !== "number") {
|
|
5295
|
+
throw new Error(`get_organization on ${organizationId} returned no rootQuorum.threshold: ${JSON.stringify(r).slice(0, 200)}`);
|
|
5296
|
+
}
|
|
5297
|
+
return { threshold: q.threshold, userIds: q.userIds ?? [] };
|
|
5298
|
+
}
|
|
5299
|
+
async function getActivity(client, organizationId, activityId) {
|
|
5300
|
+
const r = await client.query("/public/v1/query/get_activity", {
|
|
5301
|
+
organizationId,
|
|
5302
|
+
activityId
|
|
5303
|
+
});
|
|
5304
|
+
if (!r.activity?.id) {
|
|
5305
|
+
throw new Error(`get_activity returned no activity for ${activityId} in ${organizationId}`);
|
|
5306
|
+
}
|
|
5307
|
+
return r.activity;
|
|
5308
|
+
}
|
|
5309
|
+
async function listPendingActivities(client, organizationId) {
|
|
5310
|
+
const r = await client.query("/public/v1/query/list_activities", { organizationId, filterByStatus: ["ACTIVITY_STATUS_CONSENSUS_NEEDED"] });
|
|
5311
|
+
return r.activities ?? [];
|
|
5312
|
+
}
|
|
5313
|
+
function approvedVoterIds(activity) {
|
|
5314
|
+
const ids = (activity.votes ?? []).filter((v) => v.selection === "VOTE_SELECTION_APPROVED").map((v) => v.userId).filter((id) => Boolean(id));
|
|
5315
|
+
return new Set(ids);
|
|
5316
|
+
}
|
|
5317
|
+
async function approveActivity(client, organizationId, fingerprint) {
|
|
5318
|
+
const r = await client.query("/public/v1/submit/approve_activity", {
|
|
5319
|
+
type: "ACTIVITY_TYPE_APPROVE_ACTIVITY",
|
|
5320
|
+
timestampMs: String(Date.now()),
|
|
5321
|
+
organizationId,
|
|
5322
|
+
parameters: { fingerprint }
|
|
5323
|
+
});
|
|
5324
|
+
if (!r.activity) {
|
|
5325
|
+
throw new Error(`approve_activity returned no activity for ${fingerprint}`);
|
|
5326
|
+
}
|
|
5327
|
+
return r.activity;
|
|
5328
|
+
}
|
|
5329
|
+
}
|
|
5330
|
+
});
|
|
5331
|
+
|
|
5332
|
+
// ../key-management/providers/turnkey/typescript/dist/admin/api-keys.js
|
|
5333
|
+
var require_api_keys = __commonJS({
|
|
5334
|
+
"../key-management/providers/turnkey/typescript/dist/admin/api-keys.js"(exports2) {
|
|
5335
|
+
"use strict";
|
|
5336
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
5337
|
+
exports2.UnsafeRevocationError = exports2.MAX_API_KEYS_PER_USER = void 0;
|
|
5338
|
+
exports2.getUser = getUser;
|
|
5339
|
+
exports2.listUsers = listUsers;
|
|
5340
|
+
exports2.addApiKeys = addApiKeys;
|
|
5341
|
+
exports2.deleteApiKeys = deleteApiKeys;
|
|
5342
|
+
exports2.isDurableApiKey = isDurableApiKey;
|
|
5343
|
+
exports2.isExpiredApiKey = isExpiredApiKey;
|
|
5344
|
+
exports2.planRevocation = planRevocation;
|
|
5345
|
+
exports2.findApiKeyByPublicKey = findApiKeyByPublicKey;
|
|
5346
|
+
exports2.MAX_API_KEYS_PER_USER = 10;
|
|
5347
|
+
async function getUser(client, organizationId, userId) {
|
|
5348
|
+
const r = await client.query("/public/v1/query/get_user", {
|
|
5349
|
+
organizationId,
|
|
5350
|
+
userId
|
|
5351
|
+
});
|
|
5352
|
+
if (!r.user?.userId) {
|
|
5353
|
+
throw new Error(`get_user returned no user for ${userId} in ${organizationId}`);
|
|
5354
|
+
}
|
|
5355
|
+
return normalizeUser(r.user);
|
|
5356
|
+
}
|
|
5357
|
+
async function listUsers(client, organizationId) {
|
|
5358
|
+
const r = await client.query("/public/v1/query/list_users", {
|
|
5359
|
+
organizationId
|
|
5360
|
+
});
|
|
5361
|
+
return (r.users ?? []).map(normalizeUser);
|
|
5362
|
+
}
|
|
5363
|
+
async function addApiKeys(client, input) {
|
|
5364
|
+
if (input.apiKeys.length === 0)
|
|
5365
|
+
throw new Error("addApiKeys called with no keys");
|
|
5366
|
+
const result = await client.executeActivity("ACTIVITY_TYPE_CREATE_API_KEYS_V2", "create_api_keys", {
|
|
5367
|
+
userId: input.userId,
|
|
5368
|
+
apiKeys: input.apiKeys.map((k) => ({
|
|
5369
|
+
apiKeyName: k.apiKeyName,
|
|
5370
|
+
publicKey: k.publicKey,
|
|
5371
|
+
curveType: k.curveType ?? "API_KEY_CURVE_P256",
|
|
5372
|
+
...k.expirationSeconds ? { expirationSeconds: k.expirationSeconds } : {}
|
|
5373
|
+
}))
|
|
5374
|
+
});
|
|
5375
|
+
const ids = result.createApiKeysResult?.apiKeyIds;
|
|
5376
|
+
if (!ids?.length) {
|
|
5377
|
+
throw new Error(`CREATE_API_KEYS_V2 returned no apiKeyIds for user ${input.userId}: ${JSON.stringify(result)}`);
|
|
5378
|
+
}
|
|
5379
|
+
return ids;
|
|
5380
|
+
}
|
|
5381
|
+
async function deleteApiKeys(client, input) {
|
|
5382
|
+
if (input.apiKeyIds.length === 0)
|
|
5383
|
+
throw new Error("deleteApiKeys called with no apiKeyIds");
|
|
5384
|
+
const result = await client.executeActivity("ACTIVITY_TYPE_DELETE_API_KEYS", "delete_api_keys", { userId: input.userId, apiKeyIds: [...input.apiKeyIds] });
|
|
5385
|
+
return result.deleteApiKeysResult?.apiKeyIds ?? [];
|
|
5386
|
+
}
|
|
5387
|
+
function isDurableApiKey(key) {
|
|
5388
|
+
return !key.expirationSeconds;
|
|
5389
|
+
}
|
|
5390
|
+
function isExpiredApiKey(key, nowSeconds) {
|
|
5391
|
+
if (!key.expirationSeconds)
|
|
5392
|
+
return false;
|
|
5393
|
+
const created = Number(key.createdAt?.seconds);
|
|
5394
|
+
const ttl = Number(key.expirationSeconds);
|
|
5395
|
+
if (!Number.isFinite(created) || !Number.isFinite(ttl))
|
|
5396
|
+
return false;
|
|
5397
|
+
return created + ttl <= nowSeconds;
|
|
5398
|
+
}
|
|
5399
|
+
var UnsafeRevocationError = class extends Error {
|
|
5400
|
+
code;
|
|
5401
|
+
constructor(code, message) {
|
|
5402
|
+
super(message);
|
|
5403
|
+
this.code = code;
|
|
5404
|
+
this.name = "UnsafeRevocationError";
|
|
5405
|
+
}
|
|
5406
|
+
};
|
|
5407
|
+
exports2.UnsafeRevocationError = UnsafeRevocationError;
|
|
5408
|
+
function planRevocation(input) {
|
|
5409
|
+
const { user, nowSeconds } = input;
|
|
5410
|
+
const stampingPub = input.stampingPublicKey.toLowerCase();
|
|
5411
|
+
const verifyPub = input.verifyPublicKey?.toLowerCase();
|
|
5412
|
+
const explicitIds = input.explicitIds;
|
|
5413
|
+
if (explicitIds.length === 0) {
|
|
5414
|
+
throw new UnsafeRevocationError("NO_KEY_ID", `No key ids given. Name every key to revoke from "${user.userName}" explicitly, so which key dies never depends on which credential is in the environment.`);
|
|
5415
|
+
}
|
|
5416
|
+
const byId = new Map(user.apiKeys.map((k) => [k.apiKeyId, k]));
|
|
5417
|
+
const unknown = explicitIds.filter((id) => !byId.has(id));
|
|
5418
|
+
if (unknown.length > 0) {
|
|
5419
|
+
throw new UnsafeRevocationError("UNKNOWN_KEY_ID", `--key-id names keys that are not on user "${user.userName}": ${unknown.join(", ")}. They may belong to another user, or already be revoked.`);
|
|
5420
|
+
}
|
|
5421
|
+
const targets = [...new Set(explicitIds)].map((id) => byId.get(id));
|
|
5422
|
+
const revokedIds = new Set(targets.map((k) => k.apiKeyId));
|
|
5423
|
+
const survivors = user.apiKeys.filter((k) => !revokedIds.has(k.apiKeyId));
|
|
5424
|
+
const live = survivors.filter((k) => !isExpiredApiKey(k, nowSeconds));
|
|
5425
|
+
const durableSurvivors = live.filter(isDurableApiKey);
|
|
5426
|
+
const hasPasskey = user.authenticators.length > 0;
|
|
5427
|
+
const stampingKey = user.apiKeys.find((k) => k.credential?.publicKey?.toLowerCase() === stampingPub);
|
|
5428
|
+
if (input.selfRotation && !stampingKey) {
|
|
5429
|
+
throw new UnsafeRevocationError("STAMPING_KEY_NOT_ON_USER", `The public key stamping this request is not among "${user.userName}"'s registered keys, yet Turnkey resolved it to that user. Nothing that protects the surviving key can be trusted in that state. Re-check the credential env vars before revoking anything.`);
|
|
5430
|
+
}
|
|
5431
|
+
const suicidal = targets.find((k) => k.credential?.publicKey?.toLowerCase() === stampingPub);
|
|
5432
|
+
if (suicidal) {
|
|
5433
|
+
throw new UnsafeRevocationError("DELETES_AUTHORIZING_KEY", `${suicidal.apiKeyId} ("${suicidal.apiKeyName}") is the key stamping this request. Stamp with the key that should survive, or name the old key with --key-id.`);
|
|
5434
|
+
}
|
|
5435
|
+
if (verifyPub) {
|
|
5436
|
+
const survivor = user.apiKeys.find((k) => k.credential?.publicKey?.toLowerCase() === verifyPub);
|
|
5437
|
+
if (!survivor) {
|
|
5438
|
+
throw new UnsafeRevocationError("SURVIVOR_NOT_REGISTERED", `--verify-public-key is not registered on "${user.userName}". Run --add first, or check you pasted the public key of the right user.`);
|
|
5439
|
+
}
|
|
5440
|
+
if (revokedIds.has(survivor.apiKeyId)) {
|
|
5441
|
+
throw new UnsafeRevocationError("SURVIVOR_IN_REVOKE_SET", `--verify-public-key resolves to ${survivor.apiKeyId} ("${survivor.apiKeyName}"), which is in the revoke set. That would delete the key you just deployed.`);
|
|
5442
|
+
}
|
|
5443
|
+
}
|
|
5444
|
+
const stampedAt = Number(stampingKey?.createdAt?.seconds);
|
|
5445
|
+
if (!input.force && Number.isFinite(stampedAt)) {
|
|
5446
|
+
const newer = targets.filter((k) => {
|
|
5447
|
+
const created = Number(k.createdAt?.seconds);
|
|
5448
|
+
return Number.isFinite(created) && created > stampedAt;
|
|
5449
|
+
});
|
|
5450
|
+
if (newer.length > 0) {
|
|
5451
|
+
const list = newer.map((k) => `${k.apiKeyId} ("${k.apiKeyName}")`).join(", ");
|
|
5452
|
+
throw new UnsafeRevocationError("DELETES_NEWER_KEY", `${list} was created AFTER the key stamping this request, so this would delete the replacement and keep the key being replaced. Stamp with the NEW key instead (that is what proves it works), or pass --force if deleting the newer key is really the intent.`);
|
|
5453
|
+
}
|
|
5454
|
+
}
|
|
5455
|
+
if (live.length === 0 && !hasPasskey) {
|
|
5456
|
+
const expiredNote = survivors.length > 0 ? " (the remaining key(s) have already expired)" : "";
|
|
5457
|
+
throw new UnsafeRevocationError("NO_WORKING_CREDENTIAL", `This would leave "${user.userName}" with no working API key and no authenticator${expiredNote}, which is unrecoverable \u2014 a parent org cannot add credentials inside a sub-org. Run --add first. There is no --force for this.`);
|
|
5458
|
+
}
|
|
5459
|
+
if (durableSurvivors.length === 0 && !hasPasskey && !input.force) {
|
|
5460
|
+
const deadlines = live.map((k) => `${k.apiKeyId} ("${k.apiKeyName}") expires ${k.expirationSeconds}s after creation`).join("; ");
|
|
5461
|
+
throw new UnsafeRevocationError("ALL_SURVIVORS_EXPIRING", `Every key that would survive on "${user.userName}" has a TTL, so this schedules a lockout rather than causing one now: ${deadlines}. Add a key with no --expiration-seconds first, or pass --force if the expiry is intended.`);
|
|
5462
|
+
}
|
|
5463
|
+
return { targets, survivors, durableSurvivors };
|
|
5464
|
+
}
|
|
5465
|
+
function findApiKeyByPublicKey(user, publicKey) {
|
|
5466
|
+
const want = publicKey.toLowerCase();
|
|
5467
|
+
return user.apiKeys.find((k) => k.credential?.publicKey?.toLowerCase() === want);
|
|
5468
|
+
}
|
|
5469
|
+
function normalizeUser(user) {
|
|
5470
|
+
return { ...user, apiKeys: user.apiKeys ?? [], authenticators: user.authenticators ?? [] };
|
|
5471
|
+
}
|
|
5472
|
+
}
|
|
5473
|
+
});
|
|
5474
|
+
|
|
3693
5475
|
// ../key-management/providers/turnkey/typescript/dist/admin/wallets.js
|
|
3694
5476
|
var require_wallets = __commonJS({
|
|
3695
5477
|
"../key-management/providers/turnkey/typescript/dist/admin/wallets.js"(exports2) {
|
|
@@ -3742,6 +5524,7 @@ var require_policies = __commonJS({
|
|
|
3742
5524
|
exports2.buildDenyApproveToNonAllowedSpenderTron = buildDenyApproveToNonAllowedSpenderTron;
|
|
3743
5525
|
exports2.listPolicies = listPolicies;
|
|
3744
5526
|
exports2.deletePolicy = deletePolicy;
|
|
5527
|
+
exports2.planPolicyChanges = planPolicyChanges;
|
|
3745
5528
|
exports2.applyPolicies = applyPolicies;
|
|
3746
5529
|
function derivePoliciesFromAllowlist(policy, chain, context) {
|
|
3747
5530
|
const policies = [];
|
|
@@ -3929,26 +5712,54 @@ var require_policies = __commonJS({
|
|
|
3929
5712
|
policyId
|
|
3930
5713
|
});
|
|
3931
5714
|
}
|
|
5715
|
+
function planPolicyChanges(existing, policies) {
|
|
5716
|
+
const existingByName = new Map(existing.map((p) => [p.policyName, p]));
|
|
5717
|
+
const drifted = [];
|
|
5718
|
+
for (const p of policies) {
|
|
5719
|
+
const prev = existingByName.get(p.policyName);
|
|
5720
|
+
if (!prev)
|
|
5721
|
+
continue;
|
|
5722
|
+
const matches = prev.effect === p.effect && prev.condition === p.condition && (prev.consensus ?? "") === (p.consensus ?? "");
|
|
5723
|
+
if (!matches)
|
|
5724
|
+
drifted.push({ name: p.policyName, diff: formatPolicyDiff(prev, p) });
|
|
5725
|
+
}
|
|
5726
|
+
const emittedNames = new Set(policies.map((p) => p.policyName));
|
|
5727
|
+
const stale = existing.filter((p) => !emittedNames.has(p.policyName));
|
|
5728
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5729
|
+
const duplicateNames = [
|
|
5730
|
+
...new Set(existing.filter((p) => !(seen.size === seen.add(p.policyName).size)).map((p) => p.policyName))
|
|
5731
|
+
];
|
|
5732
|
+
return { drifted, stale, duplicateNames };
|
|
5733
|
+
}
|
|
3932
5734
|
async function applyPolicies(client, policies, options) {
|
|
3933
5735
|
const existing = await listPolicies(client, options.organizationId);
|
|
3934
5736
|
const existingByName = new Map(existing.map((p) => [p.policyName, p]));
|
|
3935
5737
|
const created = [];
|
|
3936
5738
|
const skippedUnchanged = [];
|
|
3937
|
-
const drifted = [];
|
|
3938
5739
|
const replaced = [];
|
|
5740
|
+
const pruned = [];
|
|
5741
|
+
const { drifted, stale } = planPolicyChanges(existing, policies);
|
|
5742
|
+
if (stale.length > 0 && !options.prune) {
|
|
5743
|
+
const detail = stale.map((p) => ` - ${p.policyName} [${p.effect}] (${p.policyId})`).join("\n");
|
|
5744
|
+
throw new Error(`${stale.length} live polic${stale.length === 1 ? "y is" : "ies are"} absent from the emitted set:
|
|
5745
|
+
${detail}
|
|
5746
|
+
|
|
5747
|
+
A retired ALLOW left live keeps granting what it always granted, so a narrower replacement does not take effect until it is gone. Re-run with --prune to delete them, or reconcile the config if they are policies this set should still emit.`);
|
|
5748
|
+
}
|
|
5749
|
+
if (drifted.length > 0 && !options.update) {
|
|
5750
|
+
const detail = drifted.map((d) => ` - ${d.name}:
|
|
5751
|
+
${indent(d.diff, " ")}`).join("\n");
|
|
5752
|
+
throw new Error(`Content drift detected on ${drifted.length} polic${drifted.length === 1 ? "y" : "ies"}. Re-run with --update to delete-and-recreate, or fix the existing policy in the Turnkey console.
|
|
5753
|
+
${detail}`);
|
|
5754
|
+
}
|
|
5755
|
+
const driftedNames = new Set(drifted.map((d) => d.name));
|
|
3939
5756
|
for (const p of policies) {
|
|
3940
5757
|
const prev = existingByName.get(p.policyName);
|
|
3941
5758
|
if (prev) {
|
|
3942
|
-
|
|
3943
|
-
if (matches) {
|
|
5759
|
+
if (!driftedNames.has(p.policyName)) {
|
|
3944
5760
|
skippedUnchanged.push(p.policyName);
|
|
3945
5761
|
continue;
|
|
3946
5762
|
}
|
|
3947
|
-
const diff = formatPolicyDiff(prev, p);
|
|
3948
|
-
if (!options.update) {
|
|
3949
|
-
drifted.push({ name: p.policyName, diff });
|
|
3950
|
-
continue;
|
|
3951
|
-
}
|
|
3952
5763
|
await deletePolicy(client, prev.policyId);
|
|
3953
5764
|
const newId = await createPolicyRaw(client, p);
|
|
3954
5765
|
replaced.push({ name: p.policyName, oldPolicyId: prev.policyId, newPolicyId: newId });
|
|
@@ -3958,13 +5769,11 @@ var require_policies = __commonJS({
|
|
|
3958
5769
|
const id = await createPolicyRaw(client, p);
|
|
3959
5770
|
created.push(id);
|
|
3960
5771
|
}
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
throw new Error(`Content drift detected on ${drifted.length} polic${drifted.length === 1 ? "y" : "ies"}. Re-run with --update to delete-and-recreate, or fix the existing policy in the Turnkey console.
|
|
3965
|
-
${detail}`);
|
|
5772
|
+
for (const p of stale) {
|
|
5773
|
+
await deletePolicy(client, p.policyId);
|
|
5774
|
+
pruned.push({ name: p.policyName, policyId: p.policyId });
|
|
3966
5775
|
}
|
|
3967
|
-
return { created, skippedUnchanged, replaced };
|
|
5776
|
+
return { created, skippedUnchanged, replaced, pruned };
|
|
3968
5777
|
}
|
|
3969
5778
|
async function createPolicyRaw(client, p) {
|
|
3970
5779
|
const result = await client.executeActivity("ACTIVITY_TYPE_CREATE_POLICY_V3", "create_policy", {
|
|
@@ -4010,6 +5819,8 @@ var require_sender_policies = __commonJS({
|
|
|
4010
5819
|
"use strict";
|
|
4011
5820
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
4012
5821
|
exports2.TRON_PERMIT2 = exports2.EVM_PERMIT2 = void 0;
|
|
5822
|
+
exports2.tronTip712ChainId = tronTip712ChainId;
|
|
5823
|
+
exports2.toTronEvmHex = toTronEvmHex;
|
|
4013
5824
|
exports2.buildSenderPolicies = buildSenderPolicies;
|
|
4014
5825
|
exports2.tronBase58ToEvmHex = tronBase58ToEvmHex;
|
|
4015
5826
|
var node_crypto_1 = require("crypto");
|
|
@@ -4019,6 +5830,57 @@ var require_sender_policies = __commonJS({
|
|
|
4019
5830
|
shasta: "TPUqJPASUn1zLvbLBgRZ5pBYrx7WSe5ahp"
|
|
4020
5831
|
};
|
|
4021
5832
|
var APPROVE_SELECTOR = "0x095ea7b3";
|
|
5833
|
+
var PERMIT2_PRIMARY_TYPE = "PermitWitnessTransferFrom";
|
|
5834
|
+
var PERMIT2_DOMAIN_NAME = "Permit2";
|
|
5835
|
+
var TRON_TIP712_CHAIN_IDS = {
|
|
5836
|
+
mainnet: 728126428,
|
|
5837
|
+
shasta: 2494104990
|
|
5838
|
+
};
|
|
5839
|
+
function tronTip712ChainId(caip2) {
|
|
5840
|
+
const cluster = caip2.split(":")[1] ?? "";
|
|
5841
|
+
const id = Object.hasOwn(TRON_TIP712_CHAIN_IDS, cluster) ? TRON_TIP712_CHAIN_IDS[cluster] : void 0;
|
|
5842
|
+
if (id === void 0) {
|
|
5843
|
+
throw new Error(`Sender extras: unsupported Tron network "${caip2}". Known clusters: ${Object.keys(TRON_TIP712_CHAIN_IDS).join(", ")}.`);
|
|
5844
|
+
}
|
|
5845
|
+
return (id & 4294967295) >>> 0;
|
|
5846
|
+
}
|
|
5847
|
+
function evmNumericChainId(caip2) {
|
|
5848
|
+
const id = Number.parseInt(caip2.split(":")[1] ?? "", 10);
|
|
5849
|
+
if (!Number.isSafeInteger(id) || id <= 0) {
|
|
5850
|
+
throw new Error(`Sender extras: chain id "${caip2}" is not a usable eip155 CAIP-2 identifier.`);
|
|
5851
|
+
}
|
|
5852
|
+
return id;
|
|
5853
|
+
}
|
|
5854
|
+
var lower = (a) => a.toLowerCase();
|
|
5855
|
+
function assertEvmAddress(address, chainKey) {
|
|
5856
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {
|
|
5857
|
+
throw new Error(`Sender extras: ${JSON.stringify(address)} on chain "${chainKey}" is not a 20-byte 0x hex address. A malformed literal matches nothing, which denies every payment on this chain.`);
|
|
5858
|
+
}
|
|
5859
|
+
return address;
|
|
5860
|
+
}
|
|
5861
|
+
function toTronEvmHex(address) {
|
|
5862
|
+
if (address.startsWith("T"))
|
|
5863
|
+
return `0x${tronBase58ToEvmHex(address)}`;
|
|
5864
|
+
if (/^0x[0-9a-fA-F]{40}$/.test(address))
|
|
5865
|
+
return lower(address);
|
|
5866
|
+
throw new Error(`Sender extras: Tron address ${JSON.stringify(address)} is neither a base58 (T\u2026) address nor a 20-byte 0x hex address, so its TIP-712 message form cannot be derived.`);
|
|
5867
|
+
}
|
|
5868
|
+
var quotedLower = (xs) => xs.map((x) => `'${lower(x)}'`).join(", ");
|
|
5869
|
+
function quotedExact(xs, chainKey) {
|
|
5870
|
+
for (const x of xs) {
|
|
5871
|
+
if (x.includes("'") || x.includes("\\")) {
|
|
5872
|
+
throw new Error(`Sender extras: destination ${JSON.stringify(x)} on chain "${chainKey}" contains a quote or backslash, which cannot appear in a policy condition literal.`);
|
|
5873
|
+
}
|
|
5874
|
+
if (x.length === 0 || !x.includes("@")) {
|
|
5875
|
+
throw new Error(`Sender extras: destination ${JSON.stringify(x)} on chain "${chainKey}" is not a composed destination (<caip19-asset>@<account>). Build it with buildEscrowDestination.`);
|
|
5876
|
+
}
|
|
5877
|
+
if (Buffer.byteLength(x, "utf8") > MAX_DESTINATION_BYTES) {
|
|
5878
|
+
throw new Error(`Sender extras: destination ${JSON.stringify(x)} on chain "${chainKey}" is longer than ${MAX_DESTINATION_BYTES} bytes, which the escrow rejects as DestinationTooLong, so no deposit could ever carry it.`);
|
|
5879
|
+
}
|
|
5880
|
+
}
|
|
5881
|
+
return xs.map((x) => `'${x}'`).join(", ");
|
|
5882
|
+
}
|
|
5883
|
+
var MAX_DESTINATION_BYTES = 256;
|
|
4022
5884
|
var SOLANA_STANDARD_PROGRAMS = [
|
|
4023
5885
|
"11111111111111111111111111111111",
|
|
4024
5886
|
// System
|
|
@@ -4033,14 +5895,35 @@ var require_sender_policies = __commonJS({
|
|
|
4033
5895
|
"Ed25519SigVerify111111111111111111111111111"
|
|
4034
5896
|
// Ed25519 (inner signature verification)
|
|
4035
5897
|
];
|
|
5898
|
+
function solanaEscrowPrograms(value) {
|
|
5899
|
+
const raw = value === void 0 ? [] : typeof value === "string" ? [value] : value;
|
|
5900
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5901
|
+
const out = [];
|
|
5902
|
+
for (const entry of raw) {
|
|
5903
|
+
const id = typeof entry === "string" ? entry.trim() : "";
|
|
5904
|
+
if (!id || seen.has(id))
|
|
5905
|
+
continue;
|
|
5906
|
+
seen.add(id);
|
|
5907
|
+
out.push(id);
|
|
5908
|
+
}
|
|
5909
|
+
return out;
|
|
5910
|
+
}
|
|
4036
5911
|
function buildSenderPolicies(extras, chains) {
|
|
4037
5912
|
const policies = [];
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
}
|
|
5913
|
+
const permit2Evm = lower(extras.permit2 ?? exports2.EVM_PERMIT2);
|
|
5914
|
+
for (const chain of chains) {
|
|
5915
|
+
if (chain.kind !== "evm" && chain.kind !== "tron")
|
|
5916
|
+
continue;
|
|
5917
|
+
policies.push(permit2TypedDataAllow(chain, extras, permit2Evm));
|
|
5918
|
+
}
|
|
5919
|
+
if (chains.some((c) => c.kind === "solana")) {
|
|
5920
|
+
policies.push({
|
|
5921
|
+
policyName: "allowEd25519RawPayload",
|
|
5922
|
+
effect: "EFFECT_ALLOW",
|
|
5923
|
+
condition: `activity.type == 'ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2' && activity.params.encoding in ['PAYLOAD_ENCODING_HEXADECIMAL', 'PAYLOAD_ENCODING_TEXT_UTF8'] && activity.params.hash_function == 'HASH_FUNCTION_NOT_APPLICABLE'`,
|
|
5924
|
+
notes: "Solana deposit inner signature (ed25519 over the deposit digest). Legal on secp256k1 only with EIP712, which the API enforces, so this stays an ed25519-only path."
|
|
5925
|
+
});
|
|
5926
|
+
}
|
|
4044
5927
|
for (const chain of chains) {
|
|
4045
5928
|
if (chain.kind === "evm") {
|
|
4046
5929
|
const evmChainId = parseInt(chain.chainId.split(":")[1], 10);
|
|
@@ -4049,7 +5932,7 @@ var require_sender_policies = __commonJS({
|
|
|
4049
5932
|
throw new Error(`Sender extras: chain "${chain.key}" has no allowedTokens. Add at least one ERC-20 contract address the sender's wallet is permitted to approve, or remove this chain.`);
|
|
4050
5933
|
}
|
|
4051
5934
|
const tokenList = tokens.map((t) => `'${t}'`).join(", ");
|
|
4052
|
-
const permit2Lower =
|
|
5935
|
+
const permit2Lower = permit2Evm.replace(/^0x/, "");
|
|
4053
5936
|
policies.push({
|
|
4054
5937
|
policyName: `allowApproveToPermit2 (${chain.chainId})`,
|
|
4055
5938
|
effect: "EFFECT_ALLOW",
|
|
@@ -4111,10 +5994,11 @@ var require_sender_policies = __commonJS({
|
|
|
4111
5994
|
}
|
|
4112
5995
|
}
|
|
4113
5996
|
if (chain.kind === "solana") {
|
|
4114
|
-
|
|
4115
|
-
|
|
5997
|
+
const escrowPrograms = solanaEscrowPrograms(extras.solanaEscrowProgramId);
|
|
5998
|
+
if (escrowPrograms.length === 0) {
|
|
5999
|
+
throw new Error(`Sender extras includes Solana chain but no solanaEscrowProgramId. Set it to Atum's escrow program ID for this deployment, or to a list of them.`);
|
|
4116
6000
|
}
|
|
4117
|
-
const allowed = [...SOLANA_STANDARD_PROGRAMS,
|
|
6001
|
+
const allowed = [...SOLANA_STANDARD_PROGRAMS, ...escrowPrograms];
|
|
4118
6002
|
const list = allowed.map((p) => `'${p}'`).join(", ");
|
|
4119
6003
|
policies.push({
|
|
4120
6004
|
policyName: `allowedPrograms (${chain.chainId})`,
|
|
@@ -4138,13 +6022,70 @@ var require_sender_policies = __commonJS({
|
|
|
4138
6022
|
}
|
|
4139
6023
|
}
|
|
4140
6024
|
policies.push({
|
|
4141
|
-
policyName: "
|
|
6025
|
+
policyName: "denyNonTypedDataHashFunctions",
|
|
6026
|
+
effect: "EFFECT_DENY",
|
|
6027
|
+
condition: `activity.type in ['ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2', 'ACTIVITY_TYPE_SIGN_RAW_PAYLOADS'] && activity.params.hash_function in ['HASH_FUNCTION_NO_OP', 'HASH_FUNCTION_SHA256', 'HASH_FUNCTION_KECCAK256']`,
|
|
6028
|
+
notes: "NO_OP signs a caller-chosen digest as-is; KECCAK256 signs a caller-chosen preimage, which reproduces any EIP-712 digest and bypasses every typed-data condition."
|
|
6029
|
+
});
|
|
6030
|
+
policies.push({
|
|
6031
|
+
policyName: "denyAccountDelegationEncoding",
|
|
6032
|
+
effect: "EFFECT_DENY",
|
|
6033
|
+
condition: `activity.type in ['ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2', 'ACTIVITY_TYPE_SIGN_RAW_PAYLOADS'] && activity.params.encoding == 'PAYLOAD_ENCODING_EIP7702_AUTHORIZATION'`,
|
|
6034
|
+
notes: "One signature would delegate the sender EOA to an attacker contract."
|
|
6035
|
+
});
|
|
6036
|
+
policies.push({
|
|
6037
|
+
policyName: "denyBatchRawPayloads",
|
|
4142
6038
|
effect: "EFFECT_DENY",
|
|
4143
|
-
condition: `activity.type
|
|
4144
|
-
notes: "
|
|
6039
|
+
condition: `activity.type == 'ACTIVITY_TYPE_SIGN_RAW_PAYLOADS'`,
|
|
6040
|
+
notes: "Message conditions bind one payload of a batch, so a second could ride along unbound."
|
|
4145
6041
|
});
|
|
4146
6042
|
return policies;
|
|
4147
6043
|
}
|
|
6044
|
+
function permit2TypedDataAllow(chain, extras, permit2Evm) {
|
|
6045
|
+
const escrowsRaw = extras.escrows?.[chain.key] ?? [];
|
|
6046
|
+
if (escrowsRaw.length === 0) {
|
|
6047
|
+
throw new Error(`Sender extras: chain "${chain.key}" has no escrows. Permit2 leaves the transfer recipient out of the signed struct, so the escrow named as \`spender\` IS the funds destination \u2014 without it a stolen key can authorize a pull to anywhere. Read it from payment-gw /v1/defaults?chain_id=${chain.chainId} (escrow_contract).`);
|
|
6048
|
+
}
|
|
6049
|
+
const isTron = chain.kind === "tron";
|
|
6050
|
+
const tronCluster = isTron ? chain.chainId.split(":")[1] ?? "" : "";
|
|
6051
|
+
if (isTron) {
|
|
6052
|
+
const expected = extras.network === "mainnet" ? "mainnet" : "shasta";
|
|
6053
|
+
if (tronCluster !== expected) {
|
|
6054
|
+
throw new Error(`Sender extras: network "${extras.network}" selects the ${expected} Permit2 deployment, but chain "${chain.key}" is "${chain.chainId}". The domain would carry one cluster's Permit2 with another's chain id, which matches no signature the runtime produces.`);
|
|
6055
|
+
}
|
|
6056
|
+
}
|
|
6057
|
+
const permit2 = isTron ? `0x${tronBase58ToEvmHex(exports2.TRON_PERMIT2[tronCluster])}` : permit2Evm;
|
|
6058
|
+
const chainIdValue = isTron ? tronTip712ChainId(chain.chainId) : evmNumericChainId(chain.chainId);
|
|
6059
|
+
const addr = (xs) => quotedLower(xs.map((x) => isTron ? toTronEvmHex(x) : assertEvmAddress(x, chain.key)));
|
|
6060
|
+
const tokens = extras.allowedTokens[chain.key] ?? [];
|
|
6061
|
+
if (tokens.length === 0) {
|
|
6062
|
+
throw new Error(`Sender extras: chain "${chain.key}" has no allowedTokens, so the typed-data allow would not bind which token the permit moves.`);
|
|
6063
|
+
}
|
|
6064
|
+
const tokenClause = ` && eth.eip_712.message['permitted']['token'] in [${addr(tokens)}]`;
|
|
6065
|
+
const reservers = extras.reservers?.[chain.key] ?? [];
|
|
6066
|
+
const releasers = extras.releasers?.[chain.key] ?? [];
|
|
6067
|
+
for (const [role, vals, field] of [
|
|
6068
|
+
["reservers", reservers, "quote_selector"],
|
|
6069
|
+
["releasers", releasers, "fulfillment_verifier.account"]
|
|
6070
|
+
]) {
|
|
6071
|
+
if (vals.length === 0) {
|
|
6072
|
+
throw new Error(`Sender extras: chain "${chain.key}" has no ${role}. Either witness role can divert funds at settlement and the payer pins neither client-side, so leaving this unset is a hole this policy set is meant to close. Read it from payment-gw /v1/defaults?chain_id=${chain.chainId} (${field}).`);
|
|
6073
|
+
}
|
|
6074
|
+
}
|
|
6075
|
+
const reserverClause = ` && eth.eip_712.message['witness']['reserver'] in [${addr(reservers)}]`;
|
|
6076
|
+
const releaserClause = ` && eth.eip_712.message['witness']['releaser'] in [${addr(releasers)}]`;
|
|
6077
|
+
const destinations = extras.allowedDestinations?.[chain.key] ?? [];
|
|
6078
|
+
if (destinations.length === 0) {
|
|
6079
|
+
throw new Error(`Sender extras: chain "${chain.key}" has no allowedDestinations. Without them a stolen key can authorize a deposit whose payout instruction names the attacker, which is the hole this policy set exists to close. Compose each entry with buildEscrowDestination, or remove the chain.`);
|
|
6080
|
+
}
|
|
6081
|
+
const destinationClause = ` && eth.eip_712.message['witness']['destination'] in [${quotedExact(destinations, chain.key)}]`;
|
|
6082
|
+
return {
|
|
6083
|
+
policyName: `allowPermit2DepositTypedData (${chain.chainId})`,
|
|
6084
|
+
effect: "EFFECT_ALLOW",
|
|
6085
|
+
condition: `activity.type == 'ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2' && activity.params.encoding == 'PAYLOAD_ENCODING_EIP712' && activity.params.hash_function == 'HASH_FUNCTION_NOT_APPLICABLE' && eth.eip_712.primary_type == '${PERMIT2_PRIMARY_TYPE}' && eth.eip_712.domain.name == '${PERMIT2_DOMAIN_NAME}' && eth.eip_712.domain.verifying_contract == '${permit2}' && eth.eip_712.domain.chain_id == ${chainIdValue} && eth.eip_712.message['spender'] in [${addr(escrowsRaw)}]` + tokenClause + reserverClause + releaserClause + destinationClause,
|
|
6086
|
+
notes: "The sender's only fund-moving signature: a Permit2 deposit authorization into an allowlisted escrow, for an allowlisted token, committing to an allowlisted destination."
|
|
6087
|
+
};
|
|
6088
|
+
}
|
|
4148
6089
|
function tronBase58ToEvmHex(b58) {
|
|
4149
6090
|
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
4150
6091
|
let bn = 0n;
|
|
@@ -4229,7 +6170,7 @@ var require_extras_policies = __commonJS({
|
|
|
4229
6170
|
var sender_policies_1 = require_sender_policies();
|
|
4230
6171
|
var SPL_TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
4231
6172
|
var ASSOCIATED_TOKEN_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
4232
|
-
var
|
|
6173
|
+
var EVM_ADDRESS2 = /^0x[0-9a-fA-F]{40}$/;
|
|
4233
6174
|
var TRON_ADDRESS = /^T[1-9A-HJ-NP-Za-km-z]{33}$/;
|
|
4234
6175
|
var ALLOWED_EXTRAS_KEYS = [
|
|
4235
6176
|
"allowedErc20Recipients",
|
|
@@ -4249,7 +6190,7 @@ var require_extras_policies = __commonJS({
|
|
|
4249
6190
|
}
|
|
4250
6191
|
}
|
|
4251
6192
|
if (obj.allowedErc20Recipients != null) {
|
|
4252
|
-
validateAddressMap(obj.allowedErc20Recipients, "allowedErc20Recipients",
|
|
6193
|
+
validateAddressMap(obj.allowedErc20Recipients, "allowedErc20Recipients", EVM_ADDRESS2, source);
|
|
4253
6194
|
}
|
|
4254
6195
|
if (obj.allowedTrc20Recipients != null) {
|
|
4255
6196
|
validateAddressMap(obj.allowedTrc20Recipients, "allowedTrc20Recipients", TRON_ADDRESS, source);
|
|
@@ -4448,7 +6389,7 @@ var require_admin = __commonJS({
|
|
|
4448
6389
|
"../key-management/providers/turnkey/typescript/dist/admin/index.js"(exports2) {
|
|
4449
6390
|
"use strict";
|
|
4450
6391
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
4451
|
-
exports2.validateExtras = exports2.buildExtrasPolicies = exports2.tronBase58ToEvmHex = exports2.TRON_PERMIT2 = exports2.EVM_PERMIT2 = exports2.buildSenderPolicies = exports2.listPolicies = exports2.derivePoliciesFromAllowlist = exports2.deletePolicy = exports2.buildDenyApproveToNonAllowedSpenderTron = exports2.buildDenyApproveToNonAllowedSpenderEvm = exports2.buildAllowSignRawPayloadPolicy = exports2.applyPolicies = exports2.createWalletWithChainAccounts = exports2.provisionAgentUser = exports2.deleteSubOrganization = exports2.listSubOrganizations = exports2.createSubOrganization = void 0;
|
|
6392
|
+
exports2.validateExtras = exports2.buildExtrasPolicies = exports2.tronTip712ChainId = exports2.tronBase58ToEvmHex = exports2.toTronEvmHex = exports2.TRON_PERMIT2 = exports2.EVM_PERMIT2 = exports2.buildSenderPolicies = exports2.planPolicyChanges = exports2.listPolicies = exports2.derivePoliciesFromAllowlist = exports2.deletePolicy = exports2.buildDenyApproveToNonAllowedSpenderTron = exports2.buildDenyApproveToNonAllowedSpenderEvm = exports2.buildAllowSignRawPayloadPolicy = exports2.applyPolicies = exports2.createWalletWithChainAccounts = exports2.planRevocation = exports2.listUsers = exports2.isExpiredApiKey = exports2.isDurableApiKey = exports2.getUser = exports2.findApiKeyByPublicKey = exports2.deleteApiKeys = exports2.addApiKeys = exports2.UnsafeRevocationError = exports2.MAX_API_KEYS_PER_USER = exports2.listPendingActivities = exports2.getRootQuorum = exports2.getActivity = exports2.approvedVoterIds = exports2.approveActivity = exports2.provisionAgentUser = exports2.deleteSubOrganization = exports2.listSubOrganizations = exports2.createSubOrganization = void 0;
|
|
4452
6393
|
var sub_organizations_1 = require_sub_organizations();
|
|
4453
6394
|
Object.defineProperty(exports2, "createSubOrganization", { enumerable: true, get: function() {
|
|
4454
6395
|
return sub_organizations_1.createSubOrganization;
|
|
@@ -4465,6 +6406,53 @@ var require_admin = __commonJS({
|
|
|
4465
6406
|
Object.defineProperty(exports2, "provisionAgentUser", { enumerable: true, get: function() {
|
|
4466
6407
|
return users_1.provisionAgentUser;
|
|
4467
6408
|
} });
|
|
6409
|
+
var activities_1 = require_activities();
|
|
6410
|
+
Object.defineProperty(exports2, "approveActivity", { enumerable: true, get: function() {
|
|
6411
|
+
return activities_1.approveActivity;
|
|
6412
|
+
} });
|
|
6413
|
+
Object.defineProperty(exports2, "approvedVoterIds", { enumerable: true, get: function() {
|
|
6414
|
+
return activities_1.approvedVoterIds;
|
|
6415
|
+
} });
|
|
6416
|
+
Object.defineProperty(exports2, "getActivity", { enumerable: true, get: function() {
|
|
6417
|
+
return activities_1.getActivity;
|
|
6418
|
+
} });
|
|
6419
|
+
Object.defineProperty(exports2, "getRootQuorum", { enumerable: true, get: function() {
|
|
6420
|
+
return activities_1.getRootQuorum;
|
|
6421
|
+
} });
|
|
6422
|
+
Object.defineProperty(exports2, "listPendingActivities", { enumerable: true, get: function() {
|
|
6423
|
+
return activities_1.listPendingActivities;
|
|
6424
|
+
} });
|
|
6425
|
+
var api_keys_1 = require_api_keys();
|
|
6426
|
+
Object.defineProperty(exports2, "MAX_API_KEYS_PER_USER", { enumerable: true, get: function() {
|
|
6427
|
+
return api_keys_1.MAX_API_KEYS_PER_USER;
|
|
6428
|
+
} });
|
|
6429
|
+
Object.defineProperty(exports2, "UnsafeRevocationError", { enumerable: true, get: function() {
|
|
6430
|
+
return api_keys_1.UnsafeRevocationError;
|
|
6431
|
+
} });
|
|
6432
|
+
Object.defineProperty(exports2, "addApiKeys", { enumerable: true, get: function() {
|
|
6433
|
+
return api_keys_1.addApiKeys;
|
|
6434
|
+
} });
|
|
6435
|
+
Object.defineProperty(exports2, "deleteApiKeys", { enumerable: true, get: function() {
|
|
6436
|
+
return api_keys_1.deleteApiKeys;
|
|
6437
|
+
} });
|
|
6438
|
+
Object.defineProperty(exports2, "findApiKeyByPublicKey", { enumerable: true, get: function() {
|
|
6439
|
+
return api_keys_1.findApiKeyByPublicKey;
|
|
6440
|
+
} });
|
|
6441
|
+
Object.defineProperty(exports2, "getUser", { enumerable: true, get: function() {
|
|
6442
|
+
return api_keys_1.getUser;
|
|
6443
|
+
} });
|
|
6444
|
+
Object.defineProperty(exports2, "isDurableApiKey", { enumerable: true, get: function() {
|
|
6445
|
+
return api_keys_1.isDurableApiKey;
|
|
6446
|
+
} });
|
|
6447
|
+
Object.defineProperty(exports2, "isExpiredApiKey", { enumerable: true, get: function() {
|
|
6448
|
+
return api_keys_1.isExpiredApiKey;
|
|
6449
|
+
} });
|
|
6450
|
+
Object.defineProperty(exports2, "listUsers", { enumerable: true, get: function() {
|
|
6451
|
+
return api_keys_1.listUsers;
|
|
6452
|
+
} });
|
|
6453
|
+
Object.defineProperty(exports2, "planRevocation", { enumerable: true, get: function() {
|
|
6454
|
+
return api_keys_1.planRevocation;
|
|
6455
|
+
} });
|
|
4468
6456
|
var wallets_1 = require_wallets();
|
|
4469
6457
|
Object.defineProperty(exports2, "createWalletWithChainAccounts", { enumerable: true, get: function() {
|
|
4470
6458
|
return wallets_1.createWalletWithChainAccounts;
|
|
@@ -4491,6 +6479,9 @@ var require_admin = __commonJS({
|
|
|
4491
6479
|
Object.defineProperty(exports2, "listPolicies", { enumerable: true, get: function() {
|
|
4492
6480
|
return policies_1.listPolicies;
|
|
4493
6481
|
} });
|
|
6482
|
+
Object.defineProperty(exports2, "planPolicyChanges", { enumerable: true, get: function() {
|
|
6483
|
+
return policies_1.planPolicyChanges;
|
|
6484
|
+
} });
|
|
4494
6485
|
var sender_policies_1 = require_sender_policies();
|
|
4495
6486
|
Object.defineProperty(exports2, "buildSenderPolicies", { enumerable: true, get: function() {
|
|
4496
6487
|
return sender_policies_1.buildSenderPolicies;
|
|
@@ -4501,9 +6492,15 @@ var require_admin = __commonJS({
|
|
|
4501
6492
|
Object.defineProperty(exports2, "TRON_PERMIT2", { enumerable: true, get: function() {
|
|
4502
6493
|
return sender_policies_1.TRON_PERMIT2;
|
|
4503
6494
|
} });
|
|
6495
|
+
Object.defineProperty(exports2, "toTronEvmHex", { enumerable: true, get: function() {
|
|
6496
|
+
return sender_policies_1.toTronEvmHex;
|
|
6497
|
+
} });
|
|
4504
6498
|
Object.defineProperty(exports2, "tronBase58ToEvmHex", { enumerable: true, get: function() {
|
|
4505
6499
|
return sender_policies_1.tronBase58ToEvmHex;
|
|
4506
6500
|
} });
|
|
6501
|
+
Object.defineProperty(exports2, "tronTip712ChainId", { enumerable: true, get: function() {
|
|
6502
|
+
return sender_policies_1.tronTip712ChainId;
|
|
6503
|
+
} });
|
|
4507
6504
|
var extras_policies_1 = require_extras_policies();
|
|
4508
6505
|
Object.defineProperty(exports2, "buildExtrasPolicies", { enumerable: true, get: function() {
|
|
4509
6506
|
return extras_policies_1.buildExtrasPolicies;
|
|
@@ -4515,7 +6512,7 @@ var require_admin = __commonJS({
|
|
|
4515
6512
|
});
|
|
4516
6513
|
|
|
4517
6514
|
// ../key-management/providers/turnkey/typescript/dist/index.js
|
|
4518
|
-
var
|
|
6515
|
+
var require_dist8 = __commonJS({
|
|
4519
6516
|
"../key-management/providers/turnkey/typescript/dist/index.js"(exports2) {
|
|
4520
6517
|
"use strict";
|
|
4521
6518
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -4570,18 +6567,18 @@ var require_dist6 = __commonJS({
|
|
|
4570
6567
|
Object.defineProperty(exports2, "noopMeter", { enumerable: true, get: function() {
|
|
4571
6568
|
return meter_1.noopMeter;
|
|
4572
6569
|
} });
|
|
4573
|
-
var evm_1 =
|
|
6570
|
+
var evm_1 = require_evm3();
|
|
4574
6571
|
Object.defineProperty(exports2, "TurnkeyEvmSigner", { enumerable: true, get: function() {
|
|
4575
6572
|
return evm_1.TurnkeyEvmSigner;
|
|
4576
6573
|
} });
|
|
4577
|
-
var solana_1 =
|
|
6574
|
+
var solana_1 = require_solana3();
|
|
4578
6575
|
Object.defineProperty(exports2, "TurnkeySolanaSigner", { enumerable: true, get: function() {
|
|
4579
6576
|
return solana_1.TurnkeySolanaSigner;
|
|
4580
6577
|
} });
|
|
4581
6578
|
Object.defineProperty(exports2, "encodePayload", { enumerable: true, get: function() {
|
|
4582
6579
|
return solana_1.encodePayload;
|
|
4583
6580
|
} });
|
|
4584
|
-
var tron_1 =
|
|
6581
|
+
var tron_1 = require_tron3();
|
|
4585
6582
|
Object.defineProperty(exports2, "TurnkeyTronSigner", { enumerable: true, get: function() {
|
|
4586
6583
|
return tron_1.TurnkeyTronSigner;
|
|
4587
6584
|
} });
|
|
@@ -4634,11 +6631,12 @@ async function resolveSenderAddresses(cfg) {
|
|
|
4634
6631
|
return accounts.map((a) => ({ address: a.address, addressFormat: a.addressFormat }));
|
|
4635
6632
|
}
|
|
4636
6633
|
async function signWithTurnkeyClient(client, chainPrefix, cfg, message, messagePrehash) {
|
|
6634
|
+
const pinnedAddress = requirePinnedSender(cfg.pinnedAddress);
|
|
4637
6635
|
const deps = {
|
|
4638
6636
|
walletId: cfg.walletId,
|
|
4639
6637
|
log: cfg.logger ?? import_turnkey_signer.noopLogger,
|
|
4640
6638
|
discoveryTimeoutMs: cfg.discoveryTimeoutMs ?? DEFAULTS.discoveryTimeoutMs,
|
|
4641
|
-
...
|
|
6639
|
+
...pinnedAddress ? { pinnedAddress } : {}
|
|
4642
6640
|
};
|
|
4643
6641
|
switch (chainPrefix) {
|
|
4644
6642
|
case "eip155": {
|
|
@@ -4648,7 +6646,11 @@ async function signWithTurnkeyClient(client, chainPrefix, cfg, message, messageP
|
|
|
4648
6646
|
return { signature: await signer.signTypedData(domain, types, typedMessage) };
|
|
4649
6647
|
}
|
|
4650
6648
|
case "tron": {
|
|
4651
|
-
const {
|
|
6649
|
+
const {
|
|
6650
|
+
domain,
|
|
6651
|
+
types,
|
|
6652
|
+
message: typedMessage
|
|
6653
|
+
} = parsePrehash(messagePrehash, "Tron", message);
|
|
4652
6654
|
const signer = new import_turnkey_signer.TurnkeyTronSigner(client, deps);
|
|
4653
6655
|
await signer.initialize();
|
|
4654
6656
|
return { signature: await signer.signTypedData(domain, types, typedMessage) };
|
|
@@ -4688,23 +6690,29 @@ function parsePrehash(messagePrehash, label, advertisedDigest) {
|
|
|
4688
6690
|
}
|
|
4689
6691
|
const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
4690
6692
|
if (!isObject(parsed) || !isObject(parsed.domain) || !isObject(parsed.types) || !isObject(parsed.message)) {
|
|
4691
|
-
throw new Error(
|
|
6693
|
+
throw new Error(
|
|
6694
|
+
`Turnkey ${label} signing: message_prehash must be a JSON object with domain, types and message`
|
|
6695
|
+
);
|
|
4692
6696
|
}
|
|
4693
6697
|
const { EIP712Domain: _derived, ...structTypes } = parsed.types;
|
|
4694
|
-
const
|
|
6698
|
+
const domain = parsed.domain;
|
|
6699
|
+
const types = structTypes;
|
|
6700
|
+
const message = parsed.message;
|
|
6701
|
+
const prehashDigest = import_ethers6.TypedDataEncoder.hash(domain, types, message);
|
|
4695
6702
|
if (prehashDigest.toLowerCase() !== advertisedDigest.toLowerCase()) {
|
|
4696
6703
|
throw new Error(
|
|
4697
6704
|
`Turnkey ${label} signing: message_prehash implies digest ${prehashDigest} but message is ${advertisedDigest}`
|
|
4698
6705
|
);
|
|
4699
6706
|
}
|
|
4700
|
-
return { domain
|
|
6707
|
+
return { domain, types, message };
|
|
4701
6708
|
}
|
|
4702
|
-
var import_turnkey_signer,
|
|
6709
|
+
var import_turnkey_signer, import_ethers6, TURNKEY_API_URL, DEFAULTS;
|
|
4703
6710
|
var init_turnkey_impl = __esm({
|
|
4704
6711
|
"src/signers/turnkey-impl.ts"() {
|
|
4705
6712
|
"use strict";
|
|
4706
|
-
import_turnkey_signer = __toESM(
|
|
4707
|
-
|
|
6713
|
+
import_turnkey_signer = __toESM(require_dist8());
|
|
6714
|
+
import_ethers6 = require("ethers");
|
|
6715
|
+
init_pinned_address();
|
|
4708
6716
|
TURNKEY_API_URL = "https://api.turnkey.com";
|
|
4709
6717
|
DEFAULTS = {
|
|
4710
6718
|
concurrencyLimit: 10,
|
|
@@ -4716,6 +6724,7 @@ var init_turnkey_impl = __esm({
|
|
|
4716
6724
|
|
|
4717
6725
|
// src/cli/send-payment.ts
|
|
4718
6726
|
var import_commander = require("commander");
|
|
6727
|
+
var import_fs = require("fs");
|
|
4719
6728
|
|
|
4720
6729
|
// src/generated/core/OpenAPI.ts
|
|
4721
6730
|
var Interceptors = class {
|
|
@@ -5192,7 +7201,7 @@ payment.
|
|
|
5192
7201
|
`,
|
|
5193
7202
|
413: "Payment request too large to process",
|
|
5194
7203
|
500: "Internal server error",
|
|
5195
|
-
503: "
|
|
7204
|
+
503: "The request was not accepted: a dependency is temporarily unavailable, or this operation is paused (`SERVICE_PAUSED`). Nothing was submitted, so the request is safe to retry."
|
|
5196
7205
|
}
|
|
5197
7206
|
});
|
|
5198
7207
|
}
|
|
@@ -5277,6 +7286,9 @@ payment.
|
|
|
5277
7286
|
*
|
|
5278
7287
|
* The response includes everything needed to sign and submit a payment, except the signature itself.
|
|
5279
7288
|
*
|
|
7289
|
+
* Not available on every gateway or every source chain; where it is not, this
|
|
7290
|
+
* returns `501`. Sign the returned request and submit it to `POST /v1/payments`.
|
|
7291
|
+
*
|
|
5280
7292
|
* @param data The data for the request.
|
|
5281
7293
|
* @param data.requestBody
|
|
5282
7294
|
* @returns PreparePaymentResponse Payment request prepared successfully
|
|
@@ -5323,11 +7335,30 @@ var AuthorizationsService = class {
|
|
|
5323
7335
|
body: data.requestBody,
|
|
5324
7336
|
mediaType: "application/json",
|
|
5325
7337
|
errors: {
|
|
5326
|
-
400:
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
7338
|
+
400: `The request was rejected before authorization was attempted, so no
|
|
7339
|
+
authorization outcome exists.
|
|
7340
|
+
`,
|
|
7341
|
+
401: `The counterparty's proof was rejected (\`PROOF_INVALID\` or \`PROOF_STALE\`).
|
|
7342
|
+
This is an authorization outcome, so the body is an \`AuthorizationResult\`
|
|
7343
|
+
with \`status: error\`.
|
|
7344
|
+
`,
|
|
7345
|
+
404: `Counterparty not found (no registration for the resolved DID). An
|
|
7346
|
+
authorization outcome, so the body is an \`AuthorizationResult\` with
|
|
7347
|
+
\`status: error\` and \`error_code: COUNTERPARTY_NOT_FOUND\`.
|
|
7348
|
+
`,
|
|
7349
|
+
500: `Either shape, depending on where the failure happened. A failure before
|
|
7350
|
+
authorization was attempted returns \`ErrorResponse\`. A failure carrying an
|
|
7351
|
+
authorization outcome returns \`AuthorizationResult\` with \`status: error\`.
|
|
7352
|
+
`,
|
|
7353
|
+
502: `Counterparty webhook error (HTTP error or connection failure). An
|
|
7354
|
+
authorization outcome, so the body is an \`AuthorizationResult\` with
|
|
7355
|
+
\`status: error\` and \`error_code: WEBHOOK_ERROR\` or
|
|
7356
|
+
\`WEBHOOK_CONNECTION_ERROR\`.
|
|
7357
|
+
`,
|
|
7358
|
+
504: `Authorization timed out (the counterparty did not respond). An
|
|
7359
|
+
authorization outcome, so the body is an \`AuthorizationResult\` with
|
|
7360
|
+
\`status: timeout\`.
|
|
7361
|
+
`
|
|
5331
7362
|
}
|
|
5332
7363
|
});
|
|
5333
7364
|
}
|
|
@@ -5354,6 +7385,31 @@ var QuoteRequestsService = class {
|
|
|
5354
7385
|
* Collection continues server-side until the quote deadline regardless of the HTTP
|
|
5355
7386
|
* connection, so quotes remain retrievable via the status endpoint in either mode.
|
|
5356
7387
|
*
|
|
7388
|
+
* **Idempotency.** `request_id` is the idempotency key, scoped to the source account
|
|
7389
|
+
* and originator — the same key, and the same contract, as POST /v1/payments.
|
|
7390
|
+
* Submitting the same `request_id` again returns the ORIGINAL batch instead of opening
|
|
7391
|
+
* a second one, so a client whose request timed out or failed in transit can safely
|
|
7392
|
+
* re-submit and recover its `quote_request_id`.
|
|
7393
|
+
*
|
|
7394
|
+
* Because a re-submission must be admissible on its own, some fields legitimately
|
|
7395
|
+
* differ between attempts and are excluded from the comparison: `quote_deadline` and
|
|
7396
|
+
* `fulfillment_deadline` (both must be in the future, so a later attempt has to move
|
|
7397
|
+
* them) and the `proof` that covers them. An expired `quote_deadline` on a
|
|
7398
|
+
* re-submission is NOT an error — the request is resolved onto the batch that already
|
|
7399
|
+
* exists rather than used to open one. There is no `sender_auth` to re-sign here: this
|
|
7400
|
+
* endpoint rejects it, because the spend authorization belongs to the award call.
|
|
7401
|
+
*
|
|
7402
|
+
* The collection window belongs to the BATCH, not to the request. Asking again with a
|
|
7403
|
+
* later `quote_deadline` does not extend a window already open; `quote_deadline` in the
|
|
7404
|
+
* response is the batch's own, and `status` says whether collection is still running.
|
|
7405
|
+
*
|
|
7406
|
+
* What must NOT differ is the corridor's economics — source account and asset,
|
|
7407
|
+
* destination accounts and assets, `fulfillment_amount`, and `max_source_amount`.
|
|
7408
|
+
* Re-using one `request_id` for a genuinely different corridor is a client bug that
|
|
7409
|
+
* would otherwise be silently collapsed onto the first batch, returning quotes for a
|
|
7410
|
+
* corridor that was never requested. It is rejected with `409` and
|
|
7411
|
+
* `IDEMPOTENCY_TERMS_MISMATCH`. Use a distinct `request_id` per quote-request.
|
|
7412
|
+
*
|
|
5357
7413
|
* @param data The data for the request.
|
|
5358
7414
|
* @param data.requestBody
|
|
5359
7415
|
* @param data.wait Return a handle immediately (`false`, default) or hold the connection for collected quotes (`true`).
|
|
@@ -5373,8 +7429,19 @@ var QuoteRequestsService = class {
|
|
|
5373
7429
|
body: data.requestBody,
|
|
5374
7430
|
mediaType: "application/json",
|
|
5375
7431
|
errors: {
|
|
5376
|
-
400:
|
|
5377
|
-
|
|
7432
|
+
400: `Invalid request. \`QUOTE_DEADLINE_NOT_FUTURE\` is the one worth planning for: a NEW
|
|
7433
|
+
quote-request whose \`quote_deadline\` has already passed is refused, because there is
|
|
7434
|
+
no window left to collect quotes in. It does not apply to a re-submission \u2014 an
|
|
7435
|
+
already-used \`request_id\` resolves onto the batch that exists and its expired
|
|
7436
|
+
deadline is ignored, which is what makes a retry recoverable.
|
|
7437
|
+
`,
|
|
7438
|
+
409: `The \`request_id\` has already been used for a quote-request with different
|
|
7439
|
+
economics (\`IDEMPOTENCY_TERMS_MISMATCH\`). Re-submitting one \`request_id\` is how a
|
|
7440
|
+
retry is made safe, so it must identify one batch; use a distinct \`request_id\`
|
|
7441
|
+
per quote-request.
|
|
7442
|
+
`,
|
|
7443
|
+
500: "Internal server error",
|
|
7444
|
+
503: "The request was not accepted: a dependency is temporarily unavailable, or this operation is paused (`SERVICE_PAUSED`). Nothing was submitted, so the request is safe to retry."
|
|
5378
7445
|
}
|
|
5379
7446
|
});
|
|
5380
7447
|
}
|
|
@@ -5457,6 +7524,43 @@ var QuoteRequestsService = class {
|
|
|
5457
7524
|
});
|
|
5458
7525
|
}
|
|
5459
7526
|
};
|
|
7527
|
+
var ChainDefaultsService = class {
|
|
7528
|
+
constructor(httpRequest) {
|
|
7529
|
+
this.httpRequest = httpRequest;
|
|
7530
|
+
}
|
|
7531
|
+
/**
|
|
7532
|
+
* Get chain defaults
|
|
7533
|
+
* The addresses needed to build a payment on a chain: the escrow, the accounts named
|
|
7534
|
+
* in the deposit authorization, and the fulfillment verifier. Fetch these rather than
|
|
7535
|
+
* hardcoding them - they change when a chain's contracts are redeployed.
|
|
7536
|
+
*
|
|
7537
|
+
* With `chain_id`, returns that chain. Without it, or with an empty value, returns
|
|
7538
|
+
* every chain the gateway serves, keyed by CAIP-2 chain id.
|
|
7539
|
+
*
|
|
7540
|
+
* A chain that is not fully configured is still returned when asked for by
|
|
7541
|
+
* `chain_id`, with the missing address empty, but is left out of the full listing.
|
|
7542
|
+
* Treat an empty address as a chain you cannot pay on.
|
|
7543
|
+
*
|
|
7544
|
+
* @param data The data for the request.
|
|
7545
|
+
* @param data.chainId CAIP-2 chain identifier. Omit it, or send it empty, to receive every chain the gateway serves, keyed by chain id.
|
|
7546
|
+
* @returns GetDefaultsResult Chain defaults. A single object when `chain_id` was supplied, otherwise an object keyed by CAIP-2 chain id.
|
|
7547
|
+
* @throws ApiError
|
|
7548
|
+
*/
|
|
7549
|
+
getDefaults(data = {}) {
|
|
7550
|
+
return this.httpRequest.request({
|
|
7551
|
+
method: "GET",
|
|
7552
|
+
url: "/v1/defaults",
|
|
7553
|
+
query: {
|
|
7554
|
+
chain_id: data.chainId
|
|
7555
|
+
},
|
|
7556
|
+
errors: {
|
|
7557
|
+
400: "The `chain_id` is not a valid CAIP-2 chain identifier",
|
|
7558
|
+
404: "The requested chain is not served by this gateway, or - when `chain_id` was omitted - no chain could be resolved at all",
|
|
7559
|
+
503: "A dependency is temporarily unavailable"
|
|
7560
|
+
}
|
|
7561
|
+
});
|
|
7562
|
+
}
|
|
7563
|
+
};
|
|
5460
7564
|
var HealthService = class {
|
|
5461
7565
|
constructor(httpRequest) {
|
|
5462
7566
|
this.httpRequest = httpRequest;
|
|
@@ -5494,19 +7598,140 @@ var PaymentGatewayClient = class {
|
|
|
5494
7598
|
}
|
|
5495
7599
|
});
|
|
5496
7600
|
this.authorizations = new AuthorizationsService(this.request);
|
|
7601
|
+
this.chainDefaults = new ChainDefaultsService(this.request);
|
|
5497
7602
|
this.health = new HealthService(this.request);
|
|
5498
7603
|
this.payments = new PaymentsService(this.request);
|
|
5499
7604
|
this.quoteRequests = new QuoteRequestsService(this.request);
|
|
5500
7605
|
}
|
|
5501
7606
|
};
|
|
5502
7607
|
|
|
7608
|
+
// src/timeout-http-request.ts
|
|
7609
|
+
var import_axios2 = __toESM(require("axios"));
|
|
7610
|
+
|
|
7611
|
+
// src/errors.ts
|
|
7612
|
+
var GatewayTimeoutError = class extends Error {
|
|
7613
|
+
constructor(baseUrl, timeoutMs) {
|
|
7614
|
+
super(
|
|
7615
|
+
`Gateway at ${baseUrl || "(same origin)"} did not respond within ${formatSeconds(timeoutMs)}`
|
|
7616
|
+
);
|
|
7617
|
+
this.baseUrl = baseUrl;
|
|
7618
|
+
this.timeoutMs = timeoutMs;
|
|
7619
|
+
this.name = "GatewayTimeoutError";
|
|
7620
|
+
}
|
|
7621
|
+
};
|
|
7622
|
+
function formatSeconds(ms) {
|
|
7623
|
+
const seconds = ms / 1e3;
|
|
7624
|
+
return `${Number.isInteger(seconds) ? seconds : seconds.toFixed(1)}s`;
|
|
7625
|
+
}
|
|
7626
|
+
function isGatewayTimeoutError(err) {
|
|
7627
|
+
return err instanceof GatewayTimeoutError;
|
|
7628
|
+
}
|
|
7629
|
+
function isApiError(err) {
|
|
7630
|
+
return err instanceof ApiError;
|
|
7631
|
+
}
|
|
7632
|
+
|
|
7633
|
+
// src/request-timeout.ts
|
|
7634
|
+
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
7635
|
+
var DEFAULT_SYNC_WAIT_TIMEOUT_MS = 12e4;
|
|
7636
|
+
var SYNC_HOLD_PATHS = ["/v1/payments", "/v1/payments/awards"];
|
|
7637
|
+
function pathOf(url) {
|
|
7638
|
+
if (!url) return "";
|
|
7639
|
+
const path = url.split("?")[0];
|
|
7640
|
+
const scheme = path.indexOf("://");
|
|
7641
|
+
if (scheme === -1) return path;
|
|
7642
|
+
const host = path.indexOf("/", scheme + 3);
|
|
7643
|
+
return host === -1 ? "" : path.slice(host);
|
|
7644
|
+
}
|
|
7645
|
+
function hasWaitTrueQuery(url) {
|
|
7646
|
+
const query = url?.indexOf("?") ?? -1;
|
|
7647
|
+
if (query === -1) return false;
|
|
7648
|
+
return new URLSearchParams(url.slice(query + 1)).get("wait") === "true";
|
|
7649
|
+
}
|
|
7650
|
+
function isSyncWaitRequest({ method, url, wait }) {
|
|
7651
|
+
if (wait === true || wait === "true" || hasWaitTrueQuery(url)) return true;
|
|
7652
|
+
if (method?.toUpperCase() !== "POST") return false;
|
|
7653
|
+
const path = pathOf(url);
|
|
7654
|
+
return SYNC_HOLD_PATHS.some((held) => path === held || path.endsWith(held));
|
|
7655
|
+
}
|
|
7656
|
+
function ordinaryTimeout(timeouts = {}) {
|
|
7657
|
+
return timeouts.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
7658
|
+
}
|
|
7659
|
+
function timeoutForRequest(request2, timeouts = {}) {
|
|
7660
|
+
return isSyncWaitRequest(request2) ? timeouts.syncWaitTimeoutMs ?? DEFAULT_SYNC_WAIT_TIMEOUT_MS : ordinaryTimeout(timeouts);
|
|
7661
|
+
}
|
|
7662
|
+
function applyRequestTimeout(timeouts = {}) {
|
|
7663
|
+
return (config2) => ({
|
|
7664
|
+
...config2,
|
|
7665
|
+
timeout: config2.timeout ?? timeoutForRequest({ method: config2.method, url: config2.url }, timeouts)
|
|
7666
|
+
});
|
|
7667
|
+
}
|
|
7668
|
+
function isAxiosTimeout(error) {
|
|
7669
|
+
const failure = error;
|
|
7670
|
+
if (!failure) return false;
|
|
7671
|
+
if (failure.code === "ECONNABORTED" || failure.code === "ETIMEDOUT") return true;
|
|
7672
|
+
return failure.code === "ERR_BAD_RESPONSE" && /stream has been aborted/i.test(failure.message ?? "");
|
|
7673
|
+
}
|
|
7674
|
+
function dropPartialResponseOnTimeout(error) {
|
|
7675
|
+
if (isAxiosTimeout(error) && error !== null && typeof error === "object" && "response" in error) {
|
|
7676
|
+
delete error.response;
|
|
7677
|
+
}
|
|
7678
|
+
return error;
|
|
7679
|
+
}
|
|
7680
|
+
function translateTimeout(error, baseUrl, fallbackTimeoutMs) {
|
|
7681
|
+
if (!isAxiosTimeout(error)) return error;
|
|
7682
|
+
const configured = error.config?.timeout;
|
|
7683
|
+
return new GatewayTimeoutError(baseUrl, configured ?? fallbackTimeoutMs);
|
|
7684
|
+
}
|
|
7685
|
+
|
|
7686
|
+
// src/timeout-http-request.ts
|
|
7687
|
+
var timeoutAxios = import_axios2.default.create();
|
|
7688
|
+
timeoutAxios.interceptors.response.use(
|
|
7689
|
+
void 0,
|
|
7690
|
+
(error) => Promise.reject(dropPartialResponseOnTimeout(error))
|
|
7691
|
+
);
|
|
7692
|
+
function withRequestTimeout(config2, timeouts) {
|
|
7693
|
+
const request2 = new Interceptors();
|
|
7694
|
+
for (const fn of config2?.interceptors?.request?._fns ?? []) request2.use(fn);
|
|
7695
|
+
request2.use(applyRequestTimeout(timeouts));
|
|
7696
|
+
return {
|
|
7697
|
+
interceptors: { request: request2, response: config2?.interceptors?.response ?? new Interceptors() }
|
|
7698
|
+
};
|
|
7699
|
+
}
|
|
7700
|
+
var TimeoutHttpRequest = class extends AxiosHttpRequest {
|
|
7701
|
+
constructor(config2, timeouts = {}) {
|
|
7702
|
+
super(config2);
|
|
7703
|
+
this.timeouts = timeouts;
|
|
7704
|
+
}
|
|
7705
|
+
request(options) {
|
|
7706
|
+
return new CancelablePromise((resolve2, reject, onCancel) => {
|
|
7707
|
+
const pending = request(this.config, options, timeoutAxios);
|
|
7708
|
+
onCancel(() => pending.cancel());
|
|
7709
|
+
pending.then(resolve2, (error) => {
|
|
7710
|
+
const request2 = { method: options.method, url: options.url, wait: options.query?.wait };
|
|
7711
|
+
reject(
|
|
7712
|
+
translateTimeout(error, this.config.BASE, timeoutForRequest(request2, this.timeouts))
|
|
7713
|
+
);
|
|
7714
|
+
});
|
|
7715
|
+
});
|
|
7716
|
+
}
|
|
7717
|
+
};
|
|
7718
|
+
function timeoutHttpRequest(timeouts) {
|
|
7719
|
+
return class extends TimeoutHttpRequest {
|
|
7720
|
+
constructor(config2) {
|
|
7721
|
+
super(config2, timeouts);
|
|
7722
|
+
}
|
|
7723
|
+
};
|
|
7724
|
+
}
|
|
7725
|
+
|
|
5503
7726
|
// src/chain-adapters/evm.ts
|
|
5504
7727
|
var import_ethers = require("ethers");
|
|
5505
7728
|
|
|
5506
7729
|
// src/chain-adapters/types.ts
|
|
5507
7730
|
function assertKeyMatchesSender(matches, sender, derived) {
|
|
5508
7731
|
if (!matches) {
|
|
5509
|
-
throw new Error(
|
|
7732
|
+
throw new Error(
|
|
7733
|
+
`The private key derives ${derived}, which does not match the sender address ${sender}`
|
|
7734
|
+
);
|
|
5510
7735
|
}
|
|
5511
7736
|
}
|
|
5512
7737
|
|
|
@@ -5558,10 +7783,9 @@ var tronAdapter = {
|
|
|
5558
7783
|
throw new Error("Invalid private key");
|
|
5559
7784
|
}
|
|
5560
7785
|
},
|
|
5561
|
-
// Tron addresses are the same secp256k1-derived 20 bytes as EVM.
|
|
5562
|
-
//
|
|
5563
|
-
//
|
|
5564
|
-
// whose first byte is 0x41.
|
|
7786
|
+
// Tron addresses are the same secp256k1-derived 20 bytes as EVM. The derived
|
|
7787
|
+
// address is already canonical 20-byte hex, so only the sender side — which
|
|
7788
|
+
// arrives in whichever spelling the caller chose — needs normalizing.
|
|
5565
7789
|
verifyAddressMatchesKey(privateKey, address) {
|
|
5566
7790
|
const key = privateKey.startsWith("0x") ? privateKey : "0x" + privateKey;
|
|
5567
7791
|
const derived = new import_ethers2.ethers.Wallet(key).address;
|
|
@@ -5600,22 +7824,133 @@ function secretKeyFromPrivate(privateKey) {
|
|
|
5600
7824
|
if (decoded.length === 32) {
|
|
5601
7825
|
return import_tweetnacl.default.sign.keyPair.fromSeed(decoded).secretKey;
|
|
5602
7826
|
}
|
|
5603
|
-
throw new Error(
|
|
7827
|
+
throw new Error(
|
|
7828
|
+
`Invalid Solana private key length: expected 32 or 64 bytes, got ${decoded.length}`
|
|
7829
|
+
);
|
|
5604
7830
|
}
|
|
5605
7831
|
|
|
5606
7832
|
// src/chain-adapters/index.ts
|
|
5607
7833
|
var adapters = {
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
7834
|
+
eip155: evmAdapter,
|
|
7835
|
+
tron: tronAdapter,
|
|
7836
|
+
solana: solanaAdapter
|
|
5611
7837
|
};
|
|
5612
7838
|
function getChainAdapter(sourceChainId) {
|
|
5613
|
-
const prefix = sourceChainId.split(":")[0];
|
|
7839
|
+
const prefix = sourceChainId.split(":")[0]?.toLowerCase() ?? "";
|
|
5614
7840
|
const adapter = adapters[prefix];
|
|
5615
7841
|
if (!adapter) throw new Error(`Unsupported source chain: ${sourceChainId}`);
|
|
5616
7842
|
return adapter;
|
|
5617
7843
|
}
|
|
5618
7844
|
|
|
7845
|
+
// src/asset-identifier.ts
|
|
7846
|
+
var import_ethers3 = require("ethers");
|
|
7847
|
+
var SHAPE_EXAMPLE = "eip155:421614/erc20:0x...";
|
|
7848
|
+
var NAMESPACE = /^[a-z0-9]+$/;
|
|
7849
|
+
var CHAIN_REFERENCE = /^[a-zA-Z0-9_-]+$/;
|
|
7850
|
+
var ASSET_NAMESPACE = /^[a-z0-9-]{3,8}$/;
|
|
7851
|
+
var ASSET_REFERENCE = /^[-.%a-zA-Z0-9]{1,128}$/;
|
|
7852
|
+
var TOKEN_ID = /^[-.%a-zA-Z0-9]{1,78}$/;
|
|
7853
|
+
var EVM_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
|
|
7854
|
+
var EIP155_REFERENCE = /^[0-9]+$/;
|
|
7855
|
+
var HEX_REFERENCE = /^0[xX][0-9a-fA-F]{1,16}$/;
|
|
7856
|
+
var MAX_ECHO = 120;
|
|
7857
|
+
var MAX_REFERENCE_ECHO = 32;
|
|
7858
|
+
function parseAssetIdentifier(value) {
|
|
7859
|
+
if (typeof value !== "string" || value === "") {
|
|
7860
|
+
throw new Error(shapeError(value));
|
|
7861
|
+
}
|
|
7862
|
+
const firstSlash = value.indexOf("/");
|
|
7863
|
+
if (firstSlash === -1) {
|
|
7864
|
+
throw new Error(shapeError(value));
|
|
7865
|
+
}
|
|
7866
|
+
const chainSegments = value.slice(0, firstSlash).split(":");
|
|
7867
|
+
if (chainSegments.length !== 2) {
|
|
7868
|
+
throw new Error(shapeError(value));
|
|
7869
|
+
}
|
|
7870
|
+
const namespace = chainSegments[0].toLowerCase();
|
|
7871
|
+
const reference = namespace === "tron" ? chainSegments[1].toLowerCase() : chainSegments[1];
|
|
7872
|
+
if (!NAMESPACE.test(namespace) || !CHAIN_REFERENCE.test(reference)) {
|
|
7873
|
+
throw new Error(shapeError(value));
|
|
7874
|
+
}
|
|
7875
|
+
if (namespace === "eip155" && !EIP155_REFERENCE.test(reference)) {
|
|
7876
|
+
throw new Error(eip155ReferenceError(reference, value));
|
|
7877
|
+
}
|
|
7878
|
+
const assetPart = value.slice(firstSlash + 1);
|
|
7879
|
+
const separator = assetPart.indexOf(":");
|
|
7880
|
+
if (separator === -1) {
|
|
7881
|
+
throw new Error(tokenAddressError(value));
|
|
7882
|
+
}
|
|
7883
|
+
const assetNamespace = assetPart.slice(0, separator).toLowerCase();
|
|
7884
|
+
const rest = assetPart.slice(separator + 1);
|
|
7885
|
+
const referenceSlash = rest.indexOf("/");
|
|
7886
|
+
const tokenAddress = referenceSlash === -1 ? rest : rest.slice(0, referenceSlash);
|
|
7887
|
+
const tokenId = referenceSlash === -1 ? void 0 : rest.slice(referenceSlash + 1);
|
|
7888
|
+
if (!ASSET_NAMESPACE.test(assetNamespace)) {
|
|
7889
|
+
throw new Error(tokenAddressError(value));
|
|
7890
|
+
}
|
|
7891
|
+
if (assetNamespace === "slip44") {
|
|
7892
|
+
throw new Error(nativeAssetError(value));
|
|
7893
|
+
}
|
|
7894
|
+
if (!ASSET_REFERENCE.test(tokenAddress)) {
|
|
7895
|
+
throw new Error(tokenAddressError(value));
|
|
7896
|
+
}
|
|
7897
|
+
if (tokenId !== void 0 && !TOKEN_ID.test(tokenId)) {
|
|
7898
|
+
throw new Error(tokenAddressError(value));
|
|
7899
|
+
}
|
|
7900
|
+
assertTokenAddress(namespace, tokenAddress, value);
|
|
7901
|
+
const chainId = `${namespace}:${reference}`;
|
|
7902
|
+
return {
|
|
7903
|
+
chainId,
|
|
7904
|
+
namespace,
|
|
7905
|
+
reference,
|
|
7906
|
+
assetNamespace,
|
|
7907
|
+
tokenAddress,
|
|
7908
|
+
...tokenId === void 0 ? {} : { tokenId },
|
|
7909
|
+
normalized: `${chainId}/${assetNamespace}:${tokenAddress}${tokenId === void 0 ? "" : `/${tokenId}`}`
|
|
7910
|
+
};
|
|
7911
|
+
}
|
|
7912
|
+
function assetChainId(value) {
|
|
7913
|
+
return parseAssetIdentifier(value).chainId;
|
|
7914
|
+
}
|
|
7915
|
+
function echo(value, limit = MAX_ECHO) {
|
|
7916
|
+
const shown = typeof value === "string" ? value : String(value);
|
|
7917
|
+
return shown.length > limit ? `${shown.slice(0, limit)}\u2026` : shown;
|
|
7918
|
+
}
|
|
7919
|
+
function shapeError(value) {
|
|
7920
|
+
return `Invalid asset identifier "${echo(value)}": expected CAIP-19 "<chain>/<type>:<address>", e.g. ${SHAPE_EXAMPLE}`;
|
|
7921
|
+
}
|
|
7922
|
+
function tokenAddressError(value) {
|
|
7923
|
+
return `Invalid token address in asset "${echo(value)}".`;
|
|
7924
|
+
}
|
|
7925
|
+
function eip155ReferenceError(reference, value) {
|
|
7926
|
+
const prefix = `Invalid eip155 chain id "${echo(reference, MAX_REFERENCE_ECHO)}" in asset "${echo(value)}"`;
|
|
7927
|
+
if (HEX_REFERENCE.test(reference)) {
|
|
7928
|
+
return `${prefix}: use the decimal chain id (${BigInt(reference)}), not hex.`;
|
|
7929
|
+
}
|
|
7930
|
+
return `${prefix}: an eip155 chain id is decimal, e.g. 421614.`;
|
|
7931
|
+
}
|
|
7932
|
+
function nativeAssetError(value) {
|
|
7933
|
+
return `Asset "${echo(value)}" is a native asset (slip44) and has no contract to deposit. Use the wrapped token's erc20 identifier.`;
|
|
7934
|
+
}
|
|
7935
|
+
function assertTokenAddress(namespace, tokenAddress, value) {
|
|
7936
|
+
if (namespace !== "eip155") return;
|
|
7937
|
+
if (!EVM_ADDRESS.test(tokenAddress)) {
|
|
7938
|
+
throw new Error(tokenAddressError(value));
|
|
7939
|
+
}
|
|
7940
|
+
const body = tokenAddress.slice(2);
|
|
7941
|
+
if (body === body.toLowerCase() || body === body.toUpperCase()) return;
|
|
7942
|
+
try {
|
|
7943
|
+
(0, import_ethers3.getAddress)(tokenAddress);
|
|
7944
|
+
} catch {
|
|
7945
|
+
throw new Error(
|
|
7946
|
+
`Token address "${tokenAddress}" has an invalid checksum. Fix the capitalization or use the all-lowercase form.`
|
|
7947
|
+
);
|
|
7948
|
+
}
|
|
7949
|
+
}
|
|
7950
|
+
|
|
7951
|
+
// src/index.ts
|
|
7952
|
+
var import_chain_address = __toESM(require_dist2());
|
|
7953
|
+
|
|
5619
7954
|
// src/chain-adapters/solana-clock.ts
|
|
5620
7955
|
var DEFAULT_SOLANA_RPC_URLS = {
|
|
5621
7956
|
"5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp": "https://api.mainnet-beta.solana.com",
|
|
@@ -5684,19 +8019,84 @@ async function resolveSolanaIssuedAt(opts) {
|
|
|
5684
8019
|
}
|
|
5685
8020
|
|
|
5686
8021
|
// src/index.ts
|
|
5687
|
-
var import_payment_request_sender_auth2 = __toESM(
|
|
8022
|
+
var import_payment_request_sender_auth2 = __toESM(require_dist5());
|
|
8023
|
+
var import_chain_address2 = __toESM(require_dist2());
|
|
8024
|
+
|
|
8025
|
+
// src/payment-tracking.ts
|
|
8026
|
+
function isTerminalStatus(status) {
|
|
8027
|
+
return status === "completed" || status === "failed";
|
|
8028
|
+
}
|
|
8029
|
+
var DEFAULT_WAIT_SECONDS = 60;
|
|
8030
|
+
var DEFAULT_WAIT_BUDGET_MS = DEFAULT_WAIT_SECONDS * 1e3;
|
|
8031
|
+
var DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
8032
|
+
async function waitForTerminalStatus(params) {
|
|
8033
|
+
const {
|
|
8034
|
+
fetchStatus,
|
|
8035
|
+
budgetMs = DEFAULT_WAIT_BUDGET_MS,
|
|
8036
|
+
intervalMs = DEFAULT_POLL_INTERVAL_MS,
|
|
8037
|
+
now = () => Date.now(),
|
|
8038
|
+
signal,
|
|
8039
|
+
// Closes over `signal` so the default wakes on abort instead of sleeping out the interval.
|
|
8040
|
+
sleep = (ms) => defaultSleep(ms, signal),
|
|
8041
|
+
onError
|
|
8042
|
+
} = params;
|
|
8043
|
+
const deadline = now() + budgetMs;
|
|
8044
|
+
let snapshot;
|
|
8045
|
+
let errorCount = 0;
|
|
8046
|
+
while (now() < deadline) {
|
|
8047
|
+
if (signal?.aborted) {
|
|
8048
|
+
return { snapshot, timedOut: true, aborted: true, errorCount };
|
|
8049
|
+
}
|
|
8050
|
+
const remaining = deadline - now();
|
|
8051
|
+
await sleep(Math.min(intervalMs, remaining));
|
|
8052
|
+
if (signal?.aborted) {
|
|
8053
|
+
return { snapshot, timedOut: true, aborted: true, errorCount };
|
|
8054
|
+
}
|
|
8055
|
+
try {
|
|
8056
|
+
snapshot = await fetchStatus();
|
|
8057
|
+
} catch (error) {
|
|
8058
|
+
errorCount += 1;
|
|
8059
|
+
onError?.(error);
|
|
8060
|
+
continue;
|
|
8061
|
+
}
|
|
8062
|
+
if (isTerminalStatus(snapshot.status)) {
|
|
8063
|
+
return { snapshot, timedOut: false, aborted: false, errorCount };
|
|
8064
|
+
}
|
|
8065
|
+
}
|
|
8066
|
+
return { snapshot, timedOut: true, aborted: false, errorCount };
|
|
8067
|
+
}
|
|
8068
|
+
function defaultSleep(ms, signal) {
|
|
8069
|
+
if (!signal) {
|
|
8070
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
8071
|
+
}
|
|
8072
|
+
return new Promise((resolve2) => {
|
|
8073
|
+
const done = () => {
|
|
8074
|
+
clearTimeout(timer);
|
|
8075
|
+
signal.removeEventListener("abort", done);
|
|
8076
|
+
resolve2();
|
|
8077
|
+
};
|
|
8078
|
+
const timer = setTimeout(done, ms);
|
|
8079
|
+
signal.addEventListener("abort", done, { once: true });
|
|
8080
|
+
});
|
|
8081
|
+
}
|
|
8082
|
+
|
|
8083
|
+
// src/index.ts
|
|
8084
|
+
var import_payment_request_token_approval = __toESM(require_dist6());
|
|
5688
8085
|
|
|
5689
8086
|
// src/sender_auth_schemes/evm_permit2.ts
|
|
5690
|
-
var
|
|
5691
|
-
var import_evm_escrow_encoding = __toESM(
|
|
8087
|
+
var import_ethers4 = require("ethers");
|
|
8088
|
+
var import_evm_escrow_encoding = __toESM(require_dist3());
|
|
5692
8089
|
|
|
5693
8090
|
// src/sender_auth_schemes/solana.ts
|
|
5694
|
-
var
|
|
8091
|
+
var import_ethers5 = require("ethers");
|
|
5695
8092
|
var import_bs582 = __toESM(require("bs58"));
|
|
5696
|
-
var import_solana_escrow_encoding = __toESM(
|
|
8093
|
+
var import_solana_escrow_encoding = __toESM(require_dist4());
|
|
8094
|
+
|
|
8095
|
+
// src/signers/index.ts
|
|
8096
|
+
init_pinned_address();
|
|
5697
8097
|
|
|
5698
8098
|
// src/signers/raw.ts
|
|
5699
|
-
var import_payment_request_sender_auth = __toESM(
|
|
8099
|
+
var import_payment_request_sender_auth = __toESM(require_dist5());
|
|
5700
8100
|
var RawSenderSigner = class {
|
|
5701
8101
|
constructor(network, privateKey) {
|
|
5702
8102
|
const adapter = getChainAdapter(network);
|
|
@@ -5709,6 +8109,7 @@ var RawSenderSigner = class {
|
|
|
5709
8109
|
};
|
|
5710
8110
|
|
|
5711
8111
|
// src/signers/turnkey.ts
|
|
8112
|
+
init_pinned_address();
|
|
5712
8113
|
async function loadImpl() {
|
|
5713
8114
|
return Promise.resolve().then(() => (init_turnkey_impl(), turnkey_impl_exports));
|
|
5714
8115
|
}
|
|
@@ -5717,6 +8118,7 @@ var TurnkeySenderSigner = class {
|
|
|
5717
8118
|
this.chainPrefix = chainPrefix;
|
|
5718
8119
|
this.cfg = cfg;
|
|
5719
8120
|
this.loader = loader;
|
|
8121
|
+
this.pinnedAddress = requirePinnedSender(cfg.pinnedAddress);
|
|
5720
8122
|
}
|
|
5721
8123
|
async sign(signedMessage) {
|
|
5722
8124
|
const impl = await this.loader();
|
|
@@ -5727,7 +8129,7 @@ var TurnkeySenderSigner = class {
|
|
|
5727
8129
|
walletId: this.cfg.walletId,
|
|
5728
8130
|
apiPublicKey: this.cfg.apiPublicKey,
|
|
5729
8131
|
apiPrivateKey: this.cfg.apiPrivateKey,
|
|
5730
|
-
...this.
|
|
8132
|
+
...this.pinnedAddress ? { pinnedAddress: this.pinnedAddress } : {},
|
|
5731
8133
|
...this.cfg.logger ? { logger: this.cfg.logger } : {},
|
|
5732
8134
|
...this.cfg.meter ? { meter: this.cfg.meter } : {}
|
|
5733
8135
|
},
|
|
@@ -5739,24 +8141,30 @@ var TurnkeySenderSigner = class {
|
|
|
5739
8141
|
|
|
5740
8142
|
// src/signers/index.ts
|
|
5741
8143
|
function createSenderSigner(sourceChainId, opts) {
|
|
5742
|
-
const chainPrefix = sourceChainId.split(":")[0];
|
|
8144
|
+
const chainPrefix = sourceChainId.split(":")[0]?.toLowerCase() ?? "";
|
|
5743
8145
|
if (opts.provider === "turnkey") {
|
|
5744
8146
|
return new TurnkeySenderSigner(chainPrefix, opts);
|
|
5745
8147
|
}
|
|
8148
|
+
const pinnedAddress = requirePinnedSender(opts.pinnedAddress);
|
|
5746
8149
|
const adapter = getChainAdapter(sourceChainId);
|
|
5747
8150
|
const privateKey = adapter.formatPrivateKey(opts.privateKey);
|
|
5748
8151
|
adapter.validatePrivateKey?.(opts.privateKey);
|
|
5749
|
-
if (
|
|
8152
|
+
if (pinnedAddress) {
|
|
5750
8153
|
if (!adapter.verifyAddressMatchesKey) {
|
|
5751
|
-
throw new Error(
|
|
8154
|
+
throw new Error(
|
|
8155
|
+
`pinnedAddress was provided but the ${sourceChainId} adapter cannot verify the key derives it`
|
|
8156
|
+
);
|
|
5752
8157
|
}
|
|
5753
|
-
adapter.verifyAddressMatchesKey(privateKey,
|
|
8158
|
+
adapter.verifyAddressMatchesKey(privateKey, pinnedAddress);
|
|
5754
8159
|
}
|
|
5755
8160
|
return new RawSenderSigner(sourceChainId, opts.privateKey);
|
|
5756
8161
|
}
|
|
5757
8162
|
|
|
5758
8163
|
// src/index.ts
|
|
5759
8164
|
var PAYMENT_REQUEST_VERSION = "1.0";
|
|
8165
|
+
function assertPayableAccount(assetIdentifier, account) {
|
|
8166
|
+
(0, import_chain_address.validate)(assetChainId(assetIdentifier), account);
|
|
8167
|
+
}
|
|
5760
8168
|
var defaultGateway = "https://payment-gw.production-testnet.atum.xyz";
|
|
5761
8169
|
var OpenAPI2 = { ...OpenAPI, BASE: defaultGateway };
|
|
5762
8170
|
var DEFAULT_QUOTE_DEADLINE_SECONDS = 5;
|
|
@@ -5773,10 +8181,14 @@ function resolveDeadlines(params, defaultQuoteSeconds) {
|
|
|
5773
8181
|
const quoteDeadlineSeconds = params.quoteDeadlineSeconds ?? defaultQuoteSeconds;
|
|
5774
8182
|
const fulfillmentDeadlineSeconds = params.fulfillmentDeadlineSeconds ?? DEFAULT_FULFILLMENT_DEADLINE_SECONDS;
|
|
5775
8183
|
if (!Number.isFinite(quoteDeadlineSeconds) || !Number.isFinite(fulfillmentDeadlineSeconds)) {
|
|
5776
|
-
throw new Error(
|
|
8184
|
+
throw new Error(
|
|
8185
|
+
"quoteDeadlineSeconds and fulfillmentDeadlineSeconds must be finite numbers of seconds."
|
|
8186
|
+
);
|
|
5777
8187
|
}
|
|
5778
8188
|
if (quoteDeadlineSeconds <= 0 || fulfillmentDeadlineSeconds <= 0) {
|
|
5779
|
-
throw new Error(
|
|
8189
|
+
throw new Error(
|
|
8190
|
+
"quoteDeadlineSeconds and fulfillmentDeadlineSeconds must be positive numbers of seconds."
|
|
8191
|
+
);
|
|
5780
8192
|
}
|
|
5781
8193
|
if (quoteDeadlineSeconds >= fulfillmentDeadlineSeconds) {
|
|
5782
8194
|
throw new Error(
|
|
@@ -5789,18 +8201,67 @@ function resolveDeadlines(params, defaultQuoteSeconds) {
|
|
|
5789
8201
|
fulfillment_deadline: new Date(now + fulfillmentDeadlineSeconds * 1e3).toISOString()
|
|
5790
8202
|
};
|
|
5791
8203
|
}
|
|
8204
|
+
function defaultsErrorDetail(error) {
|
|
8205
|
+
if (!isApiError(error)) {
|
|
8206
|
+
return error instanceof Error ? error.message : String(error);
|
|
8207
|
+
}
|
|
8208
|
+
const body = error.body;
|
|
8209
|
+
const parts = [];
|
|
8210
|
+
if (typeof body?.code === "string" && body.code.trim() !== "") parts.push(body.code);
|
|
8211
|
+
if (typeof body?.message === "string" && body.message.trim() !== "") parts.push(body.message);
|
|
8212
|
+
const requestId = typeof body?.request_id === "string" && body.request_id.trim() !== "" ? body.request_id : "";
|
|
8213
|
+
if (parts.length > 0) {
|
|
8214
|
+
return `${parts.join(": ")}${requestId === "" ? "" : ` (request_id=${requestId})`}`;
|
|
8215
|
+
}
|
|
8216
|
+
return error.statusText || `HTTP ${error.status}`;
|
|
8217
|
+
}
|
|
8218
|
+
function singleChainOf(response, chainId) {
|
|
8219
|
+
if (typeof response !== "object" || response === null) {
|
|
8220
|
+
throw new Error(
|
|
8221
|
+
`Failed to fetch defaults for chain ${chainId}: the gateway did not return a JSON object. Check that the configured base URL points at the payment gateway.`
|
|
8222
|
+
);
|
|
8223
|
+
}
|
|
8224
|
+
const single = response;
|
|
8225
|
+
if (typeof single.chain_id !== "string") {
|
|
8226
|
+
throw new Error(
|
|
8227
|
+
`Failed to fetch defaults for chain ${chainId}: the gateway answered with defaults for every chain rather than the one requested`
|
|
8228
|
+
);
|
|
8229
|
+
}
|
|
8230
|
+
if (single.chain_id.toLowerCase() !== chainId.toLowerCase()) {
|
|
8231
|
+
throw new Error(
|
|
8232
|
+
`Failed to fetch defaults for chain ${chainId}: the gateway answered with defaults for ` + single.chain_id
|
|
8233
|
+
);
|
|
8234
|
+
}
|
|
8235
|
+
return single;
|
|
8236
|
+
}
|
|
5792
8237
|
async function assemblePaymentRequest(params) {
|
|
5793
|
-
const
|
|
5794
|
-
const
|
|
8238
|
+
const source = parseAssetIdentifier(params.sourceAsset);
|
|
8239
|
+
const destination = parseAssetIdentifier(params.destinationAsset);
|
|
8240
|
+
const { chainId: sourceChainId, namespace } = source;
|
|
5795
8241
|
const adapter = getChainAdapter(sourceChainId);
|
|
5796
8242
|
const nonce = params.nonce ?? (namespace === "solana" ? (0, import_payment_request_sender_auth2.deterministicSolanaNonce)({ requestId: params.requestId, depositor: params.depositor }) : (0, import_payment_request_sender_auth2.deterministicPermitNonce)({ requestId: params.requestId, depositor: params.depositor }));
|
|
5797
8243
|
const auth = await (0, import_payment_request_sender_auth2.getChainAdapter)(sourceChainId).buildAuthMessage({
|
|
5798
|
-
|
|
8244
|
+
// Canonicalized: the Tron adapter resolves its Permit2 address by exact chain-id key, so an
|
|
8245
|
+
// uppercase namespace would miss the lookup and fail inside the SDK.
|
|
8246
|
+
sourceAsset: source.normalized,
|
|
5799
8247
|
depositor: params.depositor,
|
|
5800
8248
|
// The gateway pins the signed deposit amount to max_source_amount (the cap).
|
|
5801
8249
|
maxSourceAmount: params.maxSourceAmount,
|
|
5802
8250
|
requestId: params.requestId,
|
|
5803
8251
|
sourceDefaults: params.sourceDefaults,
|
|
8252
|
+
// The payee the deposit commits to. Passed as CAIP components, not a composed string:
|
|
8253
|
+
// the adapter composes it through the shared buildEscrowDestination so this producer
|
|
8254
|
+
// and the release signer cannot disagree by a byte. These are the SAME two values that
|
|
8255
|
+
// become paymentRequest.destination[0] below, so the signed commitment and the request
|
|
8256
|
+
// body cannot describe different payees.
|
|
8257
|
+
// Canonicalized for the same reason `sourceAsset` is, and additionally because the claim
|
|
8258
|
+
// three lines up has to be TRUE: destination[0] below carries `destination.normalized`, so
|
|
8259
|
+
// passing the raw string here would sign a commitment over different bytes than the request
|
|
8260
|
+
// body names whenever a caller supplies a non-canonical namespace (e.g. "EIP155:42220").
|
|
8261
|
+
// `normalized` lowercases only the namespaces and the asset namespace — the chain reference
|
|
8262
|
+
// and token address keep their case, so base58 (Solana genesis reference, SPL mint) survives.
|
|
8263
|
+
destinationAsset: destination.normalized,
|
|
8264
|
+
destinationAccount: params.destinationAccount,
|
|
5804
8265
|
deadline: params.deadline,
|
|
5805
8266
|
nonce,
|
|
5806
8267
|
...namespace === "solana" ? {
|
|
@@ -5816,13 +8277,15 @@ async function assemblePaymentRequest(params) {
|
|
|
5816
8277
|
version: params.version ?? PAYMENT_REQUEST_VERSION,
|
|
5817
8278
|
request_id: params.requestId,
|
|
5818
8279
|
source: {
|
|
5819
|
-
asset_identifier:
|
|
8280
|
+
asset_identifier: source.normalized,
|
|
5820
8281
|
account: params.depositor
|
|
5821
8282
|
},
|
|
5822
|
-
destination: [
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
8283
|
+
destination: [
|
|
8284
|
+
{
|
|
8285
|
+
asset_identifier: destination.normalized,
|
|
8286
|
+
account: params.destinationAccount
|
|
8287
|
+
}
|
|
8288
|
+
],
|
|
5826
8289
|
fulfillment_amount: params.fulfillmentAmount,
|
|
5827
8290
|
max_source_amount: params.maxSourceAmount,
|
|
5828
8291
|
quote_deadline: params.quoteDeadline,
|
|
@@ -5837,43 +8300,58 @@ async function assemblePaymentRequest(params) {
|
|
|
5837
8300
|
...params.settlerRequirements ? { settler_requirements: params.settlerRequirements } : {},
|
|
5838
8301
|
sender_auth: {
|
|
5839
8302
|
message_scheme: auth.messageScheme,
|
|
5840
|
-
signed_messages: [
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
8303
|
+
signed_messages: [
|
|
8304
|
+
{
|
|
8305
|
+
message: auth.messageHash,
|
|
8306
|
+
message_prehash: auth.messagePrehash,
|
|
8307
|
+
signature: ""
|
|
8308
|
+
}
|
|
8309
|
+
]
|
|
5845
8310
|
}
|
|
5846
8311
|
};
|
|
5847
8312
|
}
|
|
5848
8313
|
var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
5849
|
-
constructor(config2, HttpRequest
|
|
8314
|
+
constructor(config2, HttpRequest) {
|
|
5850
8315
|
const envBase = (typeof process !== "undefined" ? process.env.GATEWAY_URL : void 0)?.trim();
|
|
5851
8316
|
const base = config2?.BASE ?? (envBase || defaultGateway);
|
|
5852
|
-
|
|
5853
|
-
|
|
8317
|
+
const timeouts = {
|
|
8318
|
+
timeoutMs: config2?.timeoutMs,
|
|
8319
|
+
syncWaitTimeoutMs: config2?.syncWaitTimeoutMs
|
|
8320
|
+
};
|
|
8321
|
+
super(
|
|
8322
|
+
{ ...config2, BASE: base, ...withRequestTimeout(config2, timeouts) },
|
|
8323
|
+
HttpRequest ?? timeoutHttpRequest(timeouts)
|
|
8324
|
+
);
|
|
5854
8325
|
}
|
|
5855
8326
|
/**
|
|
5856
8327
|
* Fetches chain defaults from the payment gateway.
|
|
5857
|
-
*
|
|
8328
|
+
*
|
|
8329
|
+
* Goes through the generated typed client, so the request shares the payment calls'
|
|
8330
|
+
* transport: one base URL, one timeout policy, and `/v1/defaults` is described by the
|
|
8331
|
+
* OpenAPI contract rather than assembled by hand here.
|
|
8332
|
+
*
|
|
5858
8333
|
* @param chainId The CAIP-2 chain identifier (e.g., "eip155:42161")
|
|
5859
8334
|
* @returns The chain defaults including escrow, quote selector, and fulfillment verifier
|
|
5860
8335
|
*/
|
|
5861
8336
|
async fetchChainDefaults(chainId) {
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
8337
|
+
if (chainId.trim() === "") {
|
|
8338
|
+
throw new Error(
|
|
8339
|
+
'payment-gateway-client: fetchChainDefaults requires a CAIP-2 chain id, for example "eip155:8453"'
|
|
8340
|
+
);
|
|
8341
|
+
}
|
|
8342
|
+
let response;
|
|
8343
|
+
try {
|
|
8344
|
+
response = await this.chainDefaults.getDefaults({ chainId });
|
|
8345
|
+
} catch (error) {
|
|
8346
|
+
if (isGatewayTimeoutError(error)) throw error;
|
|
8347
|
+
throw new Error(
|
|
8348
|
+
`Failed to fetch defaults for chain ${chainId}: ${defaultsErrorDetail(error)}`,
|
|
8349
|
+
{
|
|
8350
|
+
cause: error
|
|
5869
8351
|
}
|
|
5870
|
-
|
|
5871
|
-
}
|
|
5872
|
-
const error = new Error(`Failed to fetch defaults for chain ${chainId}: ${response.statusText}`);
|
|
5873
|
-
error.availableDefaults = availableDefaults;
|
|
5874
|
-
throw error;
|
|
8352
|
+
);
|
|
5875
8353
|
}
|
|
5876
|
-
const data =
|
|
8354
|
+
const data = singleChainOf(response, chainId);
|
|
5877
8355
|
if (!data.escrow_contract) {
|
|
5878
8356
|
throw new Error("defaults missing escrow_contract");
|
|
5879
8357
|
}
|
|
@@ -5892,23 +8370,34 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
|
5892
8370
|
if (!data.fulfillment_verifier.endpoint) {
|
|
5893
8371
|
throw new Error("defaults missing fulfillment_verifier.endpoint");
|
|
5894
8372
|
}
|
|
8373
|
+
if (typeof data.permit2_contract === "string" && data.permit2_contract.trim() === "") {
|
|
8374
|
+
throw new Error("defaults returned an empty permit2_contract");
|
|
8375
|
+
}
|
|
5895
8376
|
return {
|
|
5896
8377
|
escrowContract: data.escrow_contract,
|
|
5897
8378
|
quoteSelector: data.quote_selector,
|
|
5898
8379
|
fulfillmentVerifierAccount: data.fulfillment_verifier.account,
|
|
5899
8380
|
fulfillmentVerifierEndpoint: data.fulfillment_verifier.endpoint,
|
|
5900
8381
|
fulfillmentProxy: data.fulfillment_proxy,
|
|
5901
|
-
|
|
8382
|
+
// `?? undefined` normalises a JSON null at the boundary. The declared type is
|
|
8383
|
+
// `string | undefined`, and a consumer testing `!== undefined` or `in` - both
|
|
8384
|
+
// reasonable against that type - would otherwise build an EIP-712 domain around a
|
|
8385
|
+
// null verifyingContract.
|
|
8386
|
+
permit2Contract: data.permit2_contract ?? void 0,
|
|
8387
|
+
// Which deposit witness the escrow on this chain pins. Absent means the
|
|
8388
|
+
// four-member witness — see ChainDefaults.depositWitnessVersion for why
|
|
8389
|
+
// absence is the permissive default. EVM/Tron only; Solana uses the svm_* fields below.
|
|
8390
|
+
depositWitnessVersion: data.deposit_witness_version ?? void 0,
|
|
5902
8391
|
// V3 Solana escrow domain separation. Present only for Solana
|
|
5903
8392
|
// source chains; the Solana adapter requires them to build the deposit hash.
|
|
5904
|
-
svmSignatureClusterId: data.svm_signature_cluster_id,
|
|
5905
|
-
svmSignatureDomainVersion: data.svm_signature_domain_version
|
|
8393
|
+
svmSignatureClusterId: data.svm_signature_cluster_id ?? void 0,
|
|
8394
|
+
svmSignatureDomainVersion: data.svm_signature_domain_version ?? void 0
|
|
5906
8395
|
};
|
|
5907
8396
|
}
|
|
5908
8397
|
/**
|
|
5909
8398
|
* Prepares a payment request with defaults, ready for signing.
|
|
5910
8399
|
*
|
|
5911
|
-
* By default this resolves the corridor addresses from the gateway `/defaults`
|
|
8400
|
+
* By default this resolves the corridor addresses from the gateway `/v1/defaults`
|
|
5912
8401
|
* endpoint. It reaches the gateway only for what the caller has NOT already
|
|
5913
8402
|
* supplied via `resolvedDefaults`: supply `resolvedDefaults.source` to skip the
|
|
5914
8403
|
* source-chain fetch and `resolvedDefaults.destination` to skip the destination
|
|
@@ -5938,10 +8427,14 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
|
5938
8427
|
* @returns A complete PaymentRequest object without the signature
|
|
5939
8428
|
*/
|
|
5940
8429
|
async preparePaymentRequest(params) {
|
|
8430
|
+
assertPayableAccount(params.destinationAsset, params.destinationAccount);
|
|
5941
8431
|
const now = (params.now ?? Date.now)();
|
|
5942
|
-
const { quote_deadline, fulfillment_deadline } = resolveDeadlines(
|
|
5943
|
-
|
|
5944
|
-
|
|
8432
|
+
const { quote_deadline, fulfillment_deadline } = resolveDeadlines(
|
|
8433
|
+
{ ...params, now: () => now },
|
|
8434
|
+
DEFAULT_PAYMENT_QUOTE_DEADLINE_SECONDS
|
|
8435
|
+
);
|
|
8436
|
+
const sourceChainId = assetChainId(params.sourceAsset);
|
|
8437
|
+
const destChainId = assetChainId(params.destinationAsset);
|
|
5945
8438
|
const [sourceDefaults, fulfillmentProxy] = await Promise.all([
|
|
5946
8439
|
params.resolvedDefaults?.source ?? this.fetchChainDefaults(sourceChainId),
|
|
5947
8440
|
params.resolvedDefaults?.destination?.fulfillmentProxy ?? this.fetchChainDefaults(destChainId).then((d) => d.fulfillmentProxy)
|
|
@@ -6011,7 +8504,7 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
|
6011
8504
|
* defaults and populates the SAME contract fields (`escrow_contract_address`,
|
|
6012
8505
|
* `quote_selector`, `fulfillment_verifier`, `fulfillment_proxy`). These are not
|
|
6013
8506
|
* optional in practice: the gateway requires `fulfillment_verifier` to build the
|
|
6014
|
-
*
|
|
8507
|
+
* request event it broadcasts to settlers, so the quote-request body
|
|
6015
8508
|
* must carry the identical contract fields the payment flow does. The ONLY
|
|
6016
8509
|
* field this drops relative to `preparePaymentRequest` is `sender_auth`, which
|
|
6017
8510
|
* is supplied at award time (quote-time is unauthenticated — no signing, no
|
|
@@ -6021,26 +8514,38 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
|
6021
8514
|
* @returns A complete `CreateQuoteRequest` body (no signature step needed)
|
|
6022
8515
|
*/
|
|
6023
8516
|
async prepareQuoteRequest(params) {
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
8517
|
+
assertPayableAccount(params.destinationAsset, params.destinationAccount);
|
|
8518
|
+
if (!params.requestId) {
|
|
8519
|
+
throw new Error(
|
|
8520
|
+
"payment-gateway-client: requestId is required \u2014 it is the idempotency key the gateway dedups on; supply a stable id per logical quote-request and reuse it on retry"
|
|
8521
|
+
);
|
|
8522
|
+
}
|
|
8523
|
+
const { quote_deadline, fulfillment_deadline } = resolveDeadlines(
|
|
8524
|
+
params,
|
|
8525
|
+
DEFAULT_QUOTE_DEADLINE_SECONDS
|
|
8526
|
+
);
|
|
8527
|
+
const source = parseAssetIdentifier(params.sourceAsset);
|
|
8528
|
+
const destination = parseAssetIdentifier(params.destinationAsset);
|
|
8529
|
+
const sourceChainId = source.chainId;
|
|
8530
|
+
const destChainId = destination.chainId;
|
|
6027
8531
|
const [sourceDefaults, destDefaults] = await Promise.all([
|
|
6028
8532
|
this.fetchChainDefaults(sourceChainId),
|
|
6029
8533
|
this.fetchChainDefaults(destChainId)
|
|
6030
8534
|
]);
|
|
6031
8535
|
const contractOverrides = getChainAdapter(sourceChainId).resolveContractOverrides?.(sourceDefaults);
|
|
6032
|
-
const requestId = params.requestId || `${params.requestIdPrefix || "quote-gw-sdk"}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
6033
8536
|
return {
|
|
6034
8537
|
version: PAYMENT_REQUEST_VERSION,
|
|
6035
|
-
request_id: requestId,
|
|
8538
|
+
request_id: params.requestId,
|
|
6036
8539
|
source: {
|
|
6037
|
-
asset_identifier:
|
|
8540
|
+
asset_identifier: source.normalized,
|
|
6038
8541
|
account: params.depositor
|
|
6039
8542
|
},
|
|
6040
|
-
destination: [
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
8543
|
+
destination: [
|
|
8544
|
+
{
|
|
8545
|
+
asset_identifier: destination.normalized,
|
|
8546
|
+
account: params.destinationAccount
|
|
8547
|
+
}
|
|
8548
|
+
],
|
|
6044
8549
|
fulfillment_amount: params.fulfillmentAmount,
|
|
6045
8550
|
max_source_amount: params.maxSourceAmount ?? defaultMaxSourceAmount(params.fulfillmentAmount),
|
|
6046
8551
|
// Required + originator-supplied: the gateway injects no default and never
|
|
@@ -6065,27 +8570,43 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
|
6065
8570
|
}
|
|
6066
8571
|
};
|
|
6067
8572
|
|
|
8573
|
+
// src/cli/cli-input-error.ts
|
|
8574
|
+
var CliInputError = class extends Error {
|
|
8575
|
+
constructor(message) {
|
|
8576
|
+
super(message);
|
|
8577
|
+
this.name = "CliInputError";
|
|
8578
|
+
}
|
|
8579
|
+
};
|
|
8580
|
+
|
|
6068
8581
|
// src/cli/parse-seconds.ts
|
|
6069
8582
|
function parseSeconds(optionName) {
|
|
6070
8583
|
return (value) => {
|
|
6071
8584
|
if (!/^-?\d+$/.test(value.trim())) {
|
|
6072
|
-
throw new
|
|
8585
|
+
throw new CliInputError(`${optionName} must be an integer number of seconds`);
|
|
6073
8586
|
}
|
|
6074
8587
|
return Number(value);
|
|
6075
8588
|
};
|
|
6076
8589
|
}
|
|
6077
8590
|
|
|
8591
|
+
// src/cli/run-cli.ts
|
|
8592
|
+
function runCli(program2, ...parseArgs) {
|
|
8593
|
+
try {
|
|
8594
|
+
program2.parse(...parseArgs);
|
|
8595
|
+
} catch (error) {
|
|
8596
|
+
if (!(error instanceof CliInputError)) throw error;
|
|
8597
|
+
console.error("\n\u274C Error:", error.message);
|
|
8598
|
+
process.exit(1);
|
|
8599
|
+
}
|
|
8600
|
+
}
|
|
8601
|
+
|
|
6078
8602
|
// src/version.ts
|
|
6079
|
-
var PACKAGE_VERSION = true ? "
|
|
8603
|
+
var PACKAGE_VERSION = true ? "3.0.1" : "0.0.0-dev";
|
|
6080
8604
|
|
|
6081
8605
|
// src/cli/payment-outcome.ts
|
|
6082
8606
|
var EXIT_COMPLETED = 0;
|
|
6083
8607
|
var EXIT_ERROR = 1;
|
|
6084
8608
|
var EXIT_PENDING = 2;
|
|
6085
8609
|
var EXIT_TERMINAL_FAILURE = 3;
|
|
6086
|
-
function isTerminalStatus(status) {
|
|
6087
|
-
return status === "completed" || status === "failed" || status === "cancelled";
|
|
6088
|
-
}
|
|
6089
8610
|
function describePaymentOutcome(input) {
|
|
6090
8611
|
const { status, paymentId, requestId, idempotentReplay, errorCode } = input;
|
|
6091
8612
|
const payment = paymentId ? `payment ${paymentId}` : "the payment";
|
|
@@ -6096,7 +8617,7 @@ function describePaymentOutcome(input) {
|
|
|
6096
8617
|
summary: `completed: ${payment} settled.${replay}`
|
|
6097
8618
|
};
|
|
6098
8619
|
}
|
|
6099
|
-
if (status === "failed"
|
|
8620
|
+
if (status === "failed") {
|
|
6100
8621
|
const reason = errorCode ? ` (${errorCode})` : "";
|
|
6101
8622
|
return {
|
|
6102
8623
|
exitCode: EXIT_TERMINAL_FAILURE,
|
|
@@ -6110,43 +8631,98 @@ function describePaymentOutcome(input) {
|
|
|
6110
8631
|
};
|
|
6111
8632
|
}
|
|
6112
8633
|
|
|
6113
|
-
// src/cli/
|
|
6114
|
-
|
|
6115
|
-
var DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
6116
|
-
async function waitForTerminalStatus(params) {
|
|
8634
|
+
// src/cli/submit-and-report.ts
|
|
8635
|
+
async function submitAndReport(params) {
|
|
6117
8636
|
const {
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
8637
|
+
client,
|
|
8638
|
+
paymentRequest,
|
|
8639
|
+
requestId,
|
|
8640
|
+
wait = false,
|
|
8641
|
+
waitSeconds = DEFAULT_WAIT_SECONDS,
|
|
8642
|
+
pollIntervalMs,
|
|
8643
|
+
writeOut = (line) => console.log(line),
|
|
8644
|
+
writeErr = (line) => console.error(line)
|
|
6124
8645
|
} = params;
|
|
6125
|
-
const
|
|
6126
|
-
let
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
const
|
|
6130
|
-
await
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
onError
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
8646
|
+
const response = await client.payments.submitPayment({ requestBody: paymentRequest });
|
|
8647
|
+
let reported = response;
|
|
8648
|
+
if (wait && response.payment_id && !isTerminalStatus(response.status)) {
|
|
8649
|
+
writeErr(`waiting up to ${waitSeconds}s for ${response.payment_id} to settle...`);
|
|
8650
|
+
const paymentId = response.payment_id;
|
|
8651
|
+
const waited = await waitForTerminalStatus({
|
|
8652
|
+
budgetMs: waitSeconds * 1e3,
|
|
8653
|
+
intervalMs: pollIntervalMs,
|
|
8654
|
+
fetchStatus: () => client.payments.getPaymentStatus({ paymentId }),
|
|
8655
|
+
// A blip mid-settlement is the worst moment to give up, so report and keep checking.
|
|
8656
|
+
onError: (err) => writeErr(
|
|
8657
|
+
`status check failed, still waiting: ${err instanceof Error ? err.message : String(err)}`
|
|
8658
|
+
)
|
|
8659
|
+
});
|
|
8660
|
+
if (waited.snapshot) {
|
|
8661
|
+
reported = { ...reported, ...waited.snapshot };
|
|
8662
|
+
}
|
|
8663
|
+
if (waited.timedOut) {
|
|
8664
|
+
writeErr(`still not settled after ${waitSeconds}s \u2014 reporting it as pending.`);
|
|
8665
|
+
}
|
|
8666
|
+
}
|
|
8667
|
+
writeOut(JSON.stringify(reported, null, 2));
|
|
8668
|
+
const outcome = {
|
|
8669
|
+
status: reported.status,
|
|
8670
|
+
paymentId: reported.payment_id,
|
|
8671
|
+
requestId,
|
|
8672
|
+
idempotentReplay: reported.idempotent_replay,
|
|
8673
|
+
// Present when the gateway has recorded a reason — which includes the case where this
|
|
8674
|
+
// submission was deduplicated onto a payment that had already failed.
|
|
8675
|
+
errorCode: reported.error?.code
|
|
8676
|
+
};
|
|
8677
|
+
const { exitCode, summary } = describePaymentOutcome(outcome);
|
|
8678
|
+
writeErr(summary);
|
|
8679
|
+
return exitCode;
|
|
6143
8680
|
}
|
|
6144
|
-
|
|
6145
|
-
|
|
8681
|
+
|
|
8682
|
+
// src/cli/option-groups.ts
|
|
8683
|
+
var BUILD_ONLY_OPTIONS = [
|
|
8684
|
+
"--request-id",
|
|
8685
|
+
"--request-id-prefix",
|
|
8686
|
+
"--quote-deadline-seconds",
|
|
8687
|
+
"--fulfillment-deadline-seconds",
|
|
8688
|
+
"--whitelistSettler",
|
|
8689
|
+
"--provider",
|
|
8690
|
+
"--solana-rpc-url"
|
|
8691
|
+
];
|
|
8692
|
+
function attributeNameOf(flag) {
|
|
8693
|
+
return flag.replace(/^--/, "").replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
6146
8694
|
}
|
|
6147
8695
|
|
|
6148
8696
|
// src/cli/send-payment.ts
|
|
8697
|
+
init_pinned_address();
|
|
8698
|
+
|
|
8699
|
+
// src/cli/prompt-private-key.ts
|
|
6149
8700
|
var readline = __toESM(require("readline"));
|
|
8701
|
+
async function promptPrivateKey() {
|
|
8702
|
+
const rl = readline.createInterface({
|
|
8703
|
+
input: process.stdin,
|
|
8704
|
+
output: process.stdout,
|
|
8705
|
+
terminal: true
|
|
8706
|
+
});
|
|
8707
|
+
return new Promise((resolve2) => {
|
|
8708
|
+
process.stderr.write("Enter private key (input hidden): ");
|
|
8709
|
+
const originalWrite = process.stdout.write;
|
|
8710
|
+
process.stdout.write = function(chunk, _encoding, _callback) {
|
|
8711
|
+
if (chunk === "\n" || chunk === "\r\n") {
|
|
8712
|
+
return originalWrite.apply(process.stdout, arguments);
|
|
8713
|
+
}
|
|
8714
|
+
return true;
|
|
8715
|
+
};
|
|
8716
|
+
rl.question("", (answer) => {
|
|
8717
|
+
process.stdout.write = originalWrite;
|
|
8718
|
+
process.stderr.write("\n");
|
|
8719
|
+
rl.close();
|
|
8720
|
+
resolve2(answer);
|
|
8721
|
+
});
|
|
8722
|
+
rl._writeToOutput = function() {
|
|
8723
|
+
};
|
|
8724
|
+
});
|
|
8725
|
+
}
|
|
6150
8726
|
|
|
6151
8727
|
// src/cli/load-env.ts
|
|
6152
8728
|
var import_dotenv = require("dotenv");
|
|
@@ -6175,7 +8751,64 @@ function loadTurnkeyConfigFromEnv() {
|
|
|
6175
8751
|
};
|
|
6176
8752
|
}
|
|
6177
8753
|
var program = new import_commander.Command();
|
|
6178
|
-
program.name("send-payment").description(
|
|
8754
|
+
program.name("send-payment").description(
|
|
8755
|
+
[
|
|
8756
|
+
"Send a cross-chain payment through Atum Payment Gateway.",
|
|
8757
|
+
"",
|
|
8758
|
+
" Normally this prepares, signs and submits in one step. To have the payment",
|
|
8759
|
+
" approved before it is sent, split it in two: --prepare-only writes the signed",
|
|
8760
|
+
" request out, --submit sends one back in.",
|
|
8761
|
+
"",
|
|
8762
|
+
" PREREQUISITE: paying from an EVM or Tron chain needs a one-off ERC-20/TRC-20",
|
|
8763
|
+
" approval of the source token for the Permit2 contract, made by the sender",
|
|
8764
|
+
" before this runs. Without it the payment is built and signed correctly and",
|
|
8765
|
+
" still fails to settle. Run `approve-permit2` to grant it; contract addresses",
|
|
8766
|
+
" are at the end of this help."
|
|
8767
|
+
].join("\n")
|
|
8768
|
+
).usage(
|
|
8769
|
+
"[options] <sender> <amount> <sourceAsset> <receiver> <destinationAsset>\n or: send-payment --submit <file> [options]"
|
|
8770
|
+
).version(PACKAGE_VERSION).argument("[sender]", "Depositor address (e.g., 0xF0D0...)").argument("[amount]", "Amount to send (in smallest units, e.g., 100000 for 0.10 USDC)").argument("[sourceAsset]", "Source asset in CAIP-19 format").argument("[receiver]", "Destination account address").argument("[destinationAsset]", "Destination asset in CAIP-19 format").option(
|
|
8771
|
+
"--gateway <url>",
|
|
8772
|
+
"Payment gateway URL (overrides GATEWAY_URL env; default: production-testnet)"
|
|
8773
|
+
).option(
|
|
8774
|
+
"--request-id <id>",
|
|
8775
|
+
"Idempotency key; seeds the on-chain deposit nonce. Re-run with the SAME id to re-attempt one payment \u2014 it resolves to the original instead of paying twice. Omitted, an id is generated and printed, which makes every bare re-run a SEPARATE payment (a second charge)."
|
|
8776
|
+
).option("--request-id-prefix <prefix>", "Custom request ID prefix (default: pmt-gw-cli)").option(
|
|
8777
|
+
"--quote-deadline-seconds <n>",
|
|
8778
|
+
`Quote collection window in seconds (default: ${DEFAULT_PAYMENT_QUOTE_DEADLINE_SECONDS})`,
|
|
8779
|
+
parseSeconds("--quote-deadline-seconds")
|
|
8780
|
+
).option(
|
|
8781
|
+
"--fulfillment-deadline-seconds <n>",
|
|
8782
|
+
`Settlement horizon in seconds (default: ${DEFAULT_FULFILLMENT_DEADLINE_SECONDS})`,
|
|
8783
|
+
parseSeconds("--fulfillment-deadline-seconds")
|
|
8784
|
+
).option(
|
|
8785
|
+
"--whitelistSettler <did>",
|
|
8786
|
+
"Settler DID to whitelist (can be specified multiple times)",
|
|
8787
|
+
collect,
|
|
8788
|
+
[]
|
|
8789
|
+
).option("--provider <raw|turnkey>", "Sender signing provider", "raw").option(
|
|
8790
|
+
"--wait",
|
|
8791
|
+
"After submitting, keep checking the payment until it settles or fails instead of reporting it as still pending"
|
|
8792
|
+
).option(
|
|
8793
|
+
"--wait-seconds <n>",
|
|
8794
|
+
`How long --wait keeps checking (default: ${DEFAULT_WAIT_SECONDS}). A convenience bound only \u2014 giving up does not affect the payment`,
|
|
8795
|
+
parseSeconds("--wait-seconds")
|
|
8796
|
+
).option(
|
|
8797
|
+
"--solana-rpc-url <url>",
|
|
8798
|
+
"Solana RPC used to read the cluster clock for issued_at (falls back to the SOLANA_RPC_URL env var, then the public endpoint for the cluster)"
|
|
8799
|
+
).addOption(
|
|
8800
|
+
new import_commander.Option(
|
|
8801
|
+
"--prepare-only",
|
|
8802
|
+
"Build and sign the payment request, print it, and stop without submitting. For inspecting an authorization, or for review before paying. Send it later with --submit"
|
|
8803
|
+
).conflicts(["wait", "waitSeconds"])
|
|
8804
|
+
).addOption(
|
|
8805
|
+
new import_commander.Option(
|
|
8806
|
+
"--submit <file>",
|
|
8807
|
+
"Submit a request built earlier by --prepare-only, instead of building one. Signs nothing and needs no private key. Use - to read stdin"
|
|
8808
|
+
).conflicts(["prepareOnly", ...BUILD_ONLY_OPTIONS.map(attributeNameOf)])
|
|
8809
|
+
).addHelpText(
|
|
8810
|
+
"after",
|
|
8811
|
+
`
|
|
6179
8812
|
CAIP-19 Examples:
|
|
6180
8813
|
EVM ERC20: eip155:42161/erc20:0xaf88d065e77c8cC2239327C5EDb3A432268e5831
|
|
6181
8814
|
Tron TRC20: tron:shasta/trc20:TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs
|
|
@@ -6195,6 +8828,34 @@ Output:
|
|
|
6195
8828
|
With --wait the JSON is printed once the wait ends, reporting the payment's state
|
|
6196
8829
|
as of the last check rather than as of the submit.
|
|
6197
8830
|
|
|
8831
|
+
--prepare-only:
|
|
8832
|
+
Builds and signs the request, prints it to stdout, and stops. Nothing is
|
|
8833
|
+
submitted and no payment exists. The document printed is exactly what would
|
|
8834
|
+
have been POSTed, so you can inspect it, have it reviewed, then send it with
|
|
8835
|
+
\`send-payment --submit <file>\` (or pipe it:
|
|
8836
|
+
\`send-payment --prepare-only ... | send-payment --submit -\`).
|
|
8837
|
+
|
|
8838
|
+
It still contacts the gateway, which is where the corridor addresses come from,
|
|
8839
|
+
so it is not an offline mode.
|
|
8840
|
+
|
|
8841
|
+
The file it writes is a signed authorization, not a draft. Anyone holding it can
|
|
8842
|
+
send it with --submit, which needs no key. Treat it like a signed cheque: keep it
|
|
8843
|
+
where you would keep a credential, and delete it once the payment is sent or the
|
|
8844
|
+
request is abandoned.
|
|
8845
|
+
|
|
8846
|
+
Re-preparing with the same --request-id targets the same payment: the deposit nonce
|
|
8847
|
+
comes from the id, so it cannot pay twice. It does not reproduce the same bytes \u2014
|
|
8848
|
+
the deadlines are stamped from the clock and the signature covers them.
|
|
8849
|
+
|
|
8850
|
+
Intending to submit later? The document is only submittable while its quote
|
|
8851
|
+
window is open, and the default is ${DEFAULT_PAYMENT_QUOTE_DEADLINE_SECONDS}s, so widen it with
|
|
8852
|
+
--quote-deadline-seconds to leave room to read it.
|
|
8853
|
+
|
|
8854
|
+
Widen it by tens of seconds, not minutes. The window is also the auction: the
|
|
8855
|
+
gateway waits it out before choosing a settler, and settler quotes expire on
|
|
8856
|
+
their own, so an over-long window ends in QUOTES_EXPIRED \u2014 which is terminal,
|
|
8857
|
+
and a fresh attempt then needs a NEW --request-id.
|
|
8858
|
+
|
|
6198
8859
|
Exit codes:
|
|
6199
8860
|
0 completed \u2014 settled
|
|
6200
8861
|
2 pending \u2014 accepted, no result yet; follow it with payment-status <payment_id>,
|
|
@@ -6204,20 +8865,55 @@ Exit codes:
|
|
|
6204
8865
|
|
|
6205
8866
|
So \`send-payment ... && <next step>\` runs the next step only for a settled payment.
|
|
6206
8867
|
|
|
8868
|
+
The table above describes a SUBMITTED payment, so it does not apply to
|
|
8869
|
+
--prepare-only: there, 0 means the request was built and signed, not that anything
|
|
8870
|
+
was paid. Do not chain a payment-conditional step off a --prepare-only run.
|
|
8871
|
+
|
|
6207
8872
|
Exit 1 means unknown, not "nothing happened" \u2014 a request that timed out may still
|
|
6208
8873
|
have been accepted, and you may have no payment_id to look up. Re-run with the same
|
|
6209
8874
|
--request-id, which resolves to the payment if one was created and creates it if not.
|
|
6210
8875
|
|
|
6211
8876
|
After submission, you can check payment status at eg http://PAYMENT_GW/v1/payments/PAYMENT_ID/status
|
|
6212
8877
|
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
8878
|
+
Permit2 contract addresses, for the approval named under PREREQUISITE above:
|
|
8879
|
+
EVM: 0x000000000022D473030F116dDEE9F6B43aC78BA3 (virtually all chains)
|
|
8880
|
+
Tron mainnet: TJhMXTHQHeQyMD7TcKQFqAePNgG4b31H9m
|
|
8881
|
+
Tron Shasta: TPUqJPASUn1zLvbLBgRZ5pBYrx7WSe5ahp`
|
|
8882
|
+
).action(async (sender, amount, sourceAsset, receiver, destinationAsset, options) => {
|
|
6218
8883
|
let requestId;
|
|
8884
|
+
let submittedRequest;
|
|
6219
8885
|
try {
|
|
6220
|
-
const
|
|
8886
|
+
const corridor = [sender, amount, sourceAsset, receiver, destinationAsset];
|
|
8887
|
+
const supplied = corridor.filter((value) => value !== void 0).length;
|
|
8888
|
+
if (options.submit && supplied > 0) {
|
|
8889
|
+
throw new Error(
|
|
8890
|
+
"--submit sends a request that was already built, so the corridor arguments do not apply. Drop them, or drop --submit to build a new payment."
|
|
8891
|
+
);
|
|
8892
|
+
}
|
|
8893
|
+
if (!options.submit && supplied < corridor.length) {
|
|
8894
|
+
throw new Error(
|
|
8895
|
+
`send-payment needs five arguments (sender, amount, sourceAsset, receiver, destinationAsset), or --submit <file> to send a request prepared earlier. Got ${supplied}.`
|
|
8896
|
+
);
|
|
8897
|
+
}
|
|
8898
|
+
if (options.submit) {
|
|
8899
|
+
const prepared = await readPaymentRequest(options.submit);
|
|
8900
|
+
submittedRequest = prepared;
|
|
8901
|
+
requestId = prepared.request_id;
|
|
8902
|
+
warnIfQuoteWindowClosed(prepared);
|
|
8903
|
+
console.error(
|
|
8904
|
+
`submitting request_id ${requestId} (quote_deadline ${prepared.quote_deadline})`
|
|
8905
|
+
);
|
|
8906
|
+
const submittedCode = await submitAndReport({
|
|
8907
|
+
client: new PaymentGatewayClient2({ BASE: options.gateway }),
|
|
8908
|
+
paymentRequest: prepared,
|
|
8909
|
+
requestId,
|
|
8910
|
+
wait: options.wait,
|
|
8911
|
+
waitSeconds: options.waitSeconds
|
|
8912
|
+
});
|
|
8913
|
+
process.exit(submittedCode);
|
|
8914
|
+
}
|
|
8915
|
+
requirePinnedSender(sender);
|
|
8916
|
+
const sourceChainId = assetChainId(sourceAsset);
|
|
6221
8917
|
let privateKey = "";
|
|
6222
8918
|
let signer;
|
|
6223
8919
|
if (options.provider === "turnkey") {
|
|
@@ -6228,7 +8924,11 @@ TPUqJPASUn1zLvbLBgRZ5pBYrx7WSe5ahp on Shasta)`).action(async (sender, amount, so
|
|
|
6228
8924
|
});
|
|
6229
8925
|
} else if (options.provider === "raw") {
|
|
6230
8926
|
privateKey = process.env.PRIVATE_KEY || await promptPrivateKey();
|
|
6231
|
-
signer = createSenderSigner(sourceChainId, {
|
|
8927
|
+
signer = createSenderSigner(sourceChainId, {
|
|
8928
|
+
provider: "raw",
|
|
8929
|
+
privateKey,
|
|
8930
|
+
pinnedAddress: sender
|
|
8931
|
+
});
|
|
6232
8932
|
} else {
|
|
6233
8933
|
throw new Error(`Unknown --provider '${options.provider}' (expected 'raw' or 'turnkey')`);
|
|
6234
8934
|
}
|
|
@@ -6256,84 +8956,103 @@ TPUqJPASUn1zLvbLBgRZ5pBYrx7WSe5ahp on Shasta)`).action(async (sender, amount, so
|
|
|
6256
8956
|
delegate_signer: delegateSigner
|
|
6257
8957
|
};
|
|
6258
8958
|
}
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
console.error(
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
});
|
|
6275
|
-
if (waited.snapshot) {
|
|
6276
|
-
reported = { ...reported, ...waited.snapshot };
|
|
6277
|
-
}
|
|
6278
|
-
if (waited.timedOut) {
|
|
6279
|
-
console.error(`still not settled after ${waitSeconds}s \u2014 reporting it as pending.`);
|
|
6280
|
-
}
|
|
8959
|
+
if (options.prepareOnly) {
|
|
8960
|
+
console.log(JSON.stringify(paymentRequest, null, 2));
|
|
8961
|
+
console.error(
|
|
8962
|
+
`request_id: ${requestId} (re-preparing with this id targets the same payment, but stamps fresh deadlines and a fresh signature, so the document itself will differ)`
|
|
8963
|
+
);
|
|
8964
|
+
console.error(
|
|
8965
|
+
`quote_deadline: ${paymentRequest.quote_deadline} (the gateway refuses this document after that instant; pass --quote-deadline-seconds to widen it)`
|
|
8966
|
+
);
|
|
8967
|
+
console.error(
|
|
8968
|
+
"prepared: nothing was submitted and no payment exists. Send it with `send-payment --submit <file>`."
|
|
8969
|
+
);
|
|
8970
|
+
console.error(
|
|
8971
|
+
"KEEP IT SAFE: this file is a signed authorization for this payment, not a draft. Anyone holding it can send it, with no key. Delete it once the payment is sent or the request is abandoned."
|
|
8972
|
+
);
|
|
8973
|
+
process.exit(EXIT_COMPLETED);
|
|
6281
8974
|
}
|
|
6282
|
-
console.
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
8975
|
+
console.error(JSON.stringify(paymentRequest, null, 2));
|
|
8976
|
+
console.error(
|
|
8977
|
+
`request_id: ${requestId} (re-run with --request-id ${requestId} to retry this same payment)`
|
|
8978
|
+
);
|
|
8979
|
+
const exitCode = await submitAndReport({
|
|
8980
|
+
client,
|
|
8981
|
+
paymentRequest,
|
|
6286
8982
|
requestId,
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
errorCode: reported.error?.code
|
|
6291
|
-
};
|
|
6292
|
-
const { exitCode, summary } = describePaymentOutcome(outcome);
|
|
6293
|
-
console.error(summary);
|
|
8983
|
+
wait: options.wait,
|
|
8984
|
+
waitSeconds: options.waitSeconds
|
|
8985
|
+
});
|
|
6294
8986
|
process.exit(exitCode);
|
|
6295
8987
|
} catch (error) {
|
|
6296
8988
|
if (error instanceof ApiError && error.body) {
|
|
6297
8989
|
console.log(JSON.stringify(error.body, null, 2));
|
|
6298
8990
|
} else {
|
|
6299
8991
|
console.error("\n\u274C Error:", error instanceof Error ? error.message : String(error));
|
|
6300
|
-
if (error instanceof Error && error.availableDefaults) {
|
|
6301
|
-
console.error("\n\u{1F4CB} Available gateway defaults:");
|
|
6302
|
-
console.error(JSON.stringify(error.availableDefaults, null, 2));
|
|
6303
|
-
}
|
|
6304
8992
|
}
|
|
6305
8993
|
if (requestId) {
|
|
6306
|
-
|
|
8994
|
+
const windowStillOpen = submittedRequest !== void 0 && quoteWindowOpen(submittedRequest);
|
|
8995
|
+
console.error(
|
|
8996
|
+
options.submit ? windowStillOpen ? `request_id: ${requestId} (the quote window on this file may still be open, so sending it again is the first thing to try)` : `request_id: ${requestId} (this file's quote window has closed, so sending it again will be refused. Ask whoever holds the key to prepare a fresh request with --request-id ${requestId}: that targets this same payment, so it cannot pay twice)` : `request_id: ${requestId} (re-run with --request-id ${requestId} to retry this same payment)`
|
|
8997
|
+
);
|
|
6307
8998
|
}
|
|
6308
8999
|
process.exit(EXIT_ERROR);
|
|
6309
9000
|
}
|
|
6310
9001
|
});
|
|
6311
|
-
async function
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
});
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
9002
|
+
async function readPaymentRequest(file) {
|
|
9003
|
+
if (file === "-" && process.stdin.isTTY) {
|
|
9004
|
+
throw new Error("--submit - reads stdin, but nothing is piped in. Pass a file path instead");
|
|
9005
|
+
}
|
|
9006
|
+
const raw = file === "-" ? await readStdin() : (0, import_fs.readFileSync)(file, "utf8");
|
|
9007
|
+
if (raw.trim() === "") {
|
|
9008
|
+
throw new Error(
|
|
9009
|
+
file === "-" ? "nothing arrived on stdin. Pipe a prepared request in, or pass a file path instead" : `${file} is empty`
|
|
9010
|
+
);
|
|
9011
|
+
}
|
|
9012
|
+
let parsed;
|
|
9013
|
+
try {
|
|
9014
|
+
parsed = JSON.parse(raw);
|
|
9015
|
+
} catch (error) {
|
|
9016
|
+
throw new Error(
|
|
9017
|
+
`${file === "-" ? "stdin" : file} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
9018
|
+
{ cause: error }
|
|
9019
|
+
);
|
|
9020
|
+
}
|
|
9021
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
9022
|
+
throw new Error(`${file === "-" ? "stdin" : file} does not hold a PaymentRequest object`);
|
|
9023
|
+
}
|
|
9024
|
+
const request2 = parsed;
|
|
9025
|
+
if (!request2.request_id) {
|
|
9026
|
+
throw new Error(
|
|
9027
|
+
"this does not look like a PaymentRequest: no request_id. Produce one with `send-payment --prepare-only`"
|
|
9028
|
+
);
|
|
9029
|
+
}
|
|
9030
|
+
const signature = request2.sender_auth?.signed_messages?.[0]?.signature;
|
|
9031
|
+
if (!signature) {
|
|
9032
|
+
throw new Error(
|
|
9033
|
+
"this request carries no sender_auth signature, so it cannot be submitted. `send-payment --prepare-only` signs the request it prints; a request built with the SDK needs signPaymentRequest before it is submittable"
|
|
9034
|
+
);
|
|
9035
|
+
}
|
|
9036
|
+
return request2;
|
|
9037
|
+
}
|
|
9038
|
+
async function readStdin() {
|
|
9039
|
+
const chunks = [];
|
|
9040
|
+
for await (const chunk of process.stdin) {
|
|
9041
|
+
chunks.push(chunk);
|
|
9042
|
+
}
|
|
9043
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
9044
|
+
}
|
|
9045
|
+
function quoteWindowOpen(request2) {
|
|
9046
|
+
const deadline = Date.parse(request2.quote_deadline ?? "");
|
|
9047
|
+
return Number.isNaN(deadline) || deadline > Date.now();
|
|
9048
|
+
}
|
|
9049
|
+
function warnIfQuoteWindowClosed(request2) {
|
|
9050
|
+
if (quoteWindowOpen(request2)) return;
|
|
9051
|
+
console.error(
|
|
9052
|
+
`warning: this request's quote_deadline (${request2.quote_deadline}) has passed by this machine's clock, and the gateway refuses a closed quote window. Sending anyway, since the gateway goes by its own clock. If it rejects this, prepare a fresh request \u2014 and give the next one a longer --quote-deadline-seconds, which is an option of the form that builds a request, not of --submit.`
|
|
9053
|
+
);
|
|
6335
9054
|
}
|
|
6336
|
-
program
|
|
9055
|
+
runCli(program);
|
|
6337
9056
|
/*! Bundled license information:
|
|
6338
9057
|
|
|
6339
9058
|
@noble/hashes/utils.js:
|