@gasfree-kit/ton-gasless 0.3.0 → 1.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/README.md CHANGED
@@ -1,12 +1,24 @@
1
1
  # @gasfree-kit/ton-gasless
2
2
 
3
+ > **⚠️ Deprecation notice (v2.0.0)** — the positional methods
4
+ > `TonTransfer.transferUSDT`, `TonTransfer.checkBalance`, and
5
+ > `TonTransfer.getTransactionEstimateFee` are **deprecated** in favour of
6
+ > the options-object methods `TonTransfer.send`, `TonTransfer.getBalance`,
7
+ > and `TonTransfer.estimateFee`.
8
+ >
9
+ > **The legacy positional methods will be removed three weeks after the
10
+ > v2.0.0 publish date** in the next major release. The new methods throw
11
+ > on failure and return a flat result (no `{ success, message, data }`
12
+ > wrapper). Public TON endpoints are used by default — API keys are now
13
+ > optional but recommended for production traffic.
14
+
3
15
  Gasless USDT transfers on TON through a sponsored relay.
4
16
 
5
17
  With this package, the user only needs USDT. The relay pays the TON gas and charges a small fee back in USDT.
6
18
 
7
19
  ## What This Package Does
8
20
 
9
- - creates a WDK-backed TON wallet
21
+ - creates a TON wallet from a seed phrase
10
22
  - quotes the relay fee in USDT
11
23
  - checks that balance covers transfer amount plus fee
12
24
  - submits the gasless transfer
@@ -26,7 +38,7 @@ With this package, the user only needs USDT. The relay pays the TON gas and char
26
38
  │ │
27
39
  v v
28
40
  ┌────────────┐ ┌───────────────┐
29
- WDK TON │ │ Relay fee │
41
+ │ TON │ │ Relay fee │
30
42
  │ wallet │ │ quote (USDT) │
31
43
  └──────┬─────┘ └───────┬───────┘
32
44
  │ │
@@ -62,23 +74,27 @@ This package depends on [`@gasfree-kit/core`](../core/README.md) for:
62
74
  npm install @gasfree-kit/ton-gasless @gasfree-kit/core
63
75
  ```
64
76
 
65
- Peer dependencies:
66
-
67
- ```bash
68
- npm install @tetherto/wdk-wallet-ton-gasless tonweb
69
- ```
77
+ After installing, your package manager will prompt you to install the peer dependencies listed in `package.json`.
70
78
 
71
79
  ## Configuration
72
80
 
81
+ All URL/API-key fields are optional — the SDK falls back to the public
82
+ endpoints exported as `TON_PUBLIC_ENDPOINTS`. For production traffic,
83
+ register keys with toncenter.com / tonapi.io and pass them in.
84
+
73
85
  ```ts
74
86
  import type { TonGaslessClientConfig } from '@gasfree-kit/ton-gasless';
75
87
 
88
+ // Minimal — uses public endpoints with no API keys.
89
+ const minimalConfig: TonGaslessClientConfig = {};
90
+
91
+ // Production — bring your own keys.
76
92
  const config: TonGaslessClientConfig = {
77
- tonCenterUrl: 'https://toncenter.com/api/v2',
78
93
  tonCenterApiKey: 'your-toncenter-api-key',
79
- tonApiUrl: 'https://tonapi.io',
80
94
  tonApiSecretKey: 'your-tonapi-secret-key',
81
- // Optional:
95
+ // Optional URL overrides (default to public endpoints):
96
+ // tonCenterUrl: 'https://toncenter.com/api/v2/jsonRPC',
97
+ // tonApiUrl: 'https://tonapi.io',
82
98
  // transferMaxFee: 1_000_000,
83
99
  // usdtAddress: 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs',
84
100
  };
@@ -86,14 +102,14 @@ const config: TonGaslessClientConfig = {
86
102
 
87
103
  ### Config fields
88
104
 
89
- | Field | Purpose |
90
- | ----------------- | -------------------------------------------------- |
91
- | `tonCenterUrl` | TON Center endpoint used by the wallet client |
92
- | `tonCenterApiKey` | TON Center API key |
93
- | `tonApiUrl` | TON API endpoint |
94
- | `tonApiSecretKey` | TON API secret key |
95
- | `transferMaxFee` | Maximum fee limit in base units, capped by the SDK |
96
- | `usdtAddress` | Optional override for the TON USDT root |
105
+ | Field | Purpose |
106
+ | ----------------- | -------------------------------------------------------- |
107
+ | `tonCenterUrl` | TON Center endpoint. Defaults to `TON_PUBLIC_ENDPOINTS`. |
108
+ | `tonCenterApiKey` | TON Center API key. Optional; recommended for prod. |
109
+ | `tonApiUrl` | TON API endpoint. Defaults to `TON_PUBLIC_ENDPOINTS`. |
110
+ | `tonApiSecretKey` | TON API secret key. Optional; recommended for prod. |
111
+ | `transferMaxFee` | Maximum fee limit in base units, capped by the SDK. |
112
+ | `usdtAddress` | Optional override for the TON USDT root. |
97
113
 
98
114
  ## Quick Start
99
115
 
@@ -126,39 +142,46 @@ const walletResult = await setupTonGaslessWallet(seedPhrase, config, "0'/0/0");
126
142
  ```ts
127
143
  import { TonTransfer } from '@gasfree-kit/ton-gasless';
128
144
 
129
- const balance = await TonTransfer.checkBalance(seedPhrase, config);
145
+ const balance = await TonTransfer.getBalance({ seedPhrase, config });
130
146
 
131
- console.log(balance.data.usdBalance);
132
- console.log(balance.data.tokenBalance);
147
+ console.log(balance.balance); // "42.50"
148
+ console.log(balance.balanceRaw); // 42500000n
149
+ console.log(balance.address); // wallet address
133
150
  ```
134
151
 
135
152
  ### 4. Estimate the fee
136
153
 
137
154
  ```ts
138
- const estimate = await TonTransfer.getTransactionEstimateFee(
155
+ const estimate = await TonTransfer.estimateFee({
139
156
  seedPhrase,
140
157
  config,
141
- '10.00',
142
- 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs',
143
- );
158
+ to: 'EQRecipient...',
159
+ amount: '10.00',
160
+ });
144
161
 
145
- console.log(estimate.data.fee);
162
+ console.log(estimate.fee); // "0.05" (gasless commission in USDT)
146
163
  ```
147
164
 
148
165
  ### 5. Execute the gasless transfer
149
166
 
150
167
  ```ts
151
- const result = await TonTransfer.transferUSDT(
168
+ const result = await TonTransfer.send({
152
169
  seedPhrase,
153
170
  config,
154
- '50.00',
155
- 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs',
156
- );
171
+ to: 'EQRecipient...',
172
+ amount: '50.00',
173
+ });
157
174
 
158
- console.log(result.data.transactionHash);
159
- console.log(result.data.fee);
175
+ console.log(result.transactionHash);
176
+ console.log(result.fee); // bigint, base units
177
+ console.log(result.submittedAt);
160
178
  ```
161
179
 
180
+ > The legacy positional methods (`transferUSDT`, `checkBalance`,
181
+ > `getTransactionEstimateFee`) remain available and return the previous
182
+ > `{ success, message, data }` envelope. They are marked `@deprecated` and
183
+ > wrap the new methods above.
184
+
162
185
  ## How The Flow Behaves
163
186
 
164
187
  1. The SDK validates the recipient address.
@@ -169,15 +192,15 @@ console.log(result.data.fee);
169
192
 
170
193
  ## Main Exports
171
194
 
172
- | Export | What it does |
173
- | ------------------------ | ---------------------------------------------------------- |
174
- | `setupTonGaslessWallet` | Creates the WDK-backed TON wallet and resolves the address |
175
- | `TonTransfer` | Checks balances, estimates fees, and sends transfers |
176
- | `getTonGaslessConfig` | Expands and validates the runtime config |
177
- | `tonUsdtTokenRoot` | Built-in TON USDT root address |
178
- | `usdtTonBaseUnits` | Converts human-readable USDT to base units |
179
- | `fromTonBaseUnitsToUsdt` | Converts base units back to readable USDT |
180
- | `getTonUsdtValue` | Utility helper for TON to USDT conversions |
195
+ | Export | What it does |
196
+ | ------------------------ | ------------------------------------------------------------------ |
197
+ | `setupTonGaslessWallet` | Creates the TON wallet from a seed phrase and resolves the address |
198
+ | `TonTransfer` | Checks balances, estimates fees, and sends transfers |
199
+ | `getTonGaslessConfig` | Expands and validates the runtime config |
200
+ | `tonUsdtTokenRoot` | Built-in TON USDT root address |
201
+ | `usdtTonBaseUnits` | Converts human-readable USDT to base units |
202
+ | `fromTonBaseUnitsToUsdt` | Converts base units back to readable USDT |
203
+ | `getTonUsdtValue` | Utility helper for TON to USDT conversions |
181
204
 
182
205
  ## Safety Notes
183
206
 
package/dist/index.d.mts CHANGED
@@ -1,6 +1,19 @@
1
1
  import * as _tetherto_wdk_wallet_ton_gasless from '@tetherto/wdk-wallet-ton-gasless';
2
2
 
3
3
  declare const tonUsdtTokenRoot = "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs";
4
+ /**
5
+ * Public TON mainnet RPC endpoints — used as defaults when the caller
6
+ * omits `tonCenterUrl` / `tonApiUrl`.
7
+ *
8
+ * Public endpoints are rate-limited and unauthenticated. For production
9
+ * traffic, register a key with toncenter.com / tonapi.io and pass it in
10
+ * via {@link TonGaslessClientConfig.tonCenterApiKey} and
11
+ * {@link TonGaslessClientConfig.tonApiSecretKey}.
12
+ */
13
+ declare const TON_PUBLIC_ENDPOINTS: {
14
+ readonly tonCenterUrl: "https://toncenter.com/api/v2/jsonRPC";
15
+ readonly tonApiUrl: "https://tonapi.io";
16
+ };
4
17
  type TonGaslessNetworkConfig = {
5
18
  tonClient: {
6
19
  url: string;
@@ -16,20 +29,24 @@ type TonGaslessNetworkConfig = {
16
29
  };
17
30
  };
18
31
  type TonGaslessClientConfig = {
19
- tonCenterUrl: string;
20
- tonCenterApiKey: string;
21
- tonApiUrl: string;
22
- tonApiSecretKey: string;
32
+ /** Toncenter JSON-RPC URL. Defaults to {@link TON_PUBLIC_ENDPOINTS.tonCenterUrl}. */
33
+ tonCenterUrl?: string;
34
+ /** Toncenter API key. Optional for public endpoints; recommended for prod. */
35
+ tonCenterApiKey?: string;
36
+ /** Ton API URL. Defaults to {@link TON_PUBLIC_ENDPOINTS.tonApiUrl}. */
37
+ tonApiUrl?: string;
38
+ /** Ton API secret key. Optional for public endpoints; recommended for prod. */
39
+ tonApiSecretKey?: string;
23
40
  transferMaxFee?: number;
24
41
  usdtAddress?: string;
25
42
  };
26
43
  declare function getTonGaslessConfig(config: TonGaslessClientConfig): TonGaslessNetworkConfig;
27
44
 
28
45
  /**
29
- * Set up a TON gasless wallet via WDK.
46
+ * Set up a TON gasless wallet.
30
47
  *
31
- * Uses legacy derivation path (m/44'/607'/0'/0/{index}) for compatibility
32
- * with wallets created by wdk-wallet-ton <= beta.5.
48
+ * Pins the BIP-44 derivation path at m/44'/607'/0'/0/{index} so the
49
+ * resulting address stays stable across underlying-library upgrades.
33
50
  */
34
51
  declare function setupTonGaslessWallet(seedPhrase: string, config: TonGaslessClientConfig, derivationPath?: string): Promise<{
35
52
  wallet: _tetherto_wdk_wallet_ton_gasless.default;
@@ -37,24 +54,99 @@ declare function setupTonGaslessWallet(seedPhrase: string, config: TonGaslessCli
37
54
  address: string;
38
55
  }>;
39
56
 
57
+ /** Result of a successful gasless USDT transfer on TON. */
58
+ interface TonTransferResult {
59
+ transactionHash: string;
60
+ /** Gasless commission paid in USDT base units. */
61
+ fee: bigint;
62
+ /** Sender wallet address. */
63
+ from: string;
64
+ /** Recipient wallet address. */
65
+ to: string;
66
+ /** Human-readable amount transferred. */
67
+ amount: string;
68
+ /** Wall-clock time when the transfer was submitted (ms since epoch). */
69
+ submittedAt: number;
70
+ }
71
+ /** Result of a TON USDT balance query. */
72
+ interface TonBalanceResult {
73
+ /** Human-readable balance (e.g. `"42.50"`). */
74
+ balance: string;
75
+ /** Raw balance in base units (USDT = 6 decimals). */
76
+ balanceRaw: bigint;
77
+ decimals: number;
78
+ /** Wallet address that holds the balance. */
79
+ address: string;
80
+ }
81
+ /** Result of a TON gasless transfer fee estimate. */
82
+ interface TonFeeEstimate {
83
+ /** Human-readable fee in USDT (paymaster token). */
84
+ fee: string;
85
+ feeRaw: bigint;
86
+ }
87
+ /** Options for `TonTransfer.send`. */
88
+ interface TonSendOptions {
89
+ seedPhrase: string;
90
+ config: TonGaslessClientConfig;
91
+ to: string;
92
+ /** Human-readable USDT amount (e.g. `"10.00"`). */
93
+ amount: string;
94
+ }
95
+ /** Options for `TonTransfer.getBalance`. */
96
+ interface TonBalanceOptions {
97
+ seedPhrase: string;
98
+ config: TonGaslessClientConfig;
99
+ /** Override the USDT jetton root. Defaults to the canonical mainnet USDT. */
100
+ tokenAddress?: string;
101
+ }
102
+ /** Options for `TonTransfer.estimateFee`. */
103
+ interface TonEstimateFeeOptions {
104
+ seedPhrase: string;
105
+ config: TonGaslessClientConfig;
106
+ to: string;
107
+ amount: string;
108
+ }
109
+
40
110
  declare class TonTransfer {
41
111
  /**
42
- * Get transaction fee estimate for a gasless USDT transfer on TON.
43
- * The gasless commission is returned in USDT (paymaster token units).
112
+ * Execute a gasless USDT transfer on TON.
113
+ *
114
+ * Throws `InsufficientBalanceError` / `TransactionFailedError` on failure;
115
+ * resolves with a flat `TonTransferResult` on success.
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * const receipt = await TonTransfer.send({
120
+ * seedPhrase,
121
+ * config: { tonCenterApiKey, tonApiSecretKey }, // uses public endpoints by default
122
+ * to: 'UQ...',
123
+ * amount: '10.00',
124
+ * });
125
+ * ```
126
+ */
127
+ static send(options: TonSendOptions): Promise<TonTransferResult>;
128
+ /** Query the USDT balance on TON for the wallet derived from `seedPhrase`. */
129
+ static getBalance(options: TonBalanceOptions): Promise<TonBalanceResult>;
130
+ /** Estimate the gasless commission (USDT) for a transfer. */
131
+ static estimateFee(options: TonEstimateFeeOptions): Promise<TonFeeEstimate>;
132
+ /**
133
+ * @deprecated Use {@link TonTransfer.estimateFee} instead. Returns the
134
+ * legacy `{ success, message, data: { fee } }` shape.
44
135
  */
45
136
  static getTransactionEstimateFee(seedPhrase: string, config: TonGaslessClientConfig, amountInUsdt: string, recipientAddress: string): Promise<{
46
137
  message: string;
47
- success: boolean;
138
+ success: true;
48
139
  data: {
49
140
  fee: string;
50
141
  };
51
142
  }>;
52
143
  /**
53
- * Check USDT balance on TON.
144
+ * @deprecated Use {@link TonTransfer.getBalance} instead. Returns the
145
+ * legacy `{ success, message, data }` shape.
54
146
  */
55
147
  static checkBalance(seedPhrase: string, config: TonGaslessClientConfig, tokenAddress?: string): Promise<{
56
148
  message: string;
57
- success: boolean;
149
+ success: true;
58
150
  data: {
59
151
  tokenBalance: string;
60
152
  decimals: number;
@@ -62,17 +154,16 @@ declare class TonTransfer {
62
154
  };
63
155
  }>;
64
156
  /**
65
- * Execute a gasless USDT transfer on TON.
66
- *
67
- * The relay pays Toncoin gas and deducts a small USDT commission.
68
- * User only needs USDT — balance must cover amount + gas commission.
157
+ * @deprecated Use {@link TonTransfer.send} instead accepts an options
158
+ * object and returns a flat `TonTransferResult` (no `success`/`message`
159
+ * wrapper).
69
160
  */
70
161
  static transferUSDT(seedPhrase: string, config: TonGaslessClientConfig, amountInUsdt: string, recipientAddress: string): Promise<{
71
162
  message: string;
72
- success: boolean;
163
+ success: true;
73
164
  data: {
74
165
  transactionHash: string;
75
- fee: unknown;
166
+ fee: bigint;
76
167
  tonTransferContext: {
77
168
  wdkHash: string;
78
169
  walletAddress: string;
@@ -98,4 +189,4 @@ declare function fromTonBaseUnitsToUsdt(amount: bigint, dec?: number): string;
98
189
  */
99
190
  declare function getTonUsdtValue(amountInBaseUnits: bigint, exchangeRate: number): number;
100
191
 
101
- export { type TonGaslessClientConfig, type TonGaslessNetworkConfig, TonTransfer, fromTonBaseUnitsToUsdt, getTonGaslessConfig, getTonUsdtValue, setupTonGaslessWallet, tonUsdtTokenRoot, usdtTonBaseUnits };
192
+ export { TON_PUBLIC_ENDPOINTS, type TonBalanceOptions, type TonBalanceResult, type TonEstimateFeeOptions, type TonFeeEstimate, type TonGaslessClientConfig, type TonGaslessNetworkConfig, type TonSendOptions, TonTransfer, type TonTransferResult, fromTonBaseUnitsToUsdt, getTonGaslessConfig, getTonUsdtValue, setupTonGaslessWallet, tonUsdtTokenRoot, usdtTonBaseUnits };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,19 @@
1
1
  import * as _tetherto_wdk_wallet_ton_gasless from '@tetherto/wdk-wallet-ton-gasless';
2
2
 
3
3
  declare const tonUsdtTokenRoot = "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs";
4
+ /**
5
+ * Public TON mainnet RPC endpoints — used as defaults when the caller
6
+ * omits `tonCenterUrl` / `tonApiUrl`.
7
+ *
8
+ * Public endpoints are rate-limited and unauthenticated. For production
9
+ * traffic, register a key with toncenter.com / tonapi.io and pass it in
10
+ * via {@link TonGaslessClientConfig.tonCenterApiKey} and
11
+ * {@link TonGaslessClientConfig.tonApiSecretKey}.
12
+ */
13
+ declare const TON_PUBLIC_ENDPOINTS: {
14
+ readonly tonCenterUrl: "https://toncenter.com/api/v2/jsonRPC";
15
+ readonly tonApiUrl: "https://tonapi.io";
16
+ };
4
17
  type TonGaslessNetworkConfig = {
5
18
  tonClient: {
6
19
  url: string;
@@ -16,20 +29,24 @@ type TonGaslessNetworkConfig = {
16
29
  };
17
30
  };
18
31
  type TonGaslessClientConfig = {
19
- tonCenterUrl: string;
20
- tonCenterApiKey: string;
21
- tonApiUrl: string;
22
- tonApiSecretKey: string;
32
+ /** Toncenter JSON-RPC URL. Defaults to {@link TON_PUBLIC_ENDPOINTS.tonCenterUrl}. */
33
+ tonCenterUrl?: string;
34
+ /** Toncenter API key. Optional for public endpoints; recommended for prod. */
35
+ tonCenterApiKey?: string;
36
+ /** Ton API URL. Defaults to {@link TON_PUBLIC_ENDPOINTS.tonApiUrl}. */
37
+ tonApiUrl?: string;
38
+ /** Ton API secret key. Optional for public endpoints; recommended for prod. */
39
+ tonApiSecretKey?: string;
23
40
  transferMaxFee?: number;
24
41
  usdtAddress?: string;
25
42
  };
26
43
  declare function getTonGaslessConfig(config: TonGaslessClientConfig): TonGaslessNetworkConfig;
27
44
 
28
45
  /**
29
- * Set up a TON gasless wallet via WDK.
46
+ * Set up a TON gasless wallet.
30
47
  *
31
- * Uses legacy derivation path (m/44'/607'/0'/0/{index}) for compatibility
32
- * with wallets created by wdk-wallet-ton <= beta.5.
48
+ * Pins the BIP-44 derivation path at m/44'/607'/0'/0/{index} so the
49
+ * resulting address stays stable across underlying-library upgrades.
33
50
  */
34
51
  declare function setupTonGaslessWallet(seedPhrase: string, config: TonGaslessClientConfig, derivationPath?: string): Promise<{
35
52
  wallet: _tetherto_wdk_wallet_ton_gasless.default;
@@ -37,24 +54,99 @@ declare function setupTonGaslessWallet(seedPhrase: string, config: TonGaslessCli
37
54
  address: string;
38
55
  }>;
39
56
 
57
+ /** Result of a successful gasless USDT transfer on TON. */
58
+ interface TonTransferResult {
59
+ transactionHash: string;
60
+ /** Gasless commission paid in USDT base units. */
61
+ fee: bigint;
62
+ /** Sender wallet address. */
63
+ from: string;
64
+ /** Recipient wallet address. */
65
+ to: string;
66
+ /** Human-readable amount transferred. */
67
+ amount: string;
68
+ /** Wall-clock time when the transfer was submitted (ms since epoch). */
69
+ submittedAt: number;
70
+ }
71
+ /** Result of a TON USDT balance query. */
72
+ interface TonBalanceResult {
73
+ /** Human-readable balance (e.g. `"42.50"`). */
74
+ balance: string;
75
+ /** Raw balance in base units (USDT = 6 decimals). */
76
+ balanceRaw: bigint;
77
+ decimals: number;
78
+ /** Wallet address that holds the balance. */
79
+ address: string;
80
+ }
81
+ /** Result of a TON gasless transfer fee estimate. */
82
+ interface TonFeeEstimate {
83
+ /** Human-readable fee in USDT (paymaster token). */
84
+ fee: string;
85
+ feeRaw: bigint;
86
+ }
87
+ /** Options for `TonTransfer.send`. */
88
+ interface TonSendOptions {
89
+ seedPhrase: string;
90
+ config: TonGaslessClientConfig;
91
+ to: string;
92
+ /** Human-readable USDT amount (e.g. `"10.00"`). */
93
+ amount: string;
94
+ }
95
+ /** Options for `TonTransfer.getBalance`. */
96
+ interface TonBalanceOptions {
97
+ seedPhrase: string;
98
+ config: TonGaslessClientConfig;
99
+ /** Override the USDT jetton root. Defaults to the canonical mainnet USDT. */
100
+ tokenAddress?: string;
101
+ }
102
+ /** Options for `TonTransfer.estimateFee`. */
103
+ interface TonEstimateFeeOptions {
104
+ seedPhrase: string;
105
+ config: TonGaslessClientConfig;
106
+ to: string;
107
+ amount: string;
108
+ }
109
+
40
110
  declare class TonTransfer {
41
111
  /**
42
- * Get transaction fee estimate for a gasless USDT transfer on TON.
43
- * The gasless commission is returned in USDT (paymaster token units).
112
+ * Execute a gasless USDT transfer on TON.
113
+ *
114
+ * Throws `InsufficientBalanceError` / `TransactionFailedError` on failure;
115
+ * resolves with a flat `TonTransferResult` on success.
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * const receipt = await TonTransfer.send({
120
+ * seedPhrase,
121
+ * config: { tonCenterApiKey, tonApiSecretKey }, // uses public endpoints by default
122
+ * to: 'UQ...',
123
+ * amount: '10.00',
124
+ * });
125
+ * ```
126
+ */
127
+ static send(options: TonSendOptions): Promise<TonTransferResult>;
128
+ /** Query the USDT balance on TON for the wallet derived from `seedPhrase`. */
129
+ static getBalance(options: TonBalanceOptions): Promise<TonBalanceResult>;
130
+ /** Estimate the gasless commission (USDT) for a transfer. */
131
+ static estimateFee(options: TonEstimateFeeOptions): Promise<TonFeeEstimate>;
132
+ /**
133
+ * @deprecated Use {@link TonTransfer.estimateFee} instead. Returns the
134
+ * legacy `{ success, message, data: { fee } }` shape.
44
135
  */
45
136
  static getTransactionEstimateFee(seedPhrase: string, config: TonGaslessClientConfig, amountInUsdt: string, recipientAddress: string): Promise<{
46
137
  message: string;
47
- success: boolean;
138
+ success: true;
48
139
  data: {
49
140
  fee: string;
50
141
  };
51
142
  }>;
52
143
  /**
53
- * Check USDT balance on TON.
144
+ * @deprecated Use {@link TonTransfer.getBalance} instead. Returns the
145
+ * legacy `{ success, message, data }` shape.
54
146
  */
55
147
  static checkBalance(seedPhrase: string, config: TonGaslessClientConfig, tokenAddress?: string): Promise<{
56
148
  message: string;
57
- success: boolean;
149
+ success: true;
58
150
  data: {
59
151
  tokenBalance: string;
60
152
  decimals: number;
@@ -62,17 +154,16 @@ declare class TonTransfer {
62
154
  };
63
155
  }>;
64
156
  /**
65
- * Execute a gasless USDT transfer on TON.
66
- *
67
- * The relay pays Toncoin gas and deducts a small USDT commission.
68
- * User only needs USDT — balance must cover amount + gas commission.
157
+ * @deprecated Use {@link TonTransfer.send} instead accepts an options
158
+ * object and returns a flat `TonTransferResult` (no `success`/`message`
159
+ * wrapper).
69
160
  */
70
161
  static transferUSDT(seedPhrase: string, config: TonGaslessClientConfig, amountInUsdt: string, recipientAddress: string): Promise<{
71
162
  message: string;
72
- success: boolean;
163
+ success: true;
73
164
  data: {
74
165
  transactionHash: string;
75
- fee: unknown;
166
+ fee: bigint;
76
167
  tonTransferContext: {
77
168
  wdkHash: string;
78
169
  walletAddress: string;
@@ -98,4 +189,4 @@ declare function fromTonBaseUnitsToUsdt(amount: bigint, dec?: number): string;
98
189
  */
99
190
  declare function getTonUsdtValue(amountInBaseUnits: bigint, exchangeRate: number): number;
100
191
 
101
- export { type TonGaslessClientConfig, type TonGaslessNetworkConfig, TonTransfer, fromTonBaseUnitsToUsdt, getTonGaslessConfig, getTonUsdtValue, setupTonGaslessWallet, tonUsdtTokenRoot, usdtTonBaseUnits };
192
+ export { TON_PUBLIC_ENDPOINTS, type TonBalanceOptions, type TonBalanceResult, type TonEstimateFeeOptions, type TonFeeEstimate, type TonGaslessClientConfig, type TonGaslessNetworkConfig, type TonSendOptions, TonTransfer, type TonTransferResult, fromTonBaseUnitsToUsdt, getTonGaslessConfig, getTonUsdtValue, setupTonGaslessWallet, tonUsdtTokenRoot, usdtTonBaseUnits };
package/dist/index.js CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ TON_PUBLIC_ENDPOINTS: () => TON_PUBLIC_ENDPOINTS,
33
34
  TonTransfer: () => TonTransfer,
34
35
  fromTonBaseUnitsToUsdt: () => fromTonBaseUnitsToUsdt,
35
36
  getTonGaslessConfig: () => getTonGaslessConfig,
@@ -42,6 +43,10 @@ module.exports = __toCommonJS(index_exports);
42
43
 
43
44
  // src/tonNetworkConfiguration.ts
44
45
  var tonUsdtTokenRoot = "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs";
46
+ var TON_PUBLIC_ENDPOINTS = {
47
+ tonCenterUrl: "https://toncenter.com/api/v2/jsonRPC",
48
+ tonApiUrl: "https://tonapi.io"
49
+ };
45
50
  var MAX_TRANSFER_FEE = 5e7;
46
51
  var DEFAULT_TRANSFER_FEE = 1e6;
47
52
  function getTonGaslessConfig(config) {
@@ -53,16 +58,16 @@ function getTonGaslessConfig(config) {
53
58
  }
54
59
  return {
55
60
  tonClient: {
56
- url: config.tonCenterUrl,
57
- secretKey: config.tonCenterApiKey
61
+ url: config.tonCenterUrl ?? TON_PUBLIC_ENDPOINTS.tonCenterUrl,
62
+ secretKey: config.tonCenterApiKey ?? ""
58
63
  },
59
64
  transferMaxFee: fee,
60
65
  paymasterToken: {
61
66
  address: config.usdtAddress ?? tonUsdtTokenRoot
62
67
  },
63
68
  tonApiClient: {
64
- url: config.tonApiUrl,
65
- secretKey: config.tonApiSecretKey
69
+ url: config.tonApiUrl ?? TON_PUBLIC_ENDPOINTS.tonApiUrl,
70
+ secretKey: config.tonApiSecretKey ?? ""
66
71
  }
67
72
  };
68
73
  }
@@ -113,123 +118,190 @@ function getTonUsdtValue(amountInBaseUnits, exchangeRate) {
113
118
 
114
119
  // src/tonGaslessTetherTransfer.ts
115
120
  var TonTransfer = class {
116
- /**
117
- * Get transaction fee estimate for a gasless USDT transfer on TON.
118
- * The gasless commission is returned in USDT (paymaster token units).
119
- */
120
- static async getTransactionEstimateFee(seedPhrase, config, amountInUsdt, recipientAddress) {
121
- (0, import_core.validateTonAddress)(recipientAddress, "recipient address");
122
- const amount = usdtTonBaseUnits(amountInUsdt);
123
- const { account, wallet } = await setupTonGaslessWallet(seedPhrase, config);
124
- try {
125
- const transferQuote = await account.quoteTransfer({
126
- token: tonUsdtTokenRoot,
127
- recipient: recipientAddress,
128
- amount
129
- });
130
- const feeInUsdt = fromTonBaseUnitsToUsdt(transferQuote.fee);
131
- return {
132
- message: "Transaction fee estimate retrieved successfully",
133
- success: true,
134
- data: { fee: feeInUsdt }
135
- };
136
- } finally {
137
- account.dispose();
138
- wallet.dispose();
139
- }
140
- }
141
- /**
142
- * Check USDT balance on TON.
143
- */
144
- static async checkBalance(seedPhrase, config, tokenAddress = tonUsdtTokenRoot) {
145
- const { account, wallet } = await setupTonGaslessWallet(seedPhrase, config);
146
- try {
147
- const balance = await account.getTokenBalance(tokenAddress);
148
- const usdBalance = fromTonBaseUnitsToUsdt(balance);
149
- return {
150
- message: "TON balances retrieved successfully",
151
- success: true,
152
- data: {
153
- tokenBalance: balance.toString(),
154
- decimals: 6,
155
- usdBalance: String(usdBalance)
156
- }
157
- };
158
- } finally {
159
- account.dispose();
160
- wallet.dispose();
161
- }
162
- }
121
+ // -----------------------------------------------------------------------
122
+ // New ergonomic API (v1)
123
+ // -----------------------------------------------------------------------
163
124
  /**
164
125
  * Execute a gasless USDT transfer on TON.
165
126
  *
166
- * The relay pays Toncoin gas and deducts a small USDT commission.
167
- * User only needs USDT balance must cover amount + gas commission.
127
+ * Throws `InsufficientBalanceError` / `TransactionFailedError` on failure;
128
+ * resolves with a flat `TonTransferResult` on success.
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * const receipt = await TonTransfer.send({
133
+ * seedPhrase,
134
+ * config: { tonCenterApiKey, tonApiSecretKey }, // uses public endpoints by default
135
+ * to: 'UQ...',
136
+ * amount: '10.00',
137
+ * });
138
+ * ```
168
139
  */
169
- static async transferUSDT(seedPhrase, config, amountInUsdt, recipientAddress) {
170
- const amount = usdtTonBaseUnits(amountInUsdt);
140
+ static async send(options) {
141
+ const { seedPhrase, config, to, amount } = options;
142
+ const amountRaw = usdtTonBaseUnits(amount);
171
143
  const {
172
144
  account,
173
145
  wallet,
174
146
  address: walletAddress
175
147
  } = await setupTonGaslessWallet(seedPhrase, config);
176
148
  try {
177
- (0, import_core.validateTonAddress)(recipientAddress, "recipient address");
178
- if (recipientAddress.toLowerCase() === walletAddress.toLowerCase()) {
149
+ (0, import_core.validateTonAddress)(to, "recipient address");
150
+ if (to.toLowerCase() === walletAddress.toLowerCase()) {
179
151
  throw new import_core.TransactionFailedError("ton", "Cannot transfer to your own address");
180
152
  }
181
153
  const balance = await account.getTokenBalance(tonUsdtTokenRoot);
182
154
  const quote = await account.quoteTransfer({
183
155
  token: tonUsdtTokenRoot,
184
- recipient: recipientAddress,
185
- amount
156
+ recipient: to,
157
+ amount: amountRaw
186
158
  });
187
- if (balance < amount + quote.fee) {
159
+ if (balance < amountRaw + quote.fee) {
188
160
  throw new import_core.InsufficientBalanceError("ton", "USDT (amount + gas fee)");
189
161
  }
190
162
  const result = await account.transfer({
191
163
  token: tonUsdtTokenRoot,
192
- recipient: recipientAddress,
193
- amount
164
+ recipient: to,
165
+ amount: amountRaw
194
166
  });
195
167
  return {
196
- message: "USDT transfer on TON successful (gasless)",
197
- success: true,
198
- data: {
199
- transactionHash: result.hash,
200
- fee: result.fee,
201
- tonTransferContext: {
202
- wdkHash: result.hash,
203
- walletAddress,
204
- recipientAddress,
205
- amountBaseUnits: amount.toString(),
206
- transferTimestamp: Date.now()
207
- }
208
- }
168
+ transactionHash: result.hash,
169
+ fee: BigInt(result.fee),
170
+ from: walletAddress,
171
+ to,
172
+ amount,
173
+ submittedAt: Date.now()
209
174
  };
210
175
  } catch (error) {
211
176
  if (error instanceof import_core.InsufficientBalanceError || error instanceof import_core.TransactionFailedError) {
212
177
  throw error;
213
178
  }
214
- let message = "Failed to transfer USDT on TON";
215
- if (error instanceof Error) {
216
- if (error.message.includes("insufficient balance") || error.message.includes("Failed to unpack account state")) {
217
- message = "Insufficient USDT balance for network fees";
218
- } else if (error.message.includes("invalid address")) {
219
- message = "The recipient TON address is invalid";
220
- } else if (error.message.includes("timeout")) {
221
- message = "Network timeout - please try again";
222
- }
223
- }
224
- throw new import_core.TransactionFailedError("ton", message);
179
+ throw new import_core.TransactionFailedError("ton", mapTonError(error));
180
+ } finally {
181
+ account.dispose();
182
+ wallet.dispose();
183
+ }
184
+ }
185
+ /** Query the USDT balance on TON for the wallet derived from `seedPhrase`. */
186
+ static async getBalance(options) {
187
+ const { seedPhrase, config } = options;
188
+ const tokenAddress = options.tokenAddress ?? tonUsdtTokenRoot;
189
+ const { account, wallet, address } = await setupTonGaslessWallet(seedPhrase, config);
190
+ try {
191
+ const raw = await account.getTokenBalance(tokenAddress);
192
+ return {
193
+ balance: String(fromTonBaseUnitsToUsdt(raw)),
194
+ balanceRaw: BigInt(raw),
195
+ decimals: 6,
196
+ address
197
+ };
198
+ } finally {
199
+ account.dispose();
200
+ wallet.dispose();
201
+ }
202
+ }
203
+ /** Estimate the gasless commission (USDT) for a transfer. */
204
+ static async estimateFee(options) {
205
+ const { seedPhrase, config, to, amount } = options;
206
+ (0, import_core.validateTonAddress)(to, "recipient address");
207
+ const amountRaw = usdtTonBaseUnits(amount);
208
+ const { account, wallet } = await setupTonGaslessWallet(seedPhrase, config);
209
+ try {
210
+ const quote = await account.quoteTransfer({
211
+ token: tonUsdtTokenRoot,
212
+ recipient: to,
213
+ amount: amountRaw
214
+ });
215
+ return {
216
+ fee: String(fromTonBaseUnitsToUsdt(quote.fee)),
217
+ feeRaw: BigInt(quote.fee)
218
+ };
225
219
  } finally {
226
220
  account.dispose();
227
221
  wallet.dispose();
228
222
  }
229
223
  }
224
+ // -----------------------------------------------------------------------
225
+ // Legacy positional API — preserved for backwards compatibility.
226
+ // -----------------------------------------------------------------------
227
+ /**
228
+ * @deprecated Use {@link TonTransfer.estimateFee} instead. Returns the
229
+ * legacy `{ success, message, data: { fee } }` shape.
230
+ */
231
+ static async getTransactionEstimateFee(seedPhrase, config, amountInUsdt, recipientAddress) {
232
+ const result = await this.estimateFee({
233
+ seedPhrase,
234
+ config,
235
+ to: recipientAddress,
236
+ amount: amountInUsdt
237
+ });
238
+ return {
239
+ message: "Transaction fee estimate retrieved successfully",
240
+ success: true,
241
+ data: { fee: result.fee }
242
+ };
243
+ }
244
+ /**
245
+ * @deprecated Use {@link TonTransfer.getBalance} instead. Returns the
246
+ * legacy `{ success, message, data }` shape.
247
+ */
248
+ static async checkBalance(seedPhrase, config, tokenAddress = tonUsdtTokenRoot) {
249
+ const result = await this.getBalance({ seedPhrase, config, tokenAddress });
250
+ return {
251
+ message: "TON balances retrieved successfully",
252
+ success: true,
253
+ data: {
254
+ tokenBalance: result.balanceRaw.toString(),
255
+ decimals: result.decimals,
256
+ usdBalance: result.balance
257
+ }
258
+ };
259
+ }
260
+ /**
261
+ * @deprecated Use {@link TonTransfer.send} instead — accepts an options
262
+ * object and returns a flat `TonTransferResult` (no `success`/`message`
263
+ * wrapper).
264
+ */
265
+ static async transferUSDT(seedPhrase, config, amountInUsdt, recipientAddress) {
266
+ const result = await this.send({
267
+ seedPhrase,
268
+ config,
269
+ to: recipientAddress,
270
+ amount: amountInUsdt
271
+ });
272
+ return {
273
+ message: "USDT transfer on TON successful (gasless)",
274
+ success: true,
275
+ data: {
276
+ transactionHash: result.transactionHash,
277
+ fee: result.fee,
278
+ tonTransferContext: {
279
+ wdkHash: result.transactionHash,
280
+ walletAddress: result.from,
281
+ recipientAddress: result.to,
282
+ amountBaseUnits: usdtTonBaseUnits(result.amount).toString(),
283
+ transferTimestamp: result.submittedAt
284
+ }
285
+ }
286
+ };
287
+ }
230
288
  };
289
+ function mapTonError(error) {
290
+ if (!(error instanceof Error)) return "Failed to transfer USDT on TON";
291
+ if (error.message.includes("insufficient balance") || error.message.includes("Failed to unpack account state")) {
292
+ return "Insufficient USDT balance for network fees";
293
+ }
294
+ if (error.message.includes("invalid address")) {
295
+ return "The recipient TON address is invalid";
296
+ }
297
+ if (error.message.includes("timeout")) {
298
+ return "Network timeout - please try again";
299
+ }
300
+ return "Failed to transfer USDT on TON";
301
+ }
231
302
  // Annotate the CommonJS export names for ESM import in node:
232
303
  0 && (module.exports = {
304
+ TON_PUBLIC_ENDPOINTS,
233
305
  TonTransfer,
234
306
  fromTonBaseUnitsToUsdt,
235
307
  getTonGaslessConfig,
package/dist/index.mjs CHANGED
@@ -1,5 +1,9 @@
1
1
  // src/tonNetworkConfiguration.ts
2
2
  var tonUsdtTokenRoot = "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs";
3
+ var TON_PUBLIC_ENDPOINTS = {
4
+ tonCenterUrl: "https://toncenter.com/api/v2/jsonRPC",
5
+ tonApiUrl: "https://tonapi.io"
6
+ };
3
7
  var MAX_TRANSFER_FEE = 5e7;
4
8
  var DEFAULT_TRANSFER_FEE = 1e6;
5
9
  function getTonGaslessConfig(config) {
@@ -11,16 +15,16 @@ function getTonGaslessConfig(config) {
11
15
  }
12
16
  return {
13
17
  tonClient: {
14
- url: config.tonCenterUrl,
15
- secretKey: config.tonCenterApiKey
18
+ url: config.tonCenterUrl ?? TON_PUBLIC_ENDPOINTS.tonCenterUrl,
19
+ secretKey: config.tonCenterApiKey ?? ""
16
20
  },
17
21
  transferMaxFee: fee,
18
22
  paymasterToken: {
19
23
  address: config.usdtAddress ?? tonUsdtTokenRoot
20
24
  },
21
25
  tonApiClient: {
22
- url: config.tonApiUrl,
23
- secretKey: config.tonApiSecretKey
26
+ url: config.tonApiUrl ?? TON_PUBLIC_ENDPOINTS.tonApiUrl,
27
+ secretKey: config.tonApiSecretKey ?? ""
24
28
  }
25
29
  };
26
30
  }
@@ -75,122 +79,189 @@ function getTonUsdtValue(amountInBaseUnits, exchangeRate) {
75
79
 
76
80
  // src/tonGaslessTetherTransfer.ts
77
81
  var TonTransfer = class {
78
- /**
79
- * Get transaction fee estimate for a gasless USDT transfer on TON.
80
- * The gasless commission is returned in USDT (paymaster token units).
81
- */
82
- static async getTransactionEstimateFee(seedPhrase, config, amountInUsdt, recipientAddress) {
83
- validateTonAddress(recipientAddress, "recipient address");
84
- const amount = usdtTonBaseUnits(amountInUsdt);
85
- const { account, wallet } = await setupTonGaslessWallet(seedPhrase, config);
86
- try {
87
- const transferQuote = await account.quoteTransfer({
88
- token: tonUsdtTokenRoot,
89
- recipient: recipientAddress,
90
- amount
91
- });
92
- const feeInUsdt = fromTonBaseUnitsToUsdt(transferQuote.fee);
93
- return {
94
- message: "Transaction fee estimate retrieved successfully",
95
- success: true,
96
- data: { fee: feeInUsdt }
97
- };
98
- } finally {
99
- account.dispose();
100
- wallet.dispose();
101
- }
102
- }
103
- /**
104
- * Check USDT balance on TON.
105
- */
106
- static async checkBalance(seedPhrase, config, tokenAddress = tonUsdtTokenRoot) {
107
- const { account, wallet } = await setupTonGaslessWallet(seedPhrase, config);
108
- try {
109
- const balance = await account.getTokenBalance(tokenAddress);
110
- const usdBalance = fromTonBaseUnitsToUsdt(balance);
111
- return {
112
- message: "TON balances retrieved successfully",
113
- success: true,
114
- data: {
115
- tokenBalance: balance.toString(),
116
- decimals: 6,
117
- usdBalance: String(usdBalance)
118
- }
119
- };
120
- } finally {
121
- account.dispose();
122
- wallet.dispose();
123
- }
124
- }
82
+ // -----------------------------------------------------------------------
83
+ // New ergonomic API (v1)
84
+ // -----------------------------------------------------------------------
125
85
  /**
126
86
  * Execute a gasless USDT transfer on TON.
127
87
  *
128
- * The relay pays Toncoin gas and deducts a small USDT commission.
129
- * User only needs USDT balance must cover amount + gas commission.
88
+ * Throws `InsufficientBalanceError` / `TransactionFailedError` on failure;
89
+ * resolves with a flat `TonTransferResult` on success.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * const receipt = await TonTransfer.send({
94
+ * seedPhrase,
95
+ * config: { tonCenterApiKey, tonApiSecretKey }, // uses public endpoints by default
96
+ * to: 'UQ...',
97
+ * amount: '10.00',
98
+ * });
99
+ * ```
130
100
  */
131
- static async transferUSDT(seedPhrase, config, amountInUsdt, recipientAddress) {
132
- const amount = usdtTonBaseUnits(amountInUsdt);
101
+ static async send(options) {
102
+ const { seedPhrase, config, to, amount } = options;
103
+ const amountRaw = usdtTonBaseUnits(amount);
133
104
  const {
134
105
  account,
135
106
  wallet,
136
107
  address: walletAddress
137
108
  } = await setupTonGaslessWallet(seedPhrase, config);
138
109
  try {
139
- validateTonAddress(recipientAddress, "recipient address");
140
- if (recipientAddress.toLowerCase() === walletAddress.toLowerCase()) {
110
+ validateTonAddress(to, "recipient address");
111
+ if (to.toLowerCase() === walletAddress.toLowerCase()) {
141
112
  throw new TransactionFailedError("ton", "Cannot transfer to your own address");
142
113
  }
143
114
  const balance = await account.getTokenBalance(tonUsdtTokenRoot);
144
115
  const quote = await account.quoteTransfer({
145
116
  token: tonUsdtTokenRoot,
146
- recipient: recipientAddress,
147
- amount
117
+ recipient: to,
118
+ amount: amountRaw
148
119
  });
149
- if (balance < amount + quote.fee) {
120
+ if (balance < amountRaw + quote.fee) {
150
121
  throw new InsufficientBalanceError("ton", "USDT (amount + gas fee)");
151
122
  }
152
123
  const result = await account.transfer({
153
124
  token: tonUsdtTokenRoot,
154
- recipient: recipientAddress,
155
- amount
125
+ recipient: to,
126
+ amount: amountRaw
156
127
  });
157
128
  return {
158
- message: "USDT transfer on TON successful (gasless)",
159
- success: true,
160
- data: {
161
- transactionHash: result.hash,
162
- fee: result.fee,
163
- tonTransferContext: {
164
- wdkHash: result.hash,
165
- walletAddress,
166
- recipientAddress,
167
- amountBaseUnits: amount.toString(),
168
- transferTimestamp: Date.now()
169
- }
170
- }
129
+ transactionHash: result.hash,
130
+ fee: BigInt(result.fee),
131
+ from: walletAddress,
132
+ to,
133
+ amount,
134
+ submittedAt: Date.now()
171
135
  };
172
136
  } catch (error) {
173
137
  if (error instanceof InsufficientBalanceError || error instanceof TransactionFailedError) {
174
138
  throw error;
175
139
  }
176
- let message = "Failed to transfer USDT on TON";
177
- if (error instanceof Error) {
178
- if (error.message.includes("insufficient balance") || error.message.includes("Failed to unpack account state")) {
179
- message = "Insufficient USDT balance for network fees";
180
- } else if (error.message.includes("invalid address")) {
181
- message = "The recipient TON address is invalid";
182
- } else if (error.message.includes("timeout")) {
183
- message = "Network timeout - please try again";
184
- }
185
- }
186
- throw new TransactionFailedError("ton", message);
140
+ throw new TransactionFailedError("ton", mapTonError(error));
141
+ } finally {
142
+ account.dispose();
143
+ wallet.dispose();
144
+ }
145
+ }
146
+ /** Query the USDT balance on TON for the wallet derived from `seedPhrase`. */
147
+ static async getBalance(options) {
148
+ const { seedPhrase, config } = options;
149
+ const tokenAddress = options.tokenAddress ?? tonUsdtTokenRoot;
150
+ const { account, wallet, address } = await setupTonGaslessWallet(seedPhrase, config);
151
+ try {
152
+ const raw = await account.getTokenBalance(tokenAddress);
153
+ return {
154
+ balance: String(fromTonBaseUnitsToUsdt(raw)),
155
+ balanceRaw: BigInt(raw),
156
+ decimals: 6,
157
+ address
158
+ };
159
+ } finally {
160
+ account.dispose();
161
+ wallet.dispose();
162
+ }
163
+ }
164
+ /** Estimate the gasless commission (USDT) for a transfer. */
165
+ static async estimateFee(options) {
166
+ const { seedPhrase, config, to, amount } = options;
167
+ validateTonAddress(to, "recipient address");
168
+ const amountRaw = usdtTonBaseUnits(amount);
169
+ const { account, wallet } = await setupTonGaslessWallet(seedPhrase, config);
170
+ try {
171
+ const quote = await account.quoteTransfer({
172
+ token: tonUsdtTokenRoot,
173
+ recipient: to,
174
+ amount: amountRaw
175
+ });
176
+ return {
177
+ fee: String(fromTonBaseUnitsToUsdt(quote.fee)),
178
+ feeRaw: BigInt(quote.fee)
179
+ };
187
180
  } finally {
188
181
  account.dispose();
189
182
  wallet.dispose();
190
183
  }
191
184
  }
185
+ // -----------------------------------------------------------------------
186
+ // Legacy positional API — preserved for backwards compatibility.
187
+ // -----------------------------------------------------------------------
188
+ /**
189
+ * @deprecated Use {@link TonTransfer.estimateFee} instead. Returns the
190
+ * legacy `{ success, message, data: { fee } }` shape.
191
+ */
192
+ static async getTransactionEstimateFee(seedPhrase, config, amountInUsdt, recipientAddress) {
193
+ const result = await this.estimateFee({
194
+ seedPhrase,
195
+ config,
196
+ to: recipientAddress,
197
+ amount: amountInUsdt
198
+ });
199
+ return {
200
+ message: "Transaction fee estimate retrieved successfully",
201
+ success: true,
202
+ data: { fee: result.fee }
203
+ };
204
+ }
205
+ /**
206
+ * @deprecated Use {@link TonTransfer.getBalance} instead. Returns the
207
+ * legacy `{ success, message, data }` shape.
208
+ */
209
+ static async checkBalance(seedPhrase, config, tokenAddress = tonUsdtTokenRoot) {
210
+ const result = await this.getBalance({ seedPhrase, config, tokenAddress });
211
+ return {
212
+ message: "TON balances retrieved successfully",
213
+ success: true,
214
+ data: {
215
+ tokenBalance: result.balanceRaw.toString(),
216
+ decimals: result.decimals,
217
+ usdBalance: result.balance
218
+ }
219
+ };
220
+ }
221
+ /**
222
+ * @deprecated Use {@link TonTransfer.send} instead — accepts an options
223
+ * object and returns a flat `TonTransferResult` (no `success`/`message`
224
+ * wrapper).
225
+ */
226
+ static async transferUSDT(seedPhrase, config, amountInUsdt, recipientAddress) {
227
+ const result = await this.send({
228
+ seedPhrase,
229
+ config,
230
+ to: recipientAddress,
231
+ amount: amountInUsdt
232
+ });
233
+ return {
234
+ message: "USDT transfer on TON successful (gasless)",
235
+ success: true,
236
+ data: {
237
+ transactionHash: result.transactionHash,
238
+ fee: result.fee,
239
+ tonTransferContext: {
240
+ wdkHash: result.transactionHash,
241
+ walletAddress: result.from,
242
+ recipientAddress: result.to,
243
+ amountBaseUnits: usdtTonBaseUnits(result.amount).toString(),
244
+ transferTimestamp: result.submittedAt
245
+ }
246
+ }
247
+ };
248
+ }
192
249
  };
250
+ function mapTonError(error) {
251
+ if (!(error instanceof Error)) return "Failed to transfer USDT on TON";
252
+ if (error.message.includes("insufficient balance") || error.message.includes("Failed to unpack account state")) {
253
+ return "Insufficient USDT balance for network fees";
254
+ }
255
+ if (error.message.includes("invalid address")) {
256
+ return "The recipient TON address is invalid";
257
+ }
258
+ if (error.message.includes("timeout")) {
259
+ return "Network timeout - please try again";
260
+ }
261
+ return "Failed to transfer USDT on TON";
262
+ }
193
263
  export {
264
+ TON_PUBLIC_ENDPOINTS,
194
265
  TonTransfer,
195
266
  fromTonBaseUnitsToUsdt,
196
267
  getTonGaslessConfig,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gasfree-kit/ton-gasless",
3
- "version": "0.3.0",
3
+ "version": "1.0.0",
4
4
  "description": "Gasless USDT transfers on TON via sponsored relay",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -17,12 +17,25 @@
17
17
  "README.md"
18
18
  ],
19
19
  "dependencies": {
20
- "@gasfree-kit/core": "0.2.0"
20
+ "@gasfree-kit/core": "0.2.1"
21
21
  },
22
22
  "peerDependencies": {
23
23
  "@tetherto/wdk-wallet-ton-gasless": "^1.0.0-beta.4",
24
24
  "tonweb": "^0.0.66"
25
25
  },
26
+ "keywords": [
27
+ "gasless",
28
+ "gas-free",
29
+ "ton",
30
+ "toncoin",
31
+ "usdt",
32
+ "transfer",
33
+ "sponsored",
34
+ "relay",
35
+ "web3",
36
+ "sdk",
37
+ "meta-transactions"
38
+ ],
26
39
  "license": "MIT",
27
40
  "publishConfig": {
28
41
  "access": "public"