@t402/ton 2.0.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 +53 -0
- package/dist/cjs/exact/client/index.js +181 -0
- package/dist/cjs/exact/client/index.js.map +1 -0
- package/dist/cjs/exact/facilitator/index.d.ts +79 -0
- package/dist/cjs/exact/facilitator/index.js +331 -0
- package/dist/cjs/exact/facilitator/index.js.map +1 -0
- package/dist/cjs/exact/server/index.d.ts +135 -0
- package/dist/cjs/exact/server/index.js +318 -0
- package/dist/cjs/exact/server/index.js.map +1 -0
- package/dist/cjs/index.d.ts +293 -0
- package/dist/cjs/index.js +442 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/signer-CFiw2DST.d.ts +277 -0
- package/dist/esm/chunk-6LOUEHJT.mjs +192 -0
- package/dist/esm/chunk-6LOUEHJT.mjs.map +1 -0
- package/dist/esm/chunk-RST5PY7E.mjs +85 -0
- package/dist/esm/chunk-RST5PY7E.mjs.map +1 -0
- package/dist/esm/chunk-ZCMWKFVA.mjs +101 -0
- package/dist/esm/chunk-ZCMWKFVA.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +53 -0
- package/dist/esm/exact/client/index.mjs +8 -0
- package/dist/esm/exact/client/index.mjs.map +1 -0
- package/dist/esm/exact/facilitator/index.d.mts +79 -0
- package/dist/esm/exact/facilitator/index.mjs +258 -0
- package/dist/esm/exact/facilitator/index.mjs.map +1 -0
- package/dist/esm/exact/server/index.d.mts +135 -0
- package/dist/esm/exact/server/index.mjs +212 -0
- package/dist/esm/exact/server/index.mjs.map +1 -0
- package/dist/esm/index.d.mts +293 -0
- package/dist/esm/index.mjs +108 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/signer-CFiw2DST.d.mts +277 -0
- package/package.json +99 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_FORWARD_TON,
|
|
3
|
+
DEFAULT_JETTON_TRANSFER_TON,
|
|
4
|
+
SCHEME_EXACT,
|
|
5
|
+
buildJettonTransferBody,
|
|
6
|
+
generateQueryId,
|
|
7
|
+
normalizeNetwork,
|
|
8
|
+
parseTonAddress
|
|
9
|
+
} from "./chunk-6LOUEHJT.mjs";
|
|
10
|
+
|
|
11
|
+
// src/exact/client/scheme.ts
|
|
12
|
+
import { Address, SendMode } from "@ton/core";
|
|
13
|
+
var ExactTonScheme = class {
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new ExactTonScheme instance.
|
|
16
|
+
*
|
|
17
|
+
* @param signer - The TON signer for client operations
|
|
18
|
+
* @param getJettonWalletAddress - Function to derive Jetton wallet address
|
|
19
|
+
* @param config - Optional configuration overrides
|
|
20
|
+
*/
|
|
21
|
+
constructor(signer, getJettonWalletAddress, config = {}) {
|
|
22
|
+
this.signer = signer;
|
|
23
|
+
this.getJettonWalletAddress = getJettonWalletAddress;
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.scheme = SCHEME_EXACT;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Creates a payment payload for the Exact scheme.
|
|
29
|
+
*
|
|
30
|
+
* The payload contains a pre-signed external message that performs
|
|
31
|
+
* a Jetton transfer from the client to the recipient.
|
|
32
|
+
*
|
|
33
|
+
* @param t402Version - The t402 protocol version
|
|
34
|
+
* @param paymentRequirements - The payment requirements
|
|
35
|
+
* @returns Promise resolving to a payment payload
|
|
36
|
+
*/
|
|
37
|
+
async createPaymentPayload(t402Version, paymentRequirements) {
|
|
38
|
+
const network = normalizeNetwork(paymentRequirements.network);
|
|
39
|
+
if (!paymentRequirements.asset) {
|
|
40
|
+
throw new Error("Asset (Jetton master address) is required");
|
|
41
|
+
}
|
|
42
|
+
if (!paymentRequirements.payTo) {
|
|
43
|
+
throw new Error("PayTo address is required");
|
|
44
|
+
}
|
|
45
|
+
if (!paymentRequirements.amount) {
|
|
46
|
+
throw new Error("Amount is required");
|
|
47
|
+
}
|
|
48
|
+
const jettonMasterAddress = paymentRequirements.asset;
|
|
49
|
+
const destinationAddress = parseTonAddress(paymentRequirements.payTo);
|
|
50
|
+
const senderJettonWalletAddress = await this.getJettonWalletAddress(
|
|
51
|
+
this.signer.address.toString(),
|
|
52
|
+
jettonMasterAddress
|
|
53
|
+
);
|
|
54
|
+
const senderJettonWallet = Address.parse(senderJettonWalletAddress);
|
|
55
|
+
const seqno = await this.signer.getSeqno();
|
|
56
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
57
|
+
const validUntil = now + paymentRequirements.maxTimeoutSeconds;
|
|
58
|
+
const queryId = generateQueryId();
|
|
59
|
+
const jettonAmount = BigInt(paymentRequirements.amount);
|
|
60
|
+
const jettonTransferBody = buildJettonTransferBody({
|
|
61
|
+
queryId,
|
|
62
|
+
amount: jettonAmount,
|
|
63
|
+
destination: destinationAddress,
|
|
64
|
+
responseDestination: this.signer.address,
|
|
65
|
+
forwardAmount: this.config.forwardAmount ?? DEFAULT_FORWARD_TON
|
|
66
|
+
});
|
|
67
|
+
const tonAmount = this.config.gasAmount ?? DEFAULT_JETTON_TRANSFER_TON;
|
|
68
|
+
const signedMessage = await this.signer.signMessage({
|
|
69
|
+
to: senderJettonWallet,
|
|
70
|
+
value: tonAmount,
|
|
71
|
+
body: jettonTransferBody,
|
|
72
|
+
sendMode: SendMode.PAY_GAS_SEPARATELY,
|
|
73
|
+
timeout: paymentRequirements.maxTimeoutSeconds
|
|
74
|
+
});
|
|
75
|
+
const signedBoc = signedMessage.toBoc().toString("base64");
|
|
76
|
+
const authorization = {
|
|
77
|
+
from: this.signer.address.toString({ bounceable: true }),
|
|
78
|
+
to: paymentRequirements.payTo,
|
|
79
|
+
jettonMaster: jettonMasterAddress,
|
|
80
|
+
jettonAmount: jettonAmount.toString(),
|
|
81
|
+
tonAmount: tonAmount.toString(),
|
|
82
|
+
validUntil,
|
|
83
|
+
seqno,
|
|
84
|
+
queryId: queryId.toString()
|
|
85
|
+
};
|
|
86
|
+
const payload = {
|
|
87
|
+
signedBoc,
|
|
88
|
+
authorization
|
|
89
|
+
};
|
|
90
|
+
void network;
|
|
91
|
+
return {
|
|
92
|
+
t402Version,
|
|
93
|
+
payload
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export {
|
|
99
|
+
ExactTonScheme
|
|
100
|
+
};
|
|
101
|
+
//# sourceMappingURL=chunk-ZCMWKFVA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exact/client/scheme.ts"],"sourcesContent":["/**\n * TON Client Scheme Implementation\n *\n * Creates payment payloads for TON Jetton transfers using the exact scheme.\n * Builds and signs external messages for Jetton wallet interactions.\n */\n\nimport { Address, SendMode } from \"@ton/core\";\nimport type { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport type { ClientTonSigner } from \"../../signer.js\";\nimport type { ExactTonPayloadV2 } from \"../../types.js\";\nimport { SCHEME_EXACT, DEFAULT_JETTON_TRANSFER_TON, DEFAULT_FORWARD_TON } from \"../../constants.js\";\nimport {\n generateQueryId,\n buildJettonTransferBody,\n normalizeNetwork,\n parseTonAddress,\n} from \"../../utils.js\";\n\n/**\n * Configuration for ExactTonScheme client\n */\nexport interface ExactTonSchemeConfig {\n /** Override the TON amount attached for gas (in nanoTON) */\n gasAmount?: bigint;\n /** Override the forward TON amount (in nanoTON) */\n forwardAmount?: bigint;\n}\n\n/**\n * TON client implementation for the Exact payment scheme.\n *\n * Creates signed Jetton transfer messages that can be broadcast\n * by a facilitator to complete the payment.\n */\nexport class ExactTonScheme implements SchemeNetworkClient {\n readonly scheme = SCHEME_EXACT;\n\n /**\n * Creates a new ExactTonScheme instance.\n *\n * @param signer - The TON signer for client operations\n * @param getJettonWalletAddress - Function to derive Jetton wallet address\n * @param config - Optional configuration overrides\n */\n constructor(\n private readonly signer: ClientTonSigner,\n private readonly getJettonWalletAddress: (\n ownerAddress: string,\n jettonMasterAddress: string,\n ) => Promise<string>,\n private readonly config: ExactTonSchemeConfig = {},\n ) {}\n\n /**\n * Creates a payment payload for the Exact scheme.\n *\n * The payload contains a pre-signed external message that performs\n * a Jetton transfer from the client to the recipient.\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Normalize and validate network\n const network = normalizeNetwork(paymentRequirements.network);\n\n // Validate required fields\n if (!paymentRequirements.asset) {\n throw new Error(\"Asset (Jetton master address) is required\");\n }\n if (!paymentRequirements.payTo) {\n throw new Error(\"PayTo address is required\");\n }\n if (!paymentRequirements.amount) {\n throw new Error(\"Amount is required\");\n }\n\n // Parse addresses\n const jettonMasterAddress = paymentRequirements.asset;\n const destinationAddress = parseTonAddress(paymentRequirements.payTo);\n\n // Get client's Jetton wallet address\n const senderJettonWalletAddress = await this.getJettonWalletAddress(\n this.signer.address.toString(),\n jettonMasterAddress,\n );\n const senderJettonWallet = Address.parse(senderJettonWalletAddress);\n\n // Get current seqno for replay protection\n const seqno = await this.signer.getSeqno();\n\n // Calculate validity period\n const now = Math.floor(Date.now() / 1000);\n const validUntil = now + paymentRequirements.maxTimeoutSeconds;\n\n // Generate unique query ID\n const queryId = generateQueryId();\n\n // Parse amount\n const jettonAmount = BigInt(paymentRequirements.amount);\n\n // Build Jetton transfer body\n const jettonTransferBody = buildJettonTransferBody({\n queryId,\n amount: jettonAmount,\n destination: destinationAddress,\n responseDestination: this.signer.address,\n forwardAmount: this.config.forwardAmount ?? DEFAULT_FORWARD_TON,\n });\n\n // Gas amount for the transfer\n const tonAmount = this.config.gasAmount ?? DEFAULT_JETTON_TRANSFER_TON;\n\n // Sign the message\n const signedMessage = await this.signer.signMessage({\n to: senderJettonWallet,\n value: tonAmount,\n body: jettonTransferBody,\n sendMode: SendMode.PAY_GAS_SEPARATELY,\n timeout: paymentRequirements.maxTimeoutSeconds,\n });\n\n // Encode to base64\n const signedBoc = signedMessage.toBoc().toString(\"base64\");\n\n // Build authorization metadata\n const authorization: ExactTonPayloadV2[\"authorization\"] = {\n from: this.signer.address.toString({ bounceable: true }),\n to: paymentRequirements.payTo,\n jettonMaster: jettonMasterAddress,\n jettonAmount: jettonAmount.toString(),\n tonAmount: tonAmount.toString(),\n validUntil,\n seqno,\n queryId: queryId.toString(),\n };\n\n // Create payload\n const payload: ExactTonPayloadV2 = {\n signedBoc,\n authorization,\n };\n\n // Mark network as used\n void network;\n\n return {\n t402Version,\n payload,\n };\n }\n}\n"],"mappings":";;;;;;;;;;;AAOA,SAAS,SAAS,gBAAgB;AA4B3B,IAAM,iBAAN,MAAoD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUzD,YACmB,QACA,wBAIA,SAA+B,CAAC,GACjD;AANiB;AACA;AAIA;AAfnB,SAAS,SAAS;AAAA,EAgBf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYH,MAAM,qBACJ,aACA,qBAC0D;AAE1D,UAAM,UAAU,iBAAiB,oBAAoB,OAAO;AAG5D,QAAI,CAAC,oBAAoB,OAAO;AAC9B,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AACA,QAAI,CAAC,oBAAoB,OAAO;AAC9B,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,QAAI,CAAC,oBAAoB,QAAQ;AAC/B,YAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC;AAGA,UAAM,sBAAsB,oBAAoB;AAChD,UAAM,qBAAqB,gBAAgB,oBAAoB,KAAK;AAGpE,UAAM,4BAA4B,MAAM,KAAK;AAAA,MAC3C,KAAK,OAAO,QAAQ,SAAS;AAAA,MAC7B;AAAA,IACF;AACA,UAAM,qBAAqB,QAAQ,MAAM,yBAAyB;AAGlE,UAAM,QAAQ,MAAM,KAAK,OAAO,SAAS;AAGzC,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,UAAM,aAAa,MAAM,oBAAoB;AAG7C,UAAM,UAAU,gBAAgB;AAGhC,UAAM,eAAe,OAAO,oBAAoB,MAAM;AAGtD,UAAM,qBAAqB,wBAAwB;AAAA,MACjD;AAAA,MACA,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,qBAAqB,KAAK,OAAO;AAAA,MACjC,eAAe,KAAK,OAAO,iBAAiB;AAAA,IAC9C,CAAC;AAGD,UAAM,YAAY,KAAK,OAAO,aAAa;AAG3C,UAAM,gBAAgB,MAAM,KAAK,OAAO,YAAY;AAAA,MAClD,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,MAAM;AAAA,MACN,UAAU,SAAS;AAAA,MACnB,SAAS,oBAAoB;AAAA,IAC/B,CAAC;AAGD,UAAM,YAAY,cAAc,MAAM,EAAE,SAAS,QAAQ;AAGzD,UAAM,gBAAoD;AAAA,MACxD,MAAM,KAAK,OAAO,QAAQ,SAAS,EAAE,YAAY,KAAK,CAAC;AAAA,MACvD,IAAI,oBAAoB;AAAA,MACxB,cAAc;AAAA,MACd,cAAc,aAAa,SAAS;AAAA,MACpC,WAAW,UAAU,SAAS;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,SAAS,QAAQ,SAAS;AAAA,IAC5B;AAGA,UAAM,UAA6B;AAAA,MACjC;AAAA,MACA;AAAA,IACF;AAGA,SAAK;AAEL,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { SchemeNetworkClient, PaymentRequirements, PaymentPayload } from '@t402/core/types';
|
|
2
|
+
import { C as ClientTonSigner } from '../../signer-CFiw2DST.mjs';
|
|
3
|
+
import '@ton/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* TON Client Scheme Implementation
|
|
7
|
+
*
|
|
8
|
+
* Creates payment payloads for TON Jetton transfers using the exact scheme.
|
|
9
|
+
* Builds and signs external messages for Jetton wallet interactions.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for ExactTonScheme client
|
|
14
|
+
*/
|
|
15
|
+
interface ExactTonSchemeConfig {
|
|
16
|
+
/** Override the TON amount attached for gas (in nanoTON) */
|
|
17
|
+
gasAmount?: bigint;
|
|
18
|
+
/** Override the forward TON amount (in nanoTON) */
|
|
19
|
+
forwardAmount?: bigint;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* TON client implementation for the Exact payment scheme.
|
|
23
|
+
*
|
|
24
|
+
* Creates signed Jetton transfer messages that can be broadcast
|
|
25
|
+
* by a facilitator to complete the payment.
|
|
26
|
+
*/
|
|
27
|
+
declare class ExactTonScheme implements SchemeNetworkClient {
|
|
28
|
+
private readonly signer;
|
|
29
|
+
private readonly getJettonWalletAddress;
|
|
30
|
+
private readonly config;
|
|
31
|
+
readonly scheme = "exact";
|
|
32
|
+
/**
|
|
33
|
+
* Creates a new ExactTonScheme instance.
|
|
34
|
+
*
|
|
35
|
+
* @param signer - The TON signer for client operations
|
|
36
|
+
* @param getJettonWalletAddress - Function to derive Jetton wallet address
|
|
37
|
+
* @param config - Optional configuration overrides
|
|
38
|
+
*/
|
|
39
|
+
constructor(signer: ClientTonSigner, getJettonWalletAddress: (ownerAddress: string, jettonMasterAddress: string) => Promise<string>, config?: ExactTonSchemeConfig);
|
|
40
|
+
/**
|
|
41
|
+
* Creates a payment payload for the Exact scheme.
|
|
42
|
+
*
|
|
43
|
+
* The payload contains a pre-signed external message that performs
|
|
44
|
+
* a Jetton transfer from the client to the recipient.
|
|
45
|
+
*
|
|
46
|
+
* @param t402Version - The t402 protocol version
|
|
47
|
+
* @param paymentRequirements - The payment requirements
|
|
48
|
+
* @returns Promise resolving to a payment payload
|
|
49
|
+
*/
|
|
50
|
+
createPaymentPayload(t402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "t402Version" | "payload">>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { ExactTonScheme, type ExactTonSchemeConfig };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { SchemeNetworkFacilitator, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse } from '@t402/core/types';
|
|
2
|
+
import { F as FacilitatorTonSigner } from '../../signer-CFiw2DST.mjs';
|
|
3
|
+
import '@ton/core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* TON Facilitator Scheme Implementation
|
|
7
|
+
*
|
|
8
|
+
* Verifies and settles TON Jetton payments using the exact scheme.
|
|
9
|
+
* Validates signed messages and broadcasts transactions to the network.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Configuration options for ExactTonScheme facilitator
|
|
14
|
+
*/
|
|
15
|
+
interface ExactTonSchemeConfig {
|
|
16
|
+
/** Whether this facilitator can sponsor gas for transactions */
|
|
17
|
+
canSponsorGas?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* TON facilitator implementation for the Exact payment scheme.
|
|
21
|
+
*
|
|
22
|
+
* Verifies signed Jetton transfer messages and broadcasts them
|
|
23
|
+
* to the TON network to complete payments.
|
|
24
|
+
*/
|
|
25
|
+
declare class ExactTonScheme implements SchemeNetworkFacilitator {
|
|
26
|
+
private readonly signer;
|
|
27
|
+
readonly scheme = "exact";
|
|
28
|
+
readonly caipFamily = "ton:*";
|
|
29
|
+
private config;
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new ExactTonScheme facilitator instance.
|
|
32
|
+
*
|
|
33
|
+
* @param signer - The TON signer for facilitator operations
|
|
34
|
+
* @param config - Optional configuration
|
|
35
|
+
*/
|
|
36
|
+
constructor(signer: FacilitatorTonSigner, config?: ExactTonSchemeConfig);
|
|
37
|
+
/**
|
|
38
|
+
* Get mechanism-specific extra data for the supported kinds endpoint.
|
|
39
|
+
* For TON, optionally returns gas sponsor address if configured.
|
|
40
|
+
*
|
|
41
|
+
* @param network - The network identifier
|
|
42
|
+
* @returns Extra data object or undefined
|
|
43
|
+
*/
|
|
44
|
+
getExtra(network: string): Record<string, unknown> | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Get signer addresses used by this facilitator.
|
|
47
|
+
* Returns all addresses this facilitator can use for operations.
|
|
48
|
+
*
|
|
49
|
+
* @param network - The network identifier
|
|
50
|
+
* @returns Array of facilitator addresses
|
|
51
|
+
*/
|
|
52
|
+
getSigners(network: string): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Verifies a payment payload.
|
|
55
|
+
*
|
|
56
|
+
* Performs comprehensive validation:
|
|
57
|
+
* 1. Scheme and network matching
|
|
58
|
+
* 2. BOC format validation
|
|
59
|
+
* 3. Message structure verification
|
|
60
|
+
* 4. Authorization expiry check
|
|
61
|
+
* 5. Balance verification
|
|
62
|
+
* 6. Amount and recipient validation
|
|
63
|
+
*
|
|
64
|
+
* @param payload - The payment payload to verify
|
|
65
|
+
* @param requirements - The payment requirements
|
|
66
|
+
* @returns Promise resolving to verification response
|
|
67
|
+
*/
|
|
68
|
+
verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;
|
|
69
|
+
/**
|
|
70
|
+
* Settles a payment by broadcasting the signed message.
|
|
71
|
+
*
|
|
72
|
+
* @param payload - The payment payload to settle
|
|
73
|
+
* @param requirements - The payment requirements
|
|
74
|
+
* @returns Promise resolving to settlement response
|
|
75
|
+
*/
|
|
76
|
+
settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export { ExactTonScheme, type ExactTonSchemeConfig };
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SCHEME_EXACT,
|
|
3
|
+
addressesEqual,
|
|
4
|
+
normalizeNetwork
|
|
5
|
+
} from "../../chunk-6LOUEHJT.mjs";
|
|
6
|
+
|
|
7
|
+
// src/exact/facilitator/scheme.ts
|
|
8
|
+
import { Cell } from "@ton/core";
|
|
9
|
+
var ExactTonScheme = class {
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new ExactTonScheme facilitator instance.
|
|
12
|
+
*
|
|
13
|
+
* @param signer - The TON signer for facilitator operations
|
|
14
|
+
* @param config - Optional configuration
|
|
15
|
+
*/
|
|
16
|
+
constructor(signer, config = {}) {
|
|
17
|
+
this.signer = signer;
|
|
18
|
+
this.scheme = SCHEME_EXACT;
|
|
19
|
+
this.caipFamily = "ton:*";
|
|
20
|
+
this.config = config;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get mechanism-specific extra data for the supported kinds endpoint.
|
|
24
|
+
* For TON, optionally returns gas sponsor address if configured.
|
|
25
|
+
*
|
|
26
|
+
* @param network - The network identifier
|
|
27
|
+
* @returns Extra data object or undefined
|
|
28
|
+
*/
|
|
29
|
+
getExtra(network) {
|
|
30
|
+
void network;
|
|
31
|
+
if (this.config.canSponsorGas) {
|
|
32
|
+
const addresses = this.signer.getAddresses();
|
|
33
|
+
if (addresses.length > 0) {
|
|
34
|
+
return {
|
|
35
|
+
gasSponsor: addresses[0]
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return void 0;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get signer addresses used by this facilitator.
|
|
43
|
+
* Returns all addresses this facilitator can use for operations.
|
|
44
|
+
*
|
|
45
|
+
* @param network - The network identifier
|
|
46
|
+
* @returns Array of facilitator addresses
|
|
47
|
+
*/
|
|
48
|
+
getSigners(network) {
|
|
49
|
+
void network;
|
|
50
|
+
return [...this.signer.getAddresses()];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Verifies a payment payload.
|
|
54
|
+
*
|
|
55
|
+
* Performs comprehensive validation:
|
|
56
|
+
* 1. Scheme and network matching
|
|
57
|
+
* 2. BOC format validation
|
|
58
|
+
* 3. Message structure verification
|
|
59
|
+
* 4. Authorization expiry check
|
|
60
|
+
* 5. Balance verification
|
|
61
|
+
* 6. Amount and recipient validation
|
|
62
|
+
*
|
|
63
|
+
* @param payload - The payment payload to verify
|
|
64
|
+
* @param requirements - The payment requirements
|
|
65
|
+
* @returns Promise resolving to verification response
|
|
66
|
+
*/
|
|
67
|
+
async verify(payload, requirements) {
|
|
68
|
+
const tonPayload = payload.payload;
|
|
69
|
+
const authorization = tonPayload.authorization;
|
|
70
|
+
if (payload.accepted.scheme !== SCHEME_EXACT || requirements.scheme !== SCHEME_EXACT) {
|
|
71
|
+
return {
|
|
72
|
+
isValid: false,
|
|
73
|
+
invalidReason: "unsupported_scheme",
|
|
74
|
+
payer: authorization.from
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const payloadNetwork = normalizeNetwork(payload.accepted.network);
|
|
79
|
+
const requirementsNetwork = normalizeNetwork(requirements.network);
|
|
80
|
+
if (payloadNetwork !== requirementsNetwork) {
|
|
81
|
+
return {
|
|
82
|
+
isValid: false,
|
|
83
|
+
invalidReason: "network_mismatch",
|
|
84
|
+
payer: authorization.from
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
} catch {
|
|
88
|
+
return {
|
|
89
|
+
isValid: false,
|
|
90
|
+
invalidReason: "invalid_network",
|
|
91
|
+
payer: authorization.from
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
Cell.fromBase64(tonPayload.signedBoc);
|
|
96
|
+
} catch {
|
|
97
|
+
return {
|
|
98
|
+
isValid: false,
|
|
99
|
+
invalidReason: "invalid_boc_format",
|
|
100
|
+
payer: authorization.from
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const verifyResult = await this.signer.verifyMessage({
|
|
104
|
+
signedBoc: tonPayload.signedBoc,
|
|
105
|
+
expectedFrom: authorization.from,
|
|
106
|
+
expectedTransfer: {
|
|
107
|
+
jettonAmount: BigInt(authorization.jettonAmount),
|
|
108
|
+
destination: requirements.payTo,
|
|
109
|
+
jettonMaster: requirements.asset
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
if (!verifyResult.valid) {
|
|
113
|
+
return {
|
|
114
|
+
isValid: false,
|
|
115
|
+
invalidReason: verifyResult.reason || "message_verification_failed",
|
|
116
|
+
payer: authorization.from
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
120
|
+
if (authorization.validUntil < now + 30) {
|
|
121
|
+
return {
|
|
122
|
+
isValid: false,
|
|
123
|
+
invalidReason: "authorization_expired",
|
|
124
|
+
payer: authorization.from
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
const balance = await this.signer.getJettonBalance({
|
|
129
|
+
ownerAddress: authorization.from,
|
|
130
|
+
jettonMasterAddress: requirements.asset
|
|
131
|
+
});
|
|
132
|
+
if (balance < BigInt(requirements.amount)) {
|
|
133
|
+
return {
|
|
134
|
+
isValid: false,
|
|
135
|
+
invalidReason: "insufficient_jetton_balance",
|
|
136
|
+
payer: authorization.from
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
} catch (error) {
|
|
140
|
+
console.warn("Could not verify Jetton balance:", error);
|
|
141
|
+
}
|
|
142
|
+
if (BigInt(authorization.jettonAmount) < BigInt(requirements.amount)) {
|
|
143
|
+
return {
|
|
144
|
+
isValid: false,
|
|
145
|
+
invalidReason: "insufficient_amount",
|
|
146
|
+
payer: authorization.from
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (!addressesEqual(authorization.to, requirements.payTo)) {
|
|
150
|
+
return {
|
|
151
|
+
isValid: false,
|
|
152
|
+
invalidReason: "recipient_mismatch",
|
|
153
|
+
payer: authorization.from
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
if (!addressesEqual(authorization.jettonMaster, requirements.asset)) {
|
|
157
|
+
return {
|
|
158
|
+
isValid: false,
|
|
159
|
+
invalidReason: "asset_mismatch",
|
|
160
|
+
payer: authorization.from
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const currentSeqno = await this.signer.getSeqno(authorization.from);
|
|
165
|
+
if (authorization.seqno < currentSeqno) {
|
|
166
|
+
return {
|
|
167
|
+
isValid: false,
|
|
168
|
+
invalidReason: "seqno_already_used",
|
|
169
|
+
payer: authorization.from
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
if (authorization.seqno > currentSeqno) {
|
|
173
|
+
return {
|
|
174
|
+
isValid: false,
|
|
175
|
+
invalidReason: "seqno_too_high",
|
|
176
|
+
payer: authorization.from
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
} catch (error) {
|
|
180
|
+
console.warn("Could not verify seqno:", error);
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
const isDeployed = await this.signer.isDeployed(authorization.from);
|
|
184
|
+
if (!isDeployed) {
|
|
185
|
+
return {
|
|
186
|
+
isValid: false,
|
|
187
|
+
invalidReason: "wallet_not_deployed",
|
|
188
|
+
payer: authorization.from
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
} catch (error) {
|
|
192
|
+
console.warn("Could not verify wallet deployment:", error);
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
isValid: true,
|
|
196
|
+
invalidReason: void 0,
|
|
197
|
+
payer: authorization.from
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Settles a payment by broadcasting the signed message.
|
|
202
|
+
*
|
|
203
|
+
* @param payload - The payment payload to settle
|
|
204
|
+
* @param requirements - The payment requirements
|
|
205
|
+
* @returns Promise resolving to settlement response
|
|
206
|
+
*/
|
|
207
|
+
async settle(payload, requirements) {
|
|
208
|
+
const tonPayload = payload.payload;
|
|
209
|
+
const verifyResult = await this.verify(payload, requirements);
|
|
210
|
+
if (!verifyResult.isValid) {
|
|
211
|
+
return {
|
|
212
|
+
success: false,
|
|
213
|
+
network: payload.accepted.network,
|
|
214
|
+
transaction: "",
|
|
215
|
+
errorReason: verifyResult.invalidReason ?? "verification_failed",
|
|
216
|
+
payer: tonPayload.authorization.from
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const txHash = await this.signer.sendExternalMessage(tonPayload.signedBoc);
|
|
221
|
+
const confirmation = await this.signer.waitForTransaction({
|
|
222
|
+
address: tonPayload.authorization.from,
|
|
223
|
+
seqno: tonPayload.authorization.seqno + 1,
|
|
224
|
+
// Wait for next seqno
|
|
225
|
+
timeout: 6e4
|
|
226
|
+
// 60 second timeout
|
|
227
|
+
});
|
|
228
|
+
if (!confirmation.success) {
|
|
229
|
+
return {
|
|
230
|
+
success: false,
|
|
231
|
+
errorReason: confirmation.error || "transaction_not_confirmed",
|
|
232
|
+
transaction: txHash,
|
|
233
|
+
network: payload.accepted.network,
|
|
234
|
+
payer: tonPayload.authorization.from
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
success: true,
|
|
239
|
+
transaction: confirmation.hash || txHash,
|
|
240
|
+
network: payload.accepted.network,
|
|
241
|
+
payer: tonPayload.authorization.from
|
|
242
|
+
};
|
|
243
|
+
} catch (error) {
|
|
244
|
+
console.error("Failed to settle TON transaction:", error);
|
|
245
|
+
return {
|
|
246
|
+
success: false,
|
|
247
|
+
errorReason: "transaction_failed",
|
|
248
|
+
transaction: "",
|
|
249
|
+
network: payload.accepted.network,
|
|
250
|
+
payer: tonPayload.authorization.from
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
export {
|
|
256
|
+
ExactTonScheme
|
|
257
|
+
};
|
|
258
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/exact/facilitator/scheme.ts"],"sourcesContent":["/**\n * TON Facilitator Scheme Implementation\n *\n * Verifies and settles TON Jetton payments using the exact scheme.\n * Validates signed messages and broadcasts transactions to the network.\n */\n\nimport { Cell } from \"@ton/core\";\nimport type {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport type { FacilitatorTonSigner } from \"../../signer.js\";\nimport type { ExactTonPayloadV2 } from \"../../types.js\";\nimport { SCHEME_EXACT } from \"../../constants.js\";\nimport { addressesEqual, normalizeNetwork } from \"../../utils.js\";\n\n/**\n * Configuration options for ExactTonScheme facilitator\n */\nexport interface ExactTonSchemeConfig {\n /** Whether this facilitator can sponsor gas for transactions */\n canSponsorGas?: boolean;\n}\n\n/**\n * TON facilitator implementation for the Exact payment scheme.\n *\n * Verifies signed Jetton transfer messages and broadcasts them\n * to the TON network to complete payments.\n */\nexport class ExactTonScheme implements SchemeNetworkFacilitator {\n readonly scheme = SCHEME_EXACT;\n readonly caipFamily = \"ton:*\";\n private config: ExactTonSchemeConfig;\n\n /**\n * Creates a new ExactTonScheme facilitator instance.\n *\n * @param signer - The TON signer for facilitator operations\n * @param config - Optional configuration\n */\n constructor(\n private readonly signer: FacilitatorTonSigner,\n config: ExactTonSchemeConfig = {},\n ) {\n this.config = config;\n }\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n * For TON, optionally returns gas sponsor address if configured.\n *\n * @param network - The network identifier\n * @returns Extra data object or undefined\n */\n getExtra(network: string): Record<string, unknown> | undefined {\n void network;\n\n if (this.config.canSponsorGas) {\n const addresses = this.signer.getAddresses();\n if (addresses.length > 0) {\n return {\n gasSponsor: addresses[0],\n };\n }\n }\n\n return undefined;\n }\n\n /**\n * Get signer addresses used by this facilitator.\n * Returns all addresses this facilitator can use for operations.\n *\n * @param network - The network identifier\n * @returns Array of facilitator addresses\n */\n getSigners(network: string): string[] {\n void network;\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies a payment payload.\n *\n * Performs comprehensive validation:\n * 1. Scheme and network matching\n * 2. BOC format validation\n * 3. Message structure verification\n * 4. Authorization expiry check\n * 5. Balance verification\n * 6. Amount and recipient validation\n *\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @returns Promise resolving to verification response\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const tonPayload = payload.payload as ExactTonPayloadV2;\n const authorization = tonPayload.authorization;\n\n // Step 1: Verify scheme matches\n if (payload.accepted.scheme !== SCHEME_EXACT || requirements.scheme !== SCHEME_EXACT) {\n return {\n isValid: false,\n invalidReason: \"unsupported_scheme\",\n payer: authorization.from,\n };\n }\n\n // Step 2: Verify network matches\n try {\n const payloadNetwork = normalizeNetwork(payload.accepted.network);\n const requirementsNetwork = normalizeNetwork(requirements.network);\n\n if (payloadNetwork !== requirementsNetwork) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n payer: authorization.from,\n };\n }\n } catch {\n return {\n isValid: false,\n invalidReason: \"invalid_network\",\n payer: authorization.from,\n };\n }\n\n // Step 3: Parse and validate the signed BOC\n try {\n Cell.fromBase64(tonPayload.signedBoc);\n } catch {\n return {\n isValid: false,\n invalidReason: \"invalid_boc_format\",\n payer: authorization.from,\n };\n }\n\n // Step 4: Verify the message structure and parameters\n const verifyResult = await this.signer.verifyMessage({\n signedBoc: tonPayload.signedBoc,\n expectedFrom: authorization.from,\n expectedTransfer: {\n jettonAmount: BigInt(authorization.jettonAmount),\n destination: requirements.payTo,\n jettonMaster: requirements.asset,\n },\n });\n\n if (!verifyResult.valid) {\n return {\n isValid: false,\n invalidReason: verifyResult.reason || \"message_verification_failed\",\n payer: authorization.from,\n };\n }\n\n // Step 5: Check validUntil is in the future (with 30 second buffer)\n const now = Math.floor(Date.now() / 1000);\n if (authorization.validUntil < now + 30) {\n return {\n isValid: false,\n invalidReason: \"authorization_expired\",\n payer: authorization.from,\n };\n }\n\n // Step 6: Verify Jetton balance\n try {\n const balance = await this.signer.getJettonBalance({\n ownerAddress: authorization.from,\n jettonMasterAddress: requirements.asset,\n });\n\n if (balance < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_jetton_balance\",\n payer: authorization.from,\n };\n }\n } catch (error) {\n // If we can't check balance, log warning but continue\n console.warn(\"Could not verify Jetton balance:\", error);\n }\n\n // Step 7: Verify amount is sufficient\n if (BigInt(authorization.jettonAmount) < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_amount\",\n payer: authorization.from,\n };\n }\n\n // Step 8: Verify recipient matches\n if (!addressesEqual(authorization.to, requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: \"recipient_mismatch\",\n payer: authorization.from,\n };\n }\n\n // Step 9: Verify Jetton master matches\n if (!addressesEqual(authorization.jettonMaster, requirements.asset)) {\n return {\n isValid: false,\n invalidReason: \"asset_mismatch\",\n payer: authorization.from,\n };\n }\n\n // Step 10: Check seqno hasn't been used (replay protection)\n try {\n const currentSeqno = await this.signer.getSeqno(authorization.from);\n if (authorization.seqno < currentSeqno) {\n return {\n isValid: false,\n invalidReason: \"seqno_already_used\",\n payer: authorization.from,\n };\n }\n if (authorization.seqno > currentSeqno) {\n return {\n isValid: false,\n invalidReason: \"seqno_too_high\",\n payer: authorization.from,\n };\n }\n } catch (error) {\n console.warn(\"Could not verify seqno:\", error);\n }\n\n // Step 11: Verify wallet is deployed\n try {\n const isDeployed = await this.signer.isDeployed(authorization.from);\n if (!isDeployed) {\n return {\n isValid: false,\n invalidReason: \"wallet_not_deployed\",\n payer: authorization.from,\n };\n }\n } catch (error) {\n console.warn(\"Could not verify wallet deployment:\", error);\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer: authorization.from,\n };\n }\n\n /**\n * Settles a payment by broadcasting the signed message.\n *\n * @param payload - The payment payload to settle\n * @param requirements - The payment requirements\n * @returns Promise resolving to settlement response\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const tonPayload = payload.payload as ExactTonPayloadV2;\n\n // Re-verify before settling\n const verifyResult = await this.verify(payload, requirements);\n if (!verifyResult.isValid) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: verifyResult.invalidReason ?? \"verification_failed\",\n payer: tonPayload.authorization.from,\n };\n }\n\n try {\n // Send the pre-signed external message\n const txHash = await this.signer.sendExternalMessage(tonPayload.signedBoc);\n\n // Wait for confirmation\n const confirmation = await this.signer.waitForTransaction({\n address: tonPayload.authorization.from,\n seqno: tonPayload.authorization.seqno + 1, // Wait for next seqno\n timeout: 60000, // 60 second timeout\n });\n\n if (!confirmation.success) {\n return {\n success: false,\n errorReason: confirmation.error || \"transaction_not_confirmed\",\n transaction: txHash,\n network: payload.accepted.network,\n payer: tonPayload.authorization.from,\n };\n }\n\n return {\n success: true,\n transaction: confirmation.hash || txHash,\n network: payload.accepted.network,\n payer: tonPayload.authorization.from,\n };\n } catch (error) {\n console.error(\"Failed to settle TON transaction:\", error);\n return {\n success: false,\n errorReason: \"transaction_failed\",\n transaction: \"\",\n network: payload.accepted.network,\n payer: tonPayload.authorization.from,\n };\n }\n }\n}\n"],"mappings":"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","names":[]}
|