@tychilabs/stonfi-gasless-sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tychi Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # STON.fi Gasless SDK
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@tychilabs/stonfi-gasless-sdk.svg)](https://www.npmjs.com/package/@tychilabs/stonfi-gasless-sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Universal Gas Framework SDK for paying TON transaction fees with STON tokens.
7
+
8
+ **By Tychi Labs**
9
+
10
+ ## Overview
11
+
12
+ The STON.fi Gasless SDK enables developers to build applications where users pay transaction fees with STON tokens instead of TON. This eliminates the friction of requiring users to hold native tokens for gas, making blockchain interactions more accessible and user-friendly.
13
+
14
+ ## Why UGF?
15
+
16
+ Traditional blockchain transactions create barriers for new users who must acquire native tokens just to pay gas fees. Universal Gas Framework solves this by:
17
+
18
+ - **Simplifying User Experience** - Users can transact using only STON tokens, removing the need to manage multiple token types
19
+ - **Supporting DeFi Ecosystem** - Locked STON provides liquidity to STON.fi, strengthening the broader ecosystem
20
+ - **Enabling Gasless Flows** - Developers can create seamless onboarding experiences where users never think about gas fees
21
+ - **Maintaining Security** - All transactions are cryptographically signed and verified on-chain
22
+
23
+ Whether you're building a DEX, NFT marketplace, or any dApp on TON, UGF enables truly gasless user experiences while leveraging STON's liquidity.
24
+
25
+ ## How It Works
26
+
27
+ 1. Users lock STON tokens in the UGF escrow contract
28
+ 2. Locked STON becomes an x402 balance used for gas payments
29
+ 3. Your application requests a quote via the SDK
30
+ 4. User signs the payment digest
31
+ 5. UGF verifies the signature and deducts STON
32
+ 6. The contract pays TON gas fees on the user's behalf
33
+ 7. Transaction executes seamlessly
34
+
35
+ No relaying, no wrapped tokens - just direct gas payment with STON.
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ npm install @tychilabs/stonfi-gasless-sdk
41
+ ```
42
+
43
+ ## Requirements
44
+
45
+ - Node.js 16 or higher
46
+ - `@ton/core` >= 0.63.0 (peer dependency)
47
+ - API Key - Contact us at support@tychilabs.com to get started
48
+
49
+ ## Features
50
+
51
+ - **STON Gas Payments** - Pay transaction fees with STON instead of TON
52
+ - **Cryptographic Signing** - Built-in utilities for digest signing and verification
53
+ - **Full TypeScript Support** - Complete type definitions for all API interactions
54
+ - **Simple, Intuitive API** - Clean interfaces that follow modern JavaScript patterns
55
+ - **Comprehensive Error Handling** - Typed error classes for precise error management
56
+ - **Production Ready** - Battle-tested code with proper validation and security measures
57
+
58
+ ## Documentation
59
+
60
+ Complete guides and references to get you started:
61
+
62
+ - [Quick Start Guide](./docs/QUICKSTART.md) - Get up and running in 5 minutes
63
+ - [API Reference](./docs/API.md) - Detailed documentation of all SDK methods
64
+
65
+ ## Use Cases
66
+
67
+ - **DEX Integrations** - Enable token swaps without requiring TON for gas
68
+ - **NFT Marketplaces** - Let users mint and trade NFTs using only STON
69
+ - **Gaming dApps** - Simplify in-game transactions by eliminating gas fee complexity
70
+ - **Onboarding Flows** - Create seamless signup experiences without native token requirements
71
+ - **DeFi Applications** - Build lending, staking, or yield farming platforms with gasless UX
72
+
73
+ ## Coming Soon
74
+
75
+ **ston.universalgasframework.com** - Self-service portal for API key management, analytics, and monitoring
76
+
77
+ ## Getting Help
78
+
79
+ We're here to support your integration:
80
+
81
+ - **Technical Issues** - [GitHub Issues](https://github.com/TychiWallet/stonfi-gasless-sdk/issues)
82
+ - **Integration Support** - Email us at yash@tychilabs.com
83
+ - **Feature Requests** - Open a discussion on GitHub
84
+
85
+ ## Contributing
86
+
87
+ We welcome contributions from the community. Please see our contributing guidelines and feel free to submit issues or pull requests.
88
+
89
+ ## License
90
+
91
+ MIT © Tychi Labs
package/dist/index.cjs ADDED
@@ -0,0 +1,369 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ DEFAULT_CONFIG: () => DEFAULT_CONFIG,
34
+ GasLimitExceededError: () => GasLimitExceededError,
35
+ InsufficientBalanceError: () => InsufficientBalanceError,
36
+ InvalidChainError: () => InvalidChainError,
37
+ InvalidPaymentCoinError: () => InvalidPaymentCoinError,
38
+ InvalidSignatureError: () => InvalidSignatureError,
39
+ MissingDigestError: () => MissingDigestError,
40
+ NetworkError: () => NetworkError,
41
+ PayerMismatchError: () => PayerMismatchError,
42
+ QuoteExpiredError: () => QuoteExpiredError,
43
+ QuoteNotFoundError: () => QuoteNotFoundError,
44
+ StatusNotFoundError: () => StatusNotFoundError,
45
+ UGFClient: () => UGFClient,
46
+ UGFError: () => UGFError,
47
+ UnauthorizedError: () => UnauthorizedError,
48
+ formatSTON: () => formatSTON,
49
+ fromNano: () => fromNano,
50
+ isValidBufferPct: () => isValidBufferPct,
51
+ isValidGasEstimate: () => isValidGasEstimate,
52
+ isValidHex: () => isValidHex,
53
+ isValidTONAddress: () => isValidTONAddress,
54
+ parseBackendError: () => parseBackendError,
55
+ signDigest: () => signDigest,
56
+ toNano: () => toNano,
57
+ verifySignature: () => verifySignature
58
+ });
59
+ module.exports = __toCommonJS(index_exports);
60
+
61
+ // src/utils/errors.ts
62
+ var UGFError = class extends Error {
63
+ constructor(message, code) {
64
+ super(message);
65
+ this.code = code;
66
+ this.name = "UGFError";
67
+ }
68
+ };
69
+ var QuoteNotFoundError = class extends UGFError {
70
+ constructor() {
71
+ super("quote not found or expired", "QUOTE_NOT_FOUND");
72
+ }
73
+ };
74
+ var QuoteExpiredError = class extends UGFError {
75
+ constructor() {
76
+ super("quote expired", "QUOTE_EXPIRED");
77
+ }
78
+ };
79
+ var PayerMismatchError = class extends UGFError {
80
+ constructor() {
81
+ super("payer mismatch", "PAYER_MISMATCH");
82
+ }
83
+ };
84
+ var InvalidSignatureError = class extends UGFError {
85
+ constructor() {
86
+ super("invalid signature", "INVALID_SIGNATURE");
87
+ }
88
+ };
89
+ var InsufficientBalanceError = class extends UGFError {
90
+ constructor() {
91
+ super("insufficient locked balance", "INSUFFICIENT_BALANCE");
92
+ }
93
+ };
94
+ var InvalidChainError = class extends UGFError {
95
+ constructor() {
96
+ super("invalid chain", "INVALID_CHAIN");
97
+ }
98
+ };
99
+ var InvalidPaymentCoinError = class extends UGFError {
100
+ constructor() {
101
+ super("invalid payment coin", "INVALID_COIN");
102
+ }
103
+ };
104
+ var GasLimitExceededError = class extends UGFError {
105
+ constructor() {
106
+ super("gas exceeds 0.5 TON limit", "GAS_LIMIT_EXCEEDED");
107
+ }
108
+ };
109
+ var MissingDigestError = class extends UGFError {
110
+ constructor() {
111
+ super("missing digest", "MISSING_DIGEST");
112
+ }
113
+ };
114
+ var StatusNotFoundError = class extends UGFError {
115
+ constructor() {
116
+ super("status not found", "STATUS_NOT_FOUND");
117
+ }
118
+ };
119
+ var UnauthorizedError = class extends UGFError {
120
+ constructor() {
121
+ super("unauthorized", "UNAUTHORIZED");
122
+ }
123
+ };
124
+ var NetworkError = class extends UGFError {
125
+ constructor(message = "network error") {
126
+ super(message, "NETWORK_ERROR");
127
+ }
128
+ };
129
+ function parseBackendError(message) {
130
+ const lowerMsg = message.toLowerCase();
131
+ if (lowerMsg.includes("quote not found") || lowerMsg.includes("expired")) {
132
+ return new QuoteNotFoundError();
133
+ }
134
+ if (lowerMsg.includes("quote expired")) {
135
+ return new QuoteExpiredError();
136
+ }
137
+ if (lowerMsg.includes("payer mismatch")) {
138
+ return new PayerMismatchError();
139
+ }
140
+ if (lowerMsg.includes("invalid signature")) {
141
+ return new InvalidSignatureError();
142
+ }
143
+ if (lowerMsg.includes("insufficient")) {
144
+ return new InsufficientBalanceError();
145
+ }
146
+ if (lowerMsg.includes("invalid chain")) {
147
+ return new InvalidChainError();
148
+ }
149
+ if (lowerMsg.includes("invalid payment coin")) {
150
+ return new InvalidPaymentCoinError();
151
+ }
152
+ if (lowerMsg.includes("gas exceeds")) {
153
+ return new GasLimitExceededError();
154
+ }
155
+ if (lowerMsg.includes("missing digest")) {
156
+ return new MissingDigestError();
157
+ }
158
+ if (lowerMsg.includes("status not found")) {
159
+ return new StatusNotFoundError();
160
+ }
161
+ if (lowerMsg.includes("unauthorized")) {
162
+ return new UnauthorizedError();
163
+ }
164
+ return new NetworkError(message);
165
+ }
166
+
167
+ // src/api/quote.ts
168
+ async function getQuote(apiUrl, request, apiKey) {
169
+ const res = await fetch(`${apiUrl}/quote`, {
170
+ method: "POST",
171
+ headers: {
172
+ "Content-Type": "application/json",
173
+ "X-API-Key": apiKey
174
+ },
175
+ body: JSON.stringify(request)
176
+ });
177
+ if (!res.ok) {
178
+ const text = await res.text();
179
+ throw parseBackendError(text);
180
+ }
181
+ const data = await res.json();
182
+ return data;
183
+ }
184
+
185
+ // src/api/payment.ts
186
+ async function submitPayment(apiUrl, request, apiKey) {
187
+ const res = await fetch(`${apiUrl}/payment/submit`, {
188
+ method: "POST",
189
+ headers: {
190
+ "Content-Type": "application/json",
191
+ "X-API-Key": apiKey
192
+ },
193
+ body: JSON.stringify(request)
194
+ });
195
+ if (!res.ok) {
196
+ const text = await res.text();
197
+ throw parseBackendError(text);
198
+ }
199
+ const data = await res.json();
200
+ return data;
201
+ }
202
+
203
+ // src/api/status.ts
204
+ async function getPaymentStatus(apiUrl, digest, apiKey) {
205
+ const res = await fetch(`${apiUrl}/payment/status?digest=${digest}`, {
206
+ headers: {
207
+ "X-API-Key": apiKey
208
+ }
209
+ });
210
+ if (!res.ok) {
211
+ const text = await res.text();
212
+ throw parseBackendError(text);
213
+ }
214
+ const data = await res.json();
215
+ return data;
216
+ }
217
+
218
+ // src/api/info.ts
219
+ async function getSTONInfo(apiUrl, address, apiKey) {
220
+ const res = await fetch(`${apiUrl}/ston/info/${address}`, {
221
+ headers: {
222
+ "X-API-Key": apiKey
223
+ }
224
+ });
225
+ if (!res.ok) {
226
+ const text = await res.text();
227
+ throw parseBackendError(text);
228
+ }
229
+ const data = await res.json();
230
+ return data;
231
+ }
232
+
233
+ // src/core/client.ts
234
+ var UGFClient = class {
235
+ /**
236
+ * Create a new UGF client
237
+ * @param config - Configuration with API URL and optional API key
238
+ */
239
+ constructor(config) {
240
+ this.apiUrl = config.apiUrl;
241
+ if (!config.apiKey) {
242
+ throw new Error("API key is required");
243
+ }
244
+ this.apiKey = config.apiKey;
245
+ }
246
+ /**
247
+ * Get a quote for gasless payment
248
+ * @param request - Quote request parameters
249
+ * @returns Quote with digest and payment details
250
+ */
251
+ async getQuote(request) {
252
+ return getQuote(this.apiUrl, request, this.apiKey);
253
+ }
254
+ /**
255
+ * Submit a signed payment
256
+ * @param request - Payment submission with signature
257
+ * @returns Payment status
258
+ */
259
+ async submitPayment(request) {
260
+ return submitPayment(this.apiUrl, request, this.apiKey);
261
+ }
262
+ /**
263
+ * Check payment status
264
+ * @param digest - Payment digest
265
+ * @returns Current payment status
266
+ */
267
+ async getPaymentStatus(digest) {
268
+ return getPaymentStatus(this.apiUrl, digest, this.apiKey);
269
+ }
270
+ /**
271
+ * Get user's STON balance info
272
+ * @param address - User's TON address
273
+ * @returns STON and x402 balance details
274
+ */
275
+ async getSTONInfo(address) {
276
+ return getSTONInfo(this.apiUrl, address, this.apiKey);
277
+ }
278
+ };
279
+
280
+ // src/core/config.ts
281
+ var DEFAULT_CONFIG = {
282
+ apiUrl: "https://stonfi.universalgasframework.com"
283
+ };
284
+
285
+ // src/utils/formatting.ts
286
+ function toNano(amount) {
287
+ const num = typeof amount === "string" ? parseFloat(amount) : amount;
288
+ return Math.floor(num * 1e9).toString();
289
+ }
290
+ function fromNano(nanotons, decimals = 6) {
291
+ const num = typeof nanotons === "string" ? parseFloat(nanotons) : nanotons;
292
+ return (num / 1e9).toFixed(decimals);
293
+ }
294
+ function formatSTON(amount, decimals = 2) {
295
+ return parseFloat(fromNano(amount)).toFixed(decimals);
296
+ }
297
+
298
+ // src/utils/validation.ts
299
+ var import_core = require("@ton/core");
300
+ function isValidTONAddress(address) {
301
+ try {
302
+ import_core.Address.parse(address);
303
+ return true;
304
+ } catch {
305
+ return false;
306
+ }
307
+ }
308
+ function isValidHex(hex) {
309
+ return /^[0-9a-fA-F]+$/.test(hex) && hex.length % 2 === 0;
310
+ }
311
+ function isValidGasEstimate(nanotons) {
312
+ return nanotons > 0 && nanotons <= 5e8;
313
+ }
314
+ function isValidBufferPct(pct) {
315
+ return pct >= 0 && pct <= 50;
316
+ }
317
+
318
+ // src/crypto/signature.ts
319
+ var import_tweetnacl = __toESM(require("tweetnacl"), 1);
320
+ function signDigest(digestHex, privateKeyHex) {
321
+ const digest = hexToBytes(digestHex);
322
+ const secretKey = hexToBytes(privateKeyHex);
323
+ const signature = import_tweetnacl.default.sign.detached(digest, secretKey);
324
+ return bytesToHex(signature);
325
+ }
326
+ function verifySignature(digestHex, signatureHex, publicKeyHex) {
327
+ const digest = hexToBytes(digestHex);
328
+ const signature = hexToBytes(signatureHex);
329
+ const publicKey = hexToBytes(publicKeyHex);
330
+ return import_tweetnacl.default.sign.detached.verify(digest, signature, publicKey);
331
+ }
332
+ function hexToBytes(hex) {
333
+ const bytes = new Uint8Array(hex.length / 2);
334
+ for (let i = 0; i < hex.length; i += 2) {
335
+ bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
336
+ }
337
+ return bytes;
338
+ }
339
+ function bytesToHex(bytes) {
340
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
341
+ }
342
+ // Annotate the CommonJS export names for ESM import in node:
343
+ 0 && (module.exports = {
344
+ DEFAULT_CONFIG,
345
+ GasLimitExceededError,
346
+ InsufficientBalanceError,
347
+ InvalidChainError,
348
+ InvalidPaymentCoinError,
349
+ InvalidSignatureError,
350
+ MissingDigestError,
351
+ NetworkError,
352
+ PayerMismatchError,
353
+ QuoteExpiredError,
354
+ QuoteNotFoundError,
355
+ StatusNotFoundError,
356
+ UGFClient,
357
+ UGFError,
358
+ UnauthorizedError,
359
+ formatSTON,
360
+ fromNano,
361
+ isValidBufferPct,
362
+ isValidGasEstimate,
363
+ isValidHex,
364
+ isValidTONAddress,
365
+ parseBackendError,
366
+ signDigest,
367
+ toNano,
368
+ verifySignature
369
+ });
@@ -0,0 +1,218 @@
1
+ /**
2
+ * UGF client configuration
3
+ */
4
+ interface UGFConfig {
5
+ /** UGF API base URL */
6
+ apiUrl: string;
7
+ /** API key for authentication */
8
+ apiKey: string;
9
+ }
10
+ /**
11
+ * Default configuration values
12
+ */
13
+ declare const DEFAULT_CONFIG: Partial<UGFConfig>;
14
+
15
+ /**
16
+ * Request to get a gasless payment quote
17
+ */
18
+ interface QuoteRequest {
19
+ /** Payment token (always "STON") */
20
+ payment_coin: string;
21
+ /** User's TON wallet address */
22
+ payer_address: string;
23
+ /** Blockchain network (always "TON") */
24
+ payment_chain: string;
25
+ /** Optional transaction object */
26
+ tx_object?: string;
27
+ /** Destination chain ID (always "TON") */
28
+ dest_chain_id: string;
29
+ /** Gas estimate in nanotons */
30
+ gas_ton_estimate: number;
31
+ /** Buffer percentage (0-50, default 0) */
32
+ buffer_pct?: number;
33
+ }
34
+ /**
35
+ * Response containing quote details and payment digest
36
+ */
37
+ interface QuoteResponse {
38
+ /** STON amount required for payment (in nanotons) */
39
+ payment_amount: string;
40
+ /** Payment token (STON) */
41
+ payment_coin: string;
42
+ /** Payment blockchain (TON) */
43
+ payment_chain: string;
44
+ /** Payment destination address */
45
+ payment_to: string;
46
+ /** Payment mode identifier */
47
+ payment_mode: string;
48
+ /** Gas amount in nanotons */
49
+ gas_amount: string;
50
+ /** Unique digest for this quote */
51
+ digest: string;
52
+ /** Unix timestamp when quote expires */
53
+ expires_at: number;
54
+ /** User's locked x402 STON balance */
55
+ locked_x402_ston_balance: string;
56
+ }
57
+
58
+ interface PaymentRequest {
59
+ digest: string;
60
+ payer_address: string;
61
+ signature: string;
62
+ public_key: string;
63
+ }
64
+ interface PaymentResponse {
65
+ status: string;
66
+ digest: string;
67
+ }
68
+
69
+ interface StatusResponse {
70
+ status: "pending" | "completed" | "failed";
71
+ digest: string;
72
+ }
73
+
74
+ interface STONInfoResponse {
75
+ address: string;
76
+ ston_balance: string;
77
+ x402_ston_balance: string;
78
+ escrow_address: string;
79
+ min_bridge_ston: string;
80
+ cached: boolean;
81
+ }
82
+
83
+ /**
84
+ * Main UGF SDK client for interacting with the Universal Gas Framework API
85
+ */
86
+ declare class UGFClient {
87
+ private apiUrl;
88
+ private apiKey;
89
+ /**
90
+ * Create a new UGF client
91
+ * @param config - Configuration with API URL and optional API key
92
+ */
93
+ constructor(config: UGFConfig);
94
+ /**
95
+ * Get a quote for gasless payment
96
+ * @param request - Quote request parameters
97
+ * @returns Quote with digest and payment details
98
+ */
99
+ getQuote(request: QuoteRequest): Promise<QuoteResponse>;
100
+ /**
101
+ * Submit a signed payment
102
+ * @param request - Payment submission with signature
103
+ * @returns Payment status
104
+ */
105
+ submitPayment(request: PaymentRequest): Promise<PaymentResponse>;
106
+ /**
107
+ * Check payment status
108
+ * @param digest - Payment digest
109
+ * @returns Current payment status
110
+ */
111
+ getPaymentStatus(digest: string): Promise<StatusResponse>;
112
+ /**
113
+ * Get user's STON balance info
114
+ * @param address - User's TON address
115
+ * @returns STON and x402 balance details
116
+ */
117
+ getSTONInfo(address: string): Promise<STONInfoResponse>;
118
+ }
119
+
120
+ /**
121
+ * Convert TON amount to nanotons
122
+ */
123
+ declare function toNano(amount: string | number): string;
124
+ /**
125
+ * Convert nanotons to TON
126
+ */
127
+ declare function fromNano(nanotons: string | number, decimals?: number): string;
128
+ /**
129
+ * Format STON amount (same as TON, 9 decimals)
130
+ */
131
+ declare function formatSTON(amount: string, decimals?: number): string;
132
+
133
+ /** Validate TON address format */
134
+ declare function isValidTONAddress(address: string): boolean;
135
+ /** Validate hex string */
136
+ declare function isValidHex(hex: string): boolean;
137
+ /** Validate gas estimate (must be > 0 and <= 0.5 TON) */
138
+ declare function isValidGasEstimate(nanotons: number): boolean;
139
+ /** Validate buffer percentage (0-50) */
140
+ declare function isValidBufferPct(pct: number): boolean;
141
+
142
+ /** Base error for all UGF SDK errors */
143
+ declare class UGFError extends Error {
144
+ code?: string | undefined;
145
+ constructor(message: string, code?: string | undefined);
146
+ }
147
+ /** Quote not found or expired */
148
+ declare class QuoteNotFoundError extends UGFError {
149
+ constructor();
150
+ }
151
+ /** Quote has expired */
152
+ declare class QuoteExpiredError extends UGFError {
153
+ constructor();
154
+ }
155
+ /** Payer address doesn't match quote */
156
+ declare class PayerMismatchError extends UGFError {
157
+ constructor();
158
+ }
159
+ /** Signature verification failed */
160
+ declare class InvalidSignatureError extends UGFError {
161
+ constructor();
162
+ }
163
+ /** Insufficient x402 STON balance */
164
+ declare class InsufficientBalanceError extends UGFError {
165
+ constructor();
166
+ }
167
+ /** Invalid blockchain chain */
168
+ declare class InvalidChainError extends UGFError {
169
+ constructor();
170
+ }
171
+ /** Invalid payment coin type */
172
+ declare class InvalidPaymentCoinError extends UGFError {
173
+ constructor();
174
+ }
175
+ /** Gas estimate exceeds 0.5 TON limit */
176
+ declare class GasLimitExceededError extends UGFError {
177
+ constructor();
178
+ }
179
+ /** Missing digest parameter */
180
+ declare class MissingDigestError extends UGFError {
181
+ constructor();
182
+ }
183
+ /** Payment status not found */
184
+ declare class StatusNotFoundError extends UGFError {
185
+ constructor();
186
+ }
187
+ /** Invalid or missing API key */
188
+ declare class UnauthorizedError extends UGFError {
189
+ constructor();
190
+ }
191
+ /** Network or server error */
192
+ declare class NetworkError extends UGFError {
193
+ constructor(message?: string);
194
+ }
195
+ /**
196
+ * Parse backend error message and return specific error type
197
+ * @param message - Error message from backend
198
+ * @returns Specific error instance
199
+ */
200
+ declare function parseBackendError(message: string): Error;
201
+
202
+ /**
203
+ * Sign a digest with ed25519 private key
204
+ * @param digestHex - Hex string of digest to sign
205
+ * @param privateKeyHex - 64-byte ed25519 private key in hex
206
+ * @returns Signature as hex string
207
+ */
208
+ declare function signDigest(digestHex: string, privateKeyHex: string): string;
209
+ /**
210
+ * Verify a signature
211
+ * @param digestHex - Original digest
212
+ * @param signatureHex - Signature to verify
213
+ * @param publicKeyHex - 32-byte ed25519 public key in hex
214
+ * @returns True if valid
215
+ */
216
+ declare function verifySignature(digestHex: string, signatureHex: string, publicKeyHex: string): boolean;
217
+
218
+ export { DEFAULT_CONFIG, GasLimitExceededError, InsufficientBalanceError, InvalidChainError, InvalidPaymentCoinError, InvalidSignatureError, MissingDigestError, NetworkError, PayerMismatchError, type PaymentRequest, type PaymentResponse, QuoteExpiredError, QuoteNotFoundError, type QuoteRequest, type QuoteResponse, type STONInfoResponse, StatusNotFoundError, type StatusResponse, UGFClient, type UGFConfig, UGFError, UnauthorizedError, formatSTON, fromNano, isValidBufferPct, isValidGasEstimate, isValidHex, isValidTONAddress, parseBackendError, signDigest, toNano, verifySignature };
@@ -0,0 +1,218 @@
1
+ /**
2
+ * UGF client configuration
3
+ */
4
+ interface UGFConfig {
5
+ /** UGF API base URL */
6
+ apiUrl: string;
7
+ /** API key for authentication */
8
+ apiKey: string;
9
+ }
10
+ /**
11
+ * Default configuration values
12
+ */
13
+ declare const DEFAULT_CONFIG: Partial<UGFConfig>;
14
+
15
+ /**
16
+ * Request to get a gasless payment quote
17
+ */
18
+ interface QuoteRequest {
19
+ /** Payment token (always "STON") */
20
+ payment_coin: string;
21
+ /** User's TON wallet address */
22
+ payer_address: string;
23
+ /** Blockchain network (always "TON") */
24
+ payment_chain: string;
25
+ /** Optional transaction object */
26
+ tx_object?: string;
27
+ /** Destination chain ID (always "TON") */
28
+ dest_chain_id: string;
29
+ /** Gas estimate in nanotons */
30
+ gas_ton_estimate: number;
31
+ /** Buffer percentage (0-50, default 0) */
32
+ buffer_pct?: number;
33
+ }
34
+ /**
35
+ * Response containing quote details and payment digest
36
+ */
37
+ interface QuoteResponse {
38
+ /** STON amount required for payment (in nanotons) */
39
+ payment_amount: string;
40
+ /** Payment token (STON) */
41
+ payment_coin: string;
42
+ /** Payment blockchain (TON) */
43
+ payment_chain: string;
44
+ /** Payment destination address */
45
+ payment_to: string;
46
+ /** Payment mode identifier */
47
+ payment_mode: string;
48
+ /** Gas amount in nanotons */
49
+ gas_amount: string;
50
+ /** Unique digest for this quote */
51
+ digest: string;
52
+ /** Unix timestamp when quote expires */
53
+ expires_at: number;
54
+ /** User's locked x402 STON balance */
55
+ locked_x402_ston_balance: string;
56
+ }
57
+
58
+ interface PaymentRequest {
59
+ digest: string;
60
+ payer_address: string;
61
+ signature: string;
62
+ public_key: string;
63
+ }
64
+ interface PaymentResponse {
65
+ status: string;
66
+ digest: string;
67
+ }
68
+
69
+ interface StatusResponse {
70
+ status: "pending" | "completed" | "failed";
71
+ digest: string;
72
+ }
73
+
74
+ interface STONInfoResponse {
75
+ address: string;
76
+ ston_balance: string;
77
+ x402_ston_balance: string;
78
+ escrow_address: string;
79
+ min_bridge_ston: string;
80
+ cached: boolean;
81
+ }
82
+
83
+ /**
84
+ * Main UGF SDK client for interacting with the Universal Gas Framework API
85
+ */
86
+ declare class UGFClient {
87
+ private apiUrl;
88
+ private apiKey;
89
+ /**
90
+ * Create a new UGF client
91
+ * @param config - Configuration with API URL and optional API key
92
+ */
93
+ constructor(config: UGFConfig);
94
+ /**
95
+ * Get a quote for gasless payment
96
+ * @param request - Quote request parameters
97
+ * @returns Quote with digest and payment details
98
+ */
99
+ getQuote(request: QuoteRequest): Promise<QuoteResponse>;
100
+ /**
101
+ * Submit a signed payment
102
+ * @param request - Payment submission with signature
103
+ * @returns Payment status
104
+ */
105
+ submitPayment(request: PaymentRequest): Promise<PaymentResponse>;
106
+ /**
107
+ * Check payment status
108
+ * @param digest - Payment digest
109
+ * @returns Current payment status
110
+ */
111
+ getPaymentStatus(digest: string): Promise<StatusResponse>;
112
+ /**
113
+ * Get user's STON balance info
114
+ * @param address - User's TON address
115
+ * @returns STON and x402 balance details
116
+ */
117
+ getSTONInfo(address: string): Promise<STONInfoResponse>;
118
+ }
119
+
120
+ /**
121
+ * Convert TON amount to nanotons
122
+ */
123
+ declare function toNano(amount: string | number): string;
124
+ /**
125
+ * Convert nanotons to TON
126
+ */
127
+ declare function fromNano(nanotons: string | number, decimals?: number): string;
128
+ /**
129
+ * Format STON amount (same as TON, 9 decimals)
130
+ */
131
+ declare function formatSTON(amount: string, decimals?: number): string;
132
+
133
+ /** Validate TON address format */
134
+ declare function isValidTONAddress(address: string): boolean;
135
+ /** Validate hex string */
136
+ declare function isValidHex(hex: string): boolean;
137
+ /** Validate gas estimate (must be > 0 and <= 0.5 TON) */
138
+ declare function isValidGasEstimate(nanotons: number): boolean;
139
+ /** Validate buffer percentage (0-50) */
140
+ declare function isValidBufferPct(pct: number): boolean;
141
+
142
+ /** Base error for all UGF SDK errors */
143
+ declare class UGFError extends Error {
144
+ code?: string | undefined;
145
+ constructor(message: string, code?: string | undefined);
146
+ }
147
+ /** Quote not found or expired */
148
+ declare class QuoteNotFoundError extends UGFError {
149
+ constructor();
150
+ }
151
+ /** Quote has expired */
152
+ declare class QuoteExpiredError extends UGFError {
153
+ constructor();
154
+ }
155
+ /** Payer address doesn't match quote */
156
+ declare class PayerMismatchError extends UGFError {
157
+ constructor();
158
+ }
159
+ /** Signature verification failed */
160
+ declare class InvalidSignatureError extends UGFError {
161
+ constructor();
162
+ }
163
+ /** Insufficient x402 STON balance */
164
+ declare class InsufficientBalanceError extends UGFError {
165
+ constructor();
166
+ }
167
+ /** Invalid blockchain chain */
168
+ declare class InvalidChainError extends UGFError {
169
+ constructor();
170
+ }
171
+ /** Invalid payment coin type */
172
+ declare class InvalidPaymentCoinError extends UGFError {
173
+ constructor();
174
+ }
175
+ /** Gas estimate exceeds 0.5 TON limit */
176
+ declare class GasLimitExceededError extends UGFError {
177
+ constructor();
178
+ }
179
+ /** Missing digest parameter */
180
+ declare class MissingDigestError extends UGFError {
181
+ constructor();
182
+ }
183
+ /** Payment status not found */
184
+ declare class StatusNotFoundError extends UGFError {
185
+ constructor();
186
+ }
187
+ /** Invalid or missing API key */
188
+ declare class UnauthorizedError extends UGFError {
189
+ constructor();
190
+ }
191
+ /** Network or server error */
192
+ declare class NetworkError extends UGFError {
193
+ constructor(message?: string);
194
+ }
195
+ /**
196
+ * Parse backend error message and return specific error type
197
+ * @param message - Error message from backend
198
+ * @returns Specific error instance
199
+ */
200
+ declare function parseBackendError(message: string): Error;
201
+
202
+ /**
203
+ * Sign a digest with ed25519 private key
204
+ * @param digestHex - Hex string of digest to sign
205
+ * @param privateKeyHex - 64-byte ed25519 private key in hex
206
+ * @returns Signature as hex string
207
+ */
208
+ declare function signDigest(digestHex: string, privateKeyHex: string): string;
209
+ /**
210
+ * Verify a signature
211
+ * @param digestHex - Original digest
212
+ * @param signatureHex - Signature to verify
213
+ * @param publicKeyHex - 32-byte ed25519 public key in hex
214
+ * @returns True if valid
215
+ */
216
+ declare function verifySignature(digestHex: string, signatureHex: string, publicKeyHex: string): boolean;
217
+
218
+ export { DEFAULT_CONFIG, GasLimitExceededError, InsufficientBalanceError, InvalidChainError, InvalidPaymentCoinError, InvalidSignatureError, MissingDigestError, NetworkError, PayerMismatchError, type PaymentRequest, type PaymentResponse, QuoteExpiredError, QuoteNotFoundError, type QuoteRequest, type QuoteResponse, type STONInfoResponse, StatusNotFoundError, type StatusResponse, UGFClient, type UGFConfig, UGFError, UnauthorizedError, formatSTON, fromNano, isValidBufferPct, isValidGasEstimate, isValidHex, isValidTONAddress, parseBackendError, signDigest, toNano, verifySignature };
package/dist/index.js ADDED
@@ -0,0 +1,308 @@
1
+ // src/utils/errors.ts
2
+ var UGFError = class extends Error {
3
+ constructor(message, code) {
4
+ super(message);
5
+ this.code = code;
6
+ this.name = "UGFError";
7
+ }
8
+ };
9
+ var QuoteNotFoundError = class extends UGFError {
10
+ constructor() {
11
+ super("quote not found or expired", "QUOTE_NOT_FOUND");
12
+ }
13
+ };
14
+ var QuoteExpiredError = class extends UGFError {
15
+ constructor() {
16
+ super("quote expired", "QUOTE_EXPIRED");
17
+ }
18
+ };
19
+ var PayerMismatchError = class extends UGFError {
20
+ constructor() {
21
+ super("payer mismatch", "PAYER_MISMATCH");
22
+ }
23
+ };
24
+ var InvalidSignatureError = class extends UGFError {
25
+ constructor() {
26
+ super("invalid signature", "INVALID_SIGNATURE");
27
+ }
28
+ };
29
+ var InsufficientBalanceError = class extends UGFError {
30
+ constructor() {
31
+ super("insufficient locked balance", "INSUFFICIENT_BALANCE");
32
+ }
33
+ };
34
+ var InvalidChainError = class extends UGFError {
35
+ constructor() {
36
+ super("invalid chain", "INVALID_CHAIN");
37
+ }
38
+ };
39
+ var InvalidPaymentCoinError = class extends UGFError {
40
+ constructor() {
41
+ super("invalid payment coin", "INVALID_COIN");
42
+ }
43
+ };
44
+ var GasLimitExceededError = class extends UGFError {
45
+ constructor() {
46
+ super("gas exceeds 0.5 TON limit", "GAS_LIMIT_EXCEEDED");
47
+ }
48
+ };
49
+ var MissingDigestError = class extends UGFError {
50
+ constructor() {
51
+ super("missing digest", "MISSING_DIGEST");
52
+ }
53
+ };
54
+ var StatusNotFoundError = class extends UGFError {
55
+ constructor() {
56
+ super("status not found", "STATUS_NOT_FOUND");
57
+ }
58
+ };
59
+ var UnauthorizedError = class extends UGFError {
60
+ constructor() {
61
+ super("unauthorized", "UNAUTHORIZED");
62
+ }
63
+ };
64
+ var NetworkError = class extends UGFError {
65
+ constructor(message = "network error") {
66
+ super(message, "NETWORK_ERROR");
67
+ }
68
+ };
69
+ function parseBackendError(message) {
70
+ const lowerMsg = message.toLowerCase();
71
+ if (lowerMsg.includes("quote not found") || lowerMsg.includes("expired")) {
72
+ return new QuoteNotFoundError();
73
+ }
74
+ if (lowerMsg.includes("quote expired")) {
75
+ return new QuoteExpiredError();
76
+ }
77
+ if (lowerMsg.includes("payer mismatch")) {
78
+ return new PayerMismatchError();
79
+ }
80
+ if (lowerMsg.includes("invalid signature")) {
81
+ return new InvalidSignatureError();
82
+ }
83
+ if (lowerMsg.includes("insufficient")) {
84
+ return new InsufficientBalanceError();
85
+ }
86
+ if (lowerMsg.includes("invalid chain")) {
87
+ return new InvalidChainError();
88
+ }
89
+ if (lowerMsg.includes("invalid payment coin")) {
90
+ return new InvalidPaymentCoinError();
91
+ }
92
+ if (lowerMsg.includes("gas exceeds")) {
93
+ return new GasLimitExceededError();
94
+ }
95
+ if (lowerMsg.includes("missing digest")) {
96
+ return new MissingDigestError();
97
+ }
98
+ if (lowerMsg.includes("status not found")) {
99
+ return new StatusNotFoundError();
100
+ }
101
+ if (lowerMsg.includes("unauthorized")) {
102
+ return new UnauthorizedError();
103
+ }
104
+ return new NetworkError(message);
105
+ }
106
+
107
+ // src/api/quote.ts
108
+ async function getQuote(apiUrl, request, apiKey) {
109
+ const res = await fetch(`${apiUrl}/quote`, {
110
+ method: "POST",
111
+ headers: {
112
+ "Content-Type": "application/json",
113
+ "X-API-Key": apiKey
114
+ },
115
+ body: JSON.stringify(request)
116
+ });
117
+ if (!res.ok) {
118
+ const text = await res.text();
119
+ throw parseBackendError(text);
120
+ }
121
+ const data = await res.json();
122
+ return data;
123
+ }
124
+
125
+ // src/api/payment.ts
126
+ async function submitPayment(apiUrl, request, apiKey) {
127
+ const res = await fetch(`${apiUrl}/payment/submit`, {
128
+ method: "POST",
129
+ headers: {
130
+ "Content-Type": "application/json",
131
+ "X-API-Key": apiKey
132
+ },
133
+ body: JSON.stringify(request)
134
+ });
135
+ if (!res.ok) {
136
+ const text = await res.text();
137
+ throw parseBackendError(text);
138
+ }
139
+ const data = await res.json();
140
+ return data;
141
+ }
142
+
143
+ // src/api/status.ts
144
+ async function getPaymentStatus(apiUrl, digest, apiKey) {
145
+ const res = await fetch(`${apiUrl}/payment/status?digest=${digest}`, {
146
+ headers: {
147
+ "X-API-Key": apiKey
148
+ }
149
+ });
150
+ if (!res.ok) {
151
+ const text = await res.text();
152
+ throw parseBackendError(text);
153
+ }
154
+ const data = await res.json();
155
+ return data;
156
+ }
157
+
158
+ // src/api/info.ts
159
+ async function getSTONInfo(apiUrl, address, apiKey) {
160
+ const res = await fetch(`${apiUrl}/ston/info/${address}`, {
161
+ headers: {
162
+ "X-API-Key": apiKey
163
+ }
164
+ });
165
+ if (!res.ok) {
166
+ const text = await res.text();
167
+ throw parseBackendError(text);
168
+ }
169
+ const data = await res.json();
170
+ return data;
171
+ }
172
+
173
+ // src/core/client.ts
174
+ var UGFClient = class {
175
+ /**
176
+ * Create a new UGF client
177
+ * @param config - Configuration with API URL and optional API key
178
+ */
179
+ constructor(config) {
180
+ this.apiUrl = config.apiUrl;
181
+ if (!config.apiKey) {
182
+ throw new Error("API key is required");
183
+ }
184
+ this.apiKey = config.apiKey;
185
+ }
186
+ /**
187
+ * Get a quote for gasless payment
188
+ * @param request - Quote request parameters
189
+ * @returns Quote with digest and payment details
190
+ */
191
+ async getQuote(request) {
192
+ return getQuote(this.apiUrl, request, this.apiKey);
193
+ }
194
+ /**
195
+ * Submit a signed payment
196
+ * @param request - Payment submission with signature
197
+ * @returns Payment status
198
+ */
199
+ async submitPayment(request) {
200
+ return submitPayment(this.apiUrl, request, this.apiKey);
201
+ }
202
+ /**
203
+ * Check payment status
204
+ * @param digest - Payment digest
205
+ * @returns Current payment status
206
+ */
207
+ async getPaymentStatus(digest) {
208
+ return getPaymentStatus(this.apiUrl, digest, this.apiKey);
209
+ }
210
+ /**
211
+ * Get user's STON balance info
212
+ * @param address - User's TON address
213
+ * @returns STON and x402 balance details
214
+ */
215
+ async getSTONInfo(address) {
216
+ return getSTONInfo(this.apiUrl, address, this.apiKey);
217
+ }
218
+ };
219
+
220
+ // src/core/config.ts
221
+ var DEFAULT_CONFIG = {
222
+ apiUrl: "https://stonfi.universalgasframework.com"
223
+ };
224
+
225
+ // src/utils/formatting.ts
226
+ function toNano(amount) {
227
+ const num = typeof amount === "string" ? parseFloat(amount) : amount;
228
+ return Math.floor(num * 1e9).toString();
229
+ }
230
+ function fromNano(nanotons, decimals = 6) {
231
+ const num = typeof nanotons === "string" ? parseFloat(nanotons) : nanotons;
232
+ return (num / 1e9).toFixed(decimals);
233
+ }
234
+ function formatSTON(amount, decimals = 2) {
235
+ return parseFloat(fromNano(amount)).toFixed(decimals);
236
+ }
237
+
238
+ // src/utils/validation.ts
239
+ import { Address } from "@ton/core";
240
+ function isValidTONAddress(address) {
241
+ try {
242
+ Address.parse(address);
243
+ return true;
244
+ } catch {
245
+ return false;
246
+ }
247
+ }
248
+ function isValidHex(hex) {
249
+ return /^[0-9a-fA-F]+$/.test(hex) && hex.length % 2 === 0;
250
+ }
251
+ function isValidGasEstimate(nanotons) {
252
+ return nanotons > 0 && nanotons <= 5e8;
253
+ }
254
+ function isValidBufferPct(pct) {
255
+ return pct >= 0 && pct <= 50;
256
+ }
257
+
258
+ // src/crypto/signature.ts
259
+ import nacl from "tweetnacl";
260
+ function signDigest(digestHex, privateKeyHex) {
261
+ const digest = hexToBytes(digestHex);
262
+ const secretKey = hexToBytes(privateKeyHex);
263
+ const signature = nacl.sign.detached(digest, secretKey);
264
+ return bytesToHex(signature);
265
+ }
266
+ function verifySignature(digestHex, signatureHex, publicKeyHex) {
267
+ const digest = hexToBytes(digestHex);
268
+ const signature = hexToBytes(signatureHex);
269
+ const publicKey = hexToBytes(publicKeyHex);
270
+ return nacl.sign.detached.verify(digest, signature, publicKey);
271
+ }
272
+ function hexToBytes(hex) {
273
+ const bytes = new Uint8Array(hex.length / 2);
274
+ for (let i = 0; i < hex.length; i += 2) {
275
+ bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
276
+ }
277
+ return bytes;
278
+ }
279
+ function bytesToHex(bytes) {
280
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
281
+ }
282
+ export {
283
+ DEFAULT_CONFIG,
284
+ GasLimitExceededError,
285
+ InsufficientBalanceError,
286
+ InvalidChainError,
287
+ InvalidPaymentCoinError,
288
+ InvalidSignatureError,
289
+ MissingDigestError,
290
+ NetworkError,
291
+ PayerMismatchError,
292
+ QuoteExpiredError,
293
+ QuoteNotFoundError,
294
+ StatusNotFoundError,
295
+ UGFClient,
296
+ UGFError,
297
+ UnauthorizedError,
298
+ formatSTON,
299
+ fromNano,
300
+ isValidBufferPct,
301
+ isValidGasEstimate,
302
+ isValidHex,
303
+ isValidTONAddress,
304
+ parseBackendError,
305
+ signDigest,
306
+ toNano,
307
+ verifySignature
308
+ };
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@tychilabs/stonfi-gasless-sdk",
3
+ "version": "0.0.1",
4
+ "description": "Universal Gas Framework SDK for gasless payments - pay TON transaction fees with STON token",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "keywords": [
12
+ "ton",
13
+ "tonchain",
14
+ "ston",
15
+ "stonfi",
16
+ "gasless",
17
+ "gas-fee",
18
+ "ugf",
19
+ "universal-gas",
20
+ "defi",
21
+ "blockchain",
22
+ "payments",
23
+ "transaction"
24
+ ],
25
+ "homepage": "https://github.com/TychiWallet/stonfi-gasless-sdk#readme",
26
+ "bugs": {
27
+ "url": "https://github.com/TychiWallet/stonfi-gasless-sdk/issues"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/TychiWallet/stonfi-gasless-sdk.git"
32
+ },
33
+ "license": "MIT",
34
+ "author": "yash@tychilabs.com",
35
+ "type": "module",
36
+ "scripts": {
37
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
38
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
39
+ "prepublishOnly": "npm run build"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^25.1.0",
43
+ "tsup": "^8.5.1",
44
+ "typescript": "^5.9.3"
45
+ },
46
+ "dependencies": {
47
+ "tweetnacl": "^1.0.3"
48
+ },
49
+ "peerDependencies": {
50
+ "@ton/core": ">=0.63.0"
51
+ }
52
+ }