@zebec-network/tron-transfer-sdk 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/services.js CHANGED
@@ -1,31 +1,30 @@
1
1
  import { TronWeb } from 'tronweb';
2
2
  import { createTronWeb } from './client.js';
3
- import { loadConfig } from './config.js';
4
- import { sleep, toBaseUnits } from './utils.js';
3
+ import { resolveServiceConfig } from './config.js';
4
+ import { fromBaseUnits, sleep, toBaseUnits } from './utils.js';
5
5
  const TRX_DECIMALS = 6; // 1 TRX = 1,000,000 SUN
6
6
  const DEFAULT_CONFIRMATION_TIMEOUT_MS = 60_000;
7
7
  const CONFIRMATION_POLL_INTERVAL_MS = 3_000; // roughly one TRON block
8
- /** Thrown for any failed transfer. `txid` is set when the transaction reached the network. */
8
+ const MAX_POLL_INTERVAL_MS = 15_000;
9
+ const RATE_LIMIT_BASE_DELAY_MS = 1_000;
10
+ /** Thrown for any failed transfer. `txid` is set when the transaction may have reached the network. */
9
11
  export class TronTransferError extends Error {
10
12
  txid;
11
- constructor(message, txid) {
12
- super(txid ? `${message} (txid: ${txid})` : message);
13
+ code;
14
+ constructor(message, txid, options = {}) {
15
+ super(txid ? `${message} (txid: ${txid})` : message, 'cause' in options ? { cause: options.cause } : {});
13
16
  this.name = 'TronTransferError';
14
17
  this.txid = txid;
18
+ this.code = options.code;
15
19
  }
16
20
  }
17
- function openSession(network) {
18
- const config = loadConfig(network);
19
- const from = TronWeb.address.fromPrivateKey(config.privateKey);
20
- if (!from) {
21
- throw new TronTransferError('Could not derive an address from the configured private key.');
21
+ function assertAddress(address, label) {
22
+ if (!TronWeb.isAddress(address)) {
23
+ throw new TronTransferError(`Invalid ${label} address "${address}".`);
22
24
  }
23
- return { config, tronWeb: createTronWeb(config), from };
24
25
  }
25
26
  function assertRecipient(to, from) {
26
- if (!TronWeb.isAddress(to)) {
27
- throw new TronTransferError(`Invalid recipient address "${to}".`);
28
- }
27
+ assertAddress(to, 'recipient');
29
28
  if (TronWeb.address.toHex(to) === TronWeb.address.toHex(from)) {
30
29
  throw new TronTransferError('Recipient address is the same as the sender address.');
31
30
  }
@@ -35,114 +34,275 @@ function decodeNodeMessage(message) {
35
34
  if (!message)
36
35
  return 'unknown error';
37
36
  if (/^[0-9a-fA-F]+$/.test(message) && message.length % 2 === 0) {
38
- return Buffer.from(message, 'hex').toString('utf8');
37
+ const bytes = Uint8Array.from(message.match(/../g) ?? [], (byte) => parseInt(byte, 16));
38
+ return new TextDecoder().decode(bytes);
39
39
  }
40
40
  return message;
41
41
  }
42
- async function signAndBroadcast(tronWeb, transaction) {
43
- const signed = (await tronWeb.trx.sign(transaction));
44
- const broadcast = await tronWeb.trx.sendRawTransaction(signed);
45
- if (!broadcast.result) {
46
- throw new TronTransferError(`Broadcast rejected: ${broadcast.code ?? 'ERROR'} ${decodeNodeMessage(broadcast.message)}`, broadcast.txid || signed.txID);
47
- }
48
- return broadcast.txid || signed.txID;
42
+ function errorMessage(error) {
43
+ return error instanceof Error ? error.message : String(error);
49
44
  }
50
- /** Polls until the transaction is in a block, then throws if it failed on-chain. */
51
- async function waitForConfirmation(tronWeb, txid, timeoutMs) {
52
- const deadline = Date.now() + timeoutMs;
53
- while (Date.now() < deadline) {
54
- await sleep(CONFIRMATION_POLL_INTERVAL_MS);
55
- const info = await tronWeb.trx.getUnconfirmedTransactionInfo(txid);
56
- if (!info?.id)
57
- continue;
58
- const receiptResult = info.receipt?.result;
59
- if (info.result === 'FAILED' || (receiptResult && receiptResult !== 'SUCCESS')) {
60
- const reason = decodeNodeMessage(info.resMessage) || receiptResult || 'FAILED';
61
- throw new TronTransferError(`Transaction failed on-chain: ${reason}`, txid);
62
- }
63
- return info;
64
- }
65
- throw new TronTransferError(`Transaction was broadcast but not confirmed within ${timeoutMs}ms. Check its status before retrying to avoid a double send`, txid);
45
+ /** HTTP status of a failed TronWeb request (TronWeb uses axios), if the node sent a response. */
46
+ function httpStatus(error) {
47
+ const status = error?.response?.status;
48
+ return typeof status === 'number' ? status : undefined;
66
49
  }
67
- async function finalize(session, txid, to, rawAmount, options) {
68
- const result = {
69
- txid,
70
- network: session.config.network,
71
- from: session.from,
72
- to,
73
- rawAmount: rawAmount.toString(),
74
- confirmed: false,
75
- };
76
- if (options.waitForConfirmation === false)
77
- return result;
78
- const info = await waitForConfirmation(session.tronWeb, txid, options.confirmationTimeoutMs ?? DEFAULT_CONFIRMATION_TIMEOUT_MS);
79
- return { ...result, confirmed: true, blockNumber: info.blockNumber, feeSun: info.fee ?? 0 };
80
- }
81
- async function callConstant(session, contractAddress, functionSelector, parameters = []) {
82
- const response = await session.tronWeb.transactionBuilder.triggerConstantContract(contractAddress, functionSelector, {}, parameters, session.from);
83
- const hex = response.constant_result?.[0];
84
- if (!response.result?.result || typeof hex !== 'string' || hex.length === 0) {
85
- throw new TronTransferError(`Call to ${functionSelector} on ${contractAddress} failed: ${decodeNodeMessage(response.result?.message)}. Is this a TRC-20 contract on the ${session.config.network}?`);
86
- }
87
- return BigInt(`0x${hex}`);
50
+ /** Exponential backoff with jitter (~1s, ~2s, ~4s, ...), as TronGrid recommends for HTTP 429. */
51
+ function backoffMs(attempt) {
52
+ return RATE_LIMIT_BASE_DELAY_MS * 2 ** attempt * (0.5 + Math.random());
88
53
  }
89
54
  /**
90
- * Sends native TRX from the account configured in .env.
55
+ * Sends TRX and TRC-20 tokens, with every transaction signed by `signer`.
91
56
  *
92
- * @example
93
- * await transferTrx({ to: 'TXYZ...', amount: '10' }); // 10 TRX
94
- */
95
- export async function transferTrx(params) {
96
- const session = openSession(params.network);
97
- const { tronWeb, from } = session;
98
- assertRecipient(params.to, from);
99
- const amountSun = toBaseUnits(params.amount, TRX_DECIMALS);
100
- if (amountSun > BigInt(Number.MAX_SAFE_INTEGER)) {
101
- throw new TronTransferError(`Amount ${params.amount} TRX is too large.`);
102
- }
103
- // getBalance() reads solidified state (~1 min behind); use the full node's latest view instead.
104
- const balanceSun = BigInt(await tronWeb.trx.getUnconfirmedBalance(from));
105
- if (balanceSun < amountSun) {
106
- throw new TronTransferError(`Insufficient TRX balance: have ${balanceSun} SUN, need ${amountSun} SUN (plus fees if bandwidth is exhausted).`);
107
- }
108
- const transaction = await tronWeb.transactionBuilder.sendTrx(params.to, Number(amountSun), from);
109
- const txid = await signAndBroadcast(tronWeb, transaction);
110
- return finalize(session, txid, params.to, amountSun, params);
111
- }
112
- /**
113
- * Sends a TRC-20 token (USDT by default) from the account configured in .env.
114
- * The sender needs TRX to pay for energy; up to `feeLimitSun` may be burned.
57
+ * In a browser, pass the connected wallet adapter (or `useWallet()`) as the signer: the SDK builds
58
+ * and checks the transaction, the wallet asks the user to approve it, and the SDK broadcasts it and
59
+ * waits for confirmation. The TronWeb client here never holds a private key.
115
60
  *
116
61
  * @example
117
- * await transferToken({ to: 'TXYZ...', amount: '5' }); // 5 USDT
118
- * await transferToken({ to: 'TXYZ...', amount: '1.25', tokenAddress: 'T...' }); // any TRC-20
62
+ * const service = new TronTransferService(adapter, { network: 'mainnet', apiKey: TRONGRID_KEY });
63
+ * await service.transferToken({ to: 'TXYZ...', amount: '5' }); // 5 USDT
119
64
  */
120
- export async function transferToken(params) {
121
- const session = openSession(params.network);
122
- const { tronWeb, from, config } = session;
123
- assertRecipient(params.to, from);
124
- const tokenAddress = params.tokenAddress ?? config.usdtContract;
125
- if (!tokenAddress) {
126
- throw new TronTransferError(`No token address given and TRON_${config.network.toUpperCase()}_USDT_CONTRACT is not set.`);
127
- }
128
- if (!TronWeb.isAddress(tokenAddress)) {
129
- throw new TronTransferError(`Invalid token contract address "${tokenAddress}".`);
130
- }
131
- const decimals = Number(await callConstant(session, tokenAddress, 'decimals()'));
132
- const amount = toBaseUnits(params.amount, decimals);
133
- // A TRC-20 transfer that reverts still burns energy, so check the balance up front.
134
- const balance = await callConstant(session, tokenAddress, 'balanceOf(address)', [{ type: 'address', value: from }]);
135
- if (balance < amount) {
136
- throw new TronTransferError(`Insufficient token balance: have ${balance}, need ${amount} (base units).`);
137
- }
138
- const { result, transaction } = await tronWeb.transactionBuilder.triggerSmartContract(tokenAddress, 'transfer(address,uint256)', { feeLimit: params.feeLimitSun ?? config.feeLimitSun, callValue: 0 }, [
139
- { type: 'address', value: params.to },
140
- { type: 'uint256', value: amount.toString() },
141
- ], from);
142
- if (!result?.result) {
143
- throw new TronTransferError(`Failed to build token transfer: ${decodeNodeMessage(result?.message)}`);
144
- }
145
- const txid = await signAndBroadcast(tronWeb, transaction);
146
- return finalize(session, txid, params.to, amount, params);
65
+ export class TronTransferService {
66
+ signer;
67
+ config;
68
+ tronWeb;
69
+ // A token's decimals never change, so read them once per token.
70
+ #decimals = new Map();
71
+ constructor(signer, config) {
72
+ this.signer = signer;
73
+ this.config = resolveServiceConfig(config);
74
+ this.tronWeb = createTronWeb(this.config);
75
+ }
76
+ /**
77
+ * Sends native TRX from the signer's account.
78
+ *
79
+ * @example
80
+ * await service.transferTrx({ to: 'TXYZ...', amount: '10' }); // 10 TRX
81
+ */
82
+ async transferTrx(params) {
83
+ const from = this.#requireSender();
84
+ assertRecipient(params.to, from);
85
+ const amountSun = toBaseUnits(params.amount, TRX_DECIMALS);
86
+ if (amountSun > BigInt(Number.MAX_SAFE_INTEGER)) {
87
+ throw new TronTransferError(`Amount ${params.amount} TRX is too large.`);
88
+ }
89
+ // getBalance() reads solidified state (~1 min behind); use the full node's latest view instead.
90
+ const balanceSun = BigInt(await this.#request(() => this.tronWeb.trx.getUnconfirmedBalance(from)));
91
+ if (balanceSun < amountSun) {
92
+ throw new TronTransferError(`Insufficient TRX balance: have ${balanceSun} SUN, need ${amountSun} SUN (plus fees if bandwidth is exhausted).`);
93
+ }
94
+ const transaction = await this.#request(() => this.tronWeb.transactionBuilder.sendTrx(params.to, Number(amountSun), from));
95
+ const txid = await this.#signAndBroadcast(transaction);
96
+ return this.#finalize(txid, from, params.to, amountSun, params);
97
+ }
98
+ /**
99
+ * Sends a TRC-20 token (USDT by default) from the signer's account.
100
+ * The sender needs TRX to pay for energy; up to `feeLimitSun` may be burned.
101
+ *
102
+ * @example
103
+ * await service.transferToken({ to: 'TXYZ...', amount: '5' }); // 5 USDT
104
+ * await service.transferToken({ to: 'TXYZ...', amount: '1.25', tokenAddress: 'T...' }); // any TRC-20
105
+ */
106
+ async transferToken(params) {
107
+ const from = this.#requireSender();
108
+ assertRecipient(params.to, from);
109
+ const tokenAddress = this.#resolveToken(params.tokenAddress);
110
+ const decimals = await this.#tokenDecimals(tokenAddress, from);
111
+ const amount = toBaseUnits(params.amount, decimals);
112
+ // A TRC-20 transfer that reverts still burns energy, so check the balance up front.
113
+ const balance = await this.#callConstant(tokenAddress, 'balanceOf(address)', [{ type: 'address', value: from }], from);
114
+ if (balance < amount) {
115
+ throw new TronTransferError(`Insufficient token balance: have ${balance}, need ${amount} (base units).`);
116
+ }
117
+ const { result, transaction } = await this.#request(() => this.tronWeb.transactionBuilder.triggerSmartContract(tokenAddress, 'transfer(address,uint256)', { feeLimit: params.feeLimitSun ?? this.config.feeLimitSun, callValue: 0 }, [
118
+ { type: 'address', value: params.to },
119
+ { type: 'uint256', value: amount.toString() },
120
+ ], from));
121
+ if (!result?.result) {
122
+ throw new TronTransferError(`Failed to build token transfer: ${decodeNodeMessage(result?.message)}`);
123
+ }
124
+ const txid = await this.#signAndBroadcast(transaction);
125
+ return this.#finalize(txid, from, params.to, amount, params);
126
+ }
127
+ /**
128
+ * TRX balance in whole TRX (e.g. "12.5"), from the full node's latest state.
129
+ * Defaults to the signer's address.
130
+ */
131
+ async getTrxBalance(address) {
132
+ const owner = address ?? this.#requireSender();
133
+ assertAddress(owner, 'account');
134
+ const balanceSun = BigInt(await this.#request(() => this.tronWeb.trx.getUnconfirmedBalance(owner)));
135
+ return fromBaseUnits(balanceSun, TRX_DECIMALS);
136
+ }
137
+ /**
138
+ * TRC-20 balance in whole tokens (e.g. "5.25"). Defaults to USDT and the signer's address.
139
+ */
140
+ async getTokenBalance(params = {}) {
141
+ const owner = params.owner ?? this.#requireSender();
142
+ assertAddress(owner, 'account');
143
+ const tokenAddress = this.#resolveToken(params.tokenAddress);
144
+ const decimals = await this.#tokenDecimals(tokenAddress, owner);
145
+ const balance = await this.#callConstant(tokenAddress, 'balanceOf(address)', [{ type: 'address', value: owner }], owner);
146
+ return fromBaseUnits(balance, decimals);
147
+ }
148
+ /** The signer's address, read on every call because a wallet can disconnect or switch accounts. */
149
+ #requireSender() {
150
+ const address = this.signer.address;
151
+ if (!address) {
152
+ throw new TronTransferError('No wallet connected: the signer has no address.');
153
+ }
154
+ if (!TronWeb.isAddress(address)) {
155
+ throw new TronTransferError(`Signer address "${address}" is not a valid TRON address.`);
156
+ }
157
+ return address;
158
+ }
159
+ #resolveToken(tokenAddress) {
160
+ const token = tokenAddress ?? this.config.usdtContract;
161
+ if (!token) {
162
+ throw new TronTransferError(`No token address given and no default USDT contract is known for ${this.config.fullHost}. Pass tokenAddress or set usdtContract.`);
163
+ }
164
+ if (!TronWeb.isAddress(token)) {
165
+ throw new TronTransferError(`Invalid token contract address "${token}".`);
166
+ }
167
+ return token;
168
+ }
169
+ /**
170
+ * Runs a node request that has no side effects, retrying HTTP 429 with backoff.
171
+ * Everything before the broadcast goes through here, so a failure means nothing was sent.
172
+ */
173
+ async #request(send) {
174
+ for (let attempt = 0;; attempt++) {
175
+ try {
176
+ return await send();
177
+ }
178
+ catch (error) {
179
+ const status = httpStatus(error);
180
+ if (status === 429 && attempt < this.config.rateLimitRetries) {
181
+ await sleep(backoffMs(attempt));
182
+ continue;
183
+ }
184
+ if (status === 429 || status === 403)
185
+ throw this.#httpError(status, error);
186
+ throw error;
187
+ }
188
+ }
189
+ }
190
+ #httpError(status, cause, txid) {
191
+ const host = this.config.fullHost;
192
+ return status === 429
193
+ ? new TronTransferError(`Rate limited by ${host} (HTTP 429) after ${this.config.rateLimitRetries} retries. Try again shortly; for sustained traffic set apiKey or use another fullHost.`, txid, { cause, code: 'RATE_LIMITED' })
194
+ : new TronTransferError(`Request refused by ${host} (HTTP 403): the IP may be blocked, the daily quota used up, or the apiKey invalid.`, txid, { cause, code: 'ACCESS_DENIED' });
195
+ }
196
+ async #signAndBroadcast(transaction) {
197
+ let signed;
198
+ try {
199
+ signed = await this.signer.signTransaction(transaction);
200
+ }
201
+ catch (error) {
202
+ // Wallets throw here when the user rejects the request; nothing was broadcast.
203
+ throw new TronTransferError(`Transaction was not signed: ${errorMessage(error)}`, undefined, {
204
+ cause: error,
205
+ code: 'NOT_SIGNED',
206
+ });
207
+ }
208
+ // Only broadcast exactly what was built and checked above.
209
+ if (signed?.txID !== transaction.txID || !Array.isArray(signed.signature) || signed.signature.length === 0) {
210
+ throw new TronTransferError('Signer returned a transaction that is unsigned or differs from the one requested.');
211
+ }
212
+ return this.#broadcast(signed);
213
+ }
214
+ /**
215
+ * Broadcasts a signed transaction. Resending the same signed transaction is safe: it has the same
216
+ * txid, so the network accepts it at most once. That lets HTTP 429 be retried without asking the
217
+ * wallet to sign again and without any risk of a double send.
218
+ */
219
+ async #broadcast(signed) {
220
+ const txid = signed.txID;
221
+ for (let attempt = 0;; attempt++) {
222
+ let broadcast;
223
+ try {
224
+ broadcast = await this.tronWeb.trx.sendRawTransaction(signed);
225
+ }
226
+ catch (error) {
227
+ const status = httpStatus(error);
228
+ if (status === 429 && attempt < this.config.rateLimitRetries) {
229
+ await sleep(backoffMs(attempt));
230
+ continue;
231
+ }
232
+ // Almost certainly not broadcast, but the txid is kept so the caller checks before resending.
233
+ if (status === 429 || status === 403)
234
+ throw this.#httpError(status, error, txid);
235
+ throw new TronTransferError(`Broadcast request failed: ${errorMessage(error)}. The transaction may still have reached the network; check it before retrying`, txid, { cause: error });
236
+ }
237
+ if (broadcast.result)
238
+ return broadcast.txid || txid;
239
+ // An earlier attempt got through even though its response was lost.
240
+ if (attempt > 0 && broadcast.code === 'DUP_TRANSACTION_ERROR')
241
+ return txid;
242
+ throw new TronTransferError(`Broadcast rejected: ${broadcast.code ?? 'ERROR'} ${decodeNodeMessage(broadcast.message)}`, broadcast.txid || txid);
243
+ }
244
+ }
245
+ /** Polls until the transaction is in a block, then throws if it failed on-chain. */
246
+ async #waitForConfirmation(txid, timeoutMs) {
247
+ const deadline = Date.now() + timeoutMs;
248
+ let interval = CONFIRMATION_POLL_INTERVAL_MS;
249
+ let lastError;
250
+ while (Date.now() < deadline) {
251
+ await sleep(interval);
252
+ let info;
253
+ try {
254
+ info = await this.tronWeb.trx.getUnconfirmedTransactionInfo(txid);
255
+ }
256
+ catch (error) {
257
+ // The transaction is already sent, so a failed poll must not end the wait; slow down on 429.
258
+ lastError = error;
259
+ if (httpStatus(error) === 429)
260
+ interval = Math.min(interval * 2, MAX_POLL_INTERVAL_MS);
261
+ continue;
262
+ }
263
+ interval = CONFIRMATION_POLL_INTERVAL_MS;
264
+ if (!info?.id)
265
+ continue;
266
+ const receiptResult = info.receipt?.result;
267
+ if (info.result === 'FAILED' || (receiptResult && receiptResult !== 'SUCCESS')) {
268
+ const reason = decodeNodeMessage(info.resMessage) || receiptResult || 'FAILED';
269
+ throw new TronTransferError(`Transaction failed on-chain: ${reason}`, txid);
270
+ }
271
+ return info;
272
+ }
273
+ const pollError = lastError === undefined ? '' : ` Last polling error: ${errorMessage(lastError)}.`;
274
+ throw new TronTransferError(`Transaction was broadcast but not confirmed within ${timeoutMs}ms.${pollError} Check its status before retrying to avoid a double send`, txid, lastError === undefined ? {} : { cause: lastError });
275
+ }
276
+ async #finalize(txid, from, to, rawAmount, options) {
277
+ const result = {
278
+ txid,
279
+ network: this.config.network,
280
+ from,
281
+ to,
282
+ rawAmount: rawAmount.toString(),
283
+ confirmed: false,
284
+ };
285
+ if (options.waitForConfirmation === false)
286
+ return result;
287
+ const info = await this.#waitForConfirmation(txid, options.confirmationTimeoutMs ?? DEFAULT_CONFIRMATION_TIMEOUT_MS);
288
+ return { ...result, confirmed: true, blockNumber: info.blockNumber, feeSun: info.fee ?? 0 };
289
+ }
290
+ async #tokenDecimals(tokenAddress, caller) {
291
+ const key = TronWeb.address.toHex(tokenAddress);
292
+ let decimals = this.#decimals.get(key);
293
+ if (decimals === undefined) {
294
+ decimals = Number(await this.#callConstant(tokenAddress, 'decimals()', [], caller));
295
+ this.#decimals.set(key, decimals);
296
+ }
297
+ return decimals;
298
+ }
299
+ async #callConstant(contractAddress, functionSelector, parameters, caller) {
300
+ const response = await this.#request(() => this.tronWeb.transactionBuilder.triggerConstantContract(contractAddress, functionSelector, {}, parameters, caller));
301
+ const hex = response.constant_result?.[0];
302
+ if (!response.result?.result || typeof hex !== 'string' || hex.length === 0) {
303
+ throw new TronTransferError(`Call to ${functionSelector} on ${contractAddress} failed: ${decodeNodeMessage(response.result?.message)}. Is this a TRC-20 contract on the ${this.config.network}?`);
304
+ }
305
+ return BigInt(`0x${hex}`);
306
+ }
147
307
  }
148
308
  //# sourceMappingURL=services.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"services.js","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"services.js","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Types } from 'tronweb';
2
+ /**
3
+ * Signs TRON transactions for one account.
4
+ *
5
+ * This is the same shape as a TronWallet adapter (`@tronweb3/tronwallet-adapters`, e.g. TronLinkAdapter)
6
+ * and as the object returned by `useWallet()` from `@tronweb3/tronwallet-adapter-react-hooks`, so either
7
+ * can be passed to TronTransferService as-is. For Node scripts and tests, use PrivateKeySigner.
8
+ */
9
+ export interface TronSigner {
10
+ /** Base58 address (T...) of the signing account, or null when no wallet is connected. */
11
+ readonly address: string | null;
12
+ /** Returns the transaction with its signature attached. It must not broadcast it. */
13
+ signTransaction(transaction: Types.Transaction): Promise<Types.SignedTransaction>;
14
+ }
15
+ /**
16
+ * Signs locally with a hex private key. For backends, scripts and tests only:
17
+ * never ship a private key to a browser; let the user's wallet sign there instead.
18
+ */
19
+ export declare class PrivateKeySigner implements TronSigner {
20
+ #private;
21
+ readonly address: string;
22
+ constructor(privateKey: string);
23
+ signTransaction(transaction: Types.Transaction): Promise<Types.SignedTransaction>;
24
+ }
25
+ //# sourceMappingURL=signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,yFAAyF;IACzF,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,qFAAqF;IACrF,eAAe,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;CACnF;AAED;;;GAGG;AACH,qBAAa,gBAAiB,YAAW,UAAU;;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAGb,UAAU,EAAE,MAAM;IAaxB,eAAe,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC;CAIxF"}
package/dist/signer.js ADDED
@@ -0,0 +1,26 @@
1
+ import { TronWeb, utils } from 'tronweb';
2
+ /**
3
+ * Signs locally with a hex private key. For backends, scripts and tests only:
4
+ * never ship a private key to a browser; let the user's wallet sign there instead.
5
+ */
6
+ export class PrivateKeySigner {
7
+ address;
8
+ #privateKey;
9
+ constructor(privateKey) {
10
+ const key = privateKey.trim().replace(/^0x/i, '');
11
+ if (!/^[0-9a-fA-F]{64}$/.test(key)) {
12
+ throw new Error('Private key must be a 64-character hex string.');
13
+ }
14
+ const address = TronWeb.address.fromPrivateKey(key);
15
+ if (!address) {
16
+ throw new Error('Could not derive an address from the private key.');
17
+ }
18
+ this.address = address;
19
+ this.#privateKey = key;
20
+ }
21
+ async signTransaction(transaction) {
22
+ // signTransaction() mutates its argument; copy so the caller's unsigned transaction is left as is.
23
+ return utils.crypto.signTransaction(this.#privateKey, { ...transaction });
24
+ }
25
+ }
26
+ //# sourceMappingURL=signer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.js","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAiBzC;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IAClB,OAAO,CAAS;IAChB,WAAW,CAAS;IAE7B,YAAY,UAAkB;QAC5B,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,WAA8B;QAClD,mGAAmG;QACnG,OAAO,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,GAAG,WAAW,EAAE,CAAC,CAAC;IAC5E,CAAC;CACF"}
package/dist/types.d.ts CHANGED
@@ -2,8 +2,6 @@ import type { TronNetwork } from './config.js';
2
2
  /** Human-readable amount, e.g. "10" TRX or "2.5" USDT. Strings avoid floating-point rounding. */
3
3
  export type Amount = string | number;
4
4
  export interface TransferOptions {
5
- /** Network to use. Defaults to TRON_NETWORK from .env. */
6
- network?: TronNetwork;
7
5
  /**
8
6
  * Wait until the transaction is included in a block and check it succeeded.
9
7
  * Broadcast success alone does not mean a TRC-20 transfer executed. Default: true.
@@ -12,6 +10,11 @@ export interface TransferOptions {
12
10
  /** How long to wait for confirmation, in milliseconds. Default: 60_000. */
13
11
  confirmationTimeoutMs?: number;
14
12
  }
13
+ /** Extra option for the .env-driven transferTrx() / transferToken() in the Node entry. */
14
+ export interface EnvTransferOptions {
15
+ /** Network to use. Defaults to TRON_NETWORK from .env. */
16
+ network?: TronNetwork;
17
+ }
15
18
  export interface TransferTrxParams extends TransferOptions {
16
19
  /** Recipient base58 address (T...). */
17
20
  to: string;
@@ -25,9 +28,15 @@ export interface TransferTokenParams extends TransferOptions {
25
28
  amount: Amount;
26
29
  /** TRC-20 contract address. Defaults to the USDT contract configured for the network. */
27
30
  tokenAddress?: string;
28
- /** Max TRX (in SUN) to burn for energy. Defaults to TRON_FEE_LIMIT_SUN. */
31
+ /** Max TRX (in SUN) to burn for energy. Defaults to the service's feeLimitSun. */
29
32
  feeLimitSun?: number;
30
33
  }
34
+ export interface TokenBalanceParams {
35
+ /** TRC-20 contract address. Defaults to the USDT contract configured for the network. */
36
+ tokenAddress?: string;
37
+ /** Account to read. Defaults to the signer's address. */
38
+ owner?: string;
39
+ }
31
40
  export interface TransferResult {
32
41
  txid: string;
33
42
  network: TronNetwork;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,iGAAiG;AACjG,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAErC,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,2EAA2E;IAC3E,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,oFAAoF;IACpF,MAAM,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,gGAAgG;IAChG,SAAS,EAAE,OAAO,CAAC;IACnB,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,iGAAiG;AACjG,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAErC,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,2EAA2E;IAC3E,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,0FAA0F;AAC1F,MAAM,WAAW,kBAAkB;IACjC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,oFAAoF;IACpF,MAAM,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,gGAAgG;IAChG,SAAS,EAAE,OAAO,CAAC;IACnB,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
package/dist/utils.d.ts CHANGED
@@ -4,5 +4,10 @@ import type { Amount } from './types.js';
4
4
  * e.g. toBaseUnits("1.5", 6) === 1_500_000n.
5
5
  */
6
6
  export declare function toBaseUnits(amount: Amount, decimals: number): bigint;
7
+ /**
8
+ * Converts an amount in the smallest unit into a human-readable string,
9
+ * e.g. fromBaseUnits(1_500_000n, 6) === "1.5".
10
+ */
11
+ export declare function fromBaseUnits(units: bigint, decimals: number): string;
7
12
  export declare function sleep(ms: number): Promise<void>;
8
13
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmBpE;AAaD,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmBpE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMrE;AAaD,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
package/dist/utils.js CHANGED
@@ -19,6 +19,18 @@ export function toBaseUnits(amount, decimals) {
19
19
  }
20
20
  return units;
21
21
  }
22
+ /**
23
+ * Converts an amount in the smallest unit into a human-readable string,
24
+ * e.g. fromBaseUnits(1_500_000n, 6) === "1.5".
25
+ */
26
+ export function fromBaseUnits(units, decimals) {
27
+ if (units < 0n)
28
+ return `-${fromBaseUnits(-units, decimals)}`;
29
+ const digits = units.toString().padStart(decimals + 1, '0');
30
+ const whole = digits.slice(0, digits.length - decimals);
31
+ const fraction = digits.slice(digits.length - decimals).replace(/0+$/, '');
32
+ return fraction ? `${whole}.${fraction}` : whole;
33
+ }
22
34
  function numberToPlainString(value) {
23
35
  if (!Number.isFinite(value)) {
24
36
  throw new Error(`Invalid amount ${value}.`);
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,QAAgB;IAC1D,MAAM,IAAI,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAEtF,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,+CAA+C,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;IAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,mBAAmB,QAAQ,kBAAkB,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;IAC7D,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,0CAA0C,MAAM,IAAI,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,GAAG,CAAC,CAAC;IAC9C,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,UAAU,KAAK,mEAAmE,CAAC,CAAC;IACtG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,QAAgB;IAC1D,MAAM,IAAI,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAEtF,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,+CAA+C,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;IAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,mBAAmB,QAAQ,kBAAkB,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;IAC7D,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,0CAA0C,MAAM,IAAI,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,QAAgB;IAC3D,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,IAAI,aAAa,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;IAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC3E,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;AACnD,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,GAAG,CAAC,CAAC;IAC9C,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,UAAU,KAAK,mEAAmE,CAAC,CAAC;IACtG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}