tronlink-signer 0.1.2 → 0.1.3

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
@@ -18,6 +18,7 @@ await signer.start();
18
18
 
19
19
  const { address, network } = await signer.connectWallet();
20
20
  const { txId } = await signer.sendTrx("TXxx...", 1);
21
+ const { txId: txId2, status } = await signer.signTransaction(tx, "nile", true); // broadcast + auto-confirm
21
22
  const { balance } = await signer.getBalance("TXxx...");
22
23
 
23
24
  await signer.stop();
@@ -41,21 +42,22 @@ Stops the server and clears all pending requests.
41
42
 
42
43
  Returns the current configuration.
43
44
 
44
- ### `signer.connectWallet(network?: TronNetwork): Promise<{ address: string; network: string }>`
45
+ ### `signer.connectWallet(network?, options?): Promise<{ address: string; network: string }>`
45
46
 
46
47
  Opens the browser to connect TronLink and retrieve the wallet address and current network. If the wallet is already connected (same browser tab still open), auto-completes without user interaction.
47
48
 
48
- ### `signer.sendTrx(to, amount, network?): Promise<{ txId: string }>`
49
+ ### `signer.sendTrx(to, amount, network?, options?): Promise<{ txId: string }>`
49
50
 
50
51
  Sends TRX to a recipient address. Opens a browser approval page for the user to confirm.
51
52
 
52
53
  | Parameter | Type | Description |
53
54
  | --------- | ---- | ----------- |
54
55
  | `to` | `string` | Recipient Tron address (base58) |
55
- | `amount` | `number` | Amount of TRX to send |
56
+ | `amount` | `string \| number` | Amount of TRX to send |
56
57
  | `network` | `TronNetwork` | Optional network override |
58
+ | `options` | `SignerOptions` | Optional — pass `{ signal }` to enable cancellation |
57
59
 
58
- ### `signer.sendTrc20(contractAddress, to, amount, decimals?, network?): Promise<{ txId: string }>`
60
+ ### `signer.sendTrc20(contractAddress, to, amount, decimals?, network?, options?): Promise<{ txId: string }>`
59
61
 
60
62
  Sends TRC20 tokens. Opens a browser approval page.
61
63
 
@@ -66,12 +68,13 @@ Sends TRC20 tokens. Opens a browser approval page.
66
68
  | `amount` | `string` | Amount in human-readable units (e.g., `"1.5"` for 1.5 USDT). Decimals conversion is automatic. |
67
69
  | `decimals` | `number` | Token decimals (default: 6) |
68
70
  | `network` | `TronNetwork` | Optional network override |
71
+ | `options` | `SignerOptions` | Optional — pass `{ signal }` to enable cancellation |
69
72
 
70
- ### `signer.signMessage(message, network?): Promise<{ signature: string }>`
73
+ ### `signer.signMessage(message, network?, options?): Promise<{ signature: string }>`
71
74
 
72
75
  Signs a plain text message.
73
76
 
74
- ### `signer.signTypedData(typedData, network?): Promise<{ signature: string }>`
77
+ ### `signer.signTypedData(typedData, network?, options?): Promise<{ signature: string }>`
75
78
 
76
79
  Signs EIP-712 typed data.
77
80
 
@@ -86,28 +89,94 @@ const { signature } = await signer.signTypedData({
86
89
  });
87
90
  ```
88
91
 
89
- ### `signer.signTransaction(transaction, network?, broadcast?): Promise<{ signedTransaction: Record<string, unknown>; txId?: string }>`
92
+ ### `signer.signTransaction(transaction, network?, broadcast?, options?): Promise<{ signedTransaction; txId?; status? }>`
90
93
 
91
- Signs a raw transaction. When `broadcast` is `true`, the signed transaction is also broadcast on-chain via TronLink and the `txId` is returned.
94
+ Signs a raw transaction. When `broadcast` is `true`, the signed transaction is broadcast on-chain via TronLink and the SDK automatically polls for on-chain confirmation (returns `status: "success"` or `"pending"`).
92
95
 
93
96
  | Parameter | Type | Description |
94
97
  | --------- | ---- | ----------- |
95
98
  | `transaction` | `Record<string, unknown>` | Raw transaction object to sign |
96
99
  | `network` | `TronNetwork` | Optional network override |
97
100
  | `broadcast` | `boolean` | Whether to broadcast after signing (default: `false`) |
101
+ | `options` | `SignerOptions` | Optional — cancellation, confirmation control, broadcast callback |
98
102
 
99
103
  ```ts
100
104
  // Sign only
101
105
  const { signedTransaction } = await signer.signTransaction(tx);
102
106
 
103
- // Sign and broadcast
104
- const { signedTransaction, txId } = await signer.signTransaction(tx, "nile", true);
107
+ // Sign, broadcast, and wait for confirmation (default)
108
+ const { signedTransaction, txId, status } = await signer.signTransaction(tx, "nile", true);
109
+ // status === "success" — confirmed on-chain
110
+ // status === "pending" — broadcast succeeded but not confirmed within timeout
111
+
112
+ // Broadcast without waiting for confirmation
113
+ const result = await signer.signTransaction(tx, "nile", true, { confirm: false });
114
+
115
+ // Get notified as soon as the tx enters the mempool
116
+ const result = await signer.signTransaction(tx, "nile", true, {
117
+ onBroadcasted: ({ txId }) => console.log("Broadcast:", txId),
118
+ });
119
+ ```
120
+
121
+ ### `signer.waitForTransaction(txId, network?, options?): Promise<"success" | "pending">`
122
+
123
+ Polls the network for transaction confirmation. Returns `"success"` when the transaction is confirmed on-chain, or `"pending"` if the timeout is reached. Throws if the transaction execution failed (e.g., `OUT_OF_ENERGY`, Solidity revert).
124
+
125
+ | Parameter | Type | Description |
126
+ | --------- | ---- | ----------- |
127
+ | `txId` | `string` | Transaction ID to monitor |
128
+ | `network` | `TronNetwork` | Optional network override |
129
+ | `options` | `WaitForTransactionOptions` | Optional — `timeoutMs` (default: 30000), `signal` |
130
+
131
+ ```ts
132
+ const status = await signer.waitForTransaction(txId, "nile");
133
+ if (status === "success") {
134
+ console.log("Confirmed on-chain");
135
+ }
105
136
  ```
106
137
 
138
+ > **Note:** When using `signTransaction` with `broadcast: true`, confirmation polling is automatic — you don't need to call `waitForTransaction` separately unless you set `confirm: false`.
139
+
107
140
  ### `signer.getBalance(address, network?): Promise<{ balance: string; balanceSun: number }>`
108
141
 
109
142
  Gets TRX balance for an address. No browser approval needed.
110
143
 
144
+ ### `signer.onBrowserDisconnect`
145
+
146
+ Setter for a callback that fires when the approval page is closed or loses connection (heartbeat timeout). Useful for cleanup or re-prompting the user.
147
+
148
+ ```ts
149
+ signer.onBrowserDisconnect = () => {
150
+ console.log("Browser approval page was closed");
151
+ };
152
+ ```
153
+
154
+ ### Cancellation & Options
155
+
156
+ All signing methods accept an optional `SignerOptions`:
157
+
158
+ | Option | Type | Description |
159
+ | ------ | ---- | ----------- |
160
+ | `signal` | `AbortSignal` | Cancels the pending request. If already aborted, the browser page is not opened. |
161
+ | `confirm` | `boolean` | Wait for on-chain confirmation after broadcast (default: `true`). Only applies when `broadcast: true`. |
162
+ | `confirmTimeoutMs` | `number` | Max time (ms) to wait for confirmation (default: `30000`). |
163
+ | `onBroadcasted` | `(info) => void` | Fires after the tx enters the mempool (before confirmation). Callback errors are swallowed. |
164
+
165
+ ```ts
166
+ const controller = new AbortController();
167
+
168
+ // Cancel after 30 seconds
169
+ setTimeout(() => controller.abort(), 30_000);
170
+
171
+ try {
172
+ const { txId } = await signer.sendTrx("TXxx...", 1, undefined, {
173
+ signal: controller.signal,
174
+ });
175
+ } catch (e) {
176
+ // e.message === "CANCELLED_BY_CALLER"
177
+ }
178
+ ```
179
+
111
180
  ## How It Works
112
181
 
113
182
  1. Your code calls a signing method (e.g., `signMessage`)
@@ -156,6 +225,18 @@ interface NetworkConfig {
156
225
  fullHost: string;
157
226
  explorerUrl: string;
158
227
  }
228
+
229
+ interface SignerOptions {
230
+ signal?: AbortSignal;
231
+ confirm?: boolean;
232
+ confirmTimeoutMs?: number;
233
+ onBroadcasted?: (info: { txId: string; signedTransaction: Record<string, unknown> }) => void;
234
+ }
235
+
236
+ interface WaitForTransactionOptions {
237
+ timeoutMs?: number;
238
+ signal?: AbortSignal;
239
+ }
159
240
  ```
160
241
 
161
242
  ## Exports
@@ -173,6 +254,7 @@ export type {
173
254
  PendingRequestType, PendingRequest,
174
255
  ConnectData, SendTrxData, SendTrc20Data,
175
256
  SignMessageData, SignTypedDataData, SignTransactionData,
257
+ SignerOptions, WaitForTransactionOptions,
176
258
  } from "./types.js";
177
259
  ```
178
260
 
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ interface PendingRequest<T = unknown> {
14
14
  }
15
15
  interface SendTrxData {
16
16
  to: string;
17
- amount: number;
17
+ amount: string | number;
18
18
  }
19
19
  interface SendTrc20Data {
20
20
  contractAddress: string;
@@ -37,42 +37,90 @@ interface AppConfig {
37
37
  httpPort: number;
38
38
  apiKey?: string;
39
39
  }
40
+ interface SignerOptions {
41
+ signal?: AbortSignal;
42
+ /** Wait for on-chain execution result after broadcast. Default: true. Only applies to broadcasting operations. */
43
+ confirm?: boolean;
44
+ /** Max time to wait for confirmation, in ms. Default: 30000. */
45
+ confirmTimeoutMs?: number;
46
+ /**
47
+ * Fires after the transaction has been broadcast to the Tron network
48
+ * (txId in mempool, not yet confirmed on-chain). Use this to start your
49
+ * own monitoring in parallel with the SDK's polling. Callback errors are swallowed.
50
+ */
51
+ onBroadcasted?: (info: {
52
+ txId: string;
53
+ signedTransaction: Record<string, unknown>;
54
+ }) => void;
55
+ }
56
+ interface WaitForTransactionOptions {
57
+ timeoutMs?: number;
58
+ signal?: AbortSignal;
59
+ }
40
60
 
41
61
  declare class TronSigner {
42
62
  private config;
43
63
  private pendingStore;
44
64
  private httpServer;
45
65
  private tronWeb;
66
+ private browserWatchTimer;
67
+ private _onBrowserDisconnect;
68
+ private _onWalletChanged;
69
+ private connectedWallet;
70
+ set onBrowserDisconnect(cb: (() => void) | null);
71
+ /**
72
+ * Fires when the user switches account/network or disconnects inside TronLink.
73
+ * All pending requests have already been rejected with "WALLET_CHANGED: <reason>"
74
+ * and the internal connectedWallet cache has been invalidated by the time this
75
+ * callback runs. Reasons: "account" | "network" | "disconnect".
76
+ */
77
+ set onWalletChanged(cb: ((reason: string) => void) | null);
46
78
  constructor();
47
79
  start(): Promise<void>;
48
80
  private getPort;
49
81
  stop(): Promise<void>;
50
82
  getConfig(): AppConfig;
51
83
  private resolveNetwork;
52
- connectWallet(network?: TronNetwork): Promise<{
84
+ /** @returns true if the signal was already aborted */
85
+ private attachAbortSignal;
86
+ connectWallet(network?: TronNetwork, options?: SignerOptions): Promise<{
53
87
  address: string;
54
88
  network: string;
55
89
  }>;
56
- sendTrx(to: string, amount: number, network?: TronNetwork): Promise<{
90
+ /**
91
+ * Returns the most recently connected wallet (cached in-memory).
92
+ * Cleared when the approval page disconnects (heartbeat timeout).
93
+ * Callers should treat this as a cache, not ground truth — the user may
94
+ * have switched accounts inside TronLink and the SDK has no way to know.
95
+ * To force a fresh read, call connectWallet() instead.
96
+ */
97
+ getConnectedWallet(): {
98
+ address: string;
99
+ network: TronNetwork;
100
+ } | null;
101
+ sendTrx(to: string, amount: string | number, network?: TronNetwork, options?: SignerOptions): Promise<{
57
102
  txId: string;
58
103
  }>;
59
- sendTrc20(contractAddress: string, to: string, amount: string, decimals?: number, network?: TronNetwork): Promise<{
104
+ sendTrc20(contractAddress: string, to: string, amount: string, decimals?: number, network?: TronNetwork, options?: SignerOptions): Promise<{
60
105
  txId: string;
61
106
  }>;
62
- signMessage(message: string, network?: TronNetwork): Promise<{
107
+ signMessage(message: string, network?: TronNetwork, options?: SignerOptions): Promise<{
63
108
  signature: string;
64
109
  }>;
65
- signTypedData(typedData: Record<string, unknown>, network?: TronNetwork): Promise<{
110
+ signTypedData(typedData: Record<string, unknown>, network?: TronNetwork, options?: SignerOptions): Promise<{
66
111
  signature: string;
67
112
  }>;
68
- signTransaction(transaction: Record<string, unknown>, network?: TronNetwork, broadcast?: boolean): Promise<{
113
+ signTransaction(transaction: Record<string, unknown>, network?: TronNetwork, broadcast?: boolean, options?: SignerOptions): Promise<{
69
114
  signedTransaction: Record<string, unknown>;
70
115
  txId?: string;
116
+ status?: "success" | "pending";
71
117
  }>;
72
118
  getBalance(address: string, network?: TronNetwork): Promise<{
73
119
  balance: string;
74
120
  balanceSun: number;
75
121
  }>;
122
+ private getTronWebFor;
123
+ waitForTransaction(txId: string, network?: TronNetwork, options?: WaitForTransactionOptions): Promise<"success" | "pending">;
76
124
  }
77
125
 
78
126
  declare const NETWORKS: Record<TronNetwork, NetworkConfig>;
@@ -80,4 +128,4 @@ declare const DEFAULT_HTTP_PORT = 3386;
80
128
  declare const REQUEST_TIMEOUT_MS: number;
81
129
  declare function loadConfig(): AppConfig;
82
130
 
83
- export { type AppConfig, DEFAULT_HTTP_PORT, NETWORKS, type NetworkConfig, type PendingRequest, type PendingRequestType, REQUEST_TIMEOUT_MS, type SendTrc20Data, type SendTrxData, type SignMessageData, type SignTransactionData, type SignTypedDataData, type TronNetwork, TronSigner, loadConfig };
131
+ export { type AppConfig, DEFAULT_HTTP_PORT, NETWORKS, type NetworkConfig, type PendingRequest, type PendingRequestType, REQUEST_TIMEOUT_MS, type SendTrc20Data, type SendTrxData, type SignMessageData, type SignTransactionData, type SignTypedDataData, type SignerOptions, type TronNetwork, TronSigner, type WaitForTransactionOptions, loadConfig };