@atumlabs/payment-gateway-client 1.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +127 -51
- package/THIRD-PARTY-NOTICES.txt +45 -0
- package/dist/cli/payment-status.js +1288 -668
- package/dist/cli/quote-status.js +1288 -668
- package/dist/cli/request-quote.js +1289 -669
- package/dist/cli/send-payment.js +1339 -687
- package/dist/index.d.ts +242 -174
- package/dist/index.js +1371 -648
- package/docs/idempotency.md +62 -0
- package/package.json +17 -6
- /package/{LICENSE.md → LICENSE} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026 Atum Labs, Inc. All rights reserved.
|
|
3
|
+
* Proprietary and confidential.
|
|
4
|
+
* Access and use are governed by the LICENSE file distributed with this package.
|
|
5
|
+
* Do not remove, alter, or obscure this notice.
|
|
6
|
+
*/
|
|
1
7
|
"use strict";
|
|
2
8
|
var __create = Object.create;
|
|
3
9
|
var __defProp = Object.defineProperty;
|
|
@@ -33,8 +39,378 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
33
39
|
));
|
|
34
40
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
35
41
|
|
|
36
|
-
// ../contracts/
|
|
42
|
+
// ../contracts/tvm/escrow-encoding/typescript/dist/chain-id.js
|
|
43
|
+
var require_chain_id = __commonJS({
|
|
44
|
+
"../contracts/tvm/escrow-encoding/typescript/dist/chain-id.js"(exports2) {
|
|
45
|
+
"use strict";
|
|
46
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
47
|
+
exports2.maskChainId = maskChainId2;
|
|
48
|
+
function maskChainId2(chainId) {
|
|
49
|
+
return (chainId & 4294967295) >>> 0;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// ../contracts/tvm/escrow-encoding/typescript/dist/tron-address.js
|
|
55
|
+
var require_tron_address = __commonJS({
|
|
56
|
+
"../contracts/tvm/escrow-encoding/typescript/dist/tron-address.js"(exports2) {
|
|
57
|
+
"use strict";
|
|
58
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
59
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
60
|
+
};
|
|
61
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
62
|
+
exports2.base58ToHex = base58ToHex2;
|
|
63
|
+
exports2.normalizeAddress = normalizeAddress2;
|
|
64
|
+
var ethers_1 = require("ethers");
|
|
65
|
+
var bs58_1 = __importDefault(require("bs58"));
|
|
66
|
+
var TVM_MAINNET_PREFIX = "41";
|
|
67
|
+
function base58ToHex2(base58Address) {
|
|
68
|
+
if (!base58Address || !base58Address.startsWith("T")) {
|
|
69
|
+
throw new Error(`Invalid Tron base58 address: ${base58Address}`);
|
|
70
|
+
}
|
|
71
|
+
const decoded = bs58_1.default.decode(base58Address);
|
|
72
|
+
if (decoded.length !== 25) {
|
|
73
|
+
throw new Error(`Invalid Tron base58 length (expected 25 bytes): ${base58Address}`);
|
|
74
|
+
}
|
|
75
|
+
const payload = decoded.slice(0, 21);
|
|
76
|
+
const checksum = (0, ethers_1.hexlify)(decoded.slice(21)).slice(2);
|
|
77
|
+
const computed = (0, ethers_1.sha256)((0, ethers_1.sha256)(payload)).slice(2, 10);
|
|
78
|
+
if (checksum !== computed) {
|
|
79
|
+
throw new Error(`Invalid Tron base58 checksum: ${base58Address}`);
|
|
80
|
+
}
|
|
81
|
+
return (0, ethers_1.hexlify)(payload).slice(2);
|
|
82
|
+
}
|
|
83
|
+
function normalizeAddress2(address) {
|
|
84
|
+
if (!address) {
|
|
85
|
+
throw new Error("Empty address");
|
|
86
|
+
}
|
|
87
|
+
let hexAddress = address;
|
|
88
|
+
if (address.startsWith("T")) {
|
|
89
|
+
hexAddress = base58ToHex2(address);
|
|
90
|
+
}
|
|
91
|
+
hexAddress = hexAddress.replace(/^0x/, "");
|
|
92
|
+
if (hexAddress.startsWith(TVM_MAINNET_PREFIX)) {
|
|
93
|
+
hexAddress = hexAddress.substring(2);
|
|
94
|
+
}
|
|
95
|
+
if (hexAddress.length !== 40) {
|
|
96
|
+
throw new Error(`Invalid address length: expected 40 chars, got ${hexAddress.length}`);
|
|
97
|
+
}
|
|
98
|
+
if (!/^[0-9a-fA-F]{40}$/.test(hexAddress)) {
|
|
99
|
+
throw new Error("Invalid hex address format");
|
|
100
|
+
}
|
|
101
|
+
return "0x" + hexAddress.toLowerCase();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// ../contracts/tvm/escrow-encoding/typescript/dist/reserve-encoder.js
|
|
107
|
+
var require_reserve_encoder = __commonJS({
|
|
108
|
+
"../contracts/tvm/escrow-encoding/typescript/dist/reserve-encoder.js"(exports2) {
|
|
109
|
+
"use strict";
|
|
110
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
111
|
+
exports2.computeReserveDigest = computeReserveDigest;
|
|
112
|
+
var ethers_1 = require("ethers");
|
|
113
|
+
var chain_id_1 = require_chain_id();
|
|
114
|
+
var RESERVE_WITNESS_TYPES = {
|
|
115
|
+
ReserveWitness: [
|
|
116
|
+
{ name: "paymentId", type: "bytes32" },
|
|
117
|
+
{ name: "settler", type: "address" }
|
|
118
|
+
]
|
|
119
|
+
};
|
|
120
|
+
function computeReserveDigest(input) {
|
|
121
|
+
const domain = {
|
|
122
|
+
name: "Escrow",
|
|
123
|
+
version: "3",
|
|
124
|
+
chainId: (0, chain_id_1.maskChainId)(input.chainId),
|
|
125
|
+
verifyingContract: input.escrowContract
|
|
126
|
+
};
|
|
127
|
+
return ethers_1.TypedDataEncoder.hash(domain, RESERVE_WITNESS_TYPES, {
|
|
128
|
+
paymentId: input.paymentId,
|
|
129
|
+
settler: input.settler
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// ../contracts/tvm/escrow-encoding/typescript/dist/payment-id.js
|
|
37
136
|
var require_payment_id = __commonJS({
|
|
137
|
+
"../contracts/tvm/escrow-encoding/typescript/dist/payment-id.js"(exports2) {
|
|
138
|
+
"use strict";
|
|
139
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
140
|
+
exports2.computePaymentId = computePaymentId;
|
|
141
|
+
var ethers_1 = require("ethers");
|
|
142
|
+
var tron_address_1 = require_tron_address();
|
|
143
|
+
function computePaymentId(depositor, signature, nonce) {
|
|
144
|
+
if (!/^[0-9]+$/.test(nonce)) {
|
|
145
|
+
throw new Error(`invalid nonce (expected base-10 decimal): ${nonce}`);
|
|
146
|
+
}
|
|
147
|
+
const encoded = ethers_1.AbiCoder.defaultAbiCoder().encode(["address", "bytes", "uint256"], [(0, tron_address_1.normalizeAddress)(depositor), signature, nonce]);
|
|
148
|
+
return (0, ethers_1.keccak256)(encoded);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// ../contracts/tvm/escrow-encoding/typescript/dist/deposit-encoder.js
|
|
154
|
+
var require_deposit_encoder = __commonJS({
|
|
155
|
+
"../contracts/tvm/escrow-encoding/typescript/dist/deposit-encoder.js"(exports2) {
|
|
156
|
+
"use strict";
|
|
157
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
158
|
+
exports2.createTvmPermitWitnessTransferFromPrehash = createTvmPermitWitnessTransferFromPrehash2;
|
|
159
|
+
exports2.hashTvmPermitWitnessTransferFrom = hashTvmPermitWitnessTransferFrom2;
|
|
160
|
+
var ethers_1 = require("ethers");
|
|
161
|
+
var chain_id_1 = require_chain_id();
|
|
162
|
+
var tron_address_1 = require_tron_address();
|
|
163
|
+
var PERMIT_WITNESS_TYPES_V2 = {
|
|
164
|
+
PermitWitnessTransferFrom: [
|
|
165
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
166
|
+
{ name: "spender", type: "address" },
|
|
167
|
+
{ name: "nonce", type: "uint256" },
|
|
168
|
+
{ name: "deadline", type: "uint256" },
|
|
169
|
+
{ name: "witness", type: "DepositWitness" }
|
|
170
|
+
],
|
|
171
|
+
TokenPermissions: [
|
|
172
|
+
{ name: "token", type: "address" },
|
|
173
|
+
{ name: "amount", type: "uint256" }
|
|
174
|
+
],
|
|
175
|
+
DepositWitness: [
|
|
176
|
+
{ name: "reserver", type: "address" },
|
|
177
|
+
{ name: "releaser", type: "address" }
|
|
178
|
+
]
|
|
179
|
+
};
|
|
180
|
+
function createTvmPermitWitnessTransferFromPrehash2(params) {
|
|
181
|
+
const maskedChainId = (0, chain_id_1.maskChainId)(params.chainId);
|
|
182
|
+
return {
|
|
183
|
+
types: PERMIT_WITNESS_TYPES_V2,
|
|
184
|
+
primaryType: "PermitWitnessTransferFrom",
|
|
185
|
+
domain: {
|
|
186
|
+
name: "Permit2",
|
|
187
|
+
chainId: `0x${maskedChainId.toString(16)}`,
|
|
188
|
+
verifyingContract: (0, tron_address_1.normalizeAddress)(params.permit2Address)
|
|
189
|
+
},
|
|
190
|
+
message: {
|
|
191
|
+
permitted: {
|
|
192
|
+
token: (0, tron_address_1.normalizeAddress)(params.tokenAddress),
|
|
193
|
+
amount: params.amount
|
|
194
|
+
},
|
|
195
|
+
spender: (0, tron_address_1.normalizeAddress)(params.spenderAddress),
|
|
196
|
+
nonce: params.nonce.toString(),
|
|
197
|
+
deadline: params.deadline.toString(),
|
|
198
|
+
witness: {
|
|
199
|
+
reserver: (0, tron_address_1.normalizeAddress)(params.reserverAddress),
|
|
200
|
+
releaser: (0, tron_address_1.normalizeAddress)(params.releaserAddress)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function hashTvmPermitWitnessTransferFrom2(prehash) {
|
|
206
|
+
return ethers_1.TypedDataEncoder.hash(prehash.domain, prehash.types, prehash.message);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// ../contracts/tvm/escrow-encoding/typescript/dist/index.js
|
|
212
|
+
var require_dist = __commonJS({
|
|
213
|
+
"../contracts/tvm/escrow-encoding/typescript/dist/index.js"(exports2) {
|
|
214
|
+
"use strict";
|
|
215
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
216
|
+
exports2.hashTvmPermitWitnessTransferFrom = exports2.createTvmPermitWitnessTransferFromPrehash = exports2.computePaymentId = exports2.computeReserveDigest = exports2.normalizeAddress = exports2.base58ToHex = exports2.maskChainId = void 0;
|
|
217
|
+
var chain_id_1 = require_chain_id();
|
|
218
|
+
Object.defineProperty(exports2, "maskChainId", { enumerable: true, get: function() {
|
|
219
|
+
return chain_id_1.maskChainId;
|
|
220
|
+
} });
|
|
221
|
+
var tron_address_1 = require_tron_address();
|
|
222
|
+
Object.defineProperty(exports2, "base58ToHex", { enumerable: true, get: function() {
|
|
223
|
+
return tron_address_1.base58ToHex;
|
|
224
|
+
} });
|
|
225
|
+
Object.defineProperty(exports2, "normalizeAddress", { enumerable: true, get: function() {
|
|
226
|
+
return tron_address_1.normalizeAddress;
|
|
227
|
+
} });
|
|
228
|
+
var reserve_encoder_1 = require_reserve_encoder();
|
|
229
|
+
Object.defineProperty(exports2, "computeReserveDigest", { enumerable: true, get: function() {
|
|
230
|
+
return reserve_encoder_1.computeReserveDigest;
|
|
231
|
+
} });
|
|
232
|
+
var payment_id_1 = require_payment_id();
|
|
233
|
+
Object.defineProperty(exports2, "computePaymentId", { enumerable: true, get: function() {
|
|
234
|
+
return payment_id_1.computePaymentId;
|
|
235
|
+
} });
|
|
236
|
+
var deposit_encoder_1 = require_deposit_encoder();
|
|
237
|
+
Object.defineProperty(exports2, "createTvmPermitWitnessTransferFromPrehash", { enumerable: true, get: function() {
|
|
238
|
+
return deposit_encoder_1.createTvmPermitWitnessTransferFromPrehash;
|
|
239
|
+
} });
|
|
240
|
+
Object.defineProperty(exports2, "hashTvmPermitWitnessTransferFrom", { enumerable: true, get: function() {
|
|
241
|
+
return deposit_encoder_1.hashTvmPermitWitnessTransferFrom;
|
|
242
|
+
} });
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/types.js
|
|
247
|
+
var require_types = __commonJS({
|
|
248
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/types.js"(exports2) {
|
|
249
|
+
"use strict";
|
|
250
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/utils.js
|
|
255
|
+
var require_utils = __commonJS({
|
|
256
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/utils.js"(exports2) {
|
|
257
|
+
"use strict";
|
|
258
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
259
|
+
exports2.SOLANA_REPLAY_SLOTS = exports2.PERMIT_NONCE_DOMAIN = exports2.REPLAY_HORIZON_SECS = void 0;
|
|
260
|
+
exports2.resolvePermitDeadline = resolvePermitDeadline;
|
|
261
|
+
exports2.generatePermitNonce = generatePermitNonce;
|
|
262
|
+
exports2.resolvePermitNonce = resolvePermitNonce;
|
|
263
|
+
exports2.deterministicPermitNonce = deterministicPermitNonce2;
|
|
264
|
+
exports2.deterministicSolanaNonce = deterministicSolanaNonce2;
|
|
265
|
+
exports2.sameAddress = sameAddress;
|
|
266
|
+
exports2.assertKeyMatchesSender = assertKeyMatchesSender2;
|
|
267
|
+
exports2.assertToken = assertToken;
|
|
268
|
+
exports2.assertAmountMatches = assertAmountMatches;
|
|
269
|
+
exports2.assertFresh = assertFresh;
|
|
270
|
+
exports2.assertSpender = assertSpender;
|
|
271
|
+
exports2.assertWitnessRoles = assertWitnessRoles;
|
|
272
|
+
exports2.assertRolePairComplete = assertRolePairComplete;
|
|
273
|
+
exports2.nowSec = nowSec;
|
|
274
|
+
var ethers_1 = require("ethers");
|
|
275
|
+
exports2.REPLAY_HORIZON_SECS = 128;
|
|
276
|
+
function resolvePermitDeadline(deadline) {
|
|
277
|
+
return BigInt(deadline);
|
|
278
|
+
}
|
|
279
|
+
function generatePermitNonce() {
|
|
280
|
+
const rand = new Uint32Array(1);
|
|
281
|
+
globalThis.crypto.getRandomValues(rand);
|
|
282
|
+
return (BigInt(Date.now()) << 32n) + BigInt(rand[0]);
|
|
283
|
+
}
|
|
284
|
+
function resolvePermitNonce(nonce) {
|
|
285
|
+
return BigInt(nonce);
|
|
286
|
+
}
|
|
287
|
+
exports2.PERMIT_NONCE_DOMAIN = "atum-permit:v1:";
|
|
288
|
+
exports2.SOLANA_REPLAY_SLOTS = 235n;
|
|
289
|
+
var SOLANA_BUCKET_BITS = 17n;
|
|
290
|
+
function canonicalDepositor(depositor) {
|
|
291
|
+
const lower = depositor.toLowerCase();
|
|
292
|
+
return lower.startsWith("0x") ? lower : depositor;
|
|
293
|
+
}
|
|
294
|
+
function permitNonceSeed(requestId, depositor) {
|
|
295
|
+
if (!requestId) {
|
|
296
|
+
throw new Error("sender_auth: request_id is required to derive a deterministic permit nonce");
|
|
297
|
+
}
|
|
298
|
+
return BigInt((0, ethers_1.keccak256)((0, ethers_1.toUtf8Bytes)(`${exports2.PERMIT_NONCE_DOMAIN}${requestId}:${canonicalDepositor(depositor)}`)));
|
|
299
|
+
}
|
|
300
|
+
function deterministicPermitNonce2(params) {
|
|
301
|
+
return permitNonceSeed(params.requestId, params.depositor);
|
|
302
|
+
}
|
|
303
|
+
function deterministicSolanaNonce2(params) {
|
|
304
|
+
const seed = permitNonceSeed(params.requestId, params.depositor);
|
|
305
|
+
const slot = seed % exports2.SOLANA_REPLAY_SLOTS;
|
|
306
|
+
const bucket = (seed >> 8n) % (1n << SOLANA_BUCKET_BITS);
|
|
307
|
+
return bucket << 32n | slot;
|
|
308
|
+
}
|
|
309
|
+
function sameAddress(a, b) {
|
|
310
|
+
if (a.startsWith("0x") && b.startsWith("0x")) {
|
|
311
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
312
|
+
}
|
|
313
|
+
return a === b;
|
|
314
|
+
}
|
|
315
|
+
function assertKeyMatchesSender2(matches, sender, derived) {
|
|
316
|
+
if (!matches) {
|
|
317
|
+
throw new Error(`sender_auth: private key derives ${derived}, not the expected sender ${sender}`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
function assertToken(token, sourceAsset, normalize) {
|
|
321
|
+
if (!sameAddress(token, normalize(sourceAsset))) {
|
|
322
|
+
throw new Error("sender_auth: permit token does not match the source asset");
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function assertAmountMatches(amount, maxSourceAmount) {
|
|
326
|
+
if (BigInt(amount) !== BigInt(maxSourceAmount)) {
|
|
327
|
+
throw new Error("sender_auth: permit amount does not match max_source_amount");
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function assertFresh(deadlineSec, nowSec2) {
|
|
331
|
+
if (deadlineSec <= nowSec2) {
|
|
332
|
+
throw new Error("sender_auth: permit deadline is not in the future");
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function assertSpender(spender, escrow, normalize) {
|
|
336
|
+
if (!sameAddress(spender, normalize(escrow))) {
|
|
337
|
+
throw new Error("sender_auth: permit spender is not the source escrow");
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function assertWitnessRoles(reserver, releaser, expectedReserver, expectedReleaser, normalize) {
|
|
341
|
+
if (!sameAddress(reserver, normalize(expectedReserver)) || !sameAddress(releaser, normalize(expectedReleaser))) {
|
|
342
|
+
throw new Error("sender_auth: deposit witness roles do not match the challenge");
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function assertRolePairComplete(reserver, releaser) {
|
|
346
|
+
if (reserver === void 0 !== (releaser === void 0)) {
|
|
347
|
+
throw new Error("sender_auth: reserver and releaser must be supplied together");
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function nowSec() {
|
|
351
|
+
return Math.floor(Date.now() / 1e3);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/chain-id.js
|
|
357
|
+
var require_chain_id2 = __commonJS({
|
|
358
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/chain-id.js"(exports2) {
|
|
359
|
+
"use strict";
|
|
360
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
361
|
+
exports2.TRON_PERMIT2_FALLBACKS = exports2.TRON_CHAIN_IDS = void 0;
|
|
362
|
+
exports2.namespaceOf = namespaceOf;
|
|
363
|
+
exports2.evmChainId = evmChainId;
|
|
364
|
+
exports2.tronNumericChainId = tronNumericChainId;
|
|
365
|
+
exports2.resolveTronPermit2 = resolveTronPermit2;
|
|
366
|
+
exports2.clusterIdFromName = clusterIdFromName;
|
|
367
|
+
function namespaceOf(network) {
|
|
368
|
+
return network.split(":")[0];
|
|
369
|
+
}
|
|
370
|
+
function evmChainId(network) {
|
|
371
|
+
const match = /^eip155:([0-9]+)$/.exec(network);
|
|
372
|
+
if (!match) {
|
|
373
|
+
throw new Error(`sender_auth: expected an eip155 network, got ${network}`);
|
|
374
|
+
}
|
|
375
|
+
return Number(match[1]);
|
|
376
|
+
}
|
|
377
|
+
exports2.TRON_CHAIN_IDS = {
|
|
378
|
+
mainnet: 728126428,
|
|
379
|
+
shasta: 2494104990
|
|
380
|
+
};
|
|
381
|
+
function tronNumericChainId(network) {
|
|
382
|
+
const cluster = network.split(":")[1];
|
|
383
|
+
const id = exports2.TRON_CHAIN_IDS[cluster ?? ""];
|
|
384
|
+
if (id === void 0) {
|
|
385
|
+
throw new Error(`sender_auth: unsupported Tron network '${network}'`);
|
|
386
|
+
}
|
|
387
|
+
return id;
|
|
388
|
+
}
|
|
389
|
+
exports2.TRON_PERMIT2_FALLBACKS = {
|
|
390
|
+
"tron:mainnet": "TJhMXTHQHeQyMD7TcKQFqAePNgG4b31H9m",
|
|
391
|
+
"tron:shasta": "TPUqJPASUn1zLvbLBgRZ5pBYrx7WSe5ahp"
|
|
392
|
+
};
|
|
393
|
+
function resolveTronPermit2(network) {
|
|
394
|
+
const resolved = exports2.TRON_PERMIT2_FALLBACKS[network];
|
|
395
|
+
if (!resolved) {
|
|
396
|
+
throw new Error(`sender_auth: no Permit2 address known for Tron network '${network}'`);
|
|
397
|
+
}
|
|
398
|
+
return resolved;
|
|
399
|
+
}
|
|
400
|
+
function clusterIdFromName(name) {
|
|
401
|
+
const encoded = new TextEncoder().encode(name);
|
|
402
|
+
if (encoded.length > 32) {
|
|
403
|
+
throw new Error(`sender_auth: Solana cluster name too long (${encoded.length} > 32 bytes): ${name}`);
|
|
404
|
+
}
|
|
405
|
+
const out = new Uint8Array(32);
|
|
406
|
+
out.set(encoded);
|
|
407
|
+
return out;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
// ../contracts/evm/escrow-encoding/typescript/dist/payment-id.js
|
|
413
|
+
var require_payment_id2 = __commonJS({
|
|
38
414
|
"../contracts/evm/escrow-encoding/typescript/dist/payment-id.js"(exports2) {
|
|
39
415
|
"use strict";
|
|
40
416
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -350,7 +726,7 @@ var require_escrow_abi = __commonJS({
|
|
|
350
726
|
});
|
|
351
727
|
|
|
352
728
|
// ../contracts/evm/escrow-encoding/typescript/dist/reserve-encoder.js
|
|
353
|
-
var
|
|
729
|
+
var require_reserve_encoder2 = __commonJS({
|
|
354
730
|
"../contracts/evm/escrow-encoding/typescript/dist/reserve-encoder.js"(exports2) {
|
|
355
731
|
"use strict";
|
|
356
732
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -368,7 +744,7 @@ var require_reserve_encoder = __commonJS({
|
|
|
368
744
|
});
|
|
369
745
|
|
|
370
746
|
// ../contracts/evm/escrow-encoding/typescript/dist/deposit-encoder.js
|
|
371
|
-
var
|
|
747
|
+
var require_deposit_encoder2 = __commonJS({
|
|
372
748
|
"../contracts/evm/escrow-encoding/typescript/dist/deposit-encoder.js"(exports2) {
|
|
373
749
|
"use strict";
|
|
374
750
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -409,12 +785,12 @@ var require_deposit_encoder = __commonJS({
|
|
|
409
785
|
});
|
|
410
786
|
|
|
411
787
|
// ../contracts/evm/escrow-encoding/typescript/dist/index.js
|
|
412
|
-
var
|
|
788
|
+
var require_dist2 = __commonJS({
|
|
413
789
|
"../contracts/evm/escrow-encoding/typescript/dist/index.js"(exports2) {
|
|
414
790
|
"use strict";
|
|
415
791
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
416
792
|
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;
|
|
417
|
-
var payment_id_1 =
|
|
793
|
+
var payment_id_1 = require_payment_id2();
|
|
418
794
|
Object.defineProperty(exports2, "computePaymentId", { enumerable: true, get: function() {
|
|
419
795
|
return payment_id_1.computePaymentId;
|
|
420
796
|
} });
|
|
@@ -460,11 +836,11 @@ var require_dist = __commonJS({
|
|
|
460
836
|
Object.defineProperty(exports2, "ESCROW_V3_ABI_JSON", { enumerable: true, get: function() {
|
|
461
837
|
return escrow_abi_1.ESCROW_V3_ABI_JSON;
|
|
462
838
|
} });
|
|
463
|
-
var reserve_encoder_1 =
|
|
839
|
+
var reserve_encoder_1 = require_reserve_encoder2();
|
|
464
840
|
Object.defineProperty(exports2, "computeReserveDigest", { enumerable: true, get: function() {
|
|
465
841
|
return reserve_encoder_1.computeReserveDigest;
|
|
466
842
|
} });
|
|
467
|
-
var deposit_encoder_1 =
|
|
843
|
+
var deposit_encoder_1 = require_deposit_encoder2();
|
|
468
844
|
Object.defineProperty(exports2, "createPermitWitnessTransferFromPrehash", { enumerable: true, get: function() {
|
|
469
845
|
return deposit_encoder_1.createPermitWitnessTransferFromPrehash;
|
|
470
846
|
} });
|
|
@@ -477,212 +853,263 @@ var require_dist = __commonJS({
|
|
|
477
853
|
}
|
|
478
854
|
});
|
|
479
855
|
|
|
480
|
-
// ../
|
|
481
|
-
var
|
|
482
|
-
"../
|
|
483
|
-
"use strict";
|
|
484
|
-
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
485
|
-
exports2.maskChainId = maskChainId2;
|
|
486
|
-
function maskChainId2(chainId) {
|
|
487
|
-
return (chainId & 4294967295) >>> 0;
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
// ../contracts/tvm/escrow-encoding/typescript/dist/tron-address.js
|
|
493
|
-
var require_tron_address = __commonJS({
|
|
494
|
-
"../contracts/tvm/escrow-encoding/typescript/dist/tron-address.js"(exports2) {
|
|
856
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/errors.js
|
|
857
|
+
var require_errors = __commonJS({
|
|
858
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/errors.js"(exports2) {
|
|
495
859
|
"use strict";
|
|
496
|
-
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
497
|
-
return mod && mod.__esModule ? mod : { "default": mod };
|
|
498
|
-
};
|
|
499
860
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
500
|
-
exports2.
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
function base58ToHex2(base58Address) {
|
|
506
|
-
if (!base58Address || !base58Address.startsWith("T")) {
|
|
507
|
-
throw new Error(`Invalid Tron base58 address: ${base58Address}`);
|
|
508
|
-
}
|
|
509
|
-
const decoded = bs58_1.default.decode(base58Address);
|
|
510
|
-
if (decoded.length !== 25) {
|
|
511
|
-
throw new Error(`Invalid Tron base58 length (expected 25 bytes): ${base58Address}`);
|
|
512
|
-
}
|
|
513
|
-
const payload = decoded.slice(0, 21);
|
|
514
|
-
const checksum = (0, ethers_1.hexlify)(decoded.slice(21)).slice(2);
|
|
515
|
-
const computed = (0, ethers_1.sha256)((0, ethers_1.sha256)(payload)).slice(2, 10);
|
|
516
|
-
if (checksum !== computed) {
|
|
517
|
-
throw new Error(`Invalid Tron base58 checksum: ${base58Address}`);
|
|
518
|
-
}
|
|
519
|
-
return (0, ethers_1.hexlify)(payload).slice(2);
|
|
520
|
-
}
|
|
521
|
-
function normalizeAddress2(address) {
|
|
522
|
-
if (!address) {
|
|
523
|
-
throw new Error("Empty address");
|
|
524
|
-
}
|
|
525
|
-
let hexAddress = address;
|
|
526
|
-
if (address.startsWith("T")) {
|
|
527
|
-
hexAddress = base58ToHex2(address);
|
|
528
|
-
}
|
|
529
|
-
hexAddress = hexAddress.replace(/^0x/, "");
|
|
530
|
-
if (hexAddress.startsWith(TVM_MAINNET_PREFIX)) {
|
|
531
|
-
hexAddress = hexAddress.substring(2);
|
|
861
|
+
exports2.SignerMismatchError = exports2.RecoveryFailedError = exports2.MalformedPrehashError = void 0;
|
|
862
|
+
var MalformedPrehashError = class extends Error {
|
|
863
|
+
constructor(message = "sender_auth: malformed message_prehash") {
|
|
864
|
+
super(message);
|
|
865
|
+
this.name = "MalformedPrehashError";
|
|
532
866
|
}
|
|
533
|
-
|
|
534
|
-
|
|
867
|
+
};
|
|
868
|
+
exports2.MalformedPrehashError = MalformedPrehashError;
|
|
869
|
+
var RecoveryFailedError = class extends Error {
|
|
870
|
+
constructor(message = "sender_auth: could not recover a signer from the signed message") {
|
|
871
|
+
super(message);
|
|
872
|
+
this.name = "RecoveryFailedError";
|
|
535
873
|
}
|
|
536
|
-
|
|
537
|
-
|
|
874
|
+
};
|
|
875
|
+
exports2.RecoveryFailedError = RecoveryFailedError;
|
|
876
|
+
var SignerMismatchError = class extends Error {
|
|
877
|
+
constructor(message = "sender_auth: recovered signer does not match source.account") {
|
|
878
|
+
super(message);
|
|
879
|
+
this.name = "SignerMismatchError";
|
|
538
880
|
}
|
|
539
|
-
return "0x" + hexAddress.toLowerCase();
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
});
|
|
543
|
-
|
|
544
|
-
// ../contracts/tvm/escrow-encoding/typescript/dist/reserve-encoder.js
|
|
545
|
-
var require_reserve_encoder2 = __commonJS({
|
|
546
|
-
"../contracts/tvm/escrow-encoding/typescript/dist/reserve-encoder.js"(exports2) {
|
|
547
|
-
"use strict";
|
|
548
|
-
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
549
|
-
exports2.computeReserveDigest = computeReserveDigest;
|
|
550
|
-
var ethers_1 = require("ethers");
|
|
551
|
-
var chain_id_1 = require_chain_id();
|
|
552
|
-
var RESERVE_WITNESS_TYPES = {
|
|
553
|
-
ReserveWitness: [
|
|
554
|
-
{ name: "paymentId", type: "bytes32" },
|
|
555
|
-
{ name: "settler", type: "address" }
|
|
556
|
-
]
|
|
557
881
|
};
|
|
558
|
-
|
|
559
|
-
const domain = {
|
|
560
|
-
name: "Escrow",
|
|
561
|
-
version: "3",
|
|
562
|
-
chainId: (0, chain_id_1.maskChainId)(input.chainId),
|
|
563
|
-
verifyingContract: input.escrowContract
|
|
564
|
-
};
|
|
565
|
-
return ethers_1.TypedDataEncoder.hash(domain, RESERVE_WITNESS_TYPES, {
|
|
566
|
-
paymentId: input.paymentId,
|
|
567
|
-
settler: input.settler
|
|
568
|
-
});
|
|
569
|
-
}
|
|
882
|
+
exports2.SignerMismatchError = SignerMismatchError;
|
|
570
883
|
}
|
|
571
884
|
});
|
|
572
885
|
|
|
573
|
-
// ../
|
|
574
|
-
var
|
|
575
|
-
"../
|
|
886
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/adapters/evm.js
|
|
887
|
+
var require_evm = __commonJS({
|
|
888
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/adapters/evm.js"(exports2) {
|
|
576
889
|
"use strict";
|
|
577
890
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
578
|
-
exports2.
|
|
891
|
+
exports2.evmAdapter = void 0;
|
|
579
892
|
var ethers_1 = require("ethers");
|
|
580
|
-
var
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
893
|
+
var evm_escrow_encoding_1 = require_dist2();
|
|
894
|
+
var utils_js_1 = require_utils();
|
|
895
|
+
var errors_js_1 = require_errors();
|
|
896
|
+
var chain_id_js_1 = require_chain_id2();
|
|
897
|
+
exports2.evmAdapter = {
|
|
898
|
+
async buildAuthMessage({ sourceAsset, maxSourceAmount, sourceDefaults, deadline, nonce }) {
|
|
899
|
+
if (nonce === void 0) {
|
|
900
|
+
throw new Error("sender_auth: buildAuthMessage requires an explicit nonce \u2014 derive it deterministically from a stable request id (e.g. the challenge id) so retries reproduce the same permit; pass generatePermitNonce() only for genuinely one-shot builds");
|
|
901
|
+
}
|
|
902
|
+
if (deadline === void 0) {
|
|
903
|
+
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)");
|
|
904
|
+
}
|
|
905
|
+
const sourceChainId = sourceAsset.split("/")[0];
|
|
906
|
+
const chainIdNum = parseInt(sourceChainId.split(":")[1]);
|
|
907
|
+
const tokenAddress = sourceAsset.split("/")[1].split(":")[1];
|
|
908
|
+
const permitParams = {
|
|
909
|
+
chainId: chainIdNum,
|
|
910
|
+
verifyingContract: evm_escrow_encoding_1.PERMIT2_CONTRACT_ADDRESS,
|
|
911
|
+
token: tokenAddress,
|
|
912
|
+
amount: maxSourceAmount,
|
|
913
|
+
spender: sourceDefaults.escrowContract,
|
|
914
|
+
nonce: (0, utils_js_1.resolvePermitNonce)(nonce),
|
|
915
|
+
deadline: (0, utils_js_1.resolvePermitDeadline)(deadline),
|
|
916
|
+
reserver: sourceDefaults.quoteSelector,
|
|
917
|
+
releaser: sourceDefaults.fulfillmentVerifierAccount
|
|
918
|
+
};
|
|
919
|
+
const messagePrehash = (0, evm_escrow_encoding_1.createPermitWitnessTransferFromPrehash)(permitParams);
|
|
920
|
+
const messageHash = (0, evm_escrow_encoding_1.hashPermitWitnessTransferFrom)(messagePrehash);
|
|
921
|
+
return { messageScheme: "EVM_PERMIT2", messageHash, messagePrehash: JSON.stringify(messagePrehash) };
|
|
922
|
+
},
|
|
923
|
+
async sign(signedMessage, privateKey) {
|
|
924
|
+
if (!signedMessage.message_prehash) {
|
|
925
|
+
throw new Error("EVM adapter sign(): signed_messages[i].message_prehash is required");
|
|
926
|
+
}
|
|
927
|
+
const prehash = JSON.parse(signedMessage.message_prehash);
|
|
928
|
+
const wallet = new ethers_1.Wallet(privateKey);
|
|
929
|
+
return wallet.signTypedData(prehash.domain, prehash.types, prehash.message);
|
|
930
|
+
},
|
|
931
|
+
recoverSigner(signed, source) {
|
|
932
|
+
let recovered;
|
|
933
|
+
try {
|
|
934
|
+
recovered = (0, ethers_1.recoverAddress)(signed.message, signed.signature);
|
|
935
|
+
} catch (e) {
|
|
936
|
+
throw new errors_js_1.RecoveryFailedError(`sender_auth: could not recover a signer: ${e.message}`);
|
|
937
|
+
}
|
|
938
|
+
if (!(0, utils_js_1.sameAddress)(recovered, source.account)) {
|
|
939
|
+
throw new errors_js_1.SignerMismatchError(`sender_auth: recovered ${recovered}, not source.account`);
|
|
940
|
+
}
|
|
941
|
+
return source.account;
|
|
942
|
+
},
|
|
943
|
+
recoverAndVerify(signed, source, expected) {
|
|
944
|
+
let canonical;
|
|
945
|
+
let msg;
|
|
946
|
+
try {
|
|
947
|
+
msg = JSON.parse(signed.message_prehash).message;
|
|
948
|
+
canonical = (0, evm_escrow_encoding_1.createPermitWitnessTransferFromPrehash)({
|
|
949
|
+
chainId: (0, chain_id_js_1.evmChainId)(source.network),
|
|
950
|
+
verifyingContract: evm_escrow_encoding_1.PERMIT2_CONTRACT_ADDRESS,
|
|
951
|
+
token: msg.permitted.token,
|
|
952
|
+
amount: msg.permitted.amount,
|
|
953
|
+
spender: msg.spender,
|
|
954
|
+
nonce: BigInt(msg.nonce),
|
|
955
|
+
deadline: BigInt(msg.deadline),
|
|
956
|
+
reserver: msg.witness.reserver,
|
|
957
|
+
releaser: msg.witness.releaser
|
|
958
|
+
});
|
|
959
|
+
} catch {
|
|
960
|
+
throw new errors_js_1.MalformedPrehashError();
|
|
961
|
+
}
|
|
962
|
+
let recovered;
|
|
963
|
+
try {
|
|
964
|
+
recovered = (0, ethers_1.verifyTypedData)(canonical.domain, canonical.types, canonical.message, signed.signature);
|
|
965
|
+
} catch {
|
|
966
|
+
throw new Error("sender_auth: deposit signature does not recover to source.account");
|
|
967
|
+
}
|
|
968
|
+
if (!(0, utils_js_1.sameAddress)(recovered, source.account)) {
|
|
969
|
+
throw new Error("sender_auth: deposit signature does not recover to source.account");
|
|
970
|
+
}
|
|
971
|
+
const deadlineSec = Number(msg.deadline);
|
|
972
|
+
(0, utils_js_1.assertToken)(msg.permitted.token, source.asset, (a) => a);
|
|
973
|
+
(0, utils_js_1.assertAmountMatches)(msg.permitted.amount, expected.maxSourceAmount);
|
|
974
|
+
(0, utils_js_1.assertFresh)(deadlineSec, expected.nowSec ?? (0, utils_js_1.nowSec)());
|
|
975
|
+
if (expected.escrowContract !== void 0) {
|
|
976
|
+
(0, utils_js_1.assertSpender)(msg.spender, expected.escrowContract, (a) => a);
|
|
977
|
+
}
|
|
978
|
+
(0, utils_js_1.assertRolePairComplete)(expected.reserver, expected.releaser);
|
|
979
|
+
if (expected.reserver !== void 0 && expected.releaser !== void 0) {
|
|
980
|
+
(0, utils_js_1.assertWitnessRoles)(msg.witness.reserver, msg.witness.releaser, expected.reserver, expected.releaser, (a) => a);
|
|
981
|
+
}
|
|
982
|
+
return {
|
|
983
|
+
amount: msg.permitted.amount,
|
|
984
|
+
deadlineSec,
|
|
985
|
+
permit: {
|
|
986
|
+
scheme: "EVM_PERMIT2",
|
|
987
|
+
token: msg.permitted.token,
|
|
988
|
+
amount: msg.permitted.amount,
|
|
989
|
+
deadlineSec,
|
|
990
|
+
reserver: msg.witness.reserver,
|
|
991
|
+
releaser: msg.witness.releaser,
|
|
992
|
+
spender: msg.spender
|
|
993
|
+
}
|
|
994
|
+
};
|
|
584
995
|
}
|
|
585
|
-
const encoded = ethers_1.AbiCoder.defaultAbiCoder().encode(["address", "bytes", "uint256"], [(0, tron_address_1.normalizeAddress)(depositor), signature, nonce]);
|
|
586
|
-
return (0, ethers_1.keccak256)(encoded);
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
});
|
|
590
|
-
|
|
591
|
-
// ../contracts/tvm/escrow-encoding/typescript/dist/deposit-encoder.js
|
|
592
|
-
var require_deposit_encoder2 = __commonJS({
|
|
593
|
-
"../contracts/tvm/escrow-encoding/typescript/dist/deposit-encoder.js"(exports2) {
|
|
594
|
-
"use strict";
|
|
595
|
-
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
596
|
-
exports2.createTvmPermitWitnessTransferFromPrehash = createTvmPermitWitnessTransferFromPrehash2;
|
|
597
|
-
exports2.hashTvmPermitWitnessTransferFrom = hashTvmPermitWitnessTransferFrom2;
|
|
598
|
-
var ethers_1 = require("ethers");
|
|
599
|
-
var chain_id_1 = require_chain_id();
|
|
600
|
-
var tron_address_1 = require_tron_address();
|
|
601
|
-
var PERMIT_WITNESS_TYPES_V2 = {
|
|
602
|
-
PermitWitnessTransferFrom: [
|
|
603
|
-
{ name: "permitted", type: "TokenPermissions" },
|
|
604
|
-
{ name: "spender", type: "address" },
|
|
605
|
-
{ name: "nonce", type: "uint256" },
|
|
606
|
-
{ name: "deadline", type: "uint256" },
|
|
607
|
-
{ name: "witness", type: "DepositWitness" }
|
|
608
|
-
],
|
|
609
|
-
TokenPermissions: [
|
|
610
|
-
{ name: "token", type: "address" },
|
|
611
|
-
{ name: "amount", type: "uint256" }
|
|
612
|
-
],
|
|
613
|
-
DepositWitness: [
|
|
614
|
-
{ name: "reserver", type: "address" },
|
|
615
|
-
{ name: "releaser", type: "address" }
|
|
616
|
-
]
|
|
617
996
|
};
|
|
618
|
-
function createTvmPermitWitnessTransferFromPrehash2(params) {
|
|
619
|
-
const maskedChainId = (0, chain_id_1.maskChainId)(params.chainId);
|
|
620
|
-
return {
|
|
621
|
-
types: PERMIT_WITNESS_TYPES_V2,
|
|
622
|
-
primaryType: "PermitWitnessTransferFrom",
|
|
623
|
-
domain: {
|
|
624
|
-
name: "Permit2",
|
|
625
|
-
chainId: `0x${maskedChainId.toString(16)}`,
|
|
626
|
-
verifyingContract: (0, tron_address_1.normalizeAddress)(params.permit2Address)
|
|
627
|
-
},
|
|
628
|
-
message: {
|
|
629
|
-
permitted: {
|
|
630
|
-
token: (0, tron_address_1.normalizeAddress)(params.tokenAddress),
|
|
631
|
-
amount: params.amount
|
|
632
|
-
},
|
|
633
|
-
spender: (0, tron_address_1.normalizeAddress)(params.spenderAddress),
|
|
634
|
-
nonce: params.nonce.toString(),
|
|
635
|
-
deadline: params.deadline.toString(),
|
|
636
|
-
witness: {
|
|
637
|
-
reserver: (0, tron_address_1.normalizeAddress)(params.reserverAddress),
|
|
638
|
-
releaser: (0, tron_address_1.normalizeAddress)(params.releaserAddress)
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
};
|
|
642
|
-
}
|
|
643
|
-
function hashTvmPermitWitnessTransferFrom2(prehash) {
|
|
644
|
-
return ethers_1.TypedDataEncoder.hash(prehash.domain, prehash.types, prehash.message);
|
|
645
|
-
}
|
|
646
997
|
}
|
|
647
998
|
});
|
|
648
999
|
|
|
649
|
-
// ../
|
|
650
|
-
var
|
|
651
|
-
"../
|
|
652
|
-
"use strict";
|
|
653
|
-
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
654
|
-
exports2.
|
|
655
|
-
var
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
var
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
1000
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/adapters/tron.js
|
|
1001
|
+
var require_tron = __commonJS({
|
|
1002
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/adapters/tron.js"(exports2) {
|
|
1003
|
+
"use strict";
|
|
1004
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1005
|
+
exports2.tronAdapter = void 0;
|
|
1006
|
+
var ethers_1 = require("ethers");
|
|
1007
|
+
var tvm_escrow_encoding_1 = require_dist();
|
|
1008
|
+
var utils_js_1 = require_utils();
|
|
1009
|
+
var errors_js_1 = require_errors();
|
|
1010
|
+
var chain_id_js_1 = require_chain_id2();
|
|
1011
|
+
exports2.tronAdapter = {
|
|
1012
|
+
async buildAuthMessage({ sourceAsset, maxSourceAmount, sourceDefaults, deadline, nonce }) {
|
|
1013
|
+
if (nonce === void 0) {
|
|
1014
|
+
throw new Error("sender_auth: buildAuthMessage requires an explicit nonce \u2014 derive it deterministically from a stable request id (e.g. the challenge id) so retries reproduce the same permit; pass generatePermitNonce() only for genuinely one-shot builds");
|
|
1015
|
+
}
|
|
1016
|
+
if (deadline === void 0) {
|
|
1017
|
+
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)");
|
|
1018
|
+
}
|
|
1019
|
+
const sourceChainId = sourceAsset.split("/")[0];
|
|
1020
|
+
const tokenAddress = sourceAsset.split("/")[1].split(":")[1];
|
|
1021
|
+
const permit2Address = sourceDefaults.permit2Contract ?? (0, chain_id_js_1.resolveTronPermit2)(sourceChainId);
|
|
1022
|
+
const tvmParams = {
|
|
1023
|
+
chainId: (0, chain_id_js_1.tronNumericChainId)(sourceChainId),
|
|
1024
|
+
permit2Address,
|
|
1025
|
+
tokenAddress,
|
|
1026
|
+
amount: maxSourceAmount,
|
|
1027
|
+
spenderAddress: sourceDefaults.escrowContract,
|
|
1028
|
+
nonce: (0, utils_js_1.resolvePermitNonce)(nonce),
|
|
1029
|
+
deadline: (0, utils_js_1.resolvePermitDeadline)(deadline),
|
|
1030
|
+
reserverAddress: sourceDefaults.quoteSelector,
|
|
1031
|
+
releaserAddress: sourceDefaults.fulfillmentVerifierAccount
|
|
1032
|
+
};
|
|
1033
|
+
const messagePrehash = (0, tvm_escrow_encoding_1.createTvmPermitWitnessTransferFromPrehash)(tvmParams);
|
|
1034
|
+
const messageHash = (0, tvm_escrow_encoding_1.hashTvmPermitWitnessTransferFrom)(messagePrehash);
|
|
1035
|
+
return { messageScheme: "EVM_PERMIT2", messageHash, messagePrehash: JSON.stringify(messagePrehash) };
|
|
1036
|
+
},
|
|
1037
|
+
async sign(signedMessage, privateKey) {
|
|
1038
|
+
const wallet = new ethers_1.Wallet(privateKey.startsWith("0x") ? privateKey : "0x" + privateKey);
|
|
1039
|
+
return wallet.signingKey.sign(signedMessage.message).serialized;
|
|
1040
|
+
},
|
|
1041
|
+
recoverSigner(signed, source) {
|
|
1042
|
+
let recovered;
|
|
1043
|
+
try {
|
|
1044
|
+
recovered = (0, ethers_1.recoverAddress)(signed.message, signed.signature);
|
|
1045
|
+
} catch (e) {
|
|
1046
|
+
throw new errors_js_1.RecoveryFailedError(`sender_auth: could not recover a signer: ${e.message}`);
|
|
1047
|
+
}
|
|
1048
|
+
if (!(0, utils_js_1.sameAddress)(recovered, (0, tvm_escrow_encoding_1.normalizeAddress)(source.account))) {
|
|
1049
|
+
throw new errors_js_1.SignerMismatchError(`sender_auth: recovered ${recovered}, not source.account`);
|
|
1050
|
+
}
|
|
1051
|
+
return source.account;
|
|
1052
|
+
},
|
|
1053
|
+
recoverAndVerify(signed, source, expected) {
|
|
1054
|
+
let msg;
|
|
1055
|
+
let digest;
|
|
1056
|
+
try {
|
|
1057
|
+
msg = JSON.parse(signed.message_prehash).message;
|
|
1058
|
+
const canonical = (0, tvm_escrow_encoding_1.createTvmPermitWitnessTransferFromPrehash)({
|
|
1059
|
+
chainId: (0, chain_id_js_1.tronNumericChainId)(source.network),
|
|
1060
|
+
permit2Address: (0, chain_id_js_1.resolveTronPermit2)(source.network),
|
|
1061
|
+
tokenAddress: msg.permitted.token,
|
|
1062
|
+
amount: msg.permitted.amount,
|
|
1063
|
+
spenderAddress: msg.spender,
|
|
1064
|
+
nonce: BigInt(msg.nonce),
|
|
1065
|
+
deadline: BigInt(msg.deadline),
|
|
1066
|
+
reserverAddress: msg.witness.reserver,
|
|
1067
|
+
releaserAddress: msg.witness.releaser
|
|
1068
|
+
});
|
|
1069
|
+
digest = (0, tvm_escrow_encoding_1.hashTvmPermitWitnessTransferFrom)(canonical);
|
|
1070
|
+
} catch {
|
|
1071
|
+
throw new errors_js_1.MalformedPrehashError();
|
|
1072
|
+
}
|
|
1073
|
+
let recovered;
|
|
1074
|
+
try {
|
|
1075
|
+
recovered = (0, ethers_1.recoverAddress)(digest, signed.signature);
|
|
1076
|
+
} catch {
|
|
1077
|
+
throw new Error("sender_auth: deposit signature does not recover to source.account");
|
|
1078
|
+
}
|
|
1079
|
+
if (!(0, utils_js_1.sameAddress)(recovered, (0, tvm_escrow_encoding_1.normalizeAddress)(source.account))) {
|
|
1080
|
+
throw new Error("sender_auth: deposit signature does not recover to source.account");
|
|
1081
|
+
}
|
|
1082
|
+
const deadlineSec = Number(msg.deadline);
|
|
1083
|
+
(0, utils_js_1.assertToken)(msg.permitted.token, source.asset, tvm_escrow_encoding_1.normalizeAddress);
|
|
1084
|
+
(0, utils_js_1.assertAmountMatches)(msg.permitted.amount, expected.maxSourceAmount);
|
|
1085
|
+
(0, utils_js_1.assertFresh)(deadlineSec, expected.nowSec ?? (0, utils_js_1.nowSec)());
|
|
1086
|
+
if (expected.escrowContract !== void 0) {
|
|
1087
|
+
(0, utils_js_1.assertSpender)(msg.spender, expected.escrowContract, tvm_escrow_encoding_1.normalizeAddress);
|
|
1088
|
+
}
|
|
1089
|
+
(0, utils_js_1.assertRolePairComplete)(expected.reserver, expected.releaser);
|
|
1090
|
+
if (expected.reserver !== void 0 && expected.releaser !== void 0) {
|
|
1091
|
+
(0, utils_js_1.assertWitnessRoles)(msg.witness.reserver, msg.witness.releaser, expected.reserver, expected.releaser, tvm_escrow_encoding_1.normalizeAddress);
|
|
1092
|
+
}
|
|
1093
|
+
return {
|
|
1094
|
+
amount: msg.permitted.amount,
|
|
1095
|
+
deadlineSec,
|
|
1096
|
+
permit: {
|
|
1097
|
+
scheme: "EVM_PERMIT2",
|
|
1098
|
+
token: msg.permitted.token,
|
|
1099
|
+
amount: msg.permitted.amount,
|
|
1100
|
+
deadlineSec,
|
|
1101
|
+
reserver: msg.witness.reserver,
|
|
1102
|
+
releaser: msg.witness.releaser,
|
|
1103
|
+
spender: msg.spender
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1107
|
+
};
|
|
681
1108
|
}
|
|
682
1109
|
});
|
|
683
1110
|
|
|
684
1111
|
// ../contracts/svm/escrow-encoding/typescript/dist/errors.js
|
|
685
|
-
var
|
|
1112
|
+
var require_errors2 = __commonJS({
|
|
686
1113
|
"../contracts/svm/escrow-encoding/typescript/dist/errors.js"(exports2) {
|
|
687
1114
|
"use strict";
|
|
688
1115
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -784,8 +1211,8 @@ var require_pubkey = __commonJS({
|
|
|
784
1211
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
785
1212
|
exports2.Pubkey = void 0;
|
|
786
1213
|
var bs58_1 = __importDefault(require("bs58"));
|
|
787
|
-
var errors_1 =
|
|
788
|
-
var
|
|
1214
|
+
var errors_1 = require_errors2();
|
|
1215
|
+
var Pubkey2 = class _Pubkey {
|
|
789
1216
|
constructor(data) {
|
|
790
1217
|
if (data.length !== 32) {
|
|
791
1218
|
throw new errors_1.InvalidPubkeyLengthError();
|
|
@@ -878,7 +1305,7 @@ var require_pubkey = __commonJS({
|
|
|
878
1305
|
return this.data.every((b, i) => b === other.data[i]);
|
|
879
1306
|
}
|
|
880
1307
|
};
|
|
881
|
-
exports2.Pubkey =
|
|
1308
|
+
exports2.Pubkey = Pubkey2;
|
|
882
1309
|
}
|
|
883
1310
|
});
|
|
884
1311
|
|
|
@@ -990,7 +1417,7 @@ var require_cryptoNode = __commonJS({
|
|
|
990
1417
|
});
|
|
991
1418
|
|
|
992
1419
|
// ../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/utils.js
|
|
993
|
-
var
|
|
1420
|
+
var require_utils2 = __commonJS({
|
|
994
1421
|
"../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/utils.js"(exports2) {
|
|
995
1422
|
"use strict";
|
|
996
1423
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -1239,7 +1666,7 @@ var require_sha3 = __commonJS({
|
|
|
1239
1666
|
exports2.shake256 = exports2.shake128 = exports2.keccak_512 = exports2.keccak_384 = exports2.keccak_256 = exports2.keccak_224 = exports2.sha3_512 = exports2.sha3_384 = exports2.sha3_256 = exports2.sha3_224 = exports2.Keccak = void 0;
|
|
1240
1667
|
exports2.keccakP = keccakP;
|
|
1241
1668
|
var _u64_ts_1 = require_u64();
|
|
1242
|
-
var utils_ts_1 =
|
|
1669
|
+
var utils_ts_1 = require_utils2();
|
|
1243
1670
|
var _0n = BigInt(0);
|
|
1244
1671
|
var _1n = BigInt(1);
|
|
1245
1672
|
var _2n = BigInt(2);
|
|
@@ -1504,7 +1931,7 @@ var require_deposit_encoder3 = __commonJS({
|
|
|
1504
1931
|
exports2.computeDepositHash = computeDepositHash2;
|
|
1505
1932
|
var encoding_utils_1 = require_encoding_utils();
|
|
1506
1933
|
var escrow_domain_1 = require_escrow_domain();
|
|
1507
|
-
var errors_1 =
|
|
1934
|
+
var errors_1 = require_errors2();
|
|
1508
1935
|
function computeDepositHash2(params, domain) {
|
|
1509
1936
|
if (params.paymentId.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(params.paymentId)) {
|
|
1510
1937
|
throw new errors_1.ZeroPaymentIdError();
|
|
@@ -1532,7 +1959,7 @@ var require_reserve_encoder3 = __commonJS({
|
|
|
1532
1959
|
exports2.computeReserveHash = computeReserveHash;
|
|
1533
1960
|
var encoding_utils_1 = require_encoding_utils();
|
|
1534
1961
|
var escrow_domain_1 = require_escrow_domain();
|
|
1535
|
-
var errors_1 =
|
|
1962
|
+
var errors_1 = require_errors2();
|
|
1536
1963
|
function computeReserveHash(params, domain) {
|
|
1537
1964
|
if (params.depositHash.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(params.depositHash)) {
|
|
1538
1965
|
throw new errors_1.ZeroDepositHashError();
|
|
@@ -1552,7 +1979,7 @@ var require_release_encoder = __commonJS({
|
|
|
1552
1979
|
exports2.computeReleaseHash = computeReleaseHash;
|
|
1553
1980
|
var encoding_utils_1 = require_encoding_utils();
|
|
1554
1981
|
var escrow_domain_1 = require_escrow_domain();
|
|
1555
|
-
var errors_1 =
|
|
1982
|
+
var errors_1 = require_errors2();
|
|
1556
1983
|
function computeReleaseHash(params, domain) {
|
|
1557
1984
|
if (params.depositHash.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(params.depositHash)) {
|
|
1558
1985
|
throw new errors_1.ZeroDepositHashError();
|
|
@@ -1570,7 +1997,7 @@ var require_refund_encoder = __commonJS({
|
|
|
1570
1997
|
exports2.computeRefundHash = computeRefundHash;
|
|
1571
1998
|
var encoding_utils_1 = require_encoding_utils();
|
|
1572
1999
|
var escrow_domain_1 = require_escrow_domain();
|
|
1573
|
-
var errors_1 =
|
|
2000
|
+
var errors_1 = require_errors2();
|
|
1574
2001
|
function computeRefundHash(params, domain) {
|
|
1575
2002
|
if (params.depositHash.length !== 32 || (0, encoding_utils_1.isZeroBytes32)(params.depositHash)) {
|
|
1576
2003
|
throw new errors_1.ZeroDepositHashError();
|
|
@@ -1631,7 +2058,7 @@ var require_dist3 = __commonJS({
|
|
|
1631
2058
|
Object.defineProperty(exports2, "escrowDomainPrefixBytes", { enumerable: true, get: function() {
|
|
1632
2059
|
return escrow_domain_1.escrowDomainPrefixBytes;
|
|
1633
2060
|
} });
|
|
1634
|
-
var errors_1 =
|
|
2061
|
+
var errors_1 = require_errors2();
|
|
1635
2062
|
Object.defineProperty(exports2, "EncodingError", { enumerable: true, get: function() {
|
|
1636
2063
|
return errors_1.EncodingError;
|
|
1637
2064
|
} });
|
|
@@ -1697,8 +2124,323 @@ var require_dist3 = __commonJS({
|
|
|
1697
2124
|
}
|
|
1698
2125
|
});
|
|
1699
2126
|
|
|
2127
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/adapters/solana.js
|
|
2128
|
+
var require_solana = __commonJS({
|
|
2129
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/adapters/solana.js"(exports2) {
|
|
2130
|
+
"use strict";
|
|
2131
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
2132
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
2133
|
+
};
|
|
2134
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2135
|
+
exports2.solanaAdapter = void 0;
|
|
2136
|
+
var ethers_1 = require("ethers");
|
|
2137
|
+
var tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
2138
|
+
var bs58_1 = __importDefault(require("bs58"));
|
|
2139
|
+
var solana_escrow_encoding_1 = require_dist3();
|
|
2140
|
+
var utils_js_1 = require_utils();
|
|
2141
|
+
var errors_js_1 = require_errors();
|
|
2142
|
+
var chain_id_js_1 = require_chain_id2();
|
|
2143
|
+
var idAddr = (a) => a;
|
|
2144
|
+
function generateSolanaPaymentIdV3(requestId) {
|
|
2145
|
+
return (0, ethers_1.keccak256)((0, ethers_1.toUtf8Bytes)(requestId));
|
|
2146
|
+
}
|
|
2147
|
+
function hashDeposit(prehash, domain) {
|
|
2148
|
+
return (0, ethers_1.hexlify)((0, solana_escrow_encoding_1.computeDepositHash)({
|
|
2149
|
+
paymentId: (0, ethers_1.getBytes)(prehash.payment_id),
|
|
2150
|
+
depositor: solana_escrow_encoding_1.Pubkey.fromBase58(prehash.depositor),
|
|
2151
|
+
mint: solana_escrow_encoding_1.Pubkey.fromBase58(prehash.mint),
|
|
2152
|
+
amount: BigInt(prehash.amount),
|
|
2153
|
+
reserver: solana_escrow_encoding_1.Pubkey.fromBase58(prehash.reserver),
|
|
2154
|
+
releaser: solana_escrow_encoding_1.Pubkey.fromBase58(prehash.releaser),
|
|
2155
|
+
nonce: BigInt(prehash.nonce),
|
|
2156
|
+
issuedAt: BigInt(prehash.issued_at),
|
|
2157
|
+
deadline: BigInt(prehash.deadline)
|
|
2158
|
+
}, domain));
|
|
2159
|
+
}
|
|
2160
|
+
function domainFrom(defaults) {
|
|
2161
|
+
if (!defaults.escrowContract) {
|
|
2162
|
+
throw new Error("sender_auth: Solana source requires escrowContract (escrow program id) for the deposit-hash domain");
|
|
2163
|
+
}
|
|
2164
|
+
if (!defaults.svmSignatureClusterId || defaults.svmSignatureDomainVersion == null) {
|
|
2165
|
+
throw new Error("sender_auth: Solana source requires svmSignatureClusterId and svmSignatureDomainVersion (V3 escrow domain separation)");
|
|
2166
|
+
}
|
|
2167
|
+
return {
|
|
2168
|
+
clusterId: (0, chain_id_js_1.clusterIdFromName)(defaults.svmSignatureClusterId),
|
|
2169
|
+
signatureDomainVersion: defaults.svmSignatureDomainVersion,
|
|
2170
|
+
programId: solana_escrow_encoding_1.Pubkey.fromBase58(defaults.escrowContract)
|
|
2171
|
+
};
|
|
2172
|
+
}
|
|
2173
|
+
exports2.solanaAdapter = {
|
|
2174
|
+
async buildAuthMessage({ sourceAsset, depositor, maxSourceAmount, requestId, sourceDefaults, nonce, solanaClockReader }) {
|
|
2175
|
+
if (!requestId) {
|
|
2176
|
+
throw new Error("sender_auth: request_id is required");
|
|
2177
|
+
}
|
|
2178
|
+
const sourceChainId = sourceAsset.split("/")[0];
|
|
2179
|
+
const tokenMint = sourceAsset.split("/")[1].split(":")[1];
|
|
2180
|
+
const depositNonce = nonce !== void 0 ? BigInt(nonce) : (0, solana_escrow_encoding_1.generateNonce)();
|
|
2181
|
+
if (nonce !== void 0) {
|
|
2182
|
+
if (depositNonce < 0n || depositNonce >= 1n << 64n) {
|
|
2183
|
+
throw new Error("sender_auth: Solana nonce must fit an unsigned 64-bit integer (0 <= nonce < 2^64)");
|
|
2184
|
+
}
|
|
2185
|
+
if ((depositNonce & 0xffn) >= utils_js_1.SOLANA_REPLAY_SLOTS) {
|
|
2186
|
+
throw new Error(`sender_auth: Solana nonce low byte (replay slot = nonce & 0xFF = ${depositNonce & 0xffn}) must be < ${utils_js_1.SOLANA_REPLAY_SLOTS}; slots ${utils_js_1.SOLANA_REPLAY_SLOTS}-255 are reserved`);
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
const issuedAt = solanaClockReader ? await solanaClockReader(sourceChainId) : BigInt(Math.floor(Date.now() / 1e3));
|
|
2190
|
+
const deadline = issuedAt + BigInt(utils_js_1.REPLAY_HORIZON_SECS - 8);
|
|
2191
|
+
const paymentId = generateSolanaPaymentIdV3(requestId);
|
|
2192
|
+
const prehash = {
|
|
2193
|
+
payment_id: paymentId,
|
|
2194
|
+
depositor,
|
|
2195
|
+
mint: tokenMint,
|
|
2196
|
+
amount: BigInt(maxSourceAmount).toString(),
|
|
2197
|
+
reserver: sourceDefaults.quoteSelector,
|
|
2198
|
+
releaser: sourceDefaults.fulfillmentVerifierAccount,
|
|
2199
|
+
nonce: depositNonce.toString(),
|
|
2200
|
+
issued_at: issuedAt.toString(),
|
|
2201
|
+
deadline: deadline.toString()
|
|
2202
|
+
};
|
|
2203
|
+
const depositHash = hashDeposit(prehash, domainFrom(sourceDefaults));
|
|
2204
|
+
return { messageScheme: "SOLANA", messageHash: depositHash, messagePrehash: JSON.stringify(prehash) };
|
|
2205
|
+
},
|
|
2206
|
+
async sign(signedMessage, privateKey) {
|
|
2207
|
+
const messageBytes = (0, ethers_1.getBytes)(signedMessage.message);
|
|
2208
|
+
const secretKey = secretKeyFromPrivate2(privateKey);
|
|
2209
|
+
const sig = tweetnacl_1.default.sign.detached(messageBytes, secretKey);
|
|
2210
|
+
return "0x" + Buffer.from(sig).toString("hex");
|
|
2211
|
+
},
|
|
2212
|
+
deriveDelegateSigner(privateKey) {
|
|
2213
|
+
return bs58_1.default.encode(tweetnacl_1.default.sign.keyPair.fromSecretKey(secretKeyFromPrivate2(privateKey)).publicKey);
|
|
2214
|
+
},
|
|
2215
|
+
recoverSigner(signed, source) {
|
|
2216
|
+
const provided = signed.payload?.delegate_signer;
|
|
2217
|
+
if (provided !== void 0 && provided !== source.account) {
|
|
2218
|
+
throw new errors_js_1.SignerMismatchError(`sender_auth: delegate_signer ${provided} != source.account`);
|
|
2219
|
+
}
|
|
2220
|
+
const signer = provided ?? source.account;
|
|
2221
|
+
let pub;
|
|
2222
|
+
let msg;
|
|
2223
|
+
let sig;
|
|
2224
|
+
try {
|
|
2225
|
+
pub = bs58_1.default.decode(signer);
|
|
2226
|
+
msg = (0, ethers_1.getBytes)(signed.message);
|
|
2227
|
+
sig = (0, ethers_1.getBytes)(signed.signature);
|
|
2228
|
+
} catch {
|
|
2229
|
+
throw new errors_js_1.RecoveryFailedError("sender_auth: malformed Solana pubkey/message/signature encoding");
|
|
2230
|
+
}
|
|
2231
|
+
if (pub.length !== 32 || msg.length !== 32 || sig.length !== 64) {
|
|
2232
|
+
throw new errors_js_1.RecoveryFailedError("sender_auth: Solana pubkey must be 32 bytes, message 32, signature 64");
|
|
2233
|
+
}
|
|
2234
|
+
let ok = false;
|
|
2235
|
+
try {
|
|
2236
|
+
ok = tweetnacl_1.default.sign.detached.verify(msg, sig, pub);
|
|
2237
|
+
} catch {
|
|
2238
|
+
ok = false;
|
|
2239
|
+
}
|
|
2240
|
+
if (!ok) {
|
|
2241
|
+
throw new errors_js_1.SignerMismatchError("sender_auth: ed25519 verification failed");
|
|
2242
|
+
}
|
|
2243
|
+
return source.account;
|
|
2244
|
+
},
|
|
2245
|
+
recoverAndVerify(signed, source, expected) {
|
|
2246
|
+
let prehash;
|
|
2247
|
+
let canonicalHash;
|
|
2248
|
+
try {
|
|
2249
|
+
prehash = JSON.parse(signed.message_prehash);
|
|
2250
|
+
canonicalHash = hashDeposit(prehash, domainFrom(expected));
|
|
2251
|
+
} catch {
|
|
2252
|
+
throw new errors_js_1.MalformedPrehashError();
|
|
2253
|
+
}
|
|
2254
|
+
if (canonicalHash.toLowerCase() !== signed.message.toLowerCase()) {
|
|
2255
|
+
throw new Error("sender_auth: deposit hash does not match the signed message");
|
|
2256
|
+
}
|
|
2257
|
+
const delegateSigner = signed.payload?.delegate_signer;
|
|
2258
|
+
if (!delegateSigner) {
|
|
2259
|
+
throw new Error("sender_auth: Solana credential is missing delegate_signer");
|
|
2260
|
+
}
|
|
2261
|
+
let verified = false;
|
|
2262
|
+
try {
|
|
2263
|
+
verified = tweetnacl_1.default.sign.detached.verify((0, ethers_1.getBytes)(signed.message), (0, ethers_1.getBytes)(signed.signature), bs58_1.default.decode(delegateSigner));
|
|
2264
|
+
} catch {
|
|
2265
|
+
verified = false;
|
|
2266
|
+
}
|
|
2267
|
+
if (!verified || delegateSigner !== source.account || prehash.depositor !== source.account) {
|
|
2268
|
+
throw new Error("sender_auth: deposit signature does not recover to source.account");
|
|
2269
|
+
}
|
|
2270
|
+
const deadlineSec = Number(prehash.deadline);
|
|
2271
|
+
(0, utils_js_1.assertToken)(prehash.mint, source.asset, idAddr);
|
|
2272
|
+
(0, utils_js_1.assertAmountMatches)(prehash.amount, expected.maxSourceAmount);
|
|
2273
|
+
(0, utils_js_1.assertRolePairComplete)(expected.reserver, expected.releaser);
|
|
2274
|
+
if (expected.reserver !== void 0 && expected.releaser !== void 0) {
|
|
2275
|
+
(0, utils_js_1.assertWitnessRoles)(prehash.reserver, prehash.releaser, expected.reserver, expected.releaser, idAddr);
|
|
2276
|
+
}
|
|
2277
|
+
return {
|
|
2278
|
+
amount: prehash.amount,
|
|
2279
|
+
deadlineSec,
|
|
2280
|
+
permit: {
|
|
2281
|
+
scheme: "SOLANA",
|
|
2282
|
+
token: prehash.mint,
|
|
2283
|
+
amount: prehash.amount,
|
|
2284
|
+
deadlineSec,
|
|
2285
|
+
reserver: prehash.reserver,
|
|
2286
|
+
releaser: prehash.releaser,
|
|
2287
|
+
depositor: prehash.depositor
|
|
2288
|
+
}
|
|
2289
|
+
};
|
|
2290
|
+
}
|
|
2291
|
+
};
|
|
2292
|
+
function secretKeyFromPrivate2(privateKey) {
|
|
2293
|
+
if (/^[0-9a-fA-F]{64}$/.test(privateKey)) {
|
|
2294
|
+
const seed = new Uint8Array(32);
|
|
2295
|
+
for (let i = 0; i < 32; i++) {
|
|
2296
|
+
seed[i] = parseInt(privateKey.substring(i * 2, i * 2 + 2), 16);
|
|
2297
|
+
}
|
|
2298
|
+
return tweetnacl_1.default.sign.keyPair.fromSeed(seed).secretKey;
|
|
2299
|
+
}
|
|
2300
|
+
const decoded = bs58_1.default.decode(privateKey);
|
|
2301
|
+
if (decoded.length === 64)
|
|
2302
|
+
return decoded;
|
|
2303
|
+
if (decoded.length === 32)
|
|
2304
|
+
return tweetnacl_1.default.sign.keyPair.fromSeed(decoded).secretKey;
|
|
2305
|
+
throw new Error(`Invalid Solana private key length: expected 32 or 64 bytes, got ${decoded.length}`);
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
});
|
|
2309
|
+
|
|
2310
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/adapters/index.js
|
|
2311
|
+
var require_adapters = __commonJS({
|
|
2312
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/adapters/index.js"(exports2) {
|
|
2313
|
+
"use strict";
|
|
2314
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2315
|
+
exports2.getChainAdapter = getChainAdapter2;
|
|
2316
|
+
var chain_id_js_1 = require_chain_id2();
|
|
2317
|
+
var evm_js_1 = require_evm();
|
|
2318
|
+
var tron_js_1 = require_tron();
|
|
2319
|
+
var solana_js_1 = require_solana();
|
|
2320
|
+
var adapters2 = {
|
|
2321
|
+
eip155: evm_js_1.evmAdapter,
|
|
2322
|
+
tron: tron_js_1.tronAdapter,
|
|
2323
|
+
solana: solana_js_1.solanaAdapter
|
|
2324
|
+
};
|
|
2325
|
+
function getChainAdapter2(caip2) {
|
|
2326
|
+
const adapter = adapters2[(0, chain_id_js_1.namespaceOf)(caip2)];
|
|
2327
|
+
if (!adapter) {
|
|
2328
|
+
throw new Error(`sender_auth: unsupported source chain '${caip2}'`);
|
|
2329
|
+
}
|
|
2330
|
+
return adapter;
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
});
|
|
2334
|
+
|
|
2335
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/verify.js
|
|
2336
|
+
var require_verify = __commonJS({
|
|
2337
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/verify.js"(exports2) {
|
|
2338
|
+
"use strict";
|
|
2339
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2340
|
+
exports2.verifyPaymentRequest = verifyPaymentRequest;
|
|
2341
|
+
var index_js_1 = require_adapters();
|
|
2342
|
+
function parseSourceAsset(assetIdentifier) {
|
|
2343
|
+
const parts = assetIdentifier.split("/");
|
|
2344
|
+
const nsParts = parts[1]?.split(":");
|
|
2345
|
+
if (parts.length < 2 || !nsParts || nsParts.length < 2 || !nsParts[1]) {
|
|
2346
|
+
throw new Error(`sender_auth: invalid source asset "${assetIdentifier}"`);
|
|
2347
|
+
}
|
|
2348
|
+
return { network: parts[0], asset: nsParts[1] };
|
|
2349
|
+
}
|
|
2350
|
+
function verifyPaymentRequest(request2, expected = {}) {
|
|
2351
|
+
const senderAuth = request2.sender_auth;
|
|
2352
|
+
if (!senderAuth?.signed_messages?.length) {
|
|
2353
|
+
throw new Error("sender_auth: request has no signed_messages to verify");
|
|
2354
|
+
}
|
|
2355
|
+
if (!request2.source) {
|
|
2356
|
+
throw new Error("sender_auth: request has no source");
|
|
2357
|
+
}
|
|
2358
|
+
const requestSource = parseSourceAsset(request2.source.asset_identifier);
|
|
2359
|
+
const { sourceAsset, network: networkOverride, maxSourceAmount: amountOverride, ...scheme } = expected;
|
|
2360
|
+
const network = networkOverride ?? requestSource.network;
|
|
2361
|
+
const asset = sourceAsset ?? requestSource.asset;
|
|
2362
|
+
const maxSourceAmount = amountOverride ?? request2.max_source_amount ?? "0";
|
|
2363
|
+
const source = { network, asset, account: request2.source.account };
|
|
2364
|
+
const perMessage = { ...scheme, maxSourceAmount };
|
|
2365
|
+
const adapter = (0, index_js_1.getChainAdapter)(network);
|
|
2366
|
+
const results = senderAuth.signed_messages.map((m) => adapter.recoverAndVerify(m, source, perMessage));
|
|
2367
|
+
return { results, recoveredAccount: source.account };
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
});
|
|
2371
|
+
|
|
2372
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/signer.js
|
|
2373
|
+
var require_signer = __commonJS({
|
|
2374
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/signer.js"(exports2) {
|
|
2375
|
+
"use strict";
|
|
2376
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2377
|
+
exports2.localKeySigner = localKeySigner2;
|
|
2378
|
+
var index_js_1 = require_adapters();
|
|
2379
|
+
function localKeySigner2(network, privateKey) {
|
|
2380
|
+
const adapter = (0, index_js_1.getChainAdapter)(network);
|
|
2381
|
+
return {
|
|
2382
|
+
async sign(signedMessage) {
|
|
2383
|
+
const signature = await adapter.sign(signedMessage, privateKey);
|
|
2384
|
+
const delegateSigner = adapter.deriveDelegateSigner?.(privateKey);
|
|
2385
|
+
return delegateSigner !== void 0 ? { signature, delegateSigner } : { signature };
|
|
2386
|
+
}
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
});
|
|
2391
|
+
|
|
2392
|
+
// ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/index.js
|
|
2393
|
+
var require_dist4 = __commonJS({
|
|
2394
|
+
"../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist/index.js"(exports2) {
|
|
2395
|
+
"use strict";
|
|
2396
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
2397
|
+
if (k2 === void 0) k2 = k;
|
|
2398
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
2399
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
2400
|
+
desc = { enumerable: true, get: function() {
|
|
2401
|
+
return m[k];
|
|
2402
|
+
} };
|
|
2403
|
+
}
|
|
2404
|
+
Object.defineProperty(o, k2, desc);
|
|
2405
|
+
}) : (function(o, m, k, k2) {
|
|
2406
|
+
if (k2 === void 0) k2 = k;
|
|
2407
|
+
o[k2] = m[k];
|
|
2408
|
+
}));
|
|
2409
|
+
var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {
|
|
2410
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
2411
|
+
};
|
|
2412
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2413
|
+
exports2.localKeySigner = exports2.SignerMismatchError = exports2.RecoveryFailedError = exports2.MalformedPrehashError = exports2.verifyPaymentRequest = exports2.getChainAdapter = void 0;
|
|
2414
|
+
__exportStar(require_types(), exports2);
|
|
2415
|
+
__exportStar(require_utils(), exports2);
|
|
2416
|
+
__exportStar(require_chain_id2(), exports2);
|
|
2417
|
+
var index_js_1 = require_adapters();
|
|
2418
|
+
Object.defineProperty(exports2, "getChainAdapter", { enumerable: true, get: function() {
|
|
2419
|
+
return index_js_1.getChainAdapter;
|
|
2420
|
+
} });
|
|
2421
|
+
var verify_js_1 = require_verify();
|
|
2422
|
+
Object.defineProperty(exports2, "verifyPaymentRequest", { enumerable: true, get: function() {
|
|
2423
|
+
return verify_js_1.verifyPaymentRequest;
|
|
2424
|
+
} });
|
|
2425
|
+
var errors_js_1 = require_errors();
|
|
2426
|
+
Object.defineProperty(exports2, "MalformedPrehashError", { enumerable: true, get: function() {
|
|
2427
|
+
return errors_js_1.MalformedPrehashError;
|
|
2428
|
+
} });
|
|
2429
|
+
Object.defineProperty(exports2, "RecoveryFailedError", { enumerable: true, get: function() {
|
|
2430
|
+
return errors_js_1.RecoveryFailedError;
|
|
2431
|
+
} });
|
|
2432
|
+
Object.defineProperty(exports2, "SignerMismatchError", { enumerable: true, get: function() {
|
|
2433
|
+
return errors_js_1.SignerMismatchError;
|
|
2434
|
+
} });
|
|
2435
|
+
var signer_js_1 = require_signer();
|
|
2436
|
+
Object.defineProperty(exports2, "localKeySigner", { enumerable: true, get: function() {
|
|
2437
|
+
return signer_js_1.localKeySigner;
|
|
2438
|
+
} });
|
|
2439
|
+
}
|
|
2440
|
+
});
|
|
2441
|
+
|
|
1700
2442
|
// ../key-management/common/typescript/dist/errors.js
|
|
1701
|
-
var
|
|
2443
|
+
var require_errors3 = __commonJS({
|
|
1702
2444
|
"../key-management/common/typescript/dist/errors.js"(exports2) {
|
|
1703
2445
|
"use strict";
|
|
1704
2446
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -1762,7 +2504,7 @@ var require_errors2 = __commonJS({
|
|
|
1762
2504
|
});
|
|
1763
2505
|
|
|
1764
2506
|
// ../key-management/common/typescript/dist/types.js
|
|
1765
|
-
var
|
|
2507
|
+
var require_types2 = __commonJS({
|
|
1766
2508
|
"../key-management/common/typescript/dist/types.js"(exports2) {
|
|
1767
2509
|
"use strict";
|
|
1768
2510
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -1794,7 +2536,7 @@ var require_policy = __commonJS({
|
|
|
1794
2536
|
});
|
|
1795
2537
|
|
|
1796
2538
|
// ../key-management/common/typescript/dist/index.js
|
|
1797
|
-
var
|
|
2539
|
+
var require_dist5 = __commonJS({
|
|
1798
2540
|
"../key-management/common/typescript/dist/index.js"(exports2) {
|
|
1799
2541
|
"use strict";
|
|
1800
2542
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -1814,8 +2556,8 @@ var require_dist4 = __commonJS({
|
|
|
1814
2556
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
1815
2557
|
};
|
|
1816
2558
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1817
|
-
__exportStar(
|
|
1818
|
-
__exportStar(
|
|
2559
|
+
__exportStar(require_errors3(), exports2);
|
|
2560
|
+
__exportStar(require_types2(), exports2);
|
|
1819
2561
|
__exportStar(require_policy(), exports2);
|
|
1820
2562
|
}
|
|
1821
2563
|
});
|
|
@@ -1936,7 +2678,7 @@ var require_client = __commonJS({
|
|
|
1936
2678
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1937
2679
|
exports2.TurnkeyClient = void 0;
|
|
1938
2680
|
var promises_1 = require("timers/promises");
|
|
1939
|
-
var km_core_1 =
|
|
2681
|
+
var km_core_1 = require_dist5();
|
|
1940
2682
|
var constants_1 = require_constants();
|
|
1941
2683
|
var logger_1 = require_logger();
|
|
1942
2684
|
var meter_1 = require_meter();
|
|
@@ -2297,7 +3039,7 @@ var require_signer_base = __commonJS({
|
|
|
2297
3039
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2298
3040
|
exports2.resolveTurnkeyAccountAddress = resolveTurnkeyAccountAddress;
|
|
2299
3041
|
var promises_1 = require("timers/promises");
|
|
2300
|
-
var km_core_1 =
|
|
3042
|
+
var km_core_1 = require_dist5();
|
|
2301
3043
|
var constants_1 = require_constants();
|
|
2302
3044
|
var DISCOVERY_BACKOFF_MS = constants_1.TURNKEY_RETRY_BACKOFF_MS;
|
|
2303
3045
|
async function resolveTurnkeyAccountAddress(deps, addressFormat) {
|
|
@@ -2355,7 +3097,7 @@ var require_secp256k1_helpers = __commonJS({
|
|
|
2355
3097
|
exports2.signSecp256k1PreimageAndVerify = signSecp256k1PreimageAndVerify;
|
|
2356
3098
|
exports2.bytesFromHexOrBytes = bytesFromHexOrBytes;
|
|
2357
3099
|
var ethers_1 = require("ethers");
|
|
2358
|
-
var km_core_1 =
|
|
3100
|
+
var km_core_1 = require_dist5();
|
|
2359
3101
|
async function signSecp256k1PreimageAndVerify(client, signWith, preimage, expectedEvmAddrLower) {
|
|
2360
3102
|
const preimageHex = (0, ethers_1.hexlify)(preimage).slice(2);
|
|
2361
3103
|
const { r, s, v } = await client.signRawPayload({
|
|
@@ -2388,13 +3130,13 @@ var require_secp256k1_helpers = __commonJS({
|
|
|
2388
3130
|
});
|
|
2389
3131
|
|
|
2390
3132
|
// ../key-management/providers/turnkey/typescript/dist/chains/evm.js
|
|
2391
|
-
var
|
|
3133
|
+
var require_evm2 = __commonJS({
|
|
2392
3134
|
"../key-management/providers/turnkey/typescript/dist/chains/evm.js"(exports2) {
|
|
2393
3135
|
"use strict";
|
|
2394
3136
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2395
3137
|
exports2.TurnkeyEvmSigner = void 0;
|
|
2396
3138
|
var ethers_1 = require("ethers");
|
|
2397
|
-
var km_core_1 =
|
|
3139
|
+
var km_core_1 = require_dist5();
|
|
2398
3140
|
var signer_base_1 = require_signer_base();
|
|
2399
3141
|
var secp256k1_helpers_1 = require_secp256k1_helpers();
|
|
2400
3142
|
var ADDRESS_FORMAT = "ADDRESS_FORMAT_ETHEREUM";
|
|
@@ -2511,7 +3253,7 @@ ${msgBytes.length}`);
|
|
|
2511
3253
|
});
|
|
2512
3254
|
|
|
2513
3255
|
// ../key-management/providers/turnkey/typescript/dist/chains/solana.js
|
|
2514
|
-
var
|
|
3256
|
+
var require_solana2 = __commonJS({
|
|
2515
3257
|
"../key-management/providers/turnkey/typescript/dist/chains/solana.js"(exports2) {
|
|
2516
3258
|
"use strict";
|
|
2517
3259
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -2558,7 +3300,7 @@ var require_solana = __commonJS({
|
|
|
2558
3300
|
exports2.TurnkeySolanaSigner = void 0;
|
|
2559
3301
|
var web3_js_1 = require("@solana/web3.js");
|
|
2560
3302
|
var bs58_1 = __importDefault(require("bs58"));
|
|
2561
|
-
var km_core_1 =
|
|
3303
|
+
var km_core_1 = require_dist5();
|
|
2562
3304
|
var signer_base_1 = require_signer_base();
|
|
2563
3305
|
var ADDRESS_FORMAT = "ADDRESS_FORMAT_SOLANA";
|
|
2564
3306
|
var TurnkeySolanaSigner2 = class {
|
|
@@ -2643,7 +3385,7 @@ var require_solana = __commonJS({
|
|
|
2643
3385
|
});
|
|
2644
3386
|
|
|
2645
3387
|
// ../key-management/providers/turnkey/typescript/dist/chains/tron.js
|
|
2646
|
-
var
|
|
3388
|
+
var require_tron2 = __commonJS({
|
|
2647
3389
|
"../key-management/providers/turnkey/typescript/dist/chains/tron.js"(exports2) {
|
|
2648
3390
|
"use strict";
|
|
2649
3391
|
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
@@ -2655,7 +3397,7 @@ var require_tron = __commonJS({
|
|
|
2655
3397
|
var bs58_1 = __importDefault(require("bs58"));
|
|
2656
3398
|
var ethers_1 = require("ethers");
|
|
2657
3399
|
var node_crypto_1 = require("crypto");
|
|
2658
|
-
var km_core_1 =
|
|
3400
|
+
var km_core_1 = require_dist5();
|
|
2659
3401
|
var signer_base_1 = require_signer_base();
|
|
2660
3402
|
var secp256k1_helpers_1 = require_secp256k1_helpers();
|
|
2661
3403
|
var ADDRESS_FORMAT = "ADDRESS_FORMAT_TRON";
|
|
@@ -2795,9 +3537,20 @@ var require_sub_organizations = __commonJS({
|
|
|
2795
3537
|
exports2.listSubOrganizations = listSubOrganizations;
|
|
2796
3538
|
exports2.deleteSubOrganization = deleteSubOrganization;
|
|
2797
3539
|
async function createSubOrganization(client, input) {
|
|
3540
|
+
const rootUsers = input.rootUsers.map((u) => ({
|
|
3541
|
+
userName: u.userName,
|
|
3542
|
+
...u.userEmail ? { userEmail: u.userEmail } : {},
|
|
3543
|
+
apiKeys: (u.apiKeys ?? []).map((k) => ({
|
|
3544
|
+
apiKeyName: k.apiKeyName,
|
|
3545
|
+
publicKey: k.publicKey,
|
|
3546
|
+
curveType: k.curveType ?? "API_KEY_CURVE_P256"
|
|
3547
|
+
})),
|
|
3548
|
+
authenticators: u.authenticators ?? [],
|
|
3549
|
+
oauthProviders: []
|
|
3550
|
+
}));
|
|
2798
3551
|
const params = {
|
|
2799
3552
|
subOrganizationName: input.subOrganizationName,
|
|
2800
|
-
rootUsers
|
|
3553
|
+
rootUsers,
|
|
2801
3554
|
rootQuorumThreshold: input.rootQuorumThreshold,
|
|
2802
3555
|
wallet: input.wallet ? {
|
|
2803
3556
|
walletName: input.wallet.walletName,
|
|
@@ -2818,8 +3571,8 @@ var require_sub_organizations = __commonJS({
|
|
|
2818
3571
|
const out = await client.query("/public/v1/query/list_suborgs");
|
|
2819
3572
|
return (out.organizationIds ?? []).map((id) => ({ subOrganizationId: id }));
|
|
2820
3573
|
}
|
|
2821
|
-
async function deleteSubOrganization(client,
|
|
2822
|
-
await client.executeActivity("ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION", "delete_sub_organization", {
|
|
3574
|
+
async function deleteSubOrganization(client, opts = {}) {
|
|
3575
|
+
await client.executeActivity("ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION", "delete_sub_organization", { deleteWithoutExport: opts.deleteWithoutExport ?? false });
|
|
2823
3576
|
}
|
|
2824
3577
|
}
|
|
2825
3578
|
});
|
|
@@ -3299,6 +4052,19 @@ var require_sender_policies = __commonJS({
|
|
|
3299
4052
|
condition: `activity.type == 'ACTIVITY_TYPE_SIGN_TRANSACTION_V2' && solana.tx.instructions.all(i, i.program_key in [${list}])`,
|
|
3300
4053
|
notes: "Sender Solana deposit txs invoke ComputeBudget + Ed25519Program + Atum escrow only."
|
|
3301
4054
|
});
|
|
4055
|
+
const solCap = extras.solanaMaxNativeValue ?? "10000000";
|
|
4056
|
+
policies.push({
|
|
4057
|
+
policyName: `maxNativeValue (${chain.chainId})`,
|
|
4058
|
+
effect: "EFFECT_DENY",
|
|
4059
|
+
condition: `activity.type == 'ACTIVITY_TYPE_SIGN_TRANSACTION_V2' && solana.tx.transfers.any(t, t.amount > ${solCap})`,
|
|
4060
|
+
notes: "Caps native SOL (lamports); default 10,000,000 (0.01 SOL) ATA-rent headroom."
|
|
4061
|
+
});
|
|
4062
|
+
policies.push({
|
|
4063
|
+
policyName: `denySplTransfers (${chain.chainId})`,
|
|
4064
|
+
effect: "EFFECT_DENY",
|
|
4065
|
+
condition: `activity.type == 'ACTIVITY_TYPE_SIGN_TRANSACTION_V2' && solana.tx.spl_transfers.any(t, !(t.to in []))`,
|
|
4066
|
+
notes: "Denies all top-level SPL transfers; the sender moves tokens only via escrow CPI."
|
|
4067
|
+
});
|
|
3302
4068
|
}
|
|
3303
4069
|
}
|
|
3304
4070
|
policies.push({
|
|
@@ -3419,7 +4185,7 @@ var require_extras_policies = __commonJS({
|
|
|
3419
4185
|
validateAddressMap(obj.allowedTrc20Recipients, "allowedTrc20Recipients", TRON_ADDRESS, source);
|
|
3420
4186
|
}
|
|
3421
4187
|
if (obj.allowedSplRecipients != null) {
|
|
3422
|
-
validateAddressMap(obj.allowedSplRecipients, "allowedSplRecipients", /^[1-9A-HJ-NP-Za-km-z]{32,44}$/, source);
|
|
4188
|
+
validateAddressMap(obj.allowedSplRecipients, "allowedSplRecipients", /^[1-9A-HJ-NP-Za-km-z]{32,44}$/, source, true);
|
|
3423
4189
|
}
|
|
3424
4190
|
if (obj.evmCaps != null) {
|
|
3425
4191
|
validateCapMap(obj.evmCaps, "evmCaps", ["maxGasLimit", "maxFeePerGasWei"], source);
|
|
@@ -3450,12 +4216,12 @@ var require_extras_policies = __commonJS({
|
|
|
3450
4216
|
}
|
|
3451
4217
|
}
|
|
3452
4218
|
}
|
|
3453
|
-
function validateAddressMap(map, field, pattern, source) {
|
|
4219
|
+
function validateAddressMap(map, field, pattern, source, allowEmpty = false) {
|
|
3454
4220
|
if (typeof map !== "object" || map == null || Array.isArray(map)) {
|
|
3455
4221
|
throw new Error(`${source}: ${field} must be a map keyed by chain name.`);
|
|
3456
4222
|
}
|
|
3457
4223
|
for (const [chainKey, list] of Object.entries(map)) {
|
|
3458
|
-
if (!Array.isArray(list) || list.length === 0) {
|
|
4224
|
+
if (!Array.isArray(list) || !allowEmpty && list.length === 0) {
|
|
3459
4225
|
throw new Error(`${source}: ${field}.${chainKey} must be a non-empty list of addresses.`);
|
|
3460
4226
|
}
|
|
3461
4227
|
for (const addr of list) {
|
|
@@ -3530,6 +4296,10 @@ var require_extras_policies = __commonJS({
|
|
|
3530
4296
|
const jobs = [];
|
|
3531
4297
|
for (const [chainKey, recipients] of Object.entries(extras.allowedSplRecipients)) {
|
|
3532
4298
|
const chainId = resolveChainId("allowedSplRecipients", chainKey, "solana:");
|
|
4299
|
+
if (recipients.length === 0) {
|
|
4300
|
+
out.push(buildSplRecipientPolicy(chainId, []));
|
|
4301
|
+
continue;
|
|
4302
|
+
}
|
|
3533
4303
|
const mints = ctx.solanaMintsByChainKey[chainKey] ?? [];
|
|
3534
4304
|
if (mints.length === 0) {
|
|
3535
4305
|
throw new Error(`allowedSplRecipients.${chainKey} requires the Solana chain "${chainKey}" to expose at least one asset mint; got 0.`);
|
|
@@ -3597,7 +4367,7 @@ var require_extras_policies = __commonJS({
|
|
|
3597
4367
|
policyName: `allowedSplRecipients (${chainId})`,
|
|
3598
4368
|
effect: "EFFECT_DENY",
|
|
3599
4369
|
condition: `activity.type == 'ACTIVITY_TYPE_SIGN_TRANSACTION_V2' && solana.tx.spl_transfers.any(t, !(t.to in [${list}]))`,
|
|
3600
|
-
notes: "Denies any top-level SPL transfer to a destination ATA outside the allowlist."
|
|
4370
|
+
notes: allowedAtas.length === 0 ? "Denies ALL top-level SPL transfers (empty allowlist \u2014 no destination is permitted)." : "Denies any top-level SPL transfer to a destination ATA outside the allowlist."
|
|
3601
4371
|
};
|
|
3602
4372
|
}
|
|
3603
4373
|
}
|
|
@@ -3675,7 +4445,7 @@ var require_admin = __commonJS({
|
|
|
3675
4445
|
});
|
|
3676
4446
|
|
|
3677
4447
|
// ../key-management/providers/turnkey/typescript/dist/index.js
|
|
3678
|
-
var
|
|
4448
|
+
var require_dist6 = __commonJS({
|
|
3679
4449
|
"../key-management/providers/turnkey/typescript/dist/index.js"(exports2) {
|
|
3680
4450
|
"use strict";
|
|
3681
4451
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -3730,15 +4500,15 @@ var require_dist5 = __commonJS({
|
|
|
3730
4500
|
Object.defineProperty(exports2, "noopMeter", { enumerable: true, get: function() {
|
|
3731
4501
|
return meter_1.noopMeter;
|
|
3732
4502
|
} });
|
|
3733
|
-
var evm_1 =
|
|
4503
|
+
var evm_1 = require_evm2();
|
|
3734
4504
|
Object.defineProperty(exports2, "TurnkeyEvmSigner", { enumerable: true, get: function() {
|
|
3735
4505
|
return evm_1.TurnkeyEvmSigner;
|
|
3736
4506
|
} });
|
|
3737
|
-
var solana_1 =
|
|
4507
|
+
var solana_1 = require_solana2();
|
|
3738
4508
|
Object.defineProperty(exports2, "TurnkeySolanaSigner", { enumerable: true, get: function() {
|
|
3739
4509
|
return solana_1.TurnkeySolanaSigner;
|
|
3740
4510
|
} });
|
|
3741
|
-
var tron_1 =
|
|
4511
|
+
var tron_1 = require_tron2();
|
|
3742
4512
|
Object.defineProperty(exports2, "TurnkeyTronSigner", { enumerable: true, get: function() {
|
|
3743
4513
|
return tron_1.TurnkeyTronSigner;
|
|
3744
4514
|
} });
|
|
@@ -3853,7 +4623,7 @@ var import_turnkey_signer, TURNKEY_API_URL, DEFAULTS;
|
|
|
3853
4623
|
var init_turnkey_impl = __esm({
|
|
3854
4624
|
"src/signers/turnkey-impl.ts"() {
|
|
3855
4625
|
"use strict";
|
|
3856
|
-
import_turnkey_signer = __toESM(
|
|
4626
|
+
import_turnkey_signer = __toESM(require_dist6());
|
|
3857
4627
|
TURNKEY_API_URL = "https://api.turnkey.com";
|
|
3858
4628
|
DEFAULTS = {
|
|
3859
4629
|
concurrencyLimit: 10,
|
|
@@ -3910,14 +4680,13 @@ __export(index_exports, {
|
|
|
3910
4680
|
HealthService: () => HealthService,
|
|
3911
4681
|
Interceptors: () => Interceptors,
|
|
3912
4682
|
MAX_VALID_SLOT: () => import_solana_escrow_encoding.MAX_VALID_SLOT,
|
|
3913
|
-
OpenAPI: () =>
|
|
4683
|
+
OpenAPI: () => OpenAPI2,
|
|
3914
4684
|
PAYMENT_REQUEST_VERSION: () => PAYMENT_REQUEST_VERSION,
|
|
3915
4685
|
PERMIT2_CONTRACT_ADDRESS: () => import_evm_escrow_encoding.PERMIT2_CONTRACT_ADDRESS,
|
|
3916
4686
|
PaymentGatewayClient: () => PaymentGatewayClient2,
|
|
3917
4687
|
PaymentsService: () => PaymentsService,
|
|
3918
4688
|
QuoteRequestsService: () => QuoteRequestsService,
|
|
3919
4689
|
REPLAY_HORIZON_SECS: () => REPLAY_HORIZON_SECS,
|
|
3920
|
-
RawSenderSigner: () => RawSenderSigner,
|
|
3921
4690
|
TOTAL_BUCKETS: () => TOTAL_BUCKETS,
|
|
3922
4691
|
TurnkeySenderSigner: () => TurnkeySenderSigner,
|
|
3923
4692
|
base58ToBytes: () => base58ToBytes,
|
|
@@ -3931,11 +4700,13 @@ __export(index_exports, {
|
|
|
3931
4700
|
encodeU64LE: () => import_solana_escrow_encoding.encodeU64LE,
|
|
3932
4701
|
generateSolanaNonce: () => generateSolanaNonce,
|
|
3933
4702
|
generateSolanaPaymentId: () => generateSolanaPaymentId,
|
|
4703
|
+
getErrorResponse: () => getErrorResponse,
|
|
3934
4704
|
hashPermitWitnessTransferFrom: () => import_evm_escrow_encoding.hashPermitWitnessTransferFrom,
|
|
3935
4705
|
hashRequestId: () => hashRequestId,
|
|
3936
4706
|
hashSolanaDeposit: () => hashSolanaDeposit,
|
|
3937
4707
|
hashTvmPermitWitnessTransferFrom: () => import_tvm_escrow_encoding.hashTvmPermitWitnessTransferFrom,
|
|
3938
4708
|
hexToBytes: () => hexToBytes,
|
|
4709
|
+
isApiError: () => isApiError,
|
|
3939
4710
|
maskChainId: () => import_tvm_escrow_encoding.maskChainId,
|
|
3940
4711
|
normalizeAddress: () => import_tvm_escrow_encoding.normalizeAddress,
|
|
3941
4712
|
resolveTurnkeyAddresses: () => resolveTurnkeyAddresses,
|
|
@@ -3959,7 +4730,7 @@ var Interceptors = class {
|
|
|
3959
4730
|
}
|
|
3960
4731
|
};
|
|
3961
4732
|
var OpenAPI = {
|
|
3962
|
-
BASE: "https://
|
|
4733
|
+
BASE: "https://payment-gw.production-mainnet.atum.xyz",
|
|
3963
4734
|
CREDENTIALS: "include",
|
|
3964
4735
|
ENCODE_PATH: void 0,
|
|
3965
4736
|
HEADERS: void 0,
|
|
@@ -4142,7 +4913,7 @@ var getUrl = (config, options) => {
|
|
|
4142
4913
|
var getFormData = (options) => {
|
|
4143
4914
|
if (options.formData) {
|
|
4144
4915
|
const formData = new FormData();
|
|
4145
|
-
const
|
|
4916
|
+
const process2 = (key, value) => {
|
|
4146
4917
|
if (isString(value) || isBlob(value)) {
|
|
4147
4918
|
formData.append(key, value);
|
|
4148
4919
|
} else {
|
|
@@ -4151,9 +4922,9 @@ var getFormData = (options) => {
|
|
|
4151
4922
|
};
|
|
4152
4923
|
Object.entries(options.formData).filter(([, value]) => value !== void 0 && value !== null).forEach(([key, value]) => {
|
|
4153
4924
|
if (Array.isArray(value)) {
|
|
4154
|
-
value.forEach((v) =>
|
|
4925
|
+
value.forEach((v) => process2(key, v));
|
|
4155
4926
|
} else {
|
|
4156
|
-
|
|
4927
|
+
process2(key, value);
|
|
4157
4928
|
}
|
|
4158
4929
|
});
|
|
4159
4930
|
return formData;
|
|
@@ -4391,7 +5162,11 @@ var PaymentsService = class {
|
|
|
4391
5162
|
mediaType: "application/json",
|
|
4392
5163
|
errors: {
|
|
4393
5164
|
400: "Invalid request",
|
|
4394
|
-
|
|
5165
|
+
401: "Signature or sender authorization could not be verified",
|
|
5166
|
+
403: "Payment declined during counterparty authorization",
|
|
5167
|
+
413: "Payment request too large to process",
|
|
5168
|
+
500: "Internal server error",
|
|
5169
|
+
503: "A dependency is temporarily unavailable"
|
|
4395
5170
|
}
|
|
4396
5171
|
});
|
|
4397
5172
|
}
|
|
@@ -4524,6 +5299,7 @@ var AuthorizationsService = class {
|
|
|
4524
5299
|
errors: {
|
|
4525
5300
|
400: "Invalid payment request",
|
|
4526
5301
|
404: "Counterparty not found (no registration for the resolved DID)",
|
|
5302
|
+
500: "Internal server error",
|
|
4527
5303
|
502: "Counterparty webhook error (HTTP error or connection failure)",
|
|
4528
5304
|
504: "Authorization timed out (counterparty did not respond)"
|
|
4529
5305
|
}
|
|
@@ -4677,7 +5453,7 @@ var HealthService = class {
|
|
|
4677
5453
|
var PaymentGatewayClient = class {
|
|
4678
5454
|
constructor(config, HttpRequest = AxiosHttpRequest) {
|
|
4679
5455
|
this.request = new HttpRequest({
|
|
4680
|
-
BASE: config?.BASE ?? "https://
|
|
5456
|
+
BASE: config?.BASE ?? "https://payment-gw.production-mainnet.atum.xyz",
|
|
4681
5457
|
VERSION: config?.VERSION ?? "1.0.0",
|
|
4682
5458
|
WITH_CREDENTIALS: config?.WITH_CREDENTIALS ?? false,
|
|
4683
5459
|
CREDENTIALS: config?.CREDENTIALS ?? "include",
|
|
@@ -4699,60 +5475,18 @@ var PaymentGatewayClient = class {
|
|
|
4699
5475
|
};
|
|
4700
5476
|
|
|
4701
5477
|
// src/chain-adapters/evm.ts
|
|
4702
|
-
var
|
|
5478
|
+
var import_ethers = require("ethers");
|
|
4703
5479
|
|
|
4704
5480
|
// src/chain-adapters/types.ts
|
|
4705
|
-
var PERMIT_DEADLINE = BigInt(1924991999);
|
|
4706
|
-
function resolvePermitDeadline(deadlineSeconds) {
|
|
4707
|
-
if (deadlineSeconds !== void 0) {
|
|
4708
|
-
return BigInt(Math.floor(Date.now() / 1e3) + deadlineSeconds);
|
|
4709
|
-
}
|
|
4710
|
-
return PERMIT_DEADLINE;
|
|
4711
|
-
}
|
|
4712
|
-
function generatePermitNonce() {
|
|
4713
|
-
const rand = new Uint32Array(1);
|
|
4714
|
-
globalThis.crypto.getRandomValues(rand);
|
|
4715
|
-
return (BigInt(Date.now()) << 32n) + BigInt(rand[0]);
|
|
4716
|
-
}
|
|
4717
5481
|
function assertKeyMatchesSender(matches, sender, derived) {
|
|
4718
5482
|
if (!matches) {
|
|
4719
5483
|
throw new Error(`The private key derives ${derived}, which does not match the sender address ${sender}`);
|
|
4720
5484
|
}
|
|
4721
5485
|
}
|
|
4722
5486
|
|
|
4723
|
-
// src/sender_auth_schemes/evm_permit2.ts
|
|
4724
|
-
var import_ethers = require("ethers");
|
|
4725
|
-
var import_evm_escrow_encoding = __toESM(require_dist());
|
|
4726
|
-
function hashRequestId(requestId) {
|
|
4727
|
-
return (0, import_ethers.keccak256)((0, import_ethers.toUtf8Bytes)(requestId));
|
|
4728
|
-
}
|
|
4729
|
-
|
|
4730
5487
|
// src/chain-adapters/evm.ts
|
|
4731
5488
|
var evmAdapter = {
|
|
4732
5489
|
turnkeyAddressFormat: "ADDRESS_FORMAT_ETHEREUM",
|
|
4733
|
-
async buildAuthMessage({ sourceAsset, fulfillmentAmount, sourceDefaults, deadlineSeconds }) {
|
|
4734
|
-
const sourceChainId = sourceAsset.split("/")[0];
|
|
4735
|
-
const chainIdNum = parseInt(sourceChainId.split(":")[1]);
|
|
4736
|
-
const tokenAddress = sourceAsset.split("/")[1].split(":")[1];
|
|
4737
|
-
const permitParams = {
|
|
4738
|
-
chainId: chainIdNum,
|
|
4739
|
-
verifyingContract: import_evm_escrow_encoding.PERMIT2_CONTRACT_ADDRESS,
|
|
4740
|
-
token: tokenAddress,
|
|
4741
|
-
amount: fulfillmentAmount,
|
|
4742
|
-
spender: sourceDefaults.escrowContract,
|
|
4743
|
-
nonce: generatePermitNonce(),
|
|
4744
|
-
deadline: resolvePermitDeadline(deadlineSeconds),
|
|
4745
|
-
reserver: sourceDefaults.quoteSelector,
|
|
4746
|
-
releaser: sourceDefaults.fulfillmentVerifierAccount
|
|
4747
|
-
};
|
|
4748
|
-
const messagePrehash = (0, import_evm_escrow_encoding.createPermitWitnessTransferFromPrehash)(permitParams);
|
|
4749
|
-
const messageHash = (0, import_evm_escrow_encoding.hashPermitWitnessTransferFrom)(messagePrehash);
|
|
4750
|
-
return {
|
|
4751
|
-
messageScheme: "EVM_PERMIT2",
|
|
4752
|
-
messageHash,
|
|
4753
|
-
messagePrehash: JSON.stringify(messagePrehash)
|
|
4754
|
-
};
|
|
4755
|
-
},
|
|
4756
5490
|
formatPrivateKey(key) {
|
|
4757
5491
|
return key.startsWith("0x") ? key : "0x" + key;
|
|
4758
5492
|
},
|
|
@@ -4763,78 +5497,22 @@ var evmAdapter = {
|
|
|
4763
5497
|
throw new Error("Invalid private key");
|
|
4764
5498
|
}
|
|
4765
5499
|
},
|
|
4766
|
-
/**
|
|
4767
|
-
* Sign the Permit2 PermitWitnessTransferFrom typed data via standard
|
|
4768
|
-
* EIP-712 signing. The prehash is already shaped for direct consumption
|
|
4769
|
-
* by ethers' signTypedData (Permit2 domain has no version/salt; types
|
|
4770
|
-
* omits EIP712Domain since ethers generates that from the domain object).
|
|
4771
|
-
*/
|
|
4772
|
-
async sign(signedMessage, privateKey) {
|
|
4773
|
-
if (!signedMessage.message_prehash) {
|
|
4774
|
-
throw new Error("EVM adapter sign(): signed_messages[i].message_prehash is required");
|
|
4775
|
-
}
|
|
4776
|
-
const prehash = JSON.parse(signedMessage.message_prehash);
|
|
4777
|
-
const wallet = new import_ethers2.ethers.Wallet(privateKey);
|
|
4778
|
-
return wallet.signTypedData(prehash.domain, prehash.types, prehash.message);
|
|
4779
|
-
},
|
|
4780
5500
|
// Called after validatePrivateKey, so ethers.Wallet won't echo a malformed key.
|
|
4781
5501
|
verifyAddressMatchesKey(privateKey, address) {
|
|
4782
|
-
const derived = new
|
|
5502
|
+
const derived = new import_ethers.ethers.Wallet(privateKey).address;
|
|
4783
5503
|
assertKeyMatchesSender(derived.toLowerCase() === address.toLowerCase(), address, derived);
|
|
4784
5504
|
}
|
|
4785
5505
|
};
|
|
4786
5506
|
|
|
4787
5507
|
// src/chain-adapters/tron.ts
|
|
4788
|
-
var
|
|
5508
|
+
var import_ethers2 = require("ethers");
|
|
4789
5509
|
|
|
4790
5510
|
// src/sender_auth_schemes/tron.ts
|
|
4791
|
-
var import_tvm_escrow_encoding = __toESM(
|
|
5511
|
+
var import_tvm_escrow_encoding = __toESM(require_dist());
|
|
4792
5512
|
|
|
4793
5513
|
// src/chain-adapters/tron.ts
|
|
4794
|
-
var CHAIN_ID_MAP = {
|
|
4795
|
-
"shasta": 2494104990,
|
|
4796
|
-
"mainnet": 728126428
|
|
4797
|
-
};
|
|
4798
|
-
var PERMIT2_FALLBACKS = {
|
|
4799
|
-
"tron:shasta": "TPUqJPASUn1zLvbLBgRZ5pBYrx7WSe5ahp",
|
|
4800
|
-
"tron:mainnet": "TJhMXTHQHeQyMD7TcKQFqAePNgG4b31H9m"
|
|
4801
|
-
};
|
|
4802
5514
|
var tronAdapter = {
|
|
4803
5515
|
turnkeyAddressFormat: "ADDRESS_FORMAT_TRON",
|
|
4804
|
-
async buildAuthMessage({ sourceAsset, fulfillmentAmount, sourceDefaults, deadlineSeconds }) {
|
|
4805
|
-
const sourceChainId = sourceAsset.split("/")[0];
|
|
4806
|
-
const chainName = sourceChainId.split(":")[1];
|
|
4807
|
-
const chainIdNum = CHAIN_ID_MAP[chainName];
|
|
4808
|
-
if (!chainIdNum) {
|
|
4809
|
-
throw new Error(`Unsupported Tron chain: ${chainName}`);
|
|
4810
|
-
}
|
|
4811
|
-
const tokenAddress = sourceAsset.split("/")[1].split(":")[1];
|
|
4812
|
-
let permit2Address = sourceDefaults.permit2Contract;
|
|
4813
|
-
if (permit2Address === void 0) {
|
|
4814
|
-
permit2Address = PERMIT2_FALLBACKS[sourceChainId];
|
|
4815
|
-
if (!permit2Address) {
|
|
4816
|
-
throw new Error(`don't know Permit2 address for chain ${sourceChainId}`);
|
|
4817
|
-
}
|
|
4818
|
-
}
|
|
4819
|
-
const tvmParams = {
|
|
4820
|
-
chainId: chainIdNum,
|
|
4821
|
-
permit2Address,
|
|
4822
|
-
tokenAddress,
|
|
4823
|
-
amount: fulfillmentAmount,
|
|
4824
|
-
spenderAddress: sourceDefaults.escrowContract,
|
|
4825
|
-
nonce: generatePermitNonce(),
|
|
4826
|
-
deadline: resolvePermitDeadline(deadlineSeconds),
|
|
4827
|
-
reserverAddress: sourceDefaults.quoteSelector,
|
|
4828
|
-
releaserAddress: sourceDefaults.fulfillmentVerifierAccount
|
|
4829
|
-
};
|
|
4830
|
-
const messagePrehash = (0, import_tvm_escrow_encoding.createTvmPermitWitnessTransferFromPrehash)(tvmParams);
|
|
4831
|
-
const messageHash = (0, import_tvm_escrow_encoding.hashTvmPermitWitnessTransferFrom)(messagePrehash);
|
|
4832
|
-
return {
|
|
4833
|
-
messageScheme: "EVM_PERMIT2",
|
|
4834
|
-
messageHash,
|
|
4835
|
-
messagePrehash: JSON.stringify(messagePrehash)
|
|
4836
|
-
};
|
|
4837
|
-
},
|
|
4838
5516
|
resolveContractOverrides(sourceDefaults) {
|
|
4839
5517
|
return {
|
|
4840
5518
|
quote_selector: (0, import_tvm_escrow_encoding.normalizeAddress)(sourceDefaults.quoteSelector),
|
|
@@ -4854,133 +5532,68 @@ var tronAdapter = {
|
|
|
4854
5532
|
throw new Error("Invalid private key");
|
|
4855
5533
|
}
|
|
4856
5534
|
},
|
|
4857
|
-
/**
|
|
4858
|
-
* Tron uses TIP-712 typed-data — same wire format as EIP-712. The prehash
|
|
4859
|
-
* built by createTvmPermitWitnessTransferFromPrehash is now directly
|
|
4860
|
-
* consumable by `wallet.signTypedData(prehash.domain, prehash.types,
|
|
4861
|
-
* prehash.message)`, but this adapter (an internal SDK helper) stays on the
|
|
4862
|
-
* raw-hash sign for parity with the EVM adapter — e2e tests use ethers
|
|
4863
|
-
* directly when they need the typed-data path.
|
|
4864
|
-
*/
|
|
4865
|
-
async sign(signedMessage, privateKey) {
|
|
4866
|
-
const wallet = new import_ethers3.ethers.Wallet(privateKey.startsWith("0x") ? privateKey : "0x" + privateKey);
|
|
4867
|
-
return wallet.signingKey.sign(signedMessage.message).serialized;
|
|
4868
|
-
},
|
|
4869
5535
|
// Tron addresses are the same secp256k1-derived 20 bytes as EVM. Compare the
|
|
4870
5536
|
// derived hex directly against the canonical sender; do NOT run normalizeAddress
|
|
4871
5537
|
// on the derived side — it strips a leading 41, which would corrupt an address
|
|
4872
5538
|
// whose first byte is 0x41.
|
|
4873
5539
|
verifyAddressMatchesKey(privateKey, address) {
|
|
4874
5540
|
const key = privateKey.startsWith("0x") ? privateKey : "0x" + privateKey;
|
|
4875
|
-
const derived = new
|
|
5541
|
+
const derived = new import_ethers2.ethers.Wallet(key).address;
|
|
4876
5542
|
assertKeyMatchesSender(derived.toLowerCase() === (0, import_tvm_escrow_encoding.normalizeAddress)(address), address, derived);
|
|
4877
5543
|
}
|
|
4878
5544
|
};
|
|
4879
5545
|
|
|
4880
5546
|
// src/chain-adapters/solana.ts
|
|
4881
5547
|
var import_tweetnacl = __toESM(require("tweetnacl"));
|
|
4882
|
-
var import_bs582 = __toESM(require("bs58"));
|
|
4883
|
-
var import_solana_escrow_encoding2 = __toESM(require_dist3());
|
|
4884
|
-
|
|
4885
|
-
// src/sender_auth_schemes/solana.ts
|
|
4886
|
-
var import_ethers4 = require("ethers");
|
|
4887
5548
|
var import_bs58 = __toESM(require("bs58"));
|
|
4888
|
-
var
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
}
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
return (0, import_ethers4.hexlify)(bytes);
|
|
4901
|
-
}
|
|
4902
|
-
function hexToBytes(hex) {
|
|
4903
|
-
return (0, import_ethers4.getBytes)(hex.startsWith("0x") ? hex : "0x" + hex);
|
|
4904
|
-
}
|
|
4905
|
-
function generateSolanaPaymentId(requestId, params) {
|
|
4906
|
-
const depositorBytes = base58ToBytes(params.depositor);
|
|
4907
|
-
const reserverBytes = base58ToBytes(params.reserver);
|
|
4908
|
-
const releaserBytes = base58ToBytes(params.releaser);
|
|
4909
|
-
return (0, import_ethers4.keccak256)((0, import_ethers4.concat)([
|
|
4910
|
-
(0, import_ethers4.toUtf8Bytes)(requestId),
|
|
4911
|
-
(0, import_ethers4.toUtf8Bytes)("deposit"),
|
|
4912
|
-
depositorBytes,
|
|
4913
|
-
(0, import_solana_escrow_encoding.encodeU64LE)(params.amount),
|
|
4914
|
-
reserverBytes,
|
|
4915
|
-
releaserBytes,
|
|
4916
|
-
(0, import_solana_escrow_encoding.encodeU64LE)(params.nonce),
|
|
4917
|
-
(0, import_solana_escrow_encoding.encodeU64LE)(params.issuedAt),
|
|
4918
|
-
(0, import_solana_escrow_encoding.encodeU64LE)(params.deadline)
|
|
4919
|
-
]));
|
|
4920
|
-
}
|
|
4921
|
-
function createSolanaDepositPrehash(paymentId, params) {
|
|
4922
|
-
return {
|
|
4923
|
-
payment_id: paymentId,
|
|
4924
|
-
depositor: params.depositor,
|
|
4925
|
-
mint: params.mint,
|
|
4926
|
-
amount: params.amount.toString(),
|
|
4927
|
-
reserver: params.reserver,
|
|
4928
|
-
releaser: params.releaser,
|
|
4929
|
-
nonce: params.nonce.toString(),
|
|
4930
|
-
issued_at: params.issuedAt.toString(),
|
|
4931
|
-
deadline: params.deadline.toString()
|
|
4932
|
-
};
|
|
4933
|
-
}
|
|
4934
|
-
function hashSolanaDeposit(prehash) {
|
|
4935
|
-
const paymentIdBytes = hexToBytes(prehash.payment_id);
|
|
4936
|
-
const depositorBytes = base58ToBytes(prehash.depositor);
|
|
4937
|
-
const mintBytes = base58ToBytes(prehash.mint);
|
|
4938
|
-
const reserverBytes = base58ToBytes(prehash.reserver);
|
|
4939
|
-
const releaserBytes = base58ToBytes(prehash.releaser);
|
|
4940
|
-
return (0, import_ethers4.keccak256)((0, import_ethers4.concat)([
|
|
4941
|
-
(0, import_ethers4.toUtf8Bytes)("deposit"),
|
|
4942
|
-
paymentIdBytes,
|
|
4943
|
-
depositorBytes,
|
|
4944
|
-
mintBytes,
|
|
4945
|
-
(0, import_solana_escrow_encoding.encodeU64LE)(BigInt(prehash.amount)),
|
|
4946
|
-
reserverBytes,
|
|
4947
|
-
releaserBytes,
|
|
4948
|
-
(0, import_solana_escrow_encoding.encodeU64LE)(BigInt(prehash.nonce)),
|
|
4949
|
-
(0, import_solana_escrow_encoding.encodeU64LE)(BigInt(prehash.issued_at)),
|
|
4950
|
-
(0, import_solana_escrow_encoding.encodeU64LE)(BigInt(prehash.deadline))
|
|
4951
|
-
]));
|
|
4952
|
-
}
|
|
4953
|
-
function generateSolanaNonce() {
|
|
4954
|
-
return (0, import_solana_escrow_encoding.generateNonce)();
|
|
5549
|
+
var solanaAdapter = {
|
|
5550
|
+
turnkeyAddressFormat: "ADDRESS_FORMAT_SOLANA",
|
|
5551
|
+
formatPrivateKey(key) {
|
|
5552
|
+
return key.startsWith("0x") ? key.slice(2) : key;
|
|
5553
|
+
},
|
|
5554
|
+
verifyAddressMatchesKey(privateKey, address) {
|
|
5555
|
+
const derived = deriveSolanaAddress(privateKey);
|
|
5556
|
+
assertKeyMatchesSender(derived === address, address, derived);
|
|
5557
|
+
}
|
|
5558
|
+
};
|
|
5559
|
+
function deriveSolanaAddress(privateKey) {
|
|
5560
|
+
return import_bs58.default.encode(import_tweetnacl.default.sign.keyPair.fromSecretKey(secretKeyFromPrivate(privateKey)).publicKey);
|
|
4955
5561
|
}
|
|
4956
|
-
function
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
5562
|
+
function secretKeyFromPrivate(privateKey) {
|
|
5563
|
+
if (/^[0-9a-fA-F]{64}$/.test(privateKey)) {
|
|
5564
|
+
const seed = new Uint8Array(32);
|
|
5565
|
+
for (let i = 0; i < 32; i++) {
|
|
5566
|
+
seed[i] = parseInt(privateKey.substring(i * 2, i * 2 + 2), 16);
|
|
5567
|
+
}
|
|
5568
|
+
return import_tweetnacl.default.sign.keyPair.fromSeed(seed).secretKey;
|
|
5569
|
+
}
|
|
5570
|
+
const decoded = import_bs58.default.decode(privateKey);
|
|
5571
|
+
if (decoded.length === 64) {
|
|
5572
|
+
return decoded;
|
|
5573
|
+
}
|
|
5574
|
+
if (decoded.length === 32) {
|
|
5575
|
+
return import_tweetnacl.default.sign.keyPair.fromSeed(decoded).secretKey;
|
|
5576
|
+
}
|
|
5577
|
+
throw new Error(`Invalid Solana private key length: expected 32 or 64 bytes, got ${decoded.length}`);
|
|
4964
5578
|
}
|
|
4965
|
-
|
|
4966
|
-
|
|
5579
|
+
|
|
5580
|
+
// src/chain-adapters/index.ts
|
|
5581
|
+
var adapters = {
|
|
5582
|
+
"eip155": evmAdapter,
|
|
5583
|
+
"tron": tronAdapter,
|
|
5584
|
+
"solana": solanaAdapter
|
|
5585
|
+
};
|
|
5586
|
+
function getChainAdapter(sourceChainId) {
|
|
5587
|
+
const prefix = sourceChainId.split(":")[0];
|
|
5588
|
+
const adapter = adapters[prefix];
|
|
5589
|
+
if (!adapter) throw new Error(`Unsupported source chain: ${sourceChainId}`);
|
|
5590
|
+
return adapter;
|
|
4967
5591
|
}
|
|
4968
|
-
function
|
|
4969
|
-
const
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
mint: import_solana_escrow_encoding.Pubkey.fromBase58(prehash.mint),
|
|
4974
|
-
amount: BigInt(prehash.amount),
|
|
4975
|
-
reserver: import_solana_escrow_encoding.Pubkey.fromBase58(prehash.reserver),
|
|
4976
|
-
releaser: import_solana_escrow_encoding.Pubkey.fromBase58(prehash.releaser),
|
|
4977
|
-
nonce: BigInt(prehash.nonce),
|
|
4978
|
-
issuedAt: BigInt(prehash.issued_at),
|
|
4979
|
-
deadline: BigInt(prehash.deadline)
|
|
4980
|
-
},
|
|
4981
|
-
domain
|
|
4982
|
-
);
|
|
4983
|
-
return bytesToHex(hash);
|
|
5592
|
+
function namespaceForTurnkeyAddressFormat(addressFormat) {
|
|
5593
|
+
for (const [namespace, adapter] of Object.entries(adapters)) {
|
|
5594
|
+
if (adapter.turnkeyAddressFormat === addressFormat) return namespace;
|
|
5595
|
+
}
|
|
5596
|
+
return void 0;
|
|
4984
5597
|
}
|
|
4985
5598
|
|
|
4986
5599
|
// src/chain-adapters/solana-clock.ts
|
|
@@ -5050,120 +5663,8 @@ async function resolveSolanaIssuedAt(opts) {
|
|
|
5050
5663
|
return BigInt(Math.floor(Date.now() / 1e3)) - SOLANA_ISSUED_AT_FALLBACK_SKEW_SECS;
|
|
5051
5664
|
}
|
|
5052
5665
|
|
|
5053
|
-
// src/
|
|
5054
|
-
var
|
|
5055
|
-
turnkeyAddressFormat: "ADDRESS_FORMAT_SOLANA",
|
|
5056
|
-
async buildAuthMessage({ sourceAsset, depositor, fulfillmentAmount, requestId, sourceDefaults, solanaRpcUrl, solanaClockReader, solanaLogger }) {
|
|
5057
|
-
const sourceChainId = sourceAsset.split("/")[0];
|
|
5058
|
-
const tokenMint = sourceAsset.split("/")[1].split(":")[1];
|
|
5059
|
-
const nonce = generateSolanaNonce();
|
|
5060
|
-
const issuedAt = await resolveSolanaIssuedAt({
|
|
5061
|
-
sourceChainId,
|
|
5062
|
-
rpcUrlOverride: solanaRpcUrl,
|
|
5063
|
-
reader: solanaClockReader,
|
|
5064
|
-
logger: solanaLogger
|
|
5065
|
-
});
|
|
5066
|
-
const deadline = issuedAt + BigInt(REPLAY_HORIZON_SECS - 8);
|
|
5067
|
-
const solanaParams = {
|
|
5068
|
-
depositor,
|
|
5069
|
-
mint: tokenMint,
|
|
5070
|
-
amount: BigInt(fulfillmentAmount),
|
|
5071
|
-
reserver: sourceDefaults.quoteSelector,
|
|
5072
|
-
releaser: sourceDefaults.fulfillmentVerifierAccount,
|
|
5073
|
-
nonce,
|
|
5074
|
-
issuedAt,
|
|
5075
|
-
deadline,
|
|
5076
|
-
requestId
|
|
5077
|
-
};
|
|
5078
|
-
const paymentId = generateSolanaPaymentIdV3(requestId);
|
|
5079
|
-
const prehash = createSolanaDepositPrehash(paymentId, solanaParams);
|
|
5080
|
-
if (!sourceDefaults.svmSignatureClusterId || sourceDefaults.svmSignatureDomainVersion == null) {
|
|
5081
|
-
throw new Error(
|
|
5082
|
-
"Solana source requires svm_signature_cluster_id and svm_signature_domain_version from payment-gw /defaults (V3 escrow domain separation). Is the gateway on V3?"
|
|
5083
|
-
);
|
|
5084
|
-
}
|
|
5085
|
-
const domain = {
|
|
5086
|
-
clusterId: clusterIdFromName(sourceDefaults.svmSignatureClusterId),
|
|
5087
|
-
signatureDomainVersion: sourceDefaults.svmSignatureDomainVersion,
|
|
5088
|
-
programId: import_solana_escrow_encoding2.Pubkey.fromBase58(sourceDefaults.escrowContract)
|
|
5089
|
-
};
|
|
5090
|
-
const depositHash = hashSolanaDepositV3(prehash, domain);
|
|
5091
|
-
return {
|
|
5092
|
-
messageScheme: "SOLANA",
|
|
5093
|
-
messageHash: depositHash,
|
|
5094
|
-
messagePrehash: JSON.stringify(prehash)
|
|
5095
|
-
};
|
|
5096
|
-
},
|
|
5097
|
-
formatPrivateKey(key) {
|
|
5098
|
-
return key.startsWith("0x") ? key.slice(2) : key;
|
|
5099
|
-
},
|
|
5100
|
-
/**
|
|
5101
|
-
* Solana has no EIP-712-style typed-data standard. The prehash structure
|
|
5102
|
-
* still describes what was hashed (for debugging / wallet UX), but the
|
|
5103
|
-
* canonical signing input is the chain-specific digest already in
|
|
5104
|
-
* signedMessage.message. We sign that with ed25519.
|
|
5105
|
-
*/
|
|
5106
|
-
async sign(signedMessage, privateKey) {
|
|
5107
|
-
const messageBytes = new Uint8Array(Buffer.from(signedMessage.message.replace("0x", ""), "hex"));
|
|
5108
|
-
const secretKey = secretKeyFromPrivate(privateKey);
|
|
5109
|
-
const sig = import_tweetnacl.default.sign.detached(messageBytes, secretKey);
|
|
5110
|
-
return "0x" + Buffer.from(sig).toString("hex");
|
|
5111
|
-
},
|
|
5112
|
-
/**
|
|
5113
|
-
* Solana Ed25519 signatures are not public-key-recoverable (unlike EVM
|
|
5114
|
-
* secp256k1, where ecrecover derives the signer from the signature). The
|
|
5115
|
-
* on-chain Ed25519 verify instruction must therefore be given the signer's
|
|
5116
|
-
* public key explicitly, so we ship it as signed_messages[0].payload.delegate_signer.
|
|
5117
|
-
* In the self-custody CLI flow the signer is the depositor itself, so this
|
|
5118
|
-
* equals source.account.
|
|
5119
|
-
*/
|
|
5120
|
-
deriveDelegateSigner(privateKey) {
|
|
5121
|
-
return deriveSolanaAddress(privateKey);
|
|
5122
|
-
},
|
|
5123
|
-
verifyAddressMatchesKey(privateKey, address) {
|
|
5124
|
-
const derived = deriveSolanaAddress(privateKey);
|
|
5125
|
-
assertKeyMatchesSender(derived === address, address, derived);
|
|
5126
|
-
}
|
|
5127
|
-
};
|
|
5128
|
-
function deriveSolanaAddress(privateKey) {
|
|
5129
|
-
return import_bs582.default.encode(import_tweetnacl.default.sign.keyPair.fromSecretKey(secretKeyFromPrivate(privateKey)).publicKey);
|
|
5130
|
-
}
|
|
5131
|
-
function secretKeyFromPrivate(privateKey) {
|
|
5132
|
-
if (/^[0-9a-fA-F]{64}$/.test(privateKey)) {
|
|
5133
|
-
const seed = new Uint8Array(32);
|
|
5134
|
-
for (let i = 0; i < 32; i++) {
|
|
5135
|
-
seed[i] = parseInt(privateKey.substring(i * 2, i * 2 + 2), 16);
|
|
5136
|
-
}
|
|
5137
|
-
return import_tweetnacl.default.sign.keyPair.fromSeed(seed).secretKey;
|
|
5138
|
-
}
|
|
5139
|
-
const decoded = import_bs582.default.decode(privateKey);
|
|
5140
|
-
if (decoded.length === 64) {
|
|
5141
|
-
return decoded;
|
|
5142
|
-
}
|
|
5143
|
-
if (decoded.length === 32) {
|
|
5144
|
-
return import_tweetnacl.default.sign.keyPair.fromSeed(decoded).secretKey;
|
|
5145
|
-
}
|
|
5146
|
-
throw new Error(`Invalid Solana private key length: expected 32 or 64 bytes, got ${decoded.length}`);
|
|
5147
|
-
}
|
|
5148
|
-
|
|
5149
|
-
// src/chain-adapters/index.ts
|
|
5150
|
-
var adapters = {
|
|
5151
|
-
"eip155": evmAdapter,
|
|
5152
|
-
"tron": tronAdapter,
|
|
5153
|
-
"solana": solanaAdapter
|
|
5154
|
-
};
|
|
5155
|
-
function getChainAdapter(sourceChainId) {
|
|
5156
|
-
const prefix = sourceChainId.split(":")[0];
|
|
5157
|
-
const adapter = adapters[prefix];
|
|
5158
|
-
if (!adapter) throw new Error(`Unsupported source chain: ${sourceChainId}`);
|
|
5159
|
-
return adapter;
|
|
5160
|
-
}
|
|
5161
|
-
function namespaceForTurnkeyAddressFormat(addressFormat) {
|
|
5162
|
-
for (const [namespace, adapter] of Object.entries(adapters)) {
|
|
5163
|
-
if (adapter.turnkeyAddressFormat === addressFormat) return namespace;
|
|
5164
|
-
}
|
|
5165
|
-
return void 0;
|
|
5166
|
-
}
|
|
5666
|
+
// src/index.ts
|
|
5667
|
+
var import_payment_request_sender_auth2 = __toESM(require_dist4());
|
|
5167
5668
|
|
|
5168
5669
|
// src/generated/schemas.gen.ts
|
|
5169
5670
|
var $AuthorizationResult = {
|
|
@@ -5200,15 +5701,33 @@ an error indicating why authorization could not be completed.
|
|
|
5200
5701
|
error_code: {
|
|
5201
5702
|
type: "string",
|
|
5202
5703
|
description: `Machine-readable error code (present when status is error or timeout).
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
itself and have no protobuf equivalent.
|
|
5704
|
+
Counterparty-sourced codes are derived from the error code the
|
|
5705
|
+
Counterparty Gateway publishes. GATEWAY_TIMEOUT, PROOF_INVALID, and
|
|
5706
|
+
PROOF_STALE are payment-gw-specific (no counterparty envelope corresponds).
|
|
5207
5707
|
`,
|
|
5208
5708
|
enum: ["COUNTERPARTY_NOT_FOUND", "COUNTERPARTY_TIMEOUT", "WEBHOOK_ERROR", "WEBHOOK_CONNECTION_ERROR", "INTERNAL_ERROR", "GATEWAY_TIMEOUT", "PROOF_INVALID", "PROOF_STALE"],
|
|
5209
|
-
"x-enum-description": `
|
|
5210
|
-
|
|
5211
|
-
|
|
5709
|
+
"x-enum-description": `COUNTERPARTY_NOT_FOUND, COUNTERPARTY_TIMEOUT, WEBHOOK_ERROR,
|
|
5710
|
+
WEBHOOK_CONNECTION_ERROR, and INTERNAL_ERROR are derived from the
|
|
5711
|
+
error code the Counterparty Gateway publishes.
|
|
5712
|
+
GATEWAY_TIMEOUT is emitted by payment-gw when no authorization
|
|
5713
|
+
response is received within the system-wide timeout \u2014 source unknown
|
|
5714
|
+
(counterparty delay, transport failure, or gateway unavailability).
|
|
5715
|
+
Originator should retry; counterparty-side idempotency prevents PSP re-charge
|
|
5716
|
+
if the original was already processed.
|
|
5717
|
+
|
|
5718
|
+
PROOF_INVALID is emitted when the W3C Data Integrity proof on the
|
|
5719
|
+
beneficiary PSP's AuthorizationResponse fails verification: signature
|
|
5720
|
+
recovery failed, recovered DID does not match the destination DID,
|
|
5721
|
+
response shape is malformed (missing @context / payment_id /
|
|
5722
|
+
counterparty_did / proof), or the suite type is unsupported. The
|
|
5723
|
+
underlying reason cardinality is collapsed so originators see one
|
|
5724
|
+
actionable category.
|
|
5725
|
+
|
|
5726
|
+
PROOF_STALE is emitted when proof.created falls outside the
|
|
5727
|
+
configured freshness window. Originators should retry with a fresh
|
|
5728
|
+
request \u2014 the freshness window closes a replay attack vector where a
|
|
5729
|
+
captured-but-cryptographically-valid proof could otherwise be replayed
|
|
5730
|
+
indefinitely.
|
|
5212
5731
|
`
|
|
5213
5732
|
},
|
|
5214
5733
|
error_message: {
|
|
@@ -5319,8 +5838,11 @@ Leave empty to use the default verifier.
|
|
|
5319
5838
|
endpoint: {
|
|
5320
5839
|
type: "string",
|
|
5321
5840
|
format: "uri",
|
|
5322
|
-
description:
|
|
5323
|
-
|
|
5841
|
+
description: `Origin of the fulfillment verifier service, with no path \u2014 the caller
|
|
5842
|
+
appends the verifier's own API paths. The gateway's \`/defaults\` response
|
|
5843
|
+
supplies the default fulfillment verifier for each chain.
|
|
5844
|
+
`,
|
|
5845
|
+
example: "https://veri-fill.production-testnet.atum.xyz"
|
|
5324
5846
|
}
|
|
5325
5847
|
}
|
|
5326
5848
|
},
|
|
@@ -5695,14 +6217,13 @@ code for programmatic handling and a human-readable message for debugging.
|
|
|
5695
6217
|
properties: {
|
|
5696
6218
|
code: {
|
|
5697
6219
|
type: "string",
|
|
5698
|
-
description: `
|
|
6220
|
+
description: `Public error category in SCREAMING_SNAKE_CASE.
|
|
5699
6221
|
Common codes:
|
|
5700
|
-
- \`
|
|
5701
|
-
- \`
|
|
5702
|
-
- \`
|
|
5703
|
-
- \`FULFILLMENT_TIMEOUT\`: Settlement agent didn't complete in time
|
|
6222
|
+
- \`SETTLEMENT_FAILED\`: The settlement could not be completed
|
|
6223
|
+
- \`NO_ROUTE_AVAILABLE\`: No settlement route was available
|
|
6224
|
+
- \`INTERNAL_ERROR\`: An unexpected error occurred
|
|
5704
6225
|
`,
|
|
5705
|
-
example: "
|
|
6226
|
+
example: "SETTLEMENT_FAILED"
|
|
5706
6227
|
},
|
|
5707
6228
|
message: {
|
|
5708
6229
|
type: "string",
|
|
@@ -6014,7 +6535,7 @@ var $TimelineStep = {
|
|
|
6014
6535
|
properties: {
|
|
6015
6536
|
name: {
|
|
6016
6537
|
type: "string",
|
|
6017
|
-
description: "
|
|
6538
|
+
description: "Internal name of the step (matches settlement event type)",
|
|
6018
6539
|
example: "BID_AWARDED"
|
|
6019
6540
|
},
|
|
6020
6541
|
label: {
|
|
@@ -6061,11 +6582,35 @@ var $TimelineStep = {
|
|
|
6061
6582
|
};
|
|
6062
6583
|
var $ErrorResponse = {
|
|
6063
6584
|
type: "object",
|
|
6585
|
+
description: "Safe, outward-facing error. Derived from an internal error through the shared error catalog. The public code identifies the category and the message is a curated, safe description.",
|
|
6586
|
+
required: ["code", "message"],
|
|
6064
6587
|
properties: {
|
|
6065
|
-
|
|
6588
|
+
code: {
|
|
6589
|
+
type: "string",
|
|
6590
|
+
description: "Public, machine-readable error category in SCREAMING_SNAKE_CASE.",
|
|
6591
|
+
pattern: "^[A-Z][A-Z0-9_]*$",
|
|
6592
|
+
example: "INVALID_SOURCE_ASSET"
|
|
6593
|
+
},
|
|
6594
|
+
message: {
|
|
6595
|
+
type: "string",
|
|
6596
|
+
description: "Curated, safe, human-readable message.",
|
|
6597
|
+
maxLength: 500,
|
|
6598
|
+
example: "The source asset identifier is not a valid CAIP-19 asset."
|
|
6599
|
+
},
|
|
6600
|
+
request_id: {
|
|
6601
|
+
type: "string",
|
|
6602
|
+
description: "Correlation id to quote to support to locate the internal error record.",
|
|
6603
|
+
example: "req_123456789"
|
|
6604
|
+
},
|
|
6605
|
+
docs_url: {
|
|
6606
|
+
type: "string",
|
|
6607
|
+
format: "uri",
|
|
6608
|
+
description: "Link to the documentation page for this public code."
|
|
6609
|
+
},
|
|
6610
|
+
domain: {
|
|
6066
6611
|
type: "string",
|
|
6067
|
-
description: "
|
|
6068
|
-
example: "
|
|
6612
|
+
description: "Originating service domain.",
|
|
6613
|
+
example: "PAYMENT_GATEWAY"
|
|
6069
6614
|
}
|
|
6070
6615
|
}
|
|
6071
6616
|
};
|
|
@@ -6165,8 +6710,11 @@ Leave empty to use the default selector.
|
|
|
6165
6710
|
endpoint: {
|
|
6166
6711
|
type: "string",
|
|
6167
6712
|
format: "uri",
|
|
6168
|
-
description:
|
|
6169
|
-
|
|
6713
|
+
description: `Origin of the fulfillment verifier service, with no path \u2014 the caller
|
|
6714
|
+
appends the verifier's own API paths. The gateway's \`/defaults\` response
|
|
6715
|
+
supplies the default fulfillment verifier for each chain.
|
|
6716
|
+
`,
|
|
6717
|
+
example: "https://veri-fill.production-testnet.atum.xyz"
|
|
6170
6718
|
}
|
|
6171
6719
|
}
|
|
6172
6720
|
},
|
|
@@ -6286,7 +6834,7 @@ bid_award.fulfillment_quote_json.
|
|
|
6286
6834
|
fulfillment_quote: {
|
|
6287
6835
|
type: "object",
|
|
6288
6836
|
description: `The settler-signed FulfillmentQuote (structurally the canonical FulfillmentQuote/v1
|
|
6289
|
-
declaration at https://schemas.atum.
|
|
6837
|
+
declaration at https://schemas.atum.xyz/declarations/FulfillmentQuote/v1), returned
|
|
6290
6838
|
verbatim as an opaque signed document. A client recomputes quote_hash over the returned
|
|
6291
6839
|
bytes and verifies the settler signature, then re-embeds them into
|
|
6292
6840
|
bid_award.fulfillment_quote_json at award. quote_hash is canonicalization-based
|
|
@@ -6312,7 +6860,7 @@ var $AwardedQuote = {
|
|
|
6312
6860
|
fulfillment_quote: {
|
|
6313
6861
|
type: "object",
|
|
6314
6862
|
description: `The settler-signed FulfillmentQuote (structurally the canonical FulfillmentQuote/v1
|
|
6315
|
-
declaration at https://schemas.atum.
|
|
6863
|
+
declaration at https://schemas.atum.xyz/declarations/FulfillmentQuote/v1), returned
|
|
6316
6864
|
verbatim as an opaque signed document. A client recomputes quote_hash over the returned
|
|
6317
6865
|
bytes and verifies the settler signature, then re-embeds them into
|
|
6318
6866
|
bid_award.fulfillment_quote_json at award. quote_hash is canonicalization-based
|
|
@@ -6472,7 +7020,9 @@ the quote-request batch lifecycle and is disjoint from the payment-status enum.
|
|
|
6472
7020
|
enum: ["collecting", "ready", "awarded", "expired"],
|
|
6473
7021
|
description: `Derived batch lifecycle, computed at read time (not a stored state machine). Disjoint
|
|
6474
7022
|
from the payment-status enum returned by the award and payment-status endpoints.
|
|
6475
|
-
- \`collecting\` \u2014 collection window
|
|
7023
|
+
- \`collecting\` \u2014 collection window still open; \`quotes\` lists those collected so far
|
|
7024
|
+
(a quote is awardable from arrival, by its own \`award_deadline\`; more may arrive until
|
|
7025
|
+
\`collection_close\`).
|
|
6476
7026
|
- \`ready\` \u2014 collection complete; none awarded yet; either at least one quote is still
|
|
6477
7027
|
within its \`award_deadline\`, or no settler bid (empty \`quotes\` array \u2014 the successful
|
|
6478
7028
|
"no quotes available" result).
|
|
@@ -6485,7 +7035,7 @@ from the payment-status enum returned by the award and payment-status endpoints.
|
|
|
6485
7035
|
},
|
|
6486
7036
|
quotes: {
|
|
6487
7037
|
type: "array",
|
|
6488
|
-
description: "Collected quotes with award linkage
|
|
7038
|
+
description: "Collected quotes with award linkage \u2014 those collected so far while `collecting`, the full set once the window closes.",
|
|
6489
7039
|
items: {
|
|
6490
7040
|
"$ref": "#/components/schemas/AwardedQuote"
|
|
6491
7041
|
}
|
|
@@ -6624,17 +7174,110 @@ var $AwardAccepted = {
|
|
|
6624
7174
|
}
|
|
6625
7175
|
};
|
|
6626
7176
|
|
|
7177
|
+
// src/errors.ts
|
|
7178
|
+
function isApiError(err) {
|
|
7179
|
+
return err instanceof ApiError;
|
|
7180
|
+
}
|
|
7181
|
+
function getErrorResponse(err) {
|
|
7182
|
+
if (!(err instanceof ApiError)) {
|
|
7183
|
+
return void 0;
|
|
7184
|
+
}
|
|
7185
|
+
const body = err.body;
|
|
7186
|
+
if (body && typeof body === "object" && typeof body.code === "string" && typeof body.message === "string") {
|
|
7187
|
+
return body;
|
|
7188
|
+
}
|
|
7189
|
+
return void 0;
|
|
7190
|
+
}
|
|
7191
|
+
|
|
7192
|
+
// src/sender_auth_schemes/evm_permit2.ts
|
|
7193
|
+
var import_ethers3 = require("ethers");
|
|
7194
|
+
var import_evm_escrow_encoding = __toESM(require_dist2());
|
|
7195
|
+
function hashRequestId(requestId) {
|
|
7196
|
+
return (0, import_ethers3.keccak256)((0, import_ethers3.toUtf8Bytes)(requestId));
|
|
7197
|
+
}
|
|
7198
|
+
|
|
7199
|
+
// src/sender_auth_schemes/solana.ts
|
|
7200
|
+
var import_ethers4 = require("ethers");
|
|
7201
|
+
var import_bs582 = __toESM(require("bs58"));
|
|
7202
|
+
var import_solana_escrow_encoding = __toESM(require_dist3());
|
|
7203
|
+
var REPLAY_HORIZON_SECS = 128;
|
|
7204
|
+
var TOTAL_BUCKETS = 131072;
|
|
7205
|
+
var DEPOSIT_MESSAGE_SIZE = 199;
|
|
7206
|
+
function base58ToBytes(address) {
|
|
7207
|
+
const bytes = import_bs582.default.decode(address);
|
|
7208
|
+
if (bytes.length !== 32) {
|
|
7209
|
+
throw new Error(`Invalid Solana public key length: expected 32 bytes, got ${bytes.length}`);
|
|
7210
|
+
}
|
|
7211
|
+
return bytes;
|
|
7212
|
+
}
|
|
7213
|
+
function bytesToHex(bytes) {
|
|
7214
|
+
return (0, import_ethers4.hexlify)(bytes);
|
|
7215
|
+
}
|
|
7216
|
+
function hexToBytes(hex) {
|
|
7217
|
+
return (0, import_ethers4.getBytes)(hex.startsWith("0x") ? hex : "0x" + hex);
|
|
7218
|
+
}
|
|
7219
|
+
function generateSolanaPaymentId(requestId, params) {
|
|
7220
|
+
const depositorBytes = base58ToBytes(params.depositor);
|
|
7221
|
+
const reserverBytes = base58ToBytes(params.reserver);
|
|
7222
|
+
const releaserBytes = base58ToBytes(params.releaser);
|
|
7223
|
+
return (0, import_ethers4.keccak256)((0, import_ethers4.concat)([
|
|
7224
|
+
(0, import_ethers4.toUtf8Bytes)(requestId),
|
|
7225
|
+
(0, import_ethers4.toUtf8Bytes)("deposit"),
|
|
7226
|
+
depositorBytes,
|
|
7227
|
+
(0, import_solana_escrow_encoding.encodeU64LE)(params.amount),
|
|
7228
|
+
reserverBytes,
|
|
7229
|
+
releaserBytes,
|
|
7230
|
+
(0, import_solana_escrow_encoding.encodeU64LE)(params.nonce),
|
|
7231
|
+
(0, import_solana_escrow_encoding.encodeU64LE)(params.issuedAt),
|
|
7232
|
+
(0, import_solana_escrow_encoding.encodeU64LE)(params.deadline)
|
|
7233
|
+
]));
|
|
7234
|
+
}
|
|
7235
|
+
function createSolanaDepositPrehash(paymentId, params) {
|
|
7236
|
+
return {
|
|
7237
|
+
payment_id: paymentId,
|
|
7238
|
+
depositor: params.depositor,
|
|
7239
|
+
mint: params.mint,
|
|
7240
|
+
amount: params.amount.toString(),
|
|
7241
|
+
reserver: params.reserver,
|
|
7242
|
+
releaser: params.releaser,
|
|
7243
|
+
nonce: params.nonce.toString(),
|
|
7244
|
+
issued_at: params.issuedAt.toString(),
|
|
7245
|
+
deadline: params.deadline.toString()
|
|
7246
|
+
};
|
|
7247
|
+
}
|
|
7248
|
+
function hashSolanaDeposit(prehash) {
|
|
7249
|
+
const paymentIdBytes = hexToBytes(prehash.payment_id);
|
|
7250
|
+
const depositorBytes = base58ToBytes(prehash.depositor);
|
|
7251
|
+
const mintBytes = base58ToBytes(prehash.mint);
|
|
7252
|
+
const reserverBytes = base58ToBytes(prehash.reserver);
|
|
7253
|
+
const releaserBytes = base58ToBytes(prehash.releaser);
|
|
7254
|
+
return (0, import_ethers4.keccak256)((0, import_ethers4.concat)([
|
|
7255
|
+
(0, import_ethers4.toUtf8Bytes)("deposit"),
|
|
7256
|
+
paymentIdBytes,
|
|
7257
|
+
depositorBytes,
|
|
7258
|
+
mintBytes,
|
|
7259
|
+
(0, import_solana_escrow_encoding.encodeU64LE)(BigInt(prehash.amount)),
|
|
7260
|
+
reserverBytes,
|
|
7261
|
+
releaserBytes,
|
|
7262
|
+
(0, import_solana_escrow_encoding.encodeU64LE)(BigInt(prehash.nonce)),
|
|
7263
|
+
(0, import_solana_escrow_encoding.encodeU64LE)(BigInt(prehash.issued_at)),
|
|
7264
|
+
(0, import_solana_escrow_encoding.encodeU64LE)(BigInt(prehash.deadline))
|
|
7265
|
+
]));
|
|
7266
|
+
}
|
|
7267
|
+
function generateSolanaNonce() {
|
|
7268
|
+
return (0, import_solana_escrow_encoding.generateNonce)();
|
|
7269
|
+
}
|
|
7270
|
+
|
|
6627
7271
|
// src/signers/raw.ts
|
|
7272
|
+
var import_payment_request_sender_auth = __toESM(require_dist4());
|
|
6628
7273
|
var RawSenderSigner = class {
|
|
6629
|
-
constructor(
|
|
6630
|
-
|
|
6631
|
-
this.privateKey = privateKey;
|
|
7274
|
+
constructor(network, privateKey) {
|
|
7275
|
+
const adapter = getChainAdapter(network);
|
|
6632
7276
|
adapter.validatePrivateKey?.(privateKey);
|
|
7277
|
+
this.inner = (0, import_payment_request_sender_auth.localKeySigner)(network, adapter.formatPrivateKey(privateKey));
|
|
6633
7278
|
}
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
const delegateSigner = this.adapter.deriveDelegateSigner?.(this.privateKey);
|
|
6637
|
-
return { signature, ...delegateSigner ? { delegateSigner } : {} };
|
|
7279
|
+
sign(signedMessage) {
|
|
7280
|
+
return this.inner.sign(signedMessage);
|
|
6638
7281
|
}
|
|
6639
7282
|
};
|
|
6640
7283
|
|
|
@@ -6675,14 +7318,14 @@ function createSenderSigner(sourceChainId, opts) {
|
|
|
6675
7318
|
}
|
|
6676
7319
|
const adapter = getChainAdapter(sourceChainId);
|
|
6677
7320
|
const privateKey = adapter.formatPrivateKey(opts.privateKey);
|
|
6678
|
-
|
|
7321
|
+
adapter.validatePrivateKey?.(opts.privateKey);
|
|
6679
7322
|
if (opts.pinnedAddress) {
|
|
6680
7323
|
if (!adapter.verifyAddressMatchesKey) {
|
|
6681
7324
|
throw new Error(`pinnedAddress was provided but the ${sourceChainId} adapter cannot verify the key derives it`);
|
|
6682
7325
|
}
|
|
6683
7326
|
adapter.verifyAddressMatchesKey(privateKey, opts.pinnedAddress);
|
|
6684
7327
|
}
|
|
6685
|
-
return
|
|
7328
|
+
return new RawSenderSigner(sourceChainId, opts.privateKey);
|
|
6686
7329
|
}
|
|
6687
7330
|
async function resolveTurnkeyAddresses(cfg) {
|
|
6688
7331
|
const impl = await Promise.resolve().then(() => (init_turnkey_impl(), turnkey_impl_exports));
|
|
@@ -6719,7 +7362,8 @@ async function signPaymentRequest(request2, signer) {
|
|
|
6719
7362
|
}
|
|
6720
7363
|
return request2;
|
|
6721
7364
|
}
|
|
6722
|
-
var defaultGateway = "https://payment-
|
|
7365
|
+
var defaultGateway = "https://payment-gw.production-testnet.atum.xyz";
|
|
7366
|
+
var OpenAPI2 = { ...OpenAPI, BASE: defaultGateway };
|
|
6723
7367
|
var DEFAULT_QUOTE_DEADLINE_SECONDS = 5;
|
|
6724
7368
|
var DEFAULT_FULFILLMENT_DEADLINE_SECONDS = 3600;
|
|
6725
7369
|
var DEFAULT_PAYMENT_QUOTE_DEADLINE_SECONDS = 10;
|
|
@@ -6744,16 +7388,74 @@ function resolveDeadlines(params, defaultQuoteSeconds) {
|
|
|
6744
7388
|
`quoteDeadlineSeconds (${quoteDeadlineSeconds}) must be strictly less than fulfillmentDeadlineSeconds (${fulfillmentDeadlineSeconds}). The gateway rejects a quote_deadline that is not before fulfillment_deadline.`
|
|
6745
7389
|
);
|
|
6746
7390
|
}
|
|
6747
|
-
const now = Date.now();
|
|
7391
|
+
const now = (params.now ?? Date.now)();
|
|
6748
7392
|
return {
|
|
6749
7393
|
quote_deadline: new Date(now + quoteDeadlineSeconds * 1e3).toISOString(),
|
|
6750
7394
|
fulfillment_deadline: new Date(now + fulfillmentDeadlineSeconds * 1e3).toISOString()
|
|
6751
7395
|
};
|
|
6752
7396
|
}
|
|
7397
|
+
async function assemblePaymentRequest(params) {
|
|
7398
|
+
const sourceChainId = params.sourceAsset.split("/")[0];
|
|
7399
|
+
const namespace = sourceChainId.split(":")[0];
|
|
7400
|
+
const adapter = getChainAdapter(sourceChainId);
|
|
7401
|
+
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 }));
|
|
7402
|
+
const auth = await (0, import_payment_request_sender_auth2.getChainAdapter)(sourceChainId).buildAuthMessage({
|
|
7403
|
+
sourceAsset: params.sourceAsset,
|
|
7404
|
+
depositor: params.depositor,
|
|
7405
|
+
// The gateway pins the signed deposit amount to max_source_amount (the cap).
|
|
7406
|
+
maxSourceAmount: params.maxSourceAmount,
|
|
7407
|
+
requestId: params.requestId,
|
|
7408
|
+
sourceDefaults: params.sourceDefaults,
|
|
7409
|
+
deadline: params.deadline,
|
|
7410
|
+
nonce,
|
|
7411
|
+
...namespace === "solana" ? {
|
|
7412
|
+
solanaClockReader: (chainId) => resolveSolanaIssuedAt({
|
|
7413
|
+
sourceChainId: chainId,
|
|
7414
|
+
rpcUrlOverride: params.solanaRpcUrl,
|
|
7415
|
+
reader: params.solanaClockReader
|
|
7416
|
+
})
|
|
7417
|
+
} : {}
|
|
7418
|
+
});
|
|
7419
|
+
const contractOverrides = adapter.resolveContractOverrides?.(params.sourceDefaults);
|
|
7420
|
+
return {
|
|
7421
|
+
version: params.version ?? PAYMENT_REQUEST_VERSION,
|
|
7422
|
+
request_id: params.requestId,
|
|
7423
|
+
source: {
|
|
7424
|
+
asset_identifier: params.sourceAsset,
|
|
7425
|
+
account: params.depositor
|
|
7426
|
+
},
|
|
7427
|
+
destination: [{
|
|
7428
|
+
asset_identifier: params.destinationAsset,
|
|
7429
|
+
account: params.destinationAccount
|
|
7430
|
+
}],
|
|
7431
|
+
fulfillment_amount: params.fulfillmentAmount,
|
|
7432
|
+
max_source_amount: params.maxSourceAmount,
|
|
7433
|
+
quote_deadline: params.quoteDeadline,
|
|
7434
|
+
fulfillment_deadline: params.fulfillmentDeadline,
|
|
7435
|
+
escrow_contract_address: params.sourceDefaults.escrowContract,
|
|
7436
|
+
quote_selector: contractOverrides?.quote_selector ?? params.sourceDefaults.quoteSelector,
|
|
7437
|
+
fulfillment_verifier: contractOverrides?.fulfillment_verifier ?? {
|
|
7438
|
+
account: params.sourceDefaults.fulfillmentVerifierAccount,
|
|
7439
|
+
endpoint: params.sourceDefaults.fulfillmentVerifierEndpoint
|
|
7440
|
+
},
|
|
7441
|
+
fulfillment_proxy: params.fulfillmentProxy,
|
|
7442
|
+
...params.settlerRequirements ? { settler_requirements: params.settlerRequirements } : {},
|
|
7443
|
+
sender_auth: {
|
|
7444
|
+
message_scheme: auth.messageScheme,
|
|
7445
|
+
signed_messages: [{
|
|
7446
|
+
message: auth.messageHash,
|
|
7447
|
+
message_prehash: auth.messagePrehash,
|
|
7448
|
+
signature: ""
|
|
7449
|
+
}]
|
|
7450
|
+
}
|
|
7451
|
+
};
|
|
7452
|
+
}
|
|
6753
7453
|
var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
6754
7454
|
constructor(config, HttpRequest = AxiosHttpRequest) {
|
|
6755
|
-
|
|
6756
|
-
|
|
7455
|
+
const envBase = (typeof process !== "undefined" ? process.env.GATEWAY_URL : void 0)?.trim();
|
|
7456
|
+
const base = config?.BASE ?? (envBase || defaultGateway);
|
|
7457
|
+
super({ ...config, BASE: base }, HttpRequest);
|
|
7458
|
+
this.baseUrl = base;
|
|
6757
7459
|
}
|
|
6758
7460
|
/**
|
|
6759
7461
|
* Fetches chain defaults from the payment gateway.
|
|
@@ -6810,64 +7512,84 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
|
6810
7512
|
}
|
|
6811
7513
|
/**
|
|
6812
7514
|
* Prepares a payment request with defaults, ready for signing.
|
|
6813
|
-
*
|
|
7515
|
+
*
|
|
7516
|
+
* By default this resolves the corridor addresses from the gateway `/defaults`
|
|
7517
|
+
* endpoint. It reaches the gateway only for what the caller has NOT already
|
|
7518
|
+
* supplied via `resolvedDefaults`: supply `resolvedDefaults.source` to skip the
|
|
7519
|
+
* source-chain fetch and `resolvedDefaults.destination` to skip the destination
|
|
7520
|
+
* fetch. Supplying both builds the request **entirely offline** (no network) —
|
|
7521
|
+
* how a caller that already holds the corridor addresses (e.g. from a signed
|
|
7522
|
+
* challenge) constructs and signs a request without gateway access. Such a
|
|
7523
|
+
* caller typically also injects `now` so the deadlines are deterministic.
|
|
7524
|
+
*
|
|
7525
|
+
* @example Minimal — fetch corridor addresses from the gateway, then sign
|
|
7526
|
+
* ```ts
|
|
7527
|
+
* const client = new PaymentGatewayClient({ BASE: "https://gateway.example.com" });
|
|
7528
|
+
*
|
|
7529
|
+
* const request = await client.preparePaymentRequest({
|
|
7530
|
+
* depositor: "0xPayerAddress",
|
|
7531
|
+
* sourceAsset: "eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
|
|
7532
|
+
* destinationAccount: "0xMerchantAddress",
|
|
7533
|
+
* destinationAsset: "eip155:42161/erc20:0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on Arbitrum
|
|
7534
|
+
* fulfillmentAmount: "10000000", // 10 USDC (6 decimals)
|
|
7535
|
+
* });
|
|
7536
|
+
* // max_source_amount, deadlines, request id, and nonce are all defaulted.
|
|
7537
|
+
*
|
|
7538
|
+
* const signer = createSenderSigner("eip155:8453", { provider: "raw", privateKey });
|
|
7539
|
+
* await signPaymentRequest(request, signer); // fills sender_auth, ready to submit
|
|
7540
|
+
* ```
|
|
7541
|
+
*
|
|
6814
7542
|
* @param params Payment parameters
|
|
6815
7543
|
* @returns A complete PaymentRequest object without the signature
|
|
6816
7544
|
*/
|
|
6817
7545
|
async preparePaymentRequest(params) {
|
|
6818
|
-
const
|
|
7546
|
+
const now = (params.now ?? Date.now)();
|
|
7547
|
+
const { quote_deadline, fulfillment_deadline } = resolveDeadlines({ ...params, now: () => now }, DEFAULT_PAYMENT_QUOTE_DEADLINE_SECONDS);
|
|
6819
7548
|
const sourceChainId = params.sourceAsset.split("/")[0];
|
|
6820
7549
|
const destChainId = params.destinationAsset.split("/")[0];
|
|
6821
|
-
const [sourceDefaults,
|
|
6822
|
-
this.fetchChainDefaults(sourceChainId),
|
|
6823
|
-
this.fetchChainDefaults(destChainId)
|
|
7550
|
+
const [sourceDefaults, fulfillmentProxy] = await Promise.all([
|
|
7551
|
+
params.resolvedDefaults?.source ?? this.fetchChainDefaults(sourceChainId),
|
|
7552
|
+
params.resolvedDefaults?.destination?.fulfillmentProxy ?? this.fetchChainDefaults(destChainId).then((d) => d.fulfillmentProxy)
|
|
6824
7553
|
]);
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
7554
|
+
if (!params.requestId) {
|
|
7555
|
+
throw new Error(
|
|
7556
|
+
"payment-gateway-client: requestId is required \u2014 it is the idempotency key that seeds the deterministic deposit nonce; supply a stable id per logical payment and reuse it on retry"
|
|
7557
|
+
);
|
|
7558
|
+
}
|
|
7559
|
+
const requestId = params.requestId;
|
|
7560
|
+
const sourceNamespace = sourceChainId.split(":")[0];
|
|
7561
|
+
let permitDeadline;
|
|
7562
|
+
if (sourceNamespace !== "solana") {
|
|
7563
|
+
const fulfillmentMs = Date.parse(fulfillment_deadline);
|
|
7564
|
+
if (params.deadlineSeconds !== void 0) {
|
|
7565
|
+
permitDeadline = Math.ceil(now / 1e3) + Math.ceil(params.deadlineSeconds);
|
|
7566
|
+
if (permitDeadline * 1e3 < fulfillmentMs) {
|
|
7567
|
+
throw new Error(
|
|
7568
|
+
`payment-gateway-client: deadlineSeconds (${params.deadlineSeconds}) expires the deposit permit before settlement (fulfillmentDeadlineSeconds). The permit must stay valid until settlement \u2014 pass a deadlineSeconds at least as long as fulfillmentDeadlineSeconds, or omit it to derive it from fulfillment_deadline automatically.`
|
|
7569
|
+
);
|
|
7570
|
+
}
|
|
7571
|
+
} else {
|
|
7572
|
+
permitDeadline = Math.floor(fulfillmentMs / 1e3) + 1;
|
|
7573
|
+
}
|
|
7574
|
+
}
|
|
7575
|
+
return assemblePaymentRequest({
|
|
6829
7576
|
depositor: params.depositor,
|
|
6830
7577
|
fulfillmentAmount: params.fulfillmentAmount,
|
|
7578
|
+
sourceAsset: params.sourceAsset,
|
|
7579
|
+
destinationAccount: params.destinationAccount,
|
|
7580
|
+
destinationAsset: params.destinationAsset,
|
|
7581
|
+
maxSourceAmount: params.maxSourceAmount ?? defaultMaxSourceAmount(params.fulfillmentAmount),
|
|
6831
7582
|
requestId,
|
|
7583
|
+
quoteDeadline: quote_deadline,
|
|
7584
|
+
fulfillmentDeadline: fulfillment_deadline,
|
|
6832
7585
|
sourceDefaults,
|
|
6833
|
-
|
|
6834
|
-
|
|
7586
|
+
fulfillmentProxy,
|
|
7587
|
+
nonce: params.nonce,
|
|
7588
|
+
deadline: permitDeadline,
|
|
7589
|
+
solanaRpcUrl: params.solanaRpcUrl,
|
|
7590
|
+
solanaClockReader: params.solanaClockReader,
|
|
7591
|
+
settlerRequirements: params.settlerRequirements
|
|
6835
7592
|
});
|
|
6836
|
-
const contractOverrides = adapter.resolveContractOverrides?.(sourceDefaults);
|
|
6837
|
-
return {
|
|
6838
|
-
version: PAYMENT_REQUEST_VERSION,
|
|
6839
|
-
request_id: requestId,
|
|
6840
|
-
source: {
|
|
6841
|
-
asset_identifier: params.sourceAsset,
|
|
6842
|
-
account: params.depositor
|
|
6843
|
-
},
|
|
6844
|
-
destination: [{
|
|
6845
|
-
asset_identifier: params.destinationAsset,
|
|
6846
|
-
account: params.destinationAccount
|
|
6847
|
-
}],
|
|
6848
|
-
fulfillment_amount: params.fulfillmentAmount,
|
|
6849
|
-
max_source_amount: params.maxSourceAmount ?? defaultMaxSourceAmount(params.fulfillmentAmount),
|
|
6850
|
-
// REQUIRED (the gateway injects no defaults). Callers can widen the window via
|
|
6851
|
-
// quoteDeadlineSeconds / fulfillmentDeadlineSeconds, e.g. for slow Turnkey signing.
|
|
6852
|
-
quote_deadline,
|
|
6853
|
-
fulfillment_deadline,
|
|
6854
|
-
escrow_contract_address: sourceDefaults.escrowContract,
|
|
6855
|
-
quote_selector: contractOverrides?.quote_selector ?? sourceDefaults.quoteSelector,
|
|
6856
|
-
fulfillment_verifier: contractOverrides?.fulfillment_verifier ?? {
|
|
6857
|
-
account: sourceDefaults.fulfillmentVerifierAccount,
|
|
6858
|
-
endpoint: sourceDefaults.fulfillmentVerifierEndpoint
|
|
6859
|
-
},
|
|
6860
|
-
fulfillment_proxy: destDefaults.fulfillmentProxy,
|
|
6861
|
-
...params.settlerRequirements ? { settler_requirements: params.settlerRequirements } : {},
|
|
6862
|
-
sender_auth: {
|
|
6863
|
-
message_scheme: auth.messageScheme,
|
|
6864
|
-
signed_messages: [{
|
|
6865
|
-
message: auth.messageHash,
|
|
6866
|
-
message_prehash: auth.messagePrehash,
|
|
6867
|
-
signature: ""
|
|
6868
|
-
}]
|
|
6869
|
-
}
|
|
6870
|
-
};
|
|
6871
7593
|
}
|
|
6872
7594
|
/**
|
|
6873
7595
|
* Prepares a quote-request body (`CreateQuoteRequest`), ready to POST to
|
|
@@ -7000,7 +7722,6 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
|
7000
7722
|
PaymentsService,
|
|
7001
7723
|
QuoteRequestsService,
|
|
7002
7724
|
REPLAY_HORIZON_SECS,
|
|
7003
|
-
RawSenderSigner,
|
|
7004
7725
|
TOTAL_BUCKETS,
|
|
7005
7726
|
TurnkeySenderSigner,
|
|
7006
7727
|
base58ToBytes,
|
|
@@ -7014,11 +7735,13 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
|
7014
7735
|
encodeU64LE,
|
|
7015
7736
|
generateSolanaNonce,
|
|
7016
7737
|
generateSolanaPaymentId,
|
|
7738
|
+
getErrorResponse,
|
|
7017
7739
|
hashPermitWitnessTransferFrom,
|
|
7018
7740
|
hashRequestId,
|
|
7019
7741
|
hashSolanaDeposit,
|
|
7020
7742
|
hashTvmPermitWitnessTransferFrom,
|
|
7021
7743
|
hexToBytes,
|
|
7744
|
+
isApiError,
|
|
7022
7745
|
maskChainId,
|
|
7023
7746
|
normalizeAddress,
|
|
7024
7747
|
resolveTurnkeyAddresses,
|