@t402/ton 2.0.0 → 2.3.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/dist/cjs/exact/client/index.d.ts +63 -4
- package/dist/cjs/exact/client/index.js +29 -3
- package/dist/cjs/exact/client/index.js.map +1 -1
- package/dist/cjs/exact/facilitator/index.d.ts +63 -3
- package/dist/cjs/exact/facilitator/index.js +31 -4
- package/dist/cjs/exact/facilitator/index.js.map +1 -1
- package/dist/cjs/exact/server/index.d.ts +42 -17
- package/dist/cjs/exact/server/index.js +22 -40
- package/dist/cjs/exact/server/index.js.map +1 -1
- package/dist/cjs/index.d.ts +7 -2
- package/dist/cjs/index.js +496 -13
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/{signer-CFiw2DST.d.ts → signer-Bqn2K0b4.d.ts} +1 -1
- package/dist/esm/{chunk-6LOUEHJT.mjs → chunk-3BN2G4M7.mjs} +6 -1
- package/dist/esm/chunk-3BN2G4M7.mjs.map +1 -0
- package/dist/esm/{chunk-ZCMWKFVA.mjs → chunk-7OE2PWYP.mjs} +28 -4
- package/dist/esm/chunk-7OE2PWYP.mjs.map +1 -0
- package/dist/esm/chunk-NGYEU24R.mjs +271 -0
- package/dist/esm/chunk-NGYEU24R.mjs.map +1 -0
- package/dist/esm/chunk-ZJA7AWWH.mjs +284 -0
- package/dist/esm/chunk-ZJA7AWWH.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +63 -4
- package/dist/esm/exact/client/index.mjs +6 -4
- package/dist/esm/exact/facilitator/index.d.mts +63 -3
- package/dist/esm/exact/facilitator/index.mjs +6 -254
- package/dist/esm/exact/facilitator/index.mjs.map +1 -1
- package/dist/esm/exact/server/index.d.mts +42 -17
- package/dist/esm/exact/server/index.mjs +6 -208
- package/dist/esm/exact/server/index.mjs.map +1 -1
- package/dist/esm/index.d.mts +7 -2
- package/dist/esm/index.mjs +13 -5
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/{signer-CFiw2DST.d.mts → signer-Bqn2K0b4.d.mts} +1 -1
- package/package.json +8 -7
- package/dist/esm/chunk-6LOUEHJT.mjs.map +0 -1
- package/dist/esm/chunk-RST5PY7E.mjs +0 -85
- package/dist/esm/chunk-RST5PY7E.mjs.map +0 -1
- package/dist/esm/chunk-ZCMWKFVA.mjs.map +0 -1
package/dist/cjs/index.js
CHANGED
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
7
|
var __export = (target, all) => {
|
|
7
8
|
for (var name in all)
|
|
8
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -16,6 +17,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
17
|
return to;
|
|
17
18
|
};
|
|
18
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
19
21
|
|
|
20
22
|
// src/index.ts
|
|
21
23
|
var src_exports = {};
|
|
@@ -62,6 +64,9 @@ __export(src_exports, {
|
|
|
62
64
|
normalizeNetwork: () => normalizeNetwork,
|
|
63
65
|
parseJettonTransferBody: () => parseJettonTransferBody,
|
|
64
66
|
parseTonAddress: () => parseTonAddress,
|
|
67
|
+
registerExactTonClientScheme: () => registerExactTonScheme,
|
|
68
|
+
registerExactTonFacilitatorScheme: () => registerExactTonScheme3,
|
|
69
|
+
registerExactTonServerScheme: () => registerExactTonScheme2,
|
|
65
70
|
toClientTonSigner: () => toClientTonSigner,
|
|
66
71
|
toFacilitatorTonSigner: () => toFacilitatorTonSigner,
|
|
67
72
|
validateTonAddress: () => validateTonAddress
|
|
@@ -241,7 +246,7 @@ var ExactTonScheme = class {
|
|
|
241
246
|
this.signer = signer;
|
|
242
247
|
this.getJettonWalletAddress = getJettonWalletAddress;
|
|
243
248
|
this.config = config;
|
|
244
|
-
this
|
|
249
|
+
__publicField(this, "scheme", SCHEME_EXACT);
|
|
245
250
|
}
|
|
246
251
|
/**
|
|
247
252
|
* Creates a payment payload for the Exact scheme.
|
|
@@ -314,15 +319,26 @@ var ExactTonScheme = class {
|
|
|
314
319
|
}
|
|
315
320
|
};
|
|
316
321
|
|
|
317
|
-
// src/
|
|
318
|
-
function
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
322
|
+
// src/exact/client/register.ts
|
|
323
|
+
function registerExactTonScheme(client, config) {
|
|
324
|
+
const scheme = new ExactTonScheme(
|
|
325
|
+
config.signer,
|
|
326
|
+
config.getJettonWalletAddress,
|
|
327
|
+
config.schemeConfig
|
|
328
|
+
);
|
|
329
|
+
if (config.networks && config.networks.length > 0) {
|
|
330
|
+
config.networks.forEach((network) => {
|
|
331
|
+
client.register(network, scheme);
|
|
332
|
+
});
|
|
333
|
+
} else {
|
|
334
|
+
client.register("ton:*", scheme);
|
|
335
|
+
}
|
|
336
|
+
if (config.policies) {
|
|
337
|
+
config.policies.forEach((policy) => {
|
|
338
|
+
client.registerPolicy(policy);
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
return client;
|
|
326
342
|
}
|
|
327
343
|
|
|
328
344
|
// src/tokens.ts
|
|
@@ -369,9 +385,7 @@ function getDefaultJetton(network) {
|
|
|
369
385
|
function getJettonByAddress(network, address) {
|
|
370
386
|
const jettons = JETTON_REGISTRY[network];
|
|
371
387
|
if (!jettons) return void 0;
|
|
372
|
-
return Object.values(jettons).find(
|
|
373
|
-
(j) => j.masterAddress.toLowerCase() === address.toLowerCase()
|
|
374
|
-
);
|
|
388
|
+
return Object.values(jettons).find((j) => j.masterAddress.toLowerCase() === address.toLowerCase());
|
|
375
389
|
}
|
|
376
390
|
function getNetworksForJetton(symbol) {
|
|
377
391
|
const networks = [];
|
|
@@ -391,6 +405,472 @@ function isNetworkSupported(network) {
|
|
|
391
405
|
function getSupportedNetworks() {
|
|
392
406
|
return Object.keys(JETTON_REGISTRY);
|
|
393
407
|
}
|
|
408
|
+
|
|
409
|
+
// src/exact/server/scheme.ts
|
|
410
|
+
var ExactTonScheme2 = class {
|
|
411
|
+
constructor(config = {}) {
|
|
412
|
+
__publicField(this, "scheme", SCHEME_EXACT);
|
|
413
|
+
__publicField(this, "moneyParsers", []);
|
|
414
|
+
__publicField(this, "config");
|
|
415
|
+
this.config = config;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Register a custom money parser in the parser chain.
|
|
419
|
+
* Multiple parsers can be registered - they will be tried in registration order.
|
|
420
|
+
* Each parser receives a decimal amount (e.g., 1.50 for $1.50).
|
|
421
|
+
* If a parser returns null, the next parser in the chain will be tried.
|
|
422
|
+
* The default parser is always the final fallback.
|
|
423
|
+
*
|
|
424
|
+
* @param parser - Custom function to convert amount to AssetAmount (or null to skip)
|
|
425
|
+
* @returns The server instance for chaining
|
|
426
|
+
*
|
|
427
|
+
* @example
|
|
428
|
+
* tonServer.registerMoneyParser(async (amount, network) => {
|
|
429
|
+
* // Use custom Jetton for large amounts
|
|
430
|
+
* if (amount > 1000) {
|
|
431
|
+
* return {
|
|
432
|
+
* amount: (amount * 1e9).toString(),
|
|
433
|
+
* asset: "EQCustomJettonAddress...",
|
|
434
|
+
* extra: { tier: "premium" }
|
|
435
|
+
* };
|
|
436
|
+
* }
|
|
437
|
+
* return null; // Use next parser
|
|
438
|
+
* });
|
|
439
|
+
*/
|
|
440
|
+
registerMoneyParser(parser) {
|
|
441
|
+
this.moneyParsers.push(parser);
|
|
442
|
+
return this;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Parses a price into an asset amount.
|
|
446
|
+
* If price is already an AssetAmount, returns it directly.
|
|
447
|
+
* If price is Money (string | number), parses to decimal and tries custom parsers.
|
|
448
|
+
* Falls back to default conversion if all custom parsers return null.
|
|
449
|
+
*
|
|
450
|
+
* @param price - The price to parse
|
|
451
|
+
* @param network - The network to use
|
|
452
|
+
* @returns Promise that resolves to the parsed asset amount
|
|
453
|
+
*/
|
|
454
|
+
async parsePrice(price, network) {
|
|
455
|
+
const normalizedNetwork = normalizeNetwork(network);
|
|
456
|
+
if (typeof price === "object" && price !== null && "amount" in price) {
|
|
457
|
+
if (!price.asset) {
|
|
458
|
+
throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);
|
|
459
|
+
}
|
|
460
|
+
return {
|
|
461
|
+
amount: price.amount,
|
|
462
|
+
asset: price.asset,
|
|
463
|
+
extra: price.extra || {}
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
const amount = this.parseMoneyToDecimal(price);
|
|
467
|
+
for (const parser of this.moneyParsers) {
|
|
468
|
+
const result = await parser(amount, normalizedNetwork);
|
|
469
|
+
if (result !== null) {
|
|
470
|
+
return result;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return this.defaultMoneyConversion(amount, normalizedNetwork);
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Build payment requirements for this scheme/network combination.
|
|
477
|
+
* Adds TON-specific fields like gas sponsor if provided by facilitator.
|
|
478
|
+
*
|
|
479
|
+
* @param paymentRequirements - Base payment requirements with amount/asset already set
|
|
480
|
+
* @param supportedKind - The supported kind from facilitator's /supported endpoint
|
|
481
|
+
* @param extensionKeys - Extensions supported by the facilitator (unused)
|
|
482
|
+
* @returns Enhanced payment requirements ready to be sent to clients
|
|
483
|
+
*/
|
|
484
|
+
async enhancePaymentRequirements(paymentRequirements, supportedKind, extensionKeys) {
|
|
485
|
+
void extensionKeys;
|
|
486
|
+
const extra = { ...paymentRequirements.extra };
|
|
487
|
+
if (supportedKind.extra?.gasSponsor) {
|
|
488
|
+
extra.gasSponsor = supportedKind.extra.gasSponsor;
|
|
489
|
+
}
|
|
490
|
+
return {
|
|
491
|
+
...paymentRequirements,
|
|
492
|
+
extra
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Parse Money (string | number) to a decimal number.
|
|
497
|
+
* Handles formats like "$1.50", "1.50", 1.50, etc.
|
|
498
|
+
*
|
|
499
|
+
* @param money - The money value to parse
|
|
500
|
+
* @returns Decimal number
|
|
501
|
+
*/
|
|
502
|
+
parseMoneyToDecimal(money) {
|
|
503
|
+
if (typeof money === "number") {
|
|
504
|
+
return money;
|
|
505
|
+
}
|
|
506
|
+
const cleanMoney = money.replace(/^\$/, "").trim();
|
|
507
|
+
const amount = parseFloat(cleanMoney);
|
|
508
|
+
if (isNaN(amount)) {
|
|
509
|
+
throw new Error(`Invalid money format: ${money}`);
|
|
510
|
+
}
|
|
511
|
+
return amount;
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Default money conversion implementation.
|
|
515
|
+
* Converts decimal amount to the preferred Jetton on the specified network.
|
|
516
|
+
*
|
|
517
|
+
* @param amount - The decimal amount (e.g., 1.50)
|
|
518
|
+
* @param network - The network to use
|
|
519
|
+
* @returns The parsed asset amount
|
|
520
|
+
*/
|
|
521
|
+
defaultMoneyConversion(amount, network) {
|
|
522
|
+
const jetton = this.getDefaultAsset(network);
|
|
523
|
+
const tokenAmount = this.convertToTokenAmount(amount.toString(), jetton.decimals);
|
|
524
|
+
return {
|
|
525
|
+
amount: tokenAmount,
|
|
526
|
+
asset: jetton.masterAddress,
|
|
527
|
+
extra: {
|
|
528
|
+
symbol: jetton.symbol,
|
|
529
|
+
name: jetton.name,
|
|
530
|
+
decimals: jetton.decimals
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Convert decimal amount to token units (e.g., 0.10 -> 100000 for 6-decimal tokens)
|
|
536
|
+
*
|
|
537
|
+
* @param decimalAmount - The decimal amount to convert
|
|
538
|
+
* @param decimals - Number of decimals for the token
|
|
539
|
+
* @returns The token amount as a string
|
|
540
|
+
*/
|
|
541
|
+
convertToTokenAmount(decimalAmount, decimals) {
|
|
542
|
+
const amount = parseFloat(decimalAmount);
|
|
543
|
+
if (isNaN(amount)) {
|
|
544
|
+
throw new Error(`Invalid amount: ${decimalAmount}`);
|
|
545
|
+
}
|
|
546
|
+
const tokenAmount = Math.floor(amount * Math.pow(10, decimals));
|
|
547
|
+
return tokenAmount.toString();
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Get the default asset info for a network.
|
|
551
|
+
* Priority: configured preferredJetton > USDT > first available
|
|
552
|
+
*
|
|
553
|
+
* @param network - The network to get asset info for
|
|
554
|
+
* @returns The Jetton configuration
|
|
555
|
+
*/
|
|
556
|
+
getDefaultAsset(network) {
|
|
557
|
+
if (this.config.preferredJetton) {
|
|
558
|
+
const preferred = getJettonConfig(network, this.config.preferredJetton);
|
|
559
|
+
if (preferred) return preferred;
|
|
560
|
+
}
|
|
561
|
+
const defaultJetton = getDefaultJetton(network);
|
|
562
|
+
if (defaultJetton) return defaultJetton;
|
|
563
|
+
throw new Error(`No Jettons configured for network ${network}`);
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Get all supported networks
|
|
567
|
+
*/
|
|
568
|
+
static getSupportedNetworks() {
|
|
569
|
+
return Object.keys(JETTON_REGISTRY);
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Check if a network is supported
|
|
573
|
+
*/
|
|
574
|
+
static isNetworkSupported(network) {
|
|
575
|
+
return network in JETTON_REGISTRY;
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
// src/exact/server/register.ts
|
|
580
|
+
function registerExactTonScheme2(server, config = {}) {
|
|
581
|
+
const scheme = new ExactTonScheme2(config.schemeConfig);
|
|
582
|
+
if (config.networks && config.networks.length > 0) {
|
|
583
|
+
config.networks.forEach((network) => {
|
|
584
|
+
server.register(network, scheme);
|
|
585
|
+
});
|
|
586
|
+
} else {
|
|
587
|
+
server.register("ton:*", scheme);
|
|
588
|
+
}
|
|
589
|
+
return server;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// src/exact/facilitator/scheme.ts
|
|
593
|
+
var import_core3 = require("@ton/core");
|
|
594
|
+
var ExactTonScheme3 = class {
|
|
595
|
+
/**
|
|
596
|
+
* Creates a new ExactTonScheme facilitator instance.
|
|
597
|
+
*
|
|
598
|
+
* @param signer - The TON signer for facilitator operations
|
|
599
|
+
* @param config - Optional configuration
|
|
600
|
+
*/
|
|
601
|
+
constructor(signer, config = {}) {
|
|
602
|
+
this.signer = signer;
|
|
603
|
+
__publicField(this, "scheme", SCHEME_EXACT);
|
|
604
|
+
__publicField(this, "caipFamily", "ton:*");
|
|
605
|
+
__publicField(this, "config");
|
|
606
|
+
this.config = config;
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Get mechanism-specific extra data for the supported kinds endpoint.
|
|
610
|
+
* For TON, optionally returns gas sponsor address if configured.
|
|
611
|
+
*
|
|
612
|
+
* @param network - The network identifier
|
|
613
|
+
* @returns Extra data object or undefined
|
|
614
|
+
*/
|
|
615
|
+
getExtra(network) {
|
|
616
|
+
void network;
|
|
617
|
+
if (this.config.canSponsorGas) {
|
|
618
|
+
const addresses = this.signer.getAddresses();
|
|
619
|
+
if (addresses.length > 0) {
|
|
620
|
+
return {
|
|
621
|
+
gasSponsor: addresses[0]
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
return void 0;
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Get signer addresses used by this facilitator.
|
|
629
|
+
* Returns all addresses this facilitator can use for operations.
|
|
630
|
+
*
|
|
631
|
+
* @param network - The network identifier
|
|
632
|
+
* @returns Array of facilitator addresses
|
|
633
|
+
*/
|
|
634
|
+
getSigners(network) {
|
|
635
|
+
void network;
|
|
636
|
+
return [...this.signer.getAddresses()];
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Verifies a payment payload.
|
|
640
|
+
*
|
|
641
|
+
* Performs comprehensive validation:
|
|
642
|
+
* 1. Scheme and network matching
|
|
643
|
+
* 2. BOC format validation
|
|
644
|
+
* 3. Message structure verification
|
|
645
|
+
* 4. Authorization expiry check
|
|
646
|
+
* 5. Balance verification
|
|
647
|
+
* 6. Amount and recipient validation
|
|
648
|
+
*
|
|
649
|
+
* @param payload - The payment payload to verify
|
|
650
|
+
* @param requirements - The payment requirements
|
|
651
|
+
* @returns Promise resolving to verification response
|
|
652
|
+
*/
|
|
653
|
+
async verify(payload, requirements) {
|
|
654
|
+
const tonPayload = payload.payload;
|
|
655
|
+
if (!tonPayload?.authorization?.from || !tonPayload?.signedBoc) {
|
|
656
|
+
return {
|
|
657
|
+
isValid: false,
|
|
658
|
+
invalidReason: "invalid_payload_structure",
|
|
659
|
+
payer: ""
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
const authorization = tonPayload.authorization;
|
|
663
|
+
if (payload.accepted.scheme !== SCHEME_EXACT || requirements.scheme !== SCHEME_EXACT) {
|
|
664
|
+
return {
|
|
665
|
+
isValid: false,
|
|
666
|
+
invalidReason: "unsupported_scheme",
|
|
667
|
+
payer: authorization.from
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
try {
|
|
671
|
+
const payloadNetwork = normalizeNetwork(payload.accepted.network);
|
|
672
|
+
const requirementsNetwork = normalizeNetwork(requirements.network);
|
|
673
|
+
if (payloadNetwork !== requirementsNetwork) {
|
|
674
|
+
return {
|
|
675
|
+
isValid: false,
|
|
676
|
+
invalidReason: "network_mismatch",
|
|
677
|
+
payer: authorization.from
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
} catch {
|
|
681
|
+
return {
|
|
682
|
+
isValid: false,
|
|
683
|
+
invalidReason: "invalid_network",
|
|
684
|
+
payer: authorization.from
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
try {
|
|
688
|
+
import_core3.Cell.fromBase64(tonPayload.signedBoc);
|
|
689
|
+
} catch {
|
|
690
|
+
return {
|
|
691
|
+
isValid: false,
|
|
692
|
+
invalidReason: "invalid_boc_format",
|
|
693
|
+
payer: authorization.from
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
const verifyResult = await this.signer.verifyMessage({
|
|
697
|
+
signedBoc: tonPayload.signedBoc,
|
|
698
|
+
expectedFrom: authorization.from,
|
|
699
|
+
expectedTransfer: {
|
|
700
|
+
jettonAmount: BigInt(authorization.jettonAmount),
|
|
701
|
+
destination: requirements.payTo,
|
|
702
|
+
jettonMaster: requirements.asset
|
|
703
|
+
}
|
|
704
|
+
});
|
|
705
|
+
if (!verifyResult.valid) {
|
|
706
|
+
return {
|
|
707
|
+
isValid: false,
|
|
708
|
+
invalidReason: verifyResult.reason || "message_verification_failed",
|
|
709
|
+
payer: authorization.from
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
713
|
+
if (authorization.validUntil < now + 30) {
|
|
714
|
+
return {
|
|
715
|
+
isValid: false,
|
|
716
|
+
invalidReason: "authorization_expired",
|
|
717
|
+
payer: authorization.from
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
try {
|
|
721
|
+
const balance = await this.signer.getJettonBalance({
|
|
722
|
+
ownerAddress: authorization.from,
|
|
723
|
+
jettonMasterAddress: requirements.asset
|
|
724
|
+
});
|
|
725
|
+
if (balance < BigInt(requirements.amount)) {
|
|
726
|
+
return {
|
|
727
|
+
isValid: false,
|
|
728
|
+
invalidReason: "insufficient_jetton_balance",
|
|
729
|
+
payer: authorization.from
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
} catch (error) {
|
|
733
|
+
console.warn("Could not verify Jetton balance:", error);
|
|
734
|
+
}
|
|
735
|
+
if (BigInt(authorization.jettonAmount) < BigInt(requirements.amount)) {
|
|
736
|
+
return {
|
|
737
|
+
isValid: false,
|
|
738
|
+
invalidReason: "insufficient_amount",
|
|
739
|
+
payer: authorization.from
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
if (!addressesEqual(authorization.to, requirements.payTo)) {
|
|
743
|
+
return {
|
|
744
|
+
isValid: false,
|
|
745
|
+
invalidReason: "recipient_mismatch",
|
|
746
|
+
payer: authorization.from
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
if (!addressesEqual(authorization.jettonMaster, requirements.asset)) {
|
|
750
|
+
return {
|
|
751
|
+
isValid: false,
|
|
752
|
+
invalidReason: "asset_mismatch",
|
|
753
|
+
payer: authorization.from
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
try {
|
|
757
|
+
const currentSeqno = await this.signer.getSeqno(authorization.from);
|
|
758
|
+
if (authorization.seqno < currentSeqno) {
|
|
759
|
+
return {
|
|
760
|
+
isValid: false,
|
|
761
|
+
invalidReason: "seqno_already_used",
|
|
762
|
+
payer: authorization.from
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
if (authorization.seqno > currentSeqno) {
|
|
766
|
+
return {
|
|
767
|
+
isValid: false,
|
|
768
|
+
invalidReason: "seqno_too_high",
|
|
769
|
+
payer: authorization.from
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
} catch (error) {
|
|
773
|
+
console.warn("Could not verify seqno:", error);
|
|
774
|
+
}
|
|
775
|
+
try {
|
|
776
|
+
const isDeployed = await this.signer.isDeployed(authorization.from);
|
|
777
|
+
if (!isDeployed) {
|
|
778
|
+
return {
|
|
779
|
+
isValid: false,
|
|
780
|
+
invalidReason: "wallet_not_deployed",
|
|
781
|
+
payer: authorization.from
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
} catch (error) {
|
|
785
|
+
console.warn("Could not verify wallet deployment:", error);
|
|
786
|
+
}
|
|
787
|
+
return {
|
|
788
|
+
isValid: true,
|
|
789
|
+
invalidReason: void 0,
|
|
790
|
+
payer: authorization.from
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Settles a payment by broadcasting the signed message.
|
|
795
|
+
*
|
|
796
|
+
* @param payload - The payment payload to settle
|
|
797
|
+
* @param requirements - The payment requirements
|
|
798
|
+
* @returns Promise resolving to settlement response
|
|
799
|
+
*/
|
|
800
|
+
async settle(payload, requirements) {
|
|
801
|
+
const tonPayload = payload.payload;
|
|
802
|
+
if (!tonPayload?.authorization?.from || !tonPayload?.signedBoc) {
|
|
803
|
+
return {
|
|
804
|
+
success: false,
|
|
805
|
+
network: payload.accepted.network,
|
|
806
|
+
transaction: "",
|
|
807
|
+
errorReason: "invalid_payload_structure",
|
|
808
|
+
payer: ""
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
const verifyResult = await this.verify(payload, requirements);
|
|
812
|
+
if (!verifyResult.isValid) {
|
|
813
|
+
return {
|
|
814
|
+
success: false,
|
|
815
|
+
network: payload.accepted.network,
|
|
816
|
+
transaction: "",
|
|
817
|
+
errorReason: verifyResult.invalidReason ?? "verification_failed",
|
|
818
|
+
payer: tonPayload.authorization.from
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
try {
|
|
822
|
+
const txHash = await this.signer.sendExternalMessage(tonPayload.signedBoc);
|
|
823
|
+
const confirmation = await this.signer.waitForTransaction({
|
|
824
|
+
address: tonPayload.authorization.from,
|
|
825
|
+
seqno: tonPayload.authorization.seqno + 1,
|
|
826
|
+
// Wait for next seqno
|
|
827
|
+
timeout: 6e4
|
|
828
|
+
// 60 second timeout
|
|
829
|
+
});
|
|
830
|
+
if (!confirmation.success) {
|
|
831
|
+
return {
|
|
832
|
+
success: false,
|
|
833
|
+
errorReason: confirmation.error || "transaction_not_confirmed",
|
|
834
|
+
transaction: txHash,
|
|
835
|
+
network: payload.accepted.network,
|
|
836
|
+
payer: tonPayload.authorization.from
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
return {
|
|
840
|
+
success: true,
|
|
841
|
+
transaction: confirmation.hash || txHash,
|
|
842
|
+
network: payload.accepted.network,
|
|
843
|
+
payer: tonPayload.authorization.from
|
|
844
|
+
};
|
|
845
|
+
} catch (error) {
|
|
846
|
+
console.error("Failed to settle TON transaction:", error);
|
|
847
|
+
return {
|
|
848
|
+
success: false,
|
|
849
|
+
errorReason: "transaction_failed",
|
|
850
|
+
transaction: "",
|
|
851
|
+
network: payload.accepted.network,
|
|
852
|
+
payer: tonPayload.authorization.from
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
// src/exact/facilitator/register.ts
|
|
859
|
+
function registerExactTonScheme3(facilitator, config) {
|
|
860
|
+
facilitator.register(config.networks, new ExactTonScheme3(config.signer, config.schemeConfig));
|
|
861
|
+
return facilitator;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
// src/signer.ts
|
|
865
|
+
function toClientTonSigner(signer) {
|
|
866
|
+
return signer;
|
|
867
|
+
}
|
|
868
|
+
function toFacilitatorTonSigner(client) {
|
|
869
|
+
return {
|
|
870
|
+
...client,
|
|
871
|
+
getAddresses: () => [client.address]
|
|
872
|
+
};
|
|
873
|
+
}
|
|
394
874
|
// Annotate the CommonJS export names for ESM import in node:
|
|
395
875
|
0 && (module.exports = {
|
|
396
876
|
DEFAULT_FORWARD_TON,
|
|
@@ -435,6 +915,9 @@ function getSupportedNetworks() {
|
|
|
435
915
|
normalizeNetwork,
|
|
436
916
|
parseJettonTransferBody,
|
|
437
917
|
parseTonAddress,
|
|
918
|
+
registerExactTonClientScheme,
|
|
919
|
+
registerExactTonFacilitatorScheme,
|
|
920
|
+
registerExactTonServerScheme,
|
|
438
921
|
toClientTonSigner,
|
|
439
922
|
toFacilitatorTonSigner,
|
|
440
923
|
validateTonAddress
|