@tuwaio/pulsar-core 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -4,326 +4,411 @@ import { StoreApi } from 'zustand';
4
4
  import { PersistOptions } from 'zustand/middleware';
5
5
 
6
6
  /**
7
- * A utility type for creating modular Zustand store slices, enabling composable state management.
8
- * @template T The state slice being defined.
9
- * @template S The full store state that includes the slice `T`.
7
+ * @file Core types of Pulsar: transaction shapes, the adapter contract that chain packages implement, and the state
8
+ * and actions of the transaction stores.
9
+ */
10
+
11
+ /**
12
+ * A Zustand slice creator: receives the store's `set` and `get` and returns the slice state and actions.
13
+ *
14
+ * @template T - The state slice being defined.
15
+ * @template S - The full store state that includes the slice `T`.
10
16
  */
11
17
  type StoreSlice<T extends object, S extends object = T> = (set: StoreApi<S extends T ? S : S & T>['setState'], get: StoreApi<S extends T ? S : S & T>['getState']) => T;
12
18
  /**
13
- * Enum representing the different tracking strategies available for transactions.
14
- * Each tracker corresponds to a specific method of monitoring a transaction's lifecycle.
19
+ * Tracking strategy of a transaction. The chain adapter picks it after the action returns (see
20
+ * `TxAdapter.checkTransactionsTracker`) and routes the transaction to the matching tracker.
15
21
  */
16
22
  declare enum TransactionTracker {
17
- /** For standard on-chain EVM transactions tracked by their hash. */
23
+ /** A standard EVM transaction, tracked by its hash through RPC (`@tuwaio/pulsar-evm`). */
18
24
  Ethereum = "ethereum",
19
- /** For multi-signature transactions managed and executed via a Safe contract. */
25
+ /** A Safe multisig transaction, tracked by its `safeTxHash` through the Safe Transaction Service API. */
20
26
  Safe = "safe",
21
27
  /**
22
- * For meta-transactions relayed and executed by the Gelato Network.
23
- * @deprecated Gelato gasless relay is deprecated. Use TransactionTracker.ERC4337 instead.
28
+ * A meta-transaction relayed by Gelato, tracked by its task ID through the Gelato API.
29
+ * @deprecated Gelato relay is deprecated. Use `TransactionTracker.ERC4337` instead.
24
30
  */
25
31
  Gelato = "gelato",
26
- /** The tracker for monitoring standard Solana transaction signatures. */
32
+ /** A Solana transaction, tracked by its signature through RPC (`@tuwaio/pulsar-solana`). */
27
33
  Solana = "solana",
28
- /** For native ERC-4337 UserOperation transactions tracked via bundler RPC. */
34
+ /** An ERC-4337 UserOperation, tracked by its `userOpHash` through a bundler RPC and then on-chain. */
29
35
  ERC4337 = "erc4337"
30
36
  }
31
37
  /**
32
- * Represents the terminal status of a transaction after it has been processed.
38
+ * Terminal status of a transaction. Trackers set it together with `pending: false`.
33
39
  */
34
40
  declare enum TransactionStatus {
35
- /** The transaction failed to execute due to an on-chain error or rejection. */
41
+ /** The transaction reverted, was rejected, or tracking failed (for example, it was not found in time). */
36
42
  Failed = "Failed",
37
- /** The transaction was successfully mined and included in a block. */
43
+ /** The transaction was included on-chain and executed successfully. */
38
44
  Success = "Success",
39
- /** The transaction was replaced by another with the same nonce (e.g., a speed-up or cancel). */
45
+ /** Another transaction with the same nonce was mined instead (a wallet speed-up or cancel). */
40
46
  Replaced = "Replaced"
41
47
  }
42
48
  /**
43
- * A union type representing the unique identifier returned by an `actionFunction`
44
- * after a transaction is submitted to the network or a relay service.
45
- *
46
- * This key is crucial for the adapter to determine which tracker should
47
- * monitor the transaction.
48
- *
49
- * It can be one of the following:
50
- * - A standard `0x...` transaction hash (`Hex`).
51
- * - A Solana transaction signature (string).
49
+ * The identifier returned by an `actionFunction` once the transaction is submitted: an EVM transaction hash, an
50
+ * ERC-4337 `userOpHash`, a Safe `safeTxHash`, a Gelato task ID or a Solana signature. The adapter uses it to pick the
51
+ * tracker and the `txKey` of the transaction.
52
52
  */
53
53
  type ActionTxKey = `0x${string}` | string;
54
54
  /**
55
- * The fundamental structure for any transaction being tracked by Pulsar.
56
- * This serves as the base upon which chain-specific transaction types are built.
55
+ * Fields shared by every tracked transaction. Chain-specific transaction types extend it.
57
56
  */
58
57
  type BaseTransaction = {
59
- /** The chain identifier (e.g., 1 for Ethereum Mainnet, 'SN_MAIN' for Starknet). */
58
+ /**
59
+ * The chain of the transaction: the numeric chain ID for EVM (for example `1`), or `solana:<cluster>` for Solana
60
+ * (for example `solana:devnet`). `executeTxAction` derives it from `desiredChainID`.
61
+ */
60
62
  chainId: number | string;
61
63
  /**
62
- * User-facing description. Can be a single string for all states, or a tuple for specific states.
63
- * Each string is validated before execution and persistence. It must be 300 characters or less and must not contain
64
- * executable-like patterns such as `eval(` or `javascript:`.
64
+ * User-facing description: one string for every state, or a tuple for the `[pending, success, error, replaced]`
65
+ * states. Each string must be 300 characters or less and must not contain executable-like patterns such as `eval(`
66
+ * or `javascript:`; `executeTxAction`, `addTxToPool` and the pool restore functions reject or drop transactions that
67
+ * break these rules.
65
68
  * @example
66
- * // A single description for all states
67
- * description: 'Swap 1 ETH for 1,500 USDC'
68
- * // Specific descriptions for each state in order: [pending, success, error, replaced]
69
- * description: ['Swapping...', 'Swapped Successfully', 'Swap Failed', 'Swap Replaced']
69
+ * ```ts
70
+ * description: 'Swap 1 ETH for 1,500 USDC';
71
+ * description: ['Swapping...', 'Swapped successfully', 'Swap failed', 'Swap replaced'];
72
+ * ```
70
73
  */
71
74
  description?: string | [string, string, string, string];
72
- /** The error state if the transaction failed, containing message and raw error details. */
75
+ /** The normalized error of a failed transaction (`normalizeError` from `@tuwaio/orbit-core`). */
73
76
  error?: TuwaErrorState;
74
- /** The on-chain timestamp (in seconds) when the transaction was finalized. */
77
+ /**
78
+ * Unix timestamp (seconds) of the terminal state: the block timestamp for EVM and ERC-4337 transactions confirmed
79
+ * on-chain, the execution date for Safe, and the local time otherwise.
80
+ */
75
81
  finishedTimestamp?: number;
76
- /** The sender's wallet address. */
82
+ /** The address of the wallet that sent the transaction, as reported by the adapter's `getConnectorInfo`. */
77
83
  from: string;
78
- /** A flag indicating if the transaction is in a failed state. */
84
+ /** `true` when the transaction failed; set by trackers together with `status: Failed`. */
79
85
  isError?: boolean;
80
- /** A UI flag to control the visibility of a detailed tracking modal for this transaction. */
86
+ /** UI flag for a detailed tracking modal. Set from `withTrackedModal`; `closeTxTrackedModal` sets it to `false`. */
81
87
  isTrackedModalOpen?: boolean;
82
- /** The local timestamp (in seconds) when the transaction was initiated by the user. */
88
+ /** Unix timestamp (seconds) when `executeTxAction` started. The pool is ordered and evicted by this value. */
83
89
  localTimestamp: number;
84
90
  /**
85
- * Custom JSON-serializable data (strings or numbers) to associate with the transaction.
86
- * The serialized UTF-8 payload must be 10KB or less and string values must not contain executable-like patterns.
91
+ * Custom JSON data of the application. The UTF-8 JSON must be 10 KB or less, and string keys and values must not
92
+ * contain executable-like patterns.
87
93
  */
88
94
  payload?: Record<string, string | number>;
89
- /** A flag indicating if the transaction is still awaiting on-chain confirmation. */
95
+ /** `true` while the transaction is tracked; trackers set it to `false` when it reaches a terminal status. */
90
96
  pending: boolean;
91
- /** The final on-chain status of the transaction. */
97
+ /** The terminal status, set together with `pending: false`. */
92
98
  status?: TransactionStatus;
93
99
  /**
94
- * User-facing title. Can be a single string for all states, or a tuple for specific states.
95
- * Each string is validated before execution and persistence. It must be 100 characters or less and must not contain
96
- * executable-like patterns such as `eval(` or `javascript:`.
100
+ * User-facing title: one string for every state, or a tuple for the `[pending, success, error, replaced]` states.
101
+ * Each string must be 100 characters or less and must not contain executable-like patterns such as `eval(` or
102
+ * `javascript:`.
97
103
  * @example
98
- * // A single title for all states
99
- * title: 'ETH/USDC Swap'
100
- * // Specific titles for each state in order: [pending, success, error, replaced]
101
- * title: ['Processing Swap', 'Swap Complete', 'Swap Error', 'Swap Replaced']
104
+ * ```ts
105
+ * title: 'ETH/USDC swap';
106
+ * title: ['Processing swap', 'Swap complete', 'Swap error', 'Swap replaced'];
107
+ * ```
102
108
  */
103
109
  title?: string | [string, string, string, string];
104
- /** The specific tracker responsible for monitoring this transaction's status. */
110
+ /** The tracker that monitors the transaction. */
105
111
  tracker: TransactionTracker;
106
- /** The unique identifier for the transaction (e.g., EVM hash, Solana signature, or Gelato task ID). */
112
+ /**
113
+ * The key of the transaction in the pool: the transaction hash, `userOpHash` (ERC-4337), `safeTxHash` (Safe), Gelato
114
+ * task ID or Solana signature.
115
+ */
107
116
  txKey: string;
108
- /** The application-specific type or category of the transaction (e.g., 'SWAP', 'APPROVE'). */
117
+ /** Application-specific type of the transaction, for example `'SWAP'` or `'APPROVE'`. */
109
118
  type: string;
110
- /** The type of connector used to sign the transaction (e.g., 'injected', 'walletConnect'). */
119
+ /** The connector that signed the transaction, for example `evm:metamask` or `solana:phantom`. */
111
120
  connectorType: string;
112
- /** The number of confirmations required for the transaction to be considered confirmed. */
121
+ /**
122
+ * Number of block confirmations the EVM trackers wait for before marking the transaction successful. Defaults to 1.
123
+ * The Solana tracker always waits for the `finalized` commitment instead.
124
+ */
113
125
  requiredConfirmations?: number;
114
- /** The number of confirmations received. A string value indicates a confirmed transaction, while `null` means it's pending. */
126
+ /**
127
+ * Confirmations reported by the tracker while the transaction is pending. The Solana tracker sets it to `'MAX'` when
128
+ * the transaction is finalized.
129
+ */
115
130
  confirmations?: number | string | null;
116
- /** The RPC URL to use for the transaction. Required for Solana transactions. */
131
+ /**
132
+ * RPC endpoint used by the Solana tracker, also after a page reload. Without it, the tracker uses the public
133
+ * endpoint of the cluster in `chainId`.
134
+ */
117
135
  rpcUrl?: string;
118
- /** Indicates the synchronization status of the transaction with the remote backend (Quasar). */
136
+ /**
137
+ * Remote sync state, set only when the store has an `onRemoteCreate` callback: `'pending-sync'` from the moment the
138
+ * transaction is added until `onRemoteCreate` resolves (the key is listed in `unsyncedTxKeys` meanwhile and retried
139
+ * if the call fails), then `'synced'`.
140
+ */
119
141
  syncStatus?: 'synced' | 'pending-sync';
120
142
  };
121
143
  /**
122
- * Represents an EVM-specific transaction, extending the base properties with EVM fields.
144
+ * An EVM transaction. Trackers fill the on-chain fields (`hash`, `nonce`, fees, `to`, `value`, `input`) once the
145
+ * transaction details are available.
123
146
  */
124
147
  type EvmTransaction = BaseTransaction & {
125
- /** The adapter type for EVM transactions. */
148
+ /** Always `OrbitAdapter.EVM`. */
126
149
  adapter: OrbitAdapter.EVM;
127
- /** The on-chain transaction hash, available after submission. */
150
+ /**
151
+ * The on-chain transaction hash: the `txKey` for standard transactions, and the hash of the mined transaction for
152
+ * ERC-4337, Safe and Gelato once it is known.
153
+ */
128
154
  hash?: `0x${string}`;
129
- /** The data payload for the transaction, typically for smart contract interactions. */
155
+ /** The calldata of the transaction. */
130
156
  input?: `0x${string}`;
131
- /** The maximum fee per gas for an EIP-1559 transaction (in wei). */
157
+ /** EIP-1559 max fee per gas, in wei, as a decimal string. */
132
158
  maxFeePerGas?: string;
133
- /** The maximum priority fee per gas for an EIP-1559 transaction (in wei). */
159
+ /** EIP-1559 max priority fee per gas, in wei, as a decimal string. */
134
160
  maxPriorityFeePerGas?: string;
135
- /** The transaction nonce, a sequential number for the sender's account. */
161
+ /** The nonce of the sender account. */
136
162
  nonce?: number;
137
- /** The hash of a transaction that this one replaced. */
163
+ /**
164
+ * The hash of the transaction that replaced this one (set with `status: Replaced`). For Safe transactions it is the
165
+ * `safeTxHash` of the transaction executed instead.
166
+ */
138
167
  replacedTxHash?: `0x${string}`;
139
- /** The recipient's address or contract address. */
168
+ /** The recipient or contract address. */
140
169
  to?: `0x${string}`;
141
- /** The amount of native currency (in wei) being sent. */
170
+ /** The native value sent, in wei, as a decimal string. */
142
171
  value?: string;
143
- /** Optional custom bundler RPC URL for ERC-4337 UserOperation tracking. */
172
+ /**
173
+ * Custom bundler RPC URL used to track an ERC-4337 UserOperation. Stored with the transaction, so it is persisted to
174
+ * `localStorage` and passed to `onRemoteCreate` (a backend can track through the same bundler). Keep API keys out of
175
+ * this URL; pass them as `pimlicoApiKey`.
176
+ */
144
177
  bundlerUrl?: string;
145
- /** Optional Pimlico API key for ERC-4337 UserOperation tracking. */
178
+ /**
179
+ * Pimlico API key used to track an ERC-4337 UserOperation when no `bundlerUrl` is set. Persisted to `localStorage`
180
+ * with the transaction, so tracking can resume after a reload, but never passed to `onRemoteCreate`.
181
+ */
146
182
  pimlicoApiKey?: string;
147
183
  };
148
184
  /**
149
- * Represents a Solana-specific transaction, extending the base properties.
185
+ * A Solana transaction. The Solana tracker fills the on-chain fields once the transaction is found.
150
186
  */
151
187
  type SolanaTransaction = BaseTransaction & {
152
- /** The adapter type for Solana transactions. */
188
+ /** Always `OrbitAdapter.SOLANA`. */
153
189
  adapter: OrbitAdapter.SOLANA;
154
- /** The transaction fee in lamports. */
190
+ /** The transaction fee, in lamports. */
155
191
  fee?: number;
156
- /** The instructions included in the transaction. */
192
+ /** The instructions of the transaction, as returned by the `getTransaction` RPC method. */
157
193
  instructions?: unknown[];
158
- /** The recent blockhash used for the transaction. */
194
+ /** The blockhash the transaction was signed with. */
159
195
  recentBlockhash?: string;
160
196
  /** The slot in which the transaction was processed. */
161
197
  slot?: number;
162
198
  };
163
199
  /**
164
- * Represents a Starknet-specific transaction, extending the base properties.
200
+ * A Starknet transaction. Reserved for a Starknet adapter; Pulsar does not ship one.
165
201
  */
166
202
  type StarknetTransaction = BaseTransaction & {
167
- /** The adapter type for Starknet transactions. */
203
+ /** Always `OrbitAdapter.Starknet`. */
168
204
  adapter: OrbitAdapter.Starknet;
169
205
  /** The actual fee paid for the transaction. */
170
206
  actualFee?: {
207
+ /** The fee amount. */
171
208
  amount: string;
209
+ /** The fee unit. */
172
210
  unit: string;
173
211
  };
174
212
  /** The address of the contract being interacted with. */
175
213
  contractAddress?: string;
176
214
  };
177
- /** A union type representing any possible transaction structure that Pulsar can handle. */
215
+ /** Any transaction Pulsar can track. Application transaction types extend one of its members. */
178
216
  type Transaction = EvmTransaction | SolanaTransaction | StarknetTransaction;
179
217
  /**
180
- * Represents the parameters required to initiate a new transaction tracking flow.
218
+ * The metadata of a transaction passed to `executeTxAction` (as `params`, without `actionFunction`) and kept in
219
+ * `initialTx`.
181
220
  */
182
221
  type InitialTransactionParams = Pick<BaseTransaction, 'description' | 'title' | 'type' | 'requiredConfirmations' | 'rpcUrl' | 'payload'> & Pick<EvmTransaction, 'bundlerUrl' | 'pimlicoApiKey'> & {
183
- /** The specific blockchain adapter for this transaction. */
222
+ /** The adapter that handles the transaction. When no configured adapter has this key, the first one is used. */
184
223
  adapter: OrbitAdapter;
185
- /** The function that executes the on-chain action (e.g., sending a transaction) and returns a preliminary identifier like a hash. */
186
- actionFunction: (...args: any[]) => Promise<ActionTxKey | undefined>;
187
- /** The target chain ID for the transaction. */
224
+ /**
225
+ * Signs and submits the transaction and returns its `ActionTxKey`, or `undefined` when the user cancelled.
226
+ * `executeTxAction` calls it without arguments. The adapters' `retryTxAction` call it with
227
+ * `{ config, ...payload }` (EVM) or `{ client, ...payload }` (Solana).
228
+ * @param args - No arguments from `executeTxAction`; one object from `retryTxAction`.
229
+ */
230
+ actionFunction: (...args: unknown[]) => Promise<ActionTxKey | undefined>;
231
+ /**
232
+ * The chain the transaction must be sent on: a numeric chain ID for EVM (the wallet is asked to switch if needed),
233
+ * or a cluster moniker such as `'devnet'` for Solana (compared with the cluster of the connected wallet).
234
+ */
188
235
  desiredChainID: number | string;
189
- /** If true, the detailed tracking modal will open automatically upon initiation. */
236
+ /** When `true`, the transaction is created with `isTrackedModalOpen: true`. */
190
237
  withTrackedModal?: boolean;
191
- /** The specific tracker responsible for monitoring this transaction's status. Required for Gelato / ERC-4337 tracker. */
238
+ /**
239
+ * Forces a tracker. Required for ERC-4337 (`TransactionTracker.ERC4337`) and Gelato; otherwise the adapter picks
240
+ * one from the returned key and the connector.
241
+ */
192
242
  tracker?: TransactionTracker;
193
- /** @deprecated Gelato relay is deprecated. */
243
+ /**
244
+ * Stored with the transaction and persisted to `localStorage`, but never passed to `onRemoteCreate`.
245
+ * @deprecated Gelato relay is deprecated. Use ERC-4337 with `bundlerUrl` or `pimlicoApiKey` instead.
246
+ */
194
247
  gelatoApiKey?: string;
195
248
  };
196
249
  /**
197
- * Represents a transaction in its temporary, pre-submission state.
198
- * This is used for UI feedback while the transaction is being signed and sent.
250
+ * The state of a transaction while `executeTxAction` runs, before it is added to the pool. UI layers use it for
251
+ * immediate feedback (signature prompts, preflight errors).
199
252
  */
200
253
  type InitialTransaction = InitialTransactionParams & {
201
- /** Normalized error if the initialization fails (e.g., user rejects signature). */
254
+ /** The normalized error when the flow failed before tracking started, for example a rejected signature. */
202
255
  error?: TuwaErrorState;
203
- /** A flag indicating if the transaction is being processed (e.g., waiting for signature). */
256
+ /** `true` from the start of `executeTxAction` until the transaction is added to the pool or the flow fails. */
204
257
  isInitializing: boolean;
205
- /** The `txKey` of the on-chain transaction that this action produced, used for linking the states. */
258
+ /** The `txKey` of the transaction this action added to the pool. */
206
259
  lastTxKey?: string;
207
- /** The local timestamp when the user initiated the action. */
260
+ /** Unix timestamp (seconds) when `executeTxAction` started. */
208
261
  localTimestamp: number;
209
262
  };
210
263
  /**
211
- * Defines the standard callback structure for transaction events.
212
- * @template T The specific transaction type, extending `Transaction`.
264
+ * Callbacks passed to `executeTxAction` and forwarded to the tracker of that transaction. They are not stored:
265
+ * trackers restarted by `initializeTransactionsPool` or `injectExternalPendingTxs` (for example after a page reload)
266
+ * run without them. Their return values are not awaited.
267
+ *
268
+ * @template T - The application transaction type.
213
269
  */
214
270
  interface TrackerCallbacks<T extends Transaction> {
271
+ /**
272
+ * Called when the tracker marks the transaction `Success`.
273
+ * @param tx - The transaction after the update.
274
+ */
215
275
  onSuccess?: (tx: T) => Promise<void> | void;
276
+ /**
277
+ * Called when the transaction fails: it reverted, was rejected, or tracking gave up.
278
+ * @param error - The raw error, or a generated `Error`.
279
+ * @param tx - The transaction after the update.
280
+ */
216
281
  onError?: (error: unknown, tx?: T) => Promise<void> | void;
282
+ /**
283
+ * Called when the transaction is replaced by another one with the same nonce.
284
+ * @param newTx - The tracked transaction after the update (`status: Replaced`, `replacedTxHash` set).
285
+ * @param oldTx - The transaction as tracking started.
286
+ */
217
287
  onReplaced?: (newTx: T, oldTx: T) => Promise<void> | void;
218
288
  }
219
289
  /**
220
- * Callbacks for synchronizing local transaction state with a remote backend.
221
- * These are injected into the store at creation time.
290
+ * Callbacks that synchronize the local pool with a remote backend (for example Quasar). Passed to
291
+ * `createPulsarStore`.
292
+ *
293
+ * @template T - The application transaction type.
222
294
  */
223
295
  interface SyncCallbacks<T extends Transaction> {
224
296
  /**
225
- * Called immediately after a transaction is created locally (added to pool).
226
- * Use this to POST the active pending transaction to the backend.
297
+ * Called in the background with every new transaction, right after `addTxToPool` has written it to the pool with
298
+ * `syncStatus: 'pending-sync'` and listed its key in `unsyncedTxKeys`. It never delays or blocks tracking. Resolving
299
+ * marks the transaction `'synced'` and removes the key; rejecting logs a warning and leaves the key for
300
+ * `reconcileUnsyncedTransactions`, also across reloads. Reject (throw) on failure: a resolved promise counts as
301
+ * synced. A transaction is never sent twice at the same time.
302
+ * @param tx - A copy of the pooled transaction without `pimlicoApiKey` and `gelatoApiKey`.
227
303
  */
228
304
  onRemoteCreate?: (tx: T) => Promise<void>;
229
305
  }
230
306
  /**
231
- * Callback executed before Pulsar initializes or submits a transaction.
307
+ * Preflight callback run by `executeTxAction` after metadata validation and the chain check (which can ask the wallet
308
+ * to switch networks), before `actionFunction` asks the wallet to sign. It receives no transaction data.
232
309
  *
233
- * Throw an error from this function to block the transaction before `initialTx`, wallet interaction,
234
- * persistence, or remote synchronization starts.
310
+ * Throw to block the transaction: with `abortOnTxError` (default `true`), `initialTx.error` is set and
311
+ * `executeTxAction` rejects with the thrown error. With `abortOnTxError: false`, the error is logged and the flow
312
+ * continues.
235
313
  */
236
314
  type BeforeTxProcess = () => Promise<void> | void;
237
315
  /**
238
- * The configuration object containing one or more transaction adapters.
239
- * @template T The specific transaction type.
316
+ * The configuration of `createPulsarStore`: one or more chain adapters and the store options.
317
+ *
318
+ * @template T - The application transaction type.
240
319
  */
241
320
  type PulsarAdapter<T extends Transaction> = OrbitGenericAdapter<TxAdapter<T>> & {
242
- /** Optional global preflight callback executed before every transaction unless locally overridden. */
321
+ /** Global preflight callback run before every transaction. A `beforeTxProcess` passed to `executeTxAction` replaces it. */
243
322
  beforeTxProcess?: BeforeTxProcess;
323
+ /** Maximum number of transactions in the pool. When it is full, the oldest one (by `localTimestamp`) is evicted. Defaults to 50. */
244
324
  maxTransactions?: number;
325
+ /** @deprecated Gelato relay is deprecated. Gelato API key used to track `TransactionTracker.Gelato` transactions. */
245
326
  gelatoApiKey?: string;
246
- /** Optional setting to abort the transaction if the beforeTxProcess hook or remote creation fails. Defaults to true. */
327
+ /**
328
+ * Whether an error thrown by `beforeTxProcess` aborts the transaction. Defaults to `true`. It does not apply to
329
+ * `onRemoteCreate`, whose errors never abort the transaction.
330
+ */
247
331
  abortOnTxError?: boolean;
248
332
  } & SyncCallbacks<T>;
249
333
  /**
250
- * Represents a tracker for a specific transaction tied to an action and a connector.
251
- *
252
- * @typedef {Object} CheckTxTracker
253
- * @property {ActionTxKey} actionTxKey - The key identifying the specific action related to the transaction.
254
- * @property {string} connectorType - The type of connector used for the transaction (e.g., wallet provider, blockchain interface).
255
- * @property {TransactionTracker} [tracker] - An optional tracker object that monitors the status and progress of the transaction.
256
- * @property {string} [gelatoApiKey] - @deprecated Gelato API key for Gelato relayer integration.
257
- * @property {string} [bundlerUrl] - Optional custom bundler RPC URL for ERC-4337 UserOperation tracking.
258
- * @property {string} [pimlicoApiKey] - Optional Pimlico API key for ERC-4337 UserOperation tracking.
334
+ * The input of `TxAdapter.checkTransactionsTracker`: the key returned by the action and the context needed to pick a
335
+ * tracker.
259
336
  */
260
337
  type CheckTxTracker = {
338
+ /** The key returned by `actionFunction`. */
261
339
  actionTxKey: ActionTxKey;
340
+ /** The connector that signed the transaction, for example `evm:safe` for a Safe wallet. */
262
341
  connectorType: string;
342
+ /** The tracker requested in `executeTxAction` params, if any. */
263
343
  tracker?: TransactionTracker;
264
- /** @deprecated Gelato relay is deprecated. Use bundlerUrl / pimlicoApiKey with ERC-4337 instead. */
344
+ /** @deprecated Gelato relay is deprecated. Use `bundlerUrl` / `pimlicoApiKey` with ERC-4337 instead. */
265
345
  gelatoApiKey?: string;
266
- /** Optional custom bundler RPC URL for ERC-4337 UserOperation tracking. */
346
+ /** Custom bundler RPC URL for ERC-4337 UserOperation tracking. */
267
347
  bundlerUrl?: string;
268
- /** Optional Pimlico API key for ERC-4337 UserOperation tracking. */
348
+ /** Pimlico API key for ERC-4337 UserOperation tracking. */
269
349
  pimlicoApiKey?: string;
270
350
  };
271
351
  /**
272
- * Defines the interface for a transaction adapter, which provides chain-specific logic and utilities.
273
- * @template T The specific transaction type, extending `Transaction`.
352
+ * The contract a chain adapter implements to plug into the Pulsar store. `@tuwaio/pulsar-evm` and
353
+ * `@tuwaio/pulsar-solana` provide implementations.
354
+ *
355
+ * @template T - The application transaction type.
274
356
  */
275
357
  type TxAdapter<T extends Transaction> = Pick<BaseAdapter, 'getExplorerUrl'> & {
276
- /** The unique key identifying this adapter. */
358
+ /** The chain family handled by the adapter. */
277
359
  key: OrbitAdapter;
278
- /** Returns information about the currently connected connector. */
360
+ /** Returns the connected wallet. Called by `executeTxAction` before the chain check. */
279
361
  getConnectorInfo: () => {
280
- /** The currently connected wallet address. */
362
+ /** The address of the connected wallet. */
281
363
  walletAddress: string;
282
- /** The type of the connector (e.g., 'metamask', 'phantom'). */
364
+ /** The connector type, for example `evm:metamask`. */
283
365
  connectorType: string;
284
366
  };
285
367
  /**
286
- * Ensures the connected wallet is on the correct network for the transaction.
287
- *
288
- * This method should throw an error if the chain is mismatched.
289
- * @param chainId The desired chain ID for the transaction.
290
- * @param walletChainId The connected wallet chain ID.
368
+ * Ensures the wallet is on the chain of the transaction, switching it if the adapter can. Rejects when the chain
369
+ * does not match, which aborts `executeTxAction`.
370
+ * @param chainId - The `desiredChainID` of the transaction.
291
371
  */
292
372
  checkChainForTx: (chainId: string | number) => Promise<void>;
293
373
  /**
294
- * Determines the appropriate tracker and final `txKey` from the result of an action.
295
- * @returns An object containing the final `txKey` and the `TransactionTracker` to be used.
374
+ * Picks the tracker and the final `txKey` for the key returned by `actionFunction`.
375
+ * @param params - The returned key, the connector type and the requested tracker.
376
+ * @returns The `txKey` to store the transaction under and the tracker to use.
296
377
  */
297
- checkTransactionsTracker: ({ actionTxKey, connectorType, tracker }: CheckTxTracker) => {
378
+ checkTransactionsTracker: (params: CheckTxTracker) => {
379
+ /** The key the transaction is stored under. */
298
380
  txKey: string;
381
+ /** The tracker that monitors the transaction. */
299
382
  tracker: TransactionTracker;
300
383
  };
301
384
  /**
302
- * Selects and initializes the correct background tracker for a given transaction.
303
- * @param params The parameters for initializing the tracker, including the transaction and store callbacks.
385
+ * Starts the background tracker of a transaction. Trackers update the transaction through `updateTxParams`. The
386
+ * built-in trackers keep failed transactions in the pool; `removeTxFromPool` is available to custom trackers.
387
+ * @param params - The transaction, the Gelato API key, the callbacks and the store members used by trackers.
304
388
  */
305
389
  checkAndInitializeTrackerInStore: (params: {
306
390
  tx: T;
307
391
  gelatoApiKey?: string;
308
392
  } & TrackerCallbacks<T> & Pick<ITxTrackingStore<T>, 'updateTxParams' | 'removeTxFromPool' | 'transactionsPool'>) => Promise<void> | void;
309
393
  /**
310
- * Optional: Logic to cancel a pending EVM transaction.
311
- * @param tx The transaction to cancel.
312
- * @returns The new transaction hash for the cancellation.
394
+ * Optional: cancels a pending transaction by sending a replacement with the same nonce.
395
+ * @param tx - The transaction to cancel.
396
+ * @returns The hash of the cancellation transaction.
313
397
  */
314
398
  cancelTxAction?: (tx: T) => Promise<string>;
315
399
  /**
316
- * Optional: Logic to speed up a pending EVM transaction.
317
- * @param tx The transaction to speed up.
318
- * @returns The new transaction hash for the sped-up transaction.
400
+ * Optional: speeds up a pending transaction by resending it with the same nonce and higher fees.
401
+ * @param tx - The transaction to speed up.
402
+ * @returns The hash of the replacement transaction.
319
403
  */
320
404
  speedUpTxAction?: (tx: T) => Promise<string>;
321
405
  /**
322
- * Optional: Logic to retry a failed transaction.
323
- * @param params The parameters for retrying the transaction.
324
- * @param params.txKey The unique key of the transaction to retry.
325
- * @param params.tx The initial parameters of the transaction.
326
- * @param params.onClose Callback function to close the tracking modal.
406
+ * Optional: closes the tracking modal and runs a failed transaction again through `executeTxAction`.
407
+ * @param params - The retry parameters.
408
+ * @param params.txKey - The key of the failed transaction, passed to `onClose`.
409
+ * @param params.tx - The parameters of the transaction, including its `actionFunction`.
410
+ * @param params.onClose - Closes the tracking modal.
411
+ * @param params.executeTxAction - The store's `executeTxAction`.
327
412
  */
328
413
  retryTxAction?: (params: {
329
414
  txKey: string;
@@ -331,92 +416,118 @@ type TxAdapter<T extends Transaction> = Pick<BaseAdapter, 'getExplorerUrl'> & {
331
416
  onClose: (txKey?: string) => void;
332
417
  } & Partial<Pick<ITxTrackingStore<T>, 'executeTxAction'>>) => Promise<void>;
333
418
  /**
334
- * Optional: Constructs a full explorer URL for a specific transaction.
335
- * May require the full transaction pool to resolve details for replaced transactions.
336
- * @param tx The transaction object.
337
- * @returns The full URL to the transaction on the explorer.
419
+ * Optional: builds the explorer URL of a transaction.
420
+ * @param tx - The transaction.
421
+ * @returns The URL, or an empty string when it cannot be built.
338
422
  */
339
423
  getExplorerTxUrl?: (tx: T) => string;
340
424
  };
341
425
  /**
342
- * Defines the structure of the transaction pool, a key-value store of transactions indexed by their unique keys.
343
- * @template T The type of the transaction object being tracked.
426
+ * The transaction pool: transactions indexed by `txKey`.
427
+ *
428
+ * @template T - The application transaction type.
344
429
  */
345
430
  type TransactionPool<T extends Transaction> = Record<string, T>;
346
431
  /**
347
- * A utility type that creates a union of all fields that can be safely updated
348
- * on a transaction object via the `updateTxParams` action. This ensures type safety
349
- * and prevents accidental modification of immutable properties.
432
+ * The fields `updateTxParams` accepts: the fields trackers change while a transaction is tracked.
350
433
  */
351
434
  type UpdatableTransactionFields = Partial<Pick<EvmTransaction, 'to' | 'nonce' | 'txKey' | 'pending' | 'hash' | 'status' | 'replacedTxHash' | 'error' | 'finishedTimestamp' | 'isTrackedModalOpen' | 'isError' | 'maxPriorityFeePerGas' | 'maxFeePerGas' | 'input' | 'value' | 'confirmations' | 'requiredConfirmations'>> & Partial<Pick<SolanaTransaction, 'slot' | 'confirmations' | 'fee' | 'instructions' | 'recentBlockhash' | 'rpcUrl'>>;
352
435
  /**
353
- * The interface for the base transaction tracking store slice.
354
- * It includes the state and actions for managing the transaction lifecycle.
355
- * @template T The specific transaction type.
436
+ * The state and actions of the core store slice created by `initializeTxTrackingStore`.
437
+ *
438
+ * @template T - The application transaction type.
356
439
  */
357
440
  interface IInitializeTxTrackingStore<T extends Transaction> {
358
- /** A pool of all transactions currently being tracked, indexed by `txKey`. */
441
+ /** Every tracked transaction, indexed by `txKey`. Persisted to `localStorage` by `createPulsarStore`. */
359
442
  transactionsPool: TransactionPool<T>;
360
- /** The `txKey` of the most recently added transaction. */
443
+ /** The `txKey` of the transaction added last. */
361
444
  lastAddedTxKey?: string;
362
- /** The state for a transaction being initiated, used for verify feedback before it's submitted to the chain. */
445
+ /**
446
+ * The transaction `executeTxAction` is processing, before it is added to the pool. Not persisted by
447
+ * `createPulsarStore`: after a reload it is `undefined`.
448
+ */
363
449
  initialTx?: InitialTransaction;
364
450
  /**
365
- * Adds a new transaction to the tracking pool and marks it as pending.
366
- * @param tx The transaction object to add.
451
+ * Validates a transaction and adds it to the pool with `pending: true`. When the pool already holds
452
+ * `maxTransactions` transactions, the oldest one is evicted. If `onRemoteCreate` is configured, the transaction gets
453
+ * `syncStatus: 'pending-sync'`, its key is listed in `unsyncedTxKeys`, and `onRemoteCreate` runs in the background
454
+ * (see `SyncCallbacks`). Does not start a tracker.
455
+ * @param tx - The transaction to add.
456
+ * @returns A promise that resolves once the transaction is in the pool, without waiting for `onRemoteCreate`.
457
+ * @throws `PulsarTransactionValidationError` synchronously, before anything is written, when the title, description
458
+ * or payload is invalid.
367
459
  */
368
460
  addTxToPool: (tx: T) => Promise<void>;
369
461
  /**
370
- * Updates one or more properties of an existing transaction in the pool.
371
- * @param txKey The key of the transaction to update.
372
- * @param fields The partial object containing the fields to update.
462
+ * Merges fields into a transaction of the pool; does nothing if the key is unknown. When `fields.status` is terminal
463
+ * and the transaction is in `unsyncedTxKeys`, it starts `reconcileUnsyncedTransactions` in the background.
464
+ * @param txKey - The key of the transaction.
465
+ * @param fields - The fields to merge.
373
466
  */
374
467
  updateTxParams: (txKey: string, fields: UpdatableTransactionFields) => void;
375
468
  /**
376
- * Removes a transaction from the tracking pool by its key.
377
- * @param txKey The key of the transaction to remove.
469
+ * Removes a transaction from the pool. Does not stop its tracker.
470
+ * @param txKey - The key of the transaction.
378
471
  */
379
472
  removeTxFromPool: (txKey: string) => void;
380
473
  /**
381
- * Closes the tracking modal for a transaction and clears any initial transaction state.
382
- * @param txKey The optional key of the transaction modal to close.
474
+ * Sets `isTrackedModalOpen: false` on a transaction and always clears `initialTx`.
475
+ * @param txKey - The key of the transaction whose modal is closed, if any.
383
476
  */
384
477
  closeTxTrackedModal: (txKey?: string) => void;
385
478
  /**
386
- * A selector function to retrieve the key of the last transaction added to the pool.
387
- * @returns The key of the last added transaction, or undefined if none exists.
479
+ * Returns `lastAddedTxKey`.
480
+ * @returns The key of the transaction added last, or `undefined`.
388
481
  */
389
482
  getLastTxKey: () => string | undefined;
390
483
  /**
391
- * A record of transaction keys that failed to sync with the remote backend (Quasar)
392
- * when `onRemoteCreate` was called. They will be retried automatically.
484
+ * Keys of transactions that `onRemoteCreate` has not confirmed yet: in flight, failed, or interrupted by a reload.
485
+ * `reconcileUnsyncedTransactions` retries them. Persisted to `localStorage`.
393
486
  */
394
487
  unsyncedTxKeys?: Record<string, boolean>;
395
488
  /**
396
- * Attempts to synchronize any transactions in `unsyncedTxKeys` that have reached a terminal
397
- * status but failed their initial `onRemoteCreate` call.
489
+ * Calls `onRemoteCreate` again for every key in `unsyncedTxKeys`, one after another, skipping keys whose call is still
490
+ * in flight. Successful transactions are marked `'synced'` and removed from the list; failures are logged and stay
491
+ * listed; keys of transactions no longer in the pool are removed. Does nothing without `onRemoteCreate` or while a
492
+ * previous run is in progress. Runs at the start of every `executeTxAction`, when an
493
+ * unsynced transaction reaches a terminal status, and when `createTxInMemoryStore` loads the first history page.
494
+ * @returns A promise that resolves when the run is finished. It does not reject.
398
495
  */
399
496
  reconcileUnsyncedTransactions: () => Promise<void>;
400
497
  }
401
498
  /**
402
- * The complete interface for the Pulsar transaction tracking store.
403
- * @template T The transaction type.
499
+ * The state and actions of the store created by `createPulsarStore`.
500
+ *
501
+ * @template T - The application transaction type.
404
502
  */
405
503
  type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
406
- /** A getter function that returns the configured transaction adapter(s). */
504
+ /**
505
+ * Returns the adapter configuration passed to `createPulsarStore`.
506
+ * @returns The adapter, or the array of adapters.
507
+ */
407
508
  getAdapter: () => TxAdapter<T> | TxAdapter<T>[];
408
509
  /**
409
- * The primary method for initiating and tracking a new transaction from start to finish.
410
- * It manages UI state, executes the on-chain action, and initiates background tracking.
510
+ * Runs a transaction from start to tracking: validates `params`, sets `initialTx`, checks the chain (the EVM adapter
511
+ * may ask the wallet to switch), runs `beforeTxProcess`, calls `actionFunction`, adds the transaction to the pool
512
+ * (see `addTxToPool`) and starts its tracker. When `actionFunction` returns `undefined`, `initialTx` is cleared and
513
+ * nothing is tracked. Also starts `reconcileUnsyncedTransactions` in the background.
411
514
  *
412
- * @param params The parameters for handling the transaction.
413
- * @param params.actionFunction The async function to execute (e.g., a smart contract write call). Must return a unique key or undefined.
414
- * @param params.params The metadata for the transaction. Title, description, and payload are validated before execution.
415
- * @param params.defaultTracker The default tracker to use if it cannot be determined automatically.
416
- * @param params.beforeTxProcess Optional local preflight callback. When provided, it overrides the global callback from `createPulsarStore`.
417
- * @param params.onSuccess Callback to execute when the transaction is successfully submitted.
418
- * @param params.onError Callback to execute when the transaction fails.
419
- * @param params.onReplaced Callback to execute when the transaction is replaced.
515
+ * @param params - The action, its metadata and the callbacks.
516
+ * @param params.actionFunction - Signs and submits the transaction; returns its key, or `undefined` if cancelled.
517
+ * @param params.params - The transaction metadata. `title`, `description` and `payload` are validated before
518
+ * anything else runs.
519
+ * @param params.defaultTracker - Tracker used when the adapter does not return one.
520
+ * @param params.beforeTxProcess - Preflight callback for this transaction; replaces the global one.
521
+ * @param params.abortOnTxError - Overrides the global `abortOnTxError` for this transaction.
522
+ * @param params.onSuccess - Called when the transaction succeeds (see `TrackerCallbacks`).
523
+ * @param params.onError - Called when the transaction fails after it was submitted (see `TrackerCallbacks`).
524
+ * @param params.onReplaced - Called when the transaction is replaced (see `TrackerCallbacks`).
525
+ * @returns A promise that resolves when the adapter's `checkAndInitializeTrackerInStore` resolves: once polling has
526
+ * started for polling trackers (Solana, Safe, ERC-4337, Gelato), but only when tracking has finished for standard
527
+ * EVM transactions (`TransactionTracker.Ethereum`). Read the state from the store instead of awaiting the result.
528
+ * @throws `PulsarTransactionValidationError` when the metadata is invalid (before `initialTx` is set). Rejects with
529
+ * the underlying error when no adapter is configured, or when the chain check, `beforeTxProcess` (with
530
+ * `abortOnTxError`), `actionFunction` or the tracker start fails; `initialTx.error` is set first.
420
531
  */
421
532
  executeTxAction: (params: {
422
533
  actionFunction: () => Promise<ActionTxKey | undefined>;
@@ -426,64 +537,83 @@ type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
426
537
  abortOnTxError?: boolean;
427
538
  } & TrackerCallbacks<T>) => Promise<void>;
428
539
  /**
429
- * Initializes trackers for all pending transactions in the pool.
430
- * This is essential for resuming tracking after a page reload or application restart.
540
+ * Restarts the trackers of all pending transactions in the pool, for example after a page reload. Pending
541
+ * transactions that fail validation are removed from the pool. Call it once per page load: every call starts new
542
+ * trackers, and trackers started here have no `TrackerCallbacks`.
543
+ * @returns A promise that resolves when all trackers have started.
431
544
  */
432
545
  initializeTransactionsPool: () => Promise<void>;
433
546
  /**
434
- * Cross-device synchronization bridge.
435
- * Injects remote pending transactions into the local pool and starts their lifecycle trackers.
436
- * Also self-heals local pending transactions if the remote DB knows they are terminal.
547
+ * Merges transactions from a remote backend into the pool (cross-device sync). Invalid transactions are skipped
548
+ * with a warning. Pending remote transactions that are not in the pool are added and tracked. Local pending
549
+ * transactions that are terminal remotely take the remote `status`, `txKey` and `finishedTimestamp` and are marked
550
+ * not pending.
551
+ * @param remoteTxs - Transactions returned by the backend.
552
+ * @returns A promise that resolves when the trackers of the added transactions have started.
437
553
  */
438
554
  injectExternalPendingTxs: (remoteTxs: T[]) => Promise<void>;
439
555
  };
440
556
  /**
441
- * Represents the structure and behavior of an in-memory pagination system
442
- * for managing transaction history.
557
+ * The pagination state and action of the in-memory history store, as consumed by UI components.
443
558
  */
444
559
  type TxInMemoryPagination = {
445
- /** Indicates whether the store is currently loading transaction history. */
560
+ /** `true` while a history page is loading. */
446
561
  isLoading: boolean;
447
- /** Indicates whether the last loading request ended with an error. */
562
+ /** `true` when the last history request failed. */
448
563
  isError: boolean;
449
- /** Indicates whether more history pages are available. */
564
+ /** `true` when the last loaded page reported a next page. */
450
565
  hasMore: boolean;
451
- /** The current page number in the paginated history. */
566
+ /** The last loaded page number. */
452
567
  currentPage: number;
453
- /** Loads the next page of transaction history and appends it to the pool. */
568
+ /**
569
+ * Loads the page after `currentPage` and merges it into the pool. Does nothing while loading, when `hasMore` is
570
+ * `false`, or without `getHistory`.
571
+ * @param walletAddress - The wallet whose history is loaded.
572
+ */
454
573
  fetchNextPage: (walletAddress: string) => Promise<void>;
455
574
  };
456
575
  /**
457
- * The complete interface for the Pulsar transaction in-memory store.
458
- * It keeps a paginated remote history in sync with a local transaction pool.
576
+ * The state and actions of the store created by `createTxInMemoryStore`: a paginated remote history merged with the
577
+ * local pool. Nothing in it is persisted.
459
578
  *
460
- * @template T The transaction type.
579
+ * @template T - The application transaction type.
461
580
  */
462
581
  type ITxInMemoryStore<T extends Transaction> = {
463
- /** A pool of all transactions currently being tracked and loaded from history, indexed by `txKey`. */
582
+ /** The local and remote transactions, indexed by `txKey`. */
464
583
  transactionsPool: TransactionPool<T>;
465
- /** Loads the first page of transaction history. */
584
+ /**
585
+ * Runs `reconcileUnsyncedTransactions` (if provided), then loads the first history page and merges it into the
586
+ * pool. Does nothing without `getHistory` or an empty `walletAddress`.
587
+ * @param walletAddress - The wallet whose history is loaded.
588
+ */
466
589
  fetchInitial: (walletAddress: string) => Promise<void>;
467
- /** Merges a local transaction pool into the in-memory store. */
590
+ /**
591
+ * Merges a local pool into the in-memory pool. Transactions that are `Success` or `Replaced` in memory are kept;
592
+ * pending ones are overwritten only by a terminal transaction or one with more confirmations.
593
+ * @param localPool - The pool of the persistent store, usually from its `subscribe` listener.
594
+ */
468
595
  syncWithLocalPool: (localPool: TransactionPool<T>) => void;
469
596
  } & TxInMemoryPagination;
470
597
  /**
471
- * Parameters used to configure and manage an in-memory transaction store.
598
+ * The configuration of `createTxInMemoryStore`.
472
599
  *
473
- * @template T The transaction type.
600
+ * @template T - The application transaction type.
474
601
  */
475
602
  type ITxInMemoryStoreParameters<T extends Transaction> = {
476
- /** A localTransactionsPool. */
603
+ /** The initial pool, usually `transactionsPool` of the persistent store. */
477
604
  localTransactionsPool: TransactionPool<T>;
478
- /**
479
- * Attempts to synchronize any transactions in `unsyncedTxKeys` that have reached a terminal
480
- * status but failed their initial `onRemoteCreate` call.
481
- */
605
+ /** Called by `fetchInitial` before the first page is loaded, usually the store's `reconcileUnsyncedTransactions`. */
482
606
  reconcileUnsyncedTransactions?: () => Promise<void>;
483
- /** * Callback fired when remote history is successfully fetched.
484
- * Used to inject remote pending transactions into the persistent tracking store.
607
+ /**
608
+ * Called in a microtask with the valid transactions of every loaded page, usually to pass them to the store's
609
+ * `injectExternalPendingTxs`.
610
+ * @param remoteTxs - The transactions of the loaded page.
485
611
  */
486
612
  onHistoryFetched?: (remoteTxs: T[]) => void;
613
+ /**
614
+ * Loads one page of the remote history of a wallet. Return `null` when there is no history to show (for example,
615
+ * the user is not signed in); throw on errors to set `isError`.
616
+ */
487
617
  getHistory?: ({ page, walletAddress, }: {
488
618
  /**
489
619
  * Page number for pagination.
@@ -491,6 +621,7 @@ type ITxInMemoryStoreParameters<T extends Transaction> = {
491
621
  * @defaultValue `1`
492
622
  */
493
623
  page?: number;
624
+ /** The wallet whose history is requested. */
494
625
  walletAddress: string;
495
626
  }) => Promise<{
496
627
  /** Array of transactions for the current page. */
@@ -509,95 +640,135 @@ type ITxInMemoryStoreParameters<T extends Transaction> = {
509
640
  };
510
641
 
511
642
  /**
512
- * @file This file defines the core Zustand slice for managing the state of transactions. It includes the state,
513
- * actions, and types necessary for initializing the store and performing CRUD operations on the transaction pool.
643
+ * @file The core Zustand slice of the transaction store: the transaction pool and the actions that add, update and
644
+ * remove transactions and synchronize them with a remote backend.
514
645
  */
515
646
 
516
647
  /**
517
- * Creates a Zustand store slice with the core logic for transaction state management.
518
- * This function is a slice creator intended for use with Zustand's `create` function.
648
+ * Creates the core slice of the transaction store: `transactionsPool`, `initialTx`, `unsyncedTxKeys` and the actions
649
+ * that change them. `createPulsarStore` uses it; call it directly only to compose a custom Zustand store.
519
650
  *
520
- * @template T The specific transaction type.
521
- * @param options Configuration for the store slice.
522
- * @returns A Zustand store slice implementing `IInitializeTxTrackingStore`.
651
+ * The slice keeps its state in memory; persistence is added by the store that uses it.
652
+ *
653
+ * @template T - The application transaction type.
654
+ * @param params - The slice options.
655
+ * @param params.maxTransactions - Maximum number of transactions in the pool; `addTxToPool` evicts the oldest one
656
+ * (by `localTimestamp`) when the pool is full.
657
+ * @param params.onRemoteCreate - Optional remote sync callback, called in the background by `addTxToPool` (see
658
+ * `SyncCallbacks`).
659
+ * @returns A slice creator for Zustand's `create` / `createStore`.
523
660
  */
524
661
  declare function initializeTxTrackingStore<T extends Transaction>({ maxTransactions, onRemoteCreate, }: Pick<PulsarAdapter<T>, 'onRemoteCreate'> & {
525
662
  maxTransactions: number;
526
663
  }): StoreSlice<IInitializeTxTrackingStore<T>>;
527
664
 
528
665
  /**
529
- * @file This file contains selector functions for deriving state from the transaction tracking store.
530
- * Selectors help abstract the state's shape and provide efficient, memoized access to computed data.
666
+ * @file Selectors that derive lists of transactions from a transaction pool. They are plain functions: each call
667
+ * returns a new array, so memoize the result (or compare it shallowly) when using it in a React selector.
531
668
  */
532
669
 
533
670
  /**
534
- * Selects all transactions from the pool and sorts them by their creation timestamp in ascending order.
535
- * @template T - The transaction type.
536
- * @param {TransactionPool<T>} transactionsPool - The entire transaction pool from the store.
537
- * @returns {T[]} An array of all transactions, sorted chronologically.
671
+ * Returns every transaction of the pool, oldest first (by `localTimestamp`).
672
+ *
673
+ * @template T - The application transaction type.
674
+ * @param transactionsPool - The transaction pool of the store.
675
+ * @returns A new array of all transactions, sorted chronologically.
538
676
  */
539
677
  declare const selectAllTransactions: <T extends Transaction>(transactionsPool: TransactionPool<T>) => T[];
540
678
  /**
541
- * Selects all transactions that are currently in a pending state, sorted chronologically.
542
- * @template T - The transaction type.
543
- * @param {TransactionPool<T>} transactionsPool - The entire transaction pool from the store.
544
- * @returns {T[]} An array of pending transactions.
679
+ * Returns the transactions with `pending: true`, oldest first.
680
+ *
681
+ * @template T - The application transaction type.
682
+ * @param transactionsPool - The transaction pool of the store.
683
+ * @returns A new array of pending transactions, sorted chronologically.
545
684
  */
546
685
  declare const selectPendingTransactions: <T extends Transaction>(transactionsPool: TransactionPool<T>) => T[];
547
686
  /**
548
- * Selects a single transaction from the pool by its unique key (`txKey`).
549
- * @template T - The transaction type.
550
- * @param {TransactionPool<T>} transactionsPool - The entire transaction pool from the store.
551
- * @param {string} key - The `txKey` of the transaction to retrieve.
552
- * @returns {T | undefined} The transaction object if found, otherwise undefined.
687
+ * Returns the transaction stored under a `txKey`.
688
+ *
689
+ * @template T - The application transaction type.
690
+ * @param transactionsPool - The transaction pool of the store.
691
+ * @param key - The `txKey` of the transaction.
692
+ * @returns The transaction, or `undefined` if the pool has no such key.
553
693
  */
554
694
  declare const selectTxByKey: <T extends Transaction>(transactionsPool: TransactionPool<T>, key: string) => T | undefined;
555
695
  /**
556
- * Selects all transactions initiated by a specific wallet address, sorted chronologically.
557
- * @template T - The transaction type.
558
- * @param {TransactionPool<T>} transactionsPool - The entire transaction pool from the store.
559
- * @param {string} from - The wallet address (`from` address) to filter transactions by.
560
- * @returns {T[]} An array of transactions associated with the given wallet.
696
+ * Returns the transactions sent by a wallet, oldest first. Addresses are compared case-insensitively.
697
+ *
698
+ * @template T - The application transaction type.
699
+ * @param transactionsPool - The transaction pool of the store.
700
+ * @param from - The wallet address to match against the `from` field.
701
+ * @returns A new array of the wallet's transactions, sorted chronologically.
561
702
  */
562
703
  declare const selectAllTransactionsByActiveWallet: <T extends Transaction>(transactionsPool: TransactionPool<T>, from: string) => T[];
563
704
  /**
564
- * Selects all pending transactions for a specific wallet address, sorted chronologically.
565
- * @template T - The transaction type.
566
- * @param {TransactionPool<T>} transactionsPool - The entire transaction pool from the store.
567
- * @param {string} from - The wallet address (`from` address) to filter transactions by.
568
- * @returns {T[]} An array of pending transactions for the given wallet.
705
+ * Returns the pending transactions sent by a wallet, oldest first. Addresses are compared case-insensitively.
706
+ *
707
+ * @template T - The application transaction type.
708
+ * @param transactionsPool - The transaction pool of the store.
709
+ * @param from - The wallet address to match against the `from` field.
710
+ * @returns A new array of the wallet's pending transactions, sorted chronologically.
569
711
  */
570
712
  declare const selectPendingTransactionsByActiveWallet: <T extends Transaction>(transactionsPool: TransactionPool<T>, from: string) => T[];
571
713
 
572
714
  /**
573
- * Creates an in-memory transaction store with synchronized local and remote sources.
715
+ * Creates an in-memory store that shows the remote transaction history of a wallet (for example from Quasar) together
716
+ * with the local pool of the persistent store. Nothing in it is persisted. Keep it in sync with the persistent store by
717
+ * calling `syncWithLocalPool` from that store's `subscribe` listener.
574
718
  *
575
- * The store is designed to:
576
- * - keep a local transaction pool in sync with remote history
577
- * - preserve terminal transaction states
578
- * - support paginated history loading
579
- * - avoid duplicated merge logic across store actions
719
+ * Merge rules: a transaction that is `Success` or `Replaced` in memory is never overwritten; a pending one is
720
+ * overwritten only by a terminal transaction or by one with more confirmations; any other one is overwritten.
580
721
  *
581
- * @template T The transaction type.
582
- * @param params Store configuration parameters.
583
- * @param params.getHistory Optional remote history fetcher.
584
- * @returns A Zustand vanilla store instance for in-memory transaction management.
722
+ * History pages are validated like `injectExternalPendingTxs` does: transactions whose title, description or payload
723
+ * break the safety limits are skipped with a warning and are not passed to `onHistoryFetched`.
724
+ *
725
+ * Side effects: `fetchInitial` and `fetchNextPage` call `getHistory`, usually a network request. The store uses its
726
+ * own Immer instance without auto-freeze and does not change the global Immer configuration.
727
+ *
728
+ * @template T - The application transaction type.
729
+ * @param params - The store configuration.
730
+ * @param params.localTransactionsPool - The initial pool.
731
+ * @param params.reconcileUnsyncedTransactions - Called by `fetchInitial` before the first page is loaded.
732
+ * @param params.getHistory - Loads one page of the remote history. A `null` result stops loading without changing the
733
+ * pool; a thrown error sets `isError`.
734
+ * @param params.onHistoryFetched - Called in a microtask with the valid transactions of every loaded page.
735
+ * @returns A vanilla Zustand store; bind it to React with `createBoundedUseStore`.
585
736
  */
586
737
  declare function createTxInMemoryStore<T extends Transaction>({ localTransactionsPool, reconcileUnsyncedTransactions, getHistory, onHistoryFetched, }: ITxInMemoryStoreParameters<T>): zustand.StoreApi<ITxInMemoryStore<T>>;
587
738
 
588
739
  /**
589
- * Creates the main Pulsar store for transaction tracking.
740
+ * Creates the Pulsar transaction store: a vanilla Zustand store (use it from any framework, or bind it to React with
741
+ * `createBoundedUseStore`) that runs transactions through chain adapters and tracks them in the background.
590
742
  *
591
- * This function configures a Zustand store enhanced with persistence. It combines the core transaction management
592
- * slice with a powerful orchestration logic that leverages chain-specific adapters to handle the entire
593
- * lifecycle of a transaction—from initiation and chain validation to execution and background status tracking.
743
+ * Side effects: the state is saved with Zustand's `persist` middleware under the key `name`, by default in
744
+ * `localStorage`, on every change: `transactionsPool`, `lastAddedTxKey` and `unsyncedTxKeys`. `initialTx` is neither
745
+ * saved nor restored (pass your own `partialize` and `merge` to change that). In the browser the saved state is
746
+ * restored synchronously when the store is created. Where
747
+ * `localStorage` is not available (server rendering), nothing is read or written and Zustand logs a warning on
748
+ * updates. Creating the store does not start any tracker: call `initializeTransactionsPool` once on the client.
594
749
  *
595
- * @template T The specific transaction type, extending the base `Transaction`.
750
+ * @template T - The application transaction type.
751
+ * @param params - The adapters, the store options and the options of Zustand's `persist` middleware.
752
+ * @param params.adapter - A chain adapter, or an array of adapters, such as `pulsarEvmAdapter` from
753
+ * `@tuwaio/pulsar-evm` or `pulsarSolanaAdapter` from `@tuwaio/pulsar-solana`.
754
+ * @param params.maxTransactions - Maximum number of transactions in the pool. Defaults to 50.
755
+ * @param params.onRemoteCreate - Remote sync callback (see `SyncCallbacks`).
756
+ * @param params.gelatoApiKey - Deprecated Gelato API key, passed to the trackers.
757
+ * @param params.beforeTxProcess - Global preflight callback (see `BeforeTxProcess`).
758
+ * @param params.abortOnTxError - Whether a `beforeTxProcess` error aborts the transaction. Defaults to `true`.
759
+ * @param params.name - The storage key. Required by `persist`; use a different key for every store.
760
+ * @returns The vanilla Zustand store. `store.persist` exposes the `persist` API (for example `clearStorage()`).
596
761
  *
597
- * @param config Configuration object for creating the store.
598
- * @param config.adapter Adapter or an array of adapters for different chains or transaction types.
599
- * @param options Configuration for the Zustand `persist` middleware.
600
- * @returns A fully configured Zustand store instance.
762
+ * @example
763
+ * ```ts
764
+ * import { createPulsarStore } from '@tuwaio/pulsar-core';
765
+ * import { pulsarEvmAdapter } from '@tuwaio/pulsar-evm';
766
+ *
767
+ * export const pulsarStore = createPulsarStore({
768
+ * name: 'transactions-tracking-storage',
769
+ * adapter: pulsarEvmAdapter(wagmiConfig, appChains),
770
+ * });
771
+ * ```
601
772
  */
602
773
  declare function createPulsarStore<T extends Transaction>({ adapter, maxTransactions, onRemoteCreate, gelatoApiKey, beforeTxProcess, abortOnTxError, ...options }: PulsarAdapter<T> & PersistOptions<ITxTrackingStore<T>>): Omit<zustand.StoreApi<ITxTrackingStore<T>>, "setState" | "persist"> & {
603
774
  setState(partial: ITxTrackingStore<T> | Partial<ITxTrackingStore<T>> | ((state: ITxTrackingStore<T>) => ITxTrackingStore<T> | Partial<ITxTrackingStore<T>>), replace?: false | undefined): unknown;
@@ -614,36 +785,36 @@ declare function createPulsarStore<T extends Transaction>({ adapter, maxTransact
614
785
  };
615
786
 
616
787
  /**
617
- * @file This file provides a utility for creating a type-safe, bounded Zustand hook from a vanilla store.
618
- * This pattern is recommended by the official Zustand documentation to ensure full type
619
- * safety when integrating vanilla stores with React.
788
+ * @file Binds a vanilla Zustand store (such as the Pulsar stores) to React with a typed hook.
620
789
  *
621
- * @see https://docs.pmnd.rs/zustand/guides/typescript#bounded-usestore-hook-for-vanilla-stores
790
+ * @see {@link https://zustand.docs.pmnd.rs/guides/typescript#bounded-usestore-hook-for-vanilla-stores Zustand: bounded useStore hook}
622
791
  */
623
792
 
624
793
  /**
625
- * A utility type that infers the state shape from a Zustand `StoreApi`.
626
- * It extracts the return type of the `getState` method.
627
- * @template S - The type of the Zustand store (`StoreApi`).
794
+ * The state type of a Zustand store: the return type of its `getState` method.
795
+ *
796
+ * @template S - The store type.
628
797
  */
629
798
  type ExtractState<S> = S extends {
630
799
  getState: () => infer T;
631
800
  } ? T : never;
632
801
  /**
633
- * Creates a bounded `useStore` hook from a vanilla Zustand store.
802
+ * Creates a React hook bound to a vanilla Zustand store, so components do not pass the store on every call.
634
803
  *
635
- * This function takes a vanilla Zustand store instance and returns a React hook
636
- * that is pre-bound to that store. This approach provides a cleaner API and
637
- * enhances type inference, eliminating the need to pass the store instance
638
- * on every use.
804
+ * The hook calls `useStore` from `zustand`, so it follows the rules of React hooks and needs `react` in the app. Call it
805
+ * without arguments to subscribe to the whole state, or with a selector to subscribe to a slice. A selector that
806
+ * returns a new object or array on every call (such as the transaction selectors) re-renders on every store update;
807
+ * select stable values or memoize.
639
808
  *
640
- * The returned hook supports two signatures:
641
- * 1. `useBoundedStore()`: Selects the entire state.
642
- * 2. `useBoundedStore(selector)`: Selects a slice of the state, returning only what the selector function specifies.
809
+ * @template S - The store type.
810
+ * @param store - The vanilla Zustand store, for example the result of `createPulsarStore`.
811
+ * @returns A hook: `useBoundedStore()` returns the whole state, `useBoundedStore(selector)` returns the selected value.
643
812
  *
644
- * @template S - The type of the Zustand store (`StoreApi`).
645
- * @param {S} store - The vanilla Zustand store instance to bind the hook to.
646
- * @returns {function} A fully typed React hook for accessing the store's state.
813
+ * @example
814
+ * ```ts
815
+ * const usePulsarStore = createBoundedUseStore(pulsarStore);
816
+ * const executeTxAction = usePulsarStore((state) => state.executeTxAction);
817
+ * ```
647
818
  */
648
819
  declare const createBoundedUseStore: <S extends StoreApi<unknown>>(store: S) => {
649
820
  (): ExtractState<S>;
@@ -651,95 +822,206 @@ declare const createBoundedUseStore: <S extends StoreApi<unknown>>(store: S) =>
651
822
  };
652
823
 
653
824
  /**
654
- * @file This file provides a generic utility for creating a polling mechanism to track
655
- * asynchronous tasks, such as API-based transaction status checks (e.g., for Gelato or Safe).
825
+ * @file Helper for store-connected trackers that keeps their copy of a transaction in sync with the fields they write.
656
826
  */
657
827
 
658
828
  /**
659
- * Defines the parameters for the fetcher function used within the polling tracker.
660
- * The fetcher is the core logic that performs the actual API call.
661
- * @template R The expected type of the successful API response.
662
- * @template T The type of the transaction object being tracked.
829
+ * Creates an updater for a store-connected tracker: it writes fields to the store with `updateTxParams` and returns the
830
+ * tracked transaction with every update applied so far.
831
+ *
832
+ * The `transactionsPool` a tracker receives is a snapshot taken when tracking starts, and Immer replaces the pool on
833
+ * every update, so reading the snapshot after `updateTxParams` returns stale data. Pass the object returned here to
834
+ * `TrackerCallbacks` instead. The built-in trackers of `@tuwaio/pulsar-evm` and `@tuwaio/pulsar-solana` use it; use it
835
+ * in custom trackers too.
836
+ *
837
+ * @template T - The application transaction type.
838
+ * @param params - The tracked transaction and the store members used by trackers.
839
+ * @param params.tx - The tracked transaction.
840
+ * @param params.transactionsPool - The pool snapshot; the tracked transaction is read from it once.
841
+ * @param params.updateTxParams - The store's `updateTxParams`.
842
+ * @returns A function that calls `updateTxParams(tx.txKey, fields)` and returns the updated transaction, or `undefined`
843
+ * when the transaction was not in the pool when tracking started. The snapshot is not mutated.
844
+ *
845
+ * @example
846
+ * ```ts
847
+ * const updateTx = createTxUpdater({ tx, transactionsPool, updateTxParams });
848
+ * const updatedTx = updateTx({ status: TransactionStatus.Success, pending: false });
849
+ * if (updatedTx) onSuccess?.(updatedTx);
850
+ * ```
851
+ */
852
+ declare function createTxUpdater<T extends Transaction>({ tx, transactionsPool, updateTxParams, }: Pick<ITxTrackingStore<T>, 'transactionsPool' | 'updateTxParams'> & {
853
+ tx: T;
854
+ }): (fields: UpdatableTransactionFields) => T | undefined;
855
+
856
+ /**
857
+ * @file A generic polling loop for trackers that check a transaction through an API or RPC method (Safe, Gelato,
858
+ * ERC-4337 bundlers, Solana).
859
+ */
860
+
861
+ /**
862
+ * The argument passed to a polling fetcher on every tick. The fetcher checks the transaction once and reports the result
863
+ * through the callbacks.
864
+ *
865
+ * @template R - The response type the fetcher reports.
866
+ * @template T - The tracked transaction type.
663
867
  */
664
868
  type PollingFetcherParams<R, T> = {
665
- /** The transaction object being tracked. */
869
+ /** The tracked transaction, as passed to `initializePollingTracker`. */
666
870
  tx: T;
667
- /** A callback to stop the polling mechanism, typically called on success or terminal failure. */
871
+ /**
872
+ * Stops polling. Unless `withoutRemoving` is `true`, it also calls `removeTxFromPool` (if configured) with the
873
+ * transaction key.
874
+ * @param options - Stop options.
875
+ */
668
876
  stopPolling: (options?: {
877
+ /** Keep the transaction in the pool. Defaults to `false`. */
669
878
  withoutRemoving?: boolean;
670
879
  }) => void;
671
- /** Callback to be invoked when the fetcher determines the transaction has succeeded. */
880
+ /**
881
+ * The `onSuccess` callback of the tracker configuration.
882
+ * @param response - The result of the check.
883
+ */
672
884
  onSuccess: (response: R) => void;
673
- /** Callback to be invoked when the fetcher determines the transaction has failed. */
885
+ /**
886
+ * The `onFailure` callback of the tracker configuration.
887
+ * @param response - The result of the check, if any.
888
+ */
674
889
  onFailure: (response?: R) => void;
675
- /** Optional callback for each successful poll, useful for updating UI with intermediate states. */
890
+ /**
891
+ * The `onIntervalTick` callback of the tracker configuration, if any.
892
+ * @param response - The intermediate result.
893
+ */
676
894
  onIntervalTick?: (response: R) => void;
677
- /** Optional callback for when a transaction is replaced (e.g., speed-up). */
895
+ /**
896
+ * The `onReplaced` callback of the tracker configuration, if any.
897
+ * @param response - The result describing the replacement.
898
+ */
678
899
  onReplaced?: (response: R) => void;
679
900
  };
680
901
  /**
681
- * Defines the configuration object for the `initializePollingTracker` function.
682
- * @template R The expected type of the successful API response.
683
- * @template T The type of the transaction object.
902
+ * The configuration of `initializePollingTracker`.
903
+ *
904
+ * @template R - The response type the fetcher reports.
905
+ * @template T - The tracked transaction type; only `txKey` and `pending` are required.
684
906
  */
685
- type PollingTrackerConfig<R, T extends Transaction> = {
686
- /** The transaction object to be tracked. It must include `txKey` and `pending` status. */
687
- tx: T & Pick<Transaction, 'txKey' | 'pending'>;
688
- /** The function that performs the data fetching (e.g., an API call) on each interval. */
907
+ type PollingTrackerConfig<R, T extends Pick<Transaction, 'txKey' | 'pending'>> = {
908
+ /** The transaction to track. Polling starts only if `pending` is `true`. */
909
+ tx: T;
910
+ /**
911
+ * Checks the transaction once per tick and reports through the callbacks it receives. It must call `stopPolling` on a
912
+ * terminal result. A thrown error counts as a failed attempt.
913
+ * @param params - The transaction, `stopPolling` and the callbacks.
914
+ */
689
915
  fetcher: (params: PollingFetcherParams<R, T>) => Promise<void>;
690
- /** Callback to be invoked when the transaction successfully completes. */
916
+ /**
917
+ * Called by the fetcher when the transaction succeeded.
918
+ * @param response - The result reported by the fetcher.
919
+ */
691
920
  onSuccess: (response: R) => void;
692
- /** Callback to be invoked when the transaction fails. */
921
+ /**
922
+ * Called by the fetcher when the transaction failed, and without arguments by the tracker after `maxRetries`
923
+ * consecutive failed attempts.
924
+ * @param response - The result reported by the fetcher, if any.
925
+ */
693
926
  onFailure: (response?: R) => void;
694
- /** Optional callback executed once when the tracker is initialized. */
927
+ /** Called once, synchronously, when polling starts. */
695
928
  onInitialize?: () => void;
696
- /** Optional callback for each successful poll. */
929
+ /**
930
+ * Called by the fetcher with intermediate results.
931
+ * @param response - The intermediate result.
932
+ */
697
933
  onIntervalTick?: (response: R) => void;
698
- /** Optional callback for when a transaction is replaced. */
934
+ /**
935
+ * Called by the fetcher when the transaction was replaced.
936
+ * @param response - The result describing the replacement.
937
+ */
699
938
  onReplaced?: (response: R) => void;
700
- /** Optional function to remove the transaction from the main pool, typically after polling stops. */
939
+ /**
940
+ * Called when polling stops, unless it was stopped with `withoutRemoving: true`.
941
+ * @param txKey - The `txKey` of the tracked transaction.
942
+ */
701
943
  removeTxFromPool?: (txKey: string) => void;
702
- /** The interval (in milliseconds) between polling attempts. Defaults to 5000ms. */
944
+ /** The delay before each attempt, in milliseconds. Defaults to 5000. */
703
945
  pollingInterval?: number;
704
- /** The number of consecutive failed fetches before stopping the tracker. Defaults to 10. */
946
+ /** The number of consecutive failed attempts (thrown errors) after which polling stops. Defaults to 10. */
705
947
  maxRetries?: number;
706
948
  };
707
949
  /**
708
- * Initializes a generic polling tracker that repeatedly calls a fetcher function
709
- * to monitor the status of an asynchronous task.
950
+ * Starts polling a transaction in the background and returns immediately. Does nothing if `tx.pending` is `false`.
951
+ *
952
+ * Every `pollingInterval` milliseconds (the first attempt also waits) it calls `fetcher`. Polling continues until the
953
+ * fetcher calls `stopPolling`. A fetcher that throws counts as a failed attempt; after `maxRetries` consecutive failed
954
+ * attempts the tracker calls `onFailure()` without arguments, logs a warning and stops (which calls
955
+ * `removeTxFromPool`, if configured). A successful attempt resets the count.
710
956
  *
711
- * This function handles the lifecycle of polling, including starting, stopping,
712
- * and automatic termination after a certain number of failed attempts.
957
+ * Side effects: runs a timer loop until it is stopped; there is no way to cancel it from the outside.
713
958
  *
714
- * @template R The expected type of the API response.
715
- * @template T The type of the transaction object.
716
- * @param {PollingTrackerConfig<R, T>} config - The configuration for the tracker.
959
+ * @template R - The response type the fetcher reports.
960
+ * @template T - The tracked transaction type.
961
+ * @param config - The transaction, the fetcher and the callbacks.
962
+ *
963
+ * @example
964
+ * ```ts
965
+ * initializePollingTracker<string, { txKey: string; pending: boolean }>({
966
+ * tx: { txKey: taskId, pending: true },
967
+ * fetcher: async ({ tx, stopPolling, onSuccess, onFailure }) => {
968
+ * const status = await getTaskStatus(tx.txKey); // your API call; throw on network errors
969
+ * if (status === 'done') onSuccess(status);
970
+ * if (status === 'failed') onFailure(status);
971
+ * if (status !== 'pending') stopPolling({ withoutRemoving: true });
972
+ * },
973
+ * onSuccess: () => console.log('Done'),
974
+ * onFailure: () => console.log('Failed'),
975
+ * });
976
+ * ```
717
977
  */
718
- declare function initializePollingTracker<R, T extends Transaction>(config: PollingTrackerConfig<R, T>): void;
978
+ declare function initializePollingTracker<R, T extends Pick<Transaction, 'txKey' | 'pending'>>(config: PollingTrackerConfig<R, T>): void;
719
979
 
720
- /** Maximum allowed length for each transaction title string. */
980
+ /**
981
+ * @file Safety limits for the user-facing metadata of transactions (title, description, payload), checked before a
982
+ * transaction is executed, stored, restored or synchronized.
983
+ */
984
+
985
+ /** Maximum length, in characters, of each `title` string. */
721
986
  declare const MAX_TRANSACTION_TITLE_LENGTH = 100;
722
- /** Maximum allowed length for each transaction description string. */
987
+ /** Maximum length, in characters, of each `description` string. */
723
988
  declare const MAX_TRANSACTION_DESCRIPTION_LENGTH = 300;
724
- /** Maximum allowed serialized UTF-8 payload size in bytes. */
989
+ /** Maximum size, in bytes, of the UTF-8 JSON of `payload`. */
725
990
  declare const MAX_TRANSACTION_PAYLOAD_BYTES: number;
726
991
  /**
727
- * Error thrown when transaction metadata fails Pulsar's safety limits.
992
+ * Thrown when the title, description or payload of a transaction breaks Pulsar's safety limits.
728
993
  */
729
994
  declare class PulsarTransactionValidationError extends Error {
730
- /** The transaction field that failed validation. */
995
+ /** The field that failed, for example `title`, `description[1]` or `payload.amount`. */
731
996
  readonly field: string;
997
+ /**
998
+ * @param field - The field that failed.
999
+ * @param message - The error message.
1000
+ */
732
1001
  constructor(field: string, message: string);
733
1002
  }
734
1003
  /**
735
- * Validates metadata used before a transaction action is executed.
736
- * Throws when title, description, or payload violates Pulsar safety limits.
1004
+ * Validates the metadata passed to `executeTxAction` before anything else runs.
1005
+ *
1006
+ * Each `title` string must be at most {@link MAX_TRANSACTION_TITLE_LENGTH} characters and each `description` string at
1007
+ * most {@link MAX_TRANSACTION_DESCRIPTION_LENGTH}. `payload` must be JSON-serializable and at most
1008
+ * {@link MAX_TRANSACTION_PAYLOAD_BYTES} bytes as UTF-8 JSON. Strings (including payload keys) must not match
1009
+ * executable-like patterns: `eval(`, `Function(`, `setTimeout`/`setInterval` with a string argument, and `javascript:`.
1010
+ * This is a defensive gate, not a replacement for escaping output in the UI.
1011
+ *
1012
+ * @param params - The transaction metadata.
1013
+ * @throws {@link PulsarTransactionValidationError} for the first field that breaks a rule.
737
1014
  */
738
1015
  declare function validateInitialTransactionParams(params: Omit<InitialTransactionParams, 'actionFunction'>): void;
739
1016
  /**
740
- * Validates a complete transaction before it is persisted or synchronized.
741
- * Throws when title, description, or payload violates Pulsar safety limits.
1017
+ * Validates the title, description and payload of a complete transaction with the rules of
1018
+ * {@link validateInitialTransactionParams}. Used by `addTxToPool`, `initializeTransactionsPool` and
1019
+ * `injectExternalPendingTxs`.
1020
+ *
1021
+ * @template T - The application transaction type.
1022
+ * @param tx - The transaction.
1023
+ * @throws {@link PulsarTransactionValidationError} for the first field that breaks a rule.
742
1024
  */
743
1025
  declare function validateTransaction<T extends Transaction>(tx: T): void;
744
1026
 
745
- export { type ActionTxKey, type BaseTransaction, type BeforeTxProcess, type CheckTxTracker, type EvmTransaction, type IInitializeTxTrackingStore, type ITxInMemoryStore, type ITxInMemoryStoreParameters, type ITxTrackingStore, type InitialTransaction, type InitialTransactionParams, MAX_TRANSACTION_DESCRIPTION_LENGTH, MAX_TRANSACTION_PAYLOAD_BYTES, MAX_TRANSACTION_TITLE_LENGTH, type PollingFetcherParams, type PollingTrackerConfig, type PulsarAdapter, PulsarTransactionValidationError, type SolanaTransaction, type StarknetTransaction, type StoreSlice, type SyncCallbacks, type TrackerCallbacks, type Transaction, type TransactionPool, TransactionStatus, TransactionTracker, type TxAdapter, type TxInMemoryPagination, type UpdatableTransactionFields, createBoundedUseStore, createPulsarStore, createTxInMemoryStore, initializePollingTracker, initializeTxTrackingStore, selectAllTransactions, selectAllTransactionsByActiveWallet, selectPendingTransactions, selectPendingTransactionsByActiveWallet, selectTxByKey, validateInitialTransactionParams, validateTransaction };
1027
+ export { type ActionTxKey, type BaseTransaction, type BeforeTxProcess, type CheckTxTracker, type EvmTransaction, type ExtractState, type IInitializeTxTrackingStore, type ITxInMemoryStore, type ITxInMemoryStoreParameters, type ITxTrackingStore, type InitialTransaction, type InitialTransactionParams, MAX_TRANSACTION_DESCRIPTION_LENGTH, MAX_TRANSACTION_PAYLOAD_BYTES, MAX_TRANSACTION_TITLE_LENGTH, type PollingFetcherParams, type PollingTrackerConfig, type PulsarAdapter, PulsarTransactionValidationError, type SolanaTransaction, type StarknetTransaction, type StoreSlice, type SyncCallbacks, type TrackerCallbacks, type Transaction, type TransactionPool, TransactionStatus, TransactionTracker, type TxAdapter, type TxInMemoryPagination, type UpdatableTransactionFields, createBoundedUseStore, createPulsarStore, createTxInMemoryStore, createTxUpdater, initializePollingTracker, initializeTxTrackingStore, selectAllTransactions, selectAllTransactionsByActiveWallet, selectPendingTransactions, selectPendingTransactionsByActiveWallet, selectTxByKey, validateInitialTransactionParams, validateTransaction };