@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
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { SchemeNetworkClient, PaymentRequirements, PaymentPayload } from '@t402/core/types';
|
|
2
|
-
import { C as ClientTonSigner } from '../../signer-
|
|
1
|
+
import { SchemeNetworkClient, PaymentRequirements, PaymentPayload, Network } from '@t402/core/types';
|
|
2
|
+
import { C as ClientTonSigner } from '../../signer-Bqn2K0b4.mjs';
|
|
3
|
+
import { t402Client, PaymentPolicy } from '@t402/core/client';
|
|
3
4
|
import '@ton/core';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -47,7 +48,65 @@ declare class ExactTonScheme implements SchemeNetworkClient {
|
|
|
47
48
|
* @param paymentRequirements - The payment requirements
|
|
48
49
|
* @returns Promise resolving to a payment payload
|
|
49
50
|
*/
|
|
50
|
-
createPaymentPayload(t402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload,
|
|
51
|
+
createPaymentPayload(t402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, 't402Version' | 'payload'>>;
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Configuration options for registering TON schemes to an t402Client
|
|
56
|
+
*/
|
|
57
|
+
interface TonClientConfig {
|
|
58
|
+
/**
|
|
59
|
+
* The TON signer to use for creating payment payloads
|
|
60
|
+
*/
|
|
61
|
+
signer: ClientTonSigner;
|
|
62
|
+
/**
|
|
63
|
+
* Function to get Jetton wallet address for a given owner and Jetton master
|
|
64
|
+
* This is required for building Jetton transfer messages
|
|
65
|
+
*/
|
|
66
|
+
getJettonWalletAddress: (ownerAddress: string, jettonMasterAddress: string) => Promise<string>;
|
|
67
|
+
/**
|
|
68
|
+
* Optional policies to apply to the client
|
|
69
|
+
*/
|
|
70
|
+
policies?: PaymentPolicy[];
|
|
71
|
+
/**
|
|
72
|
+
* Optional specific networks to register
|
|
73
|
+
* If not provided, registers wildcard support (ton:*)
|
|
74
|
+
*/
|
|
75
|
+
networks?: Network[];
|
|
76
|
+
/**
|
|
77
|
+
* Optional scheme configuration (gas amounts, etc.)
|
|
78
|
+
*/
|
|
79
|
+
schemeConfig?: ExactTonSchemeConfig;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Registers TON exact payment schemes to an t402Client instance.
|
|
83
|
+
*
|
|
84
|
+
* This function registers:
|
|
85
|
+
* - V2: ton:* wildcard scheme with ExactTonScheme (or specific networks if provided)
|
|
86
|
+
*
|
|
87
|
+
* @param client - The t402Client instance to register schemes to
|
|
88
|
+
* @param config - Configuration for TON client registration
|
|
89
|
+
* @returns The client instance for chaining
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* import { registerExactTonScheme } from "@t402/ton/exact/client/register";
|
|
94
|
+
* import { t402Client } from "@t402/core/client";
|
|
95
|
+
* import { TonClient } from "@ton/ton";
|
|
96
|
+
*
|
|
97
|
+
* const tonClient = new TonClient({ endpoint: "..." });
|
|
98
|
+
* const wallet = WalletContractV4.create({ ... });
|
|
99
|
+
*
|
|
100
|
+
* const client = new t402Client();
|
|
101
|
+
* registerExactTonScheme(client, {
|
|
102
|
+
* signer: toClientTonSigner(wallet, tonClient),
|
|
103
|
+
* getJettonWalletAddress: async (owner, master) => {
|
|
104
|
+
* // Derive Jetton wallet address
|
|
105
|
+
* return jettonWalletAddress;
|
|
106
|
+
* }
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
declare function registerExactTonScheme(client: t402Client, config: TonClientConfig): t402Client;
|
|
111
|
+
|
|
112
|
+
export { ExactTonScheme, type ExactTonSchemeConfig, type TonClientConfig, registerExactTonScheme };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ExactTonScheme
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
ExactTonScheme,
|
|
3
|
+
registerExactTonScheme
|
|
4
|
+
} from "../../chunk-7OE2PWYP.mjs";
|
|
5
|
+
import "../../chunk-3BN2G4M7.mjs";
|
|
5
6
|
export {
|
|
6
|
-
ExactTonScheme
|
|
7
|
+
ExactTonScheme,
|
|
8
|
+
registerExactTonScheme
|
|
7
9
|
};
|
|
8
10
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { SchemeNetworkFacilitator, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse } from '@t402/core/types';
|
|
2
|
-
import { F as FacilitatorTonSigner } from '../../signer-
|
|
1
|
+
import { SchemeNetworkFacilitator, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse, Network } from '@t402/core/types';
|
|
2
|
+
import { F as FacilitatorTonSigner } from '../../signer-Bqn2K0b4.mjs';
|
|
3
|
+
import { t402Facilitator } from '@t402/core/facilitator';
|
|
3
4
|
import '@ton/core';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -76,4 +77,63 @@ declare class ExactTonScheme implements SchemeNetworkFacilitator {
|
|
|
76
77
|
settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Configuration options for registering TON schemes to an t402Facilitator
|
|
82
|
+
*/
|
|
83
|
+
interface TonFacilitatorConfig {
|
|
84
|
+
/**
|
|
85
|
+
* The TON signer for facilitator operations (verify and settle)
|
|
86
|
+
*/
|
|
87
|
+
signer: FacilitatorTonSigner;
|
|
88
|
+
/**
|
|
89
|
+
* Networks to register (single network or array of networks)
|
|
90
|
+
* Examples: "ton:mainnet", ["ton:mainnet", "ton:testnet"]
|
|
91
|
+
*/
|
|
92
|
+
networks: Network | Network[];
|
|
93
|
+
/**
|
|
94
|
+
* Optional scheme configuration (gas sponsorship, etc.)
|
|
95
|
+
*/
|
|
96
|
+
schemeConfig?: ExactTonSchemeConfig;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Registers TON exact payment schemes to an t402Facilitator instance.
|
|
100
|
+
*
|
|
101
|
+
* This function registers:
|
|
102
|
+
* - V2: Specified networks with ExactTonScheme
|
|
103
|
+
*
|
|
104
|
+
* @param facilitator - The t402Facilitator instance to register schemes to
|
|
105
|
+
* @param config - Configuration for TON facilitator registration
|
|
106
|
+
* @returns The facilitator instance for chaining
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* import { registerExactTonScheme } from "@t402/ton/exact/facilitator/register";
|
|
111
|
+
* import { t402Facilitator } from "@t402/core/facilitator";
|
|
112
|
+
* import { TonClient } from "@ton/ton";
|
|
113
|
+
*
|
|
114
|
+
* const tonClient = new TonClient({ endpoint: "..." });
|
|
115
|
+
* const facilitator = new t402Facilitator();
|
|
116
|
+
*
|
|
117
|
+
* // Single network
|
|
118
|
+
* registerExactTonScheme(facilitator, {
|
|
119
|
+
* signer: toFacilitatorTonSigner(tonClient),
|
|
120
|
+
* networks: "ton:mainnet"
|
|
121
|
+
* });
|
|
122
|
+
*
|
|
123
|
+
* // Multiple networks
|
|
124
|
+
* registerExactTonScheme(facilitator, {
|
|
125
|
+
* signer: toFacilitatorTonSigner(tonClient),
|
|
126
|
+
* networks: ["ton:mainnet", "ton:testnet"]
|
|
127
|
+
* });
|
|
128
|
+
*
|
|
129
|
+
* // With gas sponsorship
|
|
130
|
+
* registerExactTonScheme(facilitator, {
|
|
131
|
+
* signer: toFacilitatorTonSigner(tonClient),
|
|
132
|
+
* networks: "ton:mainnet",
|
|
133
|
+
* schemeConfig: { canSponsorGas: true }
|
|
134
|
+
* });
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
declare function registerExactTonScheme(facilitator: t402Facilitator, config: TonFacilitatorConfig): t402Facilitator;
|
|
138
|
+
|
|
139
|
+
export { ExactTonScheme, type ExactTonSchemeConfig, type TonFacilitatorConfig, registerExactTonScheme };
|
|
@@ -1,258 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
};
|
|
2
|
+
ExactTonScheme,
|
|
3
|
+
registerExactTonScheme
|
|
4
|
+
} from "../../chunk-ZJA7AWWH.mjs";
|
|
5
|
+
import "../../chunk-3BN2G4M7.mjs";
|
|
255
6
|
export {
|
|
256
|
-
ExactTonScheme
|
|
7
|
+
ExactTonScheme,
|
|
8
|
+
registerExactTonScheme
|
|
257
9
|
};
|
|
258
10
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +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":";;;;;;;AAOA,SAAS,YAAY;AA2Bd,IAAM,iBAAN,MAAyD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW9D,YACmB,QACjB,SAA+B,CAAC,GAChC;AAFiB;AAXnB,SAAS,SAAS;AAClB,SAAS,aAAa;AAapB,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,SAAS,SAAsD;AAC7D,SAAK;AAEL,QAAI,KAAK,OAAO,eAAe;AAC7B,YAAM,YAAY,KAAK,OAAO,aAAa;AAC3C,UAAI,UAAU,SAAS,GAAG;AACxB,eAAO;AAAA,UACL,YAAY,UAAU,CAAC;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW,SAA2B;AACpC,SAAK;AACL,WAAO,CAAC,GAAG,KAAK,OAAO,aAAa,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,OACJ,SACA,cACyB;AACzB,UAAM,aAAa,QAAQ;AAC3B,UAAM,gBAAgB,WAAW;AAGjC,QAAI,QAAQ,SAAS,WAAW,gBAAgB,aAAa,WAAW,cAAc;AACpF,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAGA,QAAI;AACF,YAAM,iBAAiB,iBAAiB,QAAQ,SAAS,OAAO;AAChE,YAAM,sBAAsB,iBAAiB,aAAa,OAAO;AAEjE,UAAI,mBAAmB,qBAAqB;AAC1C,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,cAAc;AAAA,QACvB;AAAA,MACF;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAGA,QAAI;AACF,WAAK,WAAW,WAAW,SAAS;AAAA,IACtC,QAAQ;AACN,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAGA,UAAM,eAAe,MAAM,KAAK,OAAO,cAAc;AAAA,MACnD,WAAW,WAAW;AAAA,MACtB,cAAc,cAAc;AAAA,MAC5B,kBAAkB;AAAA,QAChB,cAAc,OAAO,cAAc,YAAY;AAAA,QAC/C,aAAa,aAAa;AAAA,QAC1B,cAAc,aAAa;AAAA,MAC7B;AAAA,IACF,CAAC;AAED,QAAI,CAAC,aAAa,OAAO;AACvB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe,aAAa,UAAU;AAAA,QACtC,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAGA,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAI,cAAc,aAAa,MAAM,IAAI;AACvC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAGA,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,OAAO,iBAAiB;AAAA,QACjD,cAAc,cAAc;AAAA,QAC5B,qBAAqB,aAAa;AAAA,MACpC,CAAC;AAED,UAAI,UAAU,OAAO,aAAa,MAAM,GAAG;AACzC,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,cAAc;AAAA,QACvB;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AAEd,cAAQ,KAAK,oCAAoC,KAAK;AAAA,IACxD;AAGA,QAAI,OAAO,cAAc,YAAY,IAAI,OAAO,aAAa,MAAM,GAAG;AACpE,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAGA,QAAI,CAAC,eAAe,cAAc,IAAI,aAAa,KAAK,GAAG;AACzD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAGA,QAAI,CAAC,eAAe,cAAc,cAAc,aAAa,KAAK,GAAG;AACnE,aAAO;AAAA,QACL,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAGA,QAAI;AACF,YAAM,eAAe,MAAM,KAAK,OAAO,SAAS,cAAc,IAAI;AAClE,UAAI,cAAc,QAAQ,cAAc;AACtC,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,cAAc;AAAA,QACvB;AAAA,MACF;AACA,UAAI,cAAc,QAAQ,cAAc;AACtC,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,cAAc;AAAA,QACvB;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,2BAA2B,KAAK;AAAA,IAC/C;AAGA,QAAI;AACF,YAAM,aAAa,MAAM,KAAK,OAAO,WAAW,cAAc,IAAI;AAClE,UAAI,CAAC,YAAY;AACf,eAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,OAAO,cAAc;AAAA,QACvB;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,uCAAuC,KAAK;AAAA,IAC3D;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,eAAe;AAAA,MACf,OAAO,cAAc;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,SACA,cACyB;AACzB,UAAM,aAAa,QAAQ;AAG3B,UAAM,eAAe,MAAM,KAAK,OAAO,SAAS,YAAY;AAC5D,QAAI,CAAC,aAAa,SAAS;AACzB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,QAAQ,SAAS;AAAA,QAC1B,aAAa;AAAA,QACb,aAAa,aAAa,iBAAiB;AAAA,QAC3C,OAAO,WAAW,cAAc;AAAA,MAClC;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,SAAS,MAAM,KAAK,OAAO,oBAAoB,WAAW,SAAS;AAGzE,YAAM,eAAe,MAAM,KAAK,OAAO,mBAAmB;AAAA,QACxD,SAAS,WAAW,cAAc;AAAA,QAClC,OAAO,WAAW,cAAc,QAAQ;AAAA;AAAA,QACxC,SAAS;AAAA;AAAA,MACX,CAAC;AAED,UAAI,CAAC,aAAa,SAAS;AACzB,eAAO;AAAA,UACL,SAAS;AAAA,UACT,aAAa,aAAa,SAAS;AAAA,UACnC,aAAa;AAAA,UACb,SAAS,QAAQ,SAAS;AAAA,UAC1B,OAAO,WAAW,cAAc;AAAA,QAClC;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa,aAAa,QAAQ;AAAA,QAClC,SAAS,QAAQ,SAAS;AAAA,QAC1B,OAAO,WAAW,cAAc;AAAA,MAClC;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,qCAAqC,KAAK;AACxD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,aAAa;AAAA,QACb,aAAa;AAAA,QACb,SAAS,QAAQ,SAAS;AAAA,QAC1B,OAAO,WAAW,cAAc;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SchemeNetworkServer, MoneyParser, Price, Network, AssetAmount, PaymentRequirements } from '@t402/core/types';
|
|
2
|
+
import { t402ResourceServer } from '@t402/core/server';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* TON Server Scheme Implementation
|
|
@@ -106,22 +107,6 @@ declare class ExactTonScheme implements SchemeNetworkServer {
|
|
|
106
107
|
* @returns The Jetton configuration
|
|
107
108
|
*/
|
|
108
109
|
private getDefaultAsset;
|
|
109
|
-
/**
|
|
110
|
-
* Get Jetton info for a given symbol on a network
|
|
111
|
-
*
|
|
112
|
-
* @param symbol - The Jetton symbol (e.g., "USDT")
|
|
113
|
-
* @param network - The network to use
|
|
114
|
-
* @returns The Jetton configuration
|
|
115
|
-
*/
|
|
116
|
-
private getAssetInfo;
|
|
117
|
-
/**
|
|
118
|
-
* Get the number of decimals for a Jetton on a network
|
|
119
|
-
*
|
|
120
|
-
* @param network - The network to use
|
|
121
|
-
* @param jettonAddress - Optional Jetton address to look up
|
|
122
|
-
* @returns The number of decimals for the Jetton
|
|
123
|
-
*/
|
|
124
|
-
private getAssetDecimals;
|
|
125
110
|
/**
|
|
126
111
|
* Get all supported networks
|
|
127
112
|
*/
|
|
@@ -132,4 +117,44 @@ declare class ExactTonScheme implements SchemeNetworkServer {
|
|
|
132
117
|
static isNetworkSupported(network: string): boolean;
|
|
133
118
|
}
|
|
134
119
|
|
|
135
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Configuration options for registering TON schemes to an t402ResourceServer
|
|
122
|
+
*/
|
|
123
|
+
interface TonResourceServerConfig {
|
|
124
|
+
/**
|
|
125
|
+
* Optional specific networks to register
|
|
126
|
+
* If not provided, registers wildcard support (ton:*)
|
|
127
|
+
*/
|
|
128
|
+
networks?: Network[];
|
|
129
|
+
/**
|
|
130
|
+
* Optional scheme configuration (preferred Jetton, etc.)
|
|
131
|
+
*/
|
|
132
|
+
schemeConfig?: ExactTonSchemeConfig;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Registers TON exact payment schemes to an t402ResourceServer instance.
|
|
136
|
+
*
|
|
137
|
+
* This function registers:
|
|
138
|
+
* - V2: ton:* wildcard scheme with ExactTonScheme (or specific networks if provided)
|
|
139
|
+
*
|
|
140
|
+
* @param server - The t402ResourceServer instance to register schemes to
|
|
141
|
+
* @param config - Configuration for TON resource server registration
|
|
142
|
+
* @returns The server instance for chaining
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* import { registerExactTonScheme } from "@t402/ton/exact/server/register";
|
|
147
|
+
* import { t402ResourceServer } from "@t402/core/server";
|
|
148
|
+
*
|
|
149
|
+
* const server = new t402ResourceServer(facilitatorClient);
|
|
150
|
+
* registerExactTonScheme(server, {});
|
|
151
|
+
*
|
|
152
|
+
* // Or with specific Jetton preference
|
|
153
|
+
* registerExactTonScheme(server, {
|
|
154
|
+
* schemeConfig: { preferredJetton: "USDT" }
|
|
155
|
+
* });
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
declare function registerExactTonScheme(server: t402ResourceServer, config?: TonResourceServerConfig): t402ResourceServer;
|
|
159
|
+
|
|
160
|
+
export { ExactTonScheme, type ExactTonSchemeConfig, type TonResourceServerConfig, registerExactTonScheme };
|