@tuwaio/pulsar-core 0.6.12 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -4,308 +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
- /** For meta-transactions relayed and executed by the Gelato Network. */
27
+ /**
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.
30
+ */
22
31
  Gelato = "gelato",
23
- /** The tracker for monitoring standard Solana transaction signatures. */
24
- Solana = "solana"
32
+ /** A Solana transaction, tracked by its signature through RPC (`@tuwaio/pulsar-solana`). */
33
+ Solana = "solana",
34
+ /** An ERC-4337 UserOperation, tracked by its `userOpHash` through a bundler RPC and then on-chain. */
35
+ ERC4337 = "erc4337"
25
36
  }
26
37
  /**
27
- * 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`.
28
39
  */
29
40
  declare enum TransactionStatus {
30
- /** 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). */
31
42
  Failed = "Failed",
32
- /** The transaction was successfully mined and included in a block. */
43
+ /** The transaction was included on-chain and executed successfully. */
33
44
  Success = "Success",
34
- /** 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). */
35
46
  Replaced = "Replaced"
36
47
  }
37
48
  /**
38
- * A union type representing the unique identifier returned by an `actionFunction`
39
- * after a transaction is submitted to the network or a relay service.
40
- *
41
- * This key is crucial for the adapter to determine which tracker should
42
- * monitor the transaction.
43
- *
44
- * It can be one of the following:
45
- * - A standard `0x...` transaction hash (`Hex`).
46
- * - 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.
47
52
  */
48
53
  type ActionTxKey = `0x${string}` | string;
49
54
  /**
50
- * The fundamental structure for any transaction being tracked by Pulsar.
51
- * 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.
52
56
  */
53
57
  type BaseTransaction = {
54
- /** 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
+ */
55
62
  chainId: number | string;
56
63
  /**
57
- * User-facing description. Can be a single string for all states, or a tuple for specific states.
58
- * Each string is validated before execution and persistence. It must be 300 characters or less and must not contain
59
- * 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.
60
68
  * @example
61
- * // A single description for all states
62
- * description: 'Swap 1 ETH for 1,500 USDC'
63
- * // Specific descriptions for each state in order: [pending, success, error, replaced]
64
- * 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
+ * ```
65
73
  */
66
74
  description?: string | [string, string, string, string];
67
- /** 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`). */
68
76
  error?: TuwaErrorState;
69
- /** 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
+ */
70
81
  finishedTimestamp?: number;
71
- /** The sender's wallet address. */
82
+ /** The address of the wallet that sent the transaction, as reported by the adapter's `getConnectorInfo`. */
72
83
  from: string;
73
- /** A flag indicating if the transaction is in a failed state. */
84
+ /** `true` when the transaction failed; set by trackers together with `status: Failed`. */
74
85
  isError?: boolean;
75
- /** 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`. */
76
87
  isTrackedModalOpen?: boolean;
77
- /** 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. */
78
89
  localTimestamp: number;
79
90
  /**
80
- * Custom JSON-serializable data (strings or numbers) to associate with the transaction.
81
- * 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.
82
93
  */
83
94
  payload?: Record<string, string | number>;
84
- /** 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. */
85
96
  pending: boolean;
86
- /** The final on-chain status of the transaction. */
97
+ /** The terminal status, set together with `pending: false`. */
87
98
  status?: TransactionStatus;
88
99
  /**
89
- * User-facing title. Can be a single string for all states, or a tuple for specific states.
90
- * Each string is validated before execution and persistence. It must be 100 characters or less and must not contain
91
- * 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:`.
92
103
  * @example
93
- * // A single title for all states
94
- * title: 'ETH/USDC Swap'
95
- * // Specific titles for each state in order: [pending, success, error, replaced]
96
- * 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
+ * ```
97
108
  */
98
109
  title?: string | [string, string, string, string];
99
- /** The specific tracker responsible for monitoring this transaction's status. */
110
+ /** The tracker that monitors the transaction. */
100
111
  tracker: TransactionTracker;
101
- /** 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
+ */
102
116
  txKey: string;
103
- /** 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'`. */
104
118
  type: string;
105
- /** 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`. */
106
120
  connectorType: string;
107
- /** 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
+ */
108
125
  requiredConfirmations?: number;
109
- /** 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
+ */
110
130
  confirmations?: number | string | null;
111
- /** 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
+ */
112
135
  rpcUrl?: string;
113
- /** 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
+ */
114
141
  syncStatus?: 'synced' | 'pending-sync';
115
142
  };
116
143
  /**
117
- * 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.
118
146
  */
119
147
  type EvmTransaction = BaseTransaction & {
120
- /** The adapter type for EVM transactions. */
148
+ /** Always `OrbitAdapter.EVM`. */
121
149
  adapter: OrbitAdapter.EVM;
122
- /** 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
+ */
123
154
  hash?: `0x${string}`;
124
- /** The data payload for the transaction, typically for smart contract interactions. */
155
+ /** The calldata of the transaction. */
125
156
  input?: `0x${string}`;
126
- /** 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. */
127
158
  maxFeePerGas?: string;
128
- /** 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. */
129
160
  maxPriorityFeePerGas?: string;
130
- /** The transaction nonce, a sequential number for the sender's account. */
161
+ /** The nonce of the sender account. */
131
162
  nonce?: number;
132
- /** 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
+ */
133
167
  replacedTxHash?: `0x${string}`;
134
- /** The recipient's address or contract address. */
168
+ /** The recipient or contract address. */
135
169
  to?: `0x${string}`;
136
- /** The amount of native currency (in wei) being sent. */
170
+ /** The native value sent, in wei, as a decimal string. */
137
171
  value?: string;
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
+ */
177
+ bundlerUrl?: string;
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
+ */
182
+ pimlicoApiKey?: string;
138
183
  };
139
184
  /**
140
- * 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.
141
186
  */
142
187
  type SolanaTransaction = BaseTransaction & {
143
- /** The adapter type for Solana transactions. */
188
+ /** Always `OrbitAdapter.SOLANA`. */
144
189
  adapter: OrbitAdapter.SOLANA;
145
- /** The transaction fee in lamports. */
190
+ /** The transaction fee, in lamports. */
146
191
  fee?: number;
147
- /** The instructions included in the transaction. */
192
+ /** The instructions of the transaction, as returned by the `getTransaction` RPC method. */
148
193
  instructions?: unknown[];
149
- /** The recent blockhash used for the transaction. */
194
+ /** The blockhash the transaction was signed with. */
150
195
  recentBlockhash?: string;
151
196
  /** The slot in which the transaction was processed. */
152
197
  slot?: number;
153
198
  };
154
199
  /**
155
- * Represents a Starknet-specific transaction, extending the base properties.
200
+ * A Starknet transaction. Reserved for a Starknet adapter; Pulsar does not ship one.
156
201
  */
157
202
  type StarknetTransaction = BaseTransaction & {
158
- /** The adapter type for Starknet transactions. */
203
+ /** Always `OrbitAdapter.Starknet`. */
159
204
  adapter: OrbitAdapter.Starknet;
160
205
  /** The actual fee paid for the transaction. */
161
206
  actualFee?: {
207
+ /** The fee amount. */
162
208
  amount: string;
209
+ /** The fee unit. */
163
210
  unit: string;
164
211
  };
165
212
  /** The address of the contract being interacted with. */
166
213
  contractAddress?: string;
167
214
  };
168
- /** 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. */
169
216
  type Transaction = EvmTransaction | SolanaTransaction | StarknetTransaction;
170
217
  /**
171
- * 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`.
172
220
  */
173
- type InitialTransactionParams = Pick<BaseTransaction, 'description' | 'title' | 'type' | 'requiredConfirmations' | 'rpcUrl' | 'payload'> & {
174
- /** The specific blockchain adapter for this transaction. */
221
+ type InitialTransactionParams = Pick<BaseTransaction, 'description' | 'title' | 'type' | 'requiredConfirmations' | 'rpcUrl' | 'payload'> & Pick<EvmTransaction, 'bundlerUrl' | 'pimlicoApiKey'> & {
222
+ /** The adapter that handles the transaction. When no configured adapter has this key, the first one is used. */
175
223
  adapter: OrbitAdapter;
176
- /** The function that executes the on-chain action (e.g., sending a transaction) and returns a preliminary identifier like a hash. */
177
- actionFunction: (...args: any[]) => Promise<ActionTxKey | undefined>;
178
- /** 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
+ */
179
235
  desiredChainID: number | string;
180
- /** If true, the detailed tracking modal will open automatically upon initiation. */
236
+ /** When `true`, the transaction is created with `isTrackedModalOpen: true`. */
181
237
  withTrackedModal?: boolean;
182
- /** The specific tracker responsible for monitoring this transaction's status. Required for Gelato 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
+ */
183
242
  tracker?: TransactionTracker;
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
+ */
247
+ gelatoApiKey?: string;
184
248
  };
185
249
  /**
186
- * Represents a transaction in its temporary, pre-submission state.
187
- * 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).
188
252
  */
189
253
  type InitialTransaction = InitialTransactionParams & {
190
- /** 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. */
191
255
  error?: TuwaErrorState;
192
- /** 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. */
193
257
  isInitializing: boolean;
194
- /** 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. */
195
259
  lastTxKey?: string;
196
- /** The local timestamp when the user initiated the action. */
260
+ /** Unix timestamp (seconds) when `executeTxAction` started. */
197
261
  localTimestamp: number;
198
262
  };
199
263
  /**
200
- * Defines the standard callback structure for transaction events.
201
- * @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.
202
269
  */
203
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
+ */
204
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
+ */
205
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
+ */
206
287
  onReplaced?: (newTx: T, oldTx: T) => Promise<void> | void;
207
288
  }
208
289
  /**
209
- * Callbacks for synchronizing local transaction state with a remote backend.
210
- * 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.
211
294
  */
212
295
  interface SyncCallbacks<T extends Transaction> {
213
296
  /**
214
- * Called immediately after a transaction is created locally (added to pool).
215
- * 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`.
216
303
  */
217
304
  onRemoteCreate?: (tx: T) => Promise<void>;
218
305
  }
219
306
  /**
220
- * 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.
221
309
  *
222
- * Throw an error from this function to block the transaction before `initialTx`, wallet interaction,
223
- * 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.
224
313
  */
225
314
  type BeforeTxProcess = () => Promise<void> | void;
226
315
  /**
227
- * The configuration object containing one or more transaction adapters.
228
- * @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.
229
319
  */
230
320
  type PulsarAdapter<T extends Transaction> = OrbitGenericAdapter<TxAdapter<T>> & {
231
- /** 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. */
232
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. */
233
324
  maxTransactions?: number;
325
+ /** @deprecated Gelato relay is deprecated. Gelato API key used to track `TransactionTracker.Gelato` transactions. */
234
326
  gelatoApiKey?: string;
235
- /** 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
+ */
236
331
  abortOnTxError?: boolean;
237
332
  } & SyncCallbacks<T>;
238
333
  /**
239
- * Represents a tracker for a specific transaction tied to an action and a connector.
240
- *
241
- * @typedef {Object} CheckTxTracker
242
- * @property {ActionTxKey} actionTxKey - The key identifying the specific action related to the transaction.
243
- * @property {string} connectorType - The type of connector used for the transaction (e.g., wallet provider, blockchain interface).
244
- * @property {TransactionTracker} [tracker] - An optional tracker object that monitors the status and progress of the transaction.
245
- * @property {string} [gelatoApiKey] - An optional Gelato API key for Gelato relayer integration.
334
+ * The input of `TxAdapter.checkTransactionsTracker`: the key returned by the action and the context needed to pick a
335
+ * tracker.
246
336
  */
247
337
  type CheckTxTracker = {
338
+ /** The key returned by `actionFunction`. */
248
339
  actionTxKey: ActionTxKey;
340
+ /** The connector that signed the transaction, for example `evm:safe` for a Safe wallet. */
249
341
  connectorType: string;
342
+ /** The tracker requested in `executeTxAction` params, if any. */
250
343
  tracker?: TransactionTracker;
344
+ /** @deprecated Gelato relay is deprecated. Use `bundlerUrl` / `pimlicoApiKey` with ERC-4337 instead. */
251
345
  gelatoApiKey?: string;
346
+ /** Custom bundler RPC URL for ERC-4337 UserOperation tracking. */
347
+ bundlerUrl?: string;
348
+ /** Pimlico API key for ERC-4337 UserOperation tracking. */
349
+ pimlicoApiKey?: string;
252
350
  };
253
351
  /**
254
- * Defines the interface for a transaction adapter, which provides chain-specific logic and utilities.
255
- * @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.
256
356
  */
257
357
  type TxAdapter<T extends Transaction> = Pick<BaseAdapter, 'getExplorerUrl'> & {
258
- /** The unique key identifying this adapter. */
358
+ /** The chain family handled by the adapter. */
259
359
  key: OrbitAdapter;
260
- /** Returns information about the currently connected connector. */
360
+ /** Returns the connected wallet. Called by `executeTxAction` before the chain check. */
261
361
  getConnectorInfo: () => {
262
- /** The currently connected wallet address. */
362
+ /** The address of the connected wallet. */
263
363
  walletAddress: string;
264
- /** The type of the connector (e.g., 'metamask', 'phantom'). */
364
+ /** The connector type, for example `evm:metamask`. */
265
365
  connectorType: string;
266
366
  };
267
367
  /**
268
- * Ensures the connected wallet is on the correct network for the transaction.
269
- *
270
- * This method should throw an error if the chain is mismatched.
271
- * @param chainId The desired chain ID for the transaction.
272
- * @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.
273
371
  */
274
372
  checkChainForTx: (chainId: string | number) => Promise<void>;
275
373
  /**
276
- * Determines the appropriate tracker and final `txKey` from the result of an action.
277
- * @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.
278
377
  */
279
- checkTransactionsTracker: ({ actionTxKey, connectorType, tracker }: CheckTxTracker) => {
378
+ checkTransactionsTracker: (params: CheckTxTracker) => {
379
+ /** The key the transaction is stored under. */
280
380
  txKey: string;
381
+ /** The tracker that monitors the transaction. */
281
382
  tracker: TransactionTracker;
282
383
  };
283
384
  /**
284
- * Selects and initializes the correct background tracker for a given transaction.
285
- * @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.
286
388
  */
287
389
  checkAndInitializeTrackerInStore: (params: {
288
390
  tx: T;
289
391
  gelatoApiKey?: string;
290
392
  } & TrackerCallbacks<T> & Pick<ITxTrackingStore<T>, 'updateTxParams' | 'removeTxFromPool' | 'transactionsPool'>) => Promise<void> | void;
291
393
  /**
292
- * Optional: Logic to cancel a pending EVM transaction.
293
- * @param tx The transaction to cancel.
294
- * @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.
295
397
  */
296
398
  cancelTxAction?: (tx: T) => Promise<string>;
297
399
  /**
298
- * Optional: Logic to speed up a pending EVM transaction.
299
- * @param tx The transaction to speed up.
300
- * @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.
301
403
  */
302
404
  speedUpTxAction?: (tx: T) => Promise<string>;
303
405
  /**
304
- * Optional: Logic to retry a failed transaction.
305
- * @param params The parameters for retrying the transaction.
306
- * @param params.txKey The unique key of the transaction to retry.
307
- * @param params.tx The initial parameters of the transaction.
308
- * @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`.
309
412
  */
310
413
  retryTxAction?: (params: {
311
414
  txKey: string;
@@ -313,92 +416,118 @@ type TxAdapter<T extends Transaction> = Pick<BaseAdapter, 'getExplorerUrl'> & {
313
416
  onClose: (txKey?: string) => void;
314
417
  } & Partial<Pick<ITxTrackingStore<T>, 'executeTxAction'>>) => Promise<void>;
315
418
  /**
316
- * Optional: Constructs a full explorer URL for a specific transaction.
317
- * May require the full transaction pool to resolve details for replaced transactions.
318
- * @param tx The transaction object.
319
- * @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.
320
422
  */
321
423
  getExplorerTxUrl?: (tx: T) => string;
322
424
  };
323
425
  /**
324
- * Defines the structure of the transaction pool, a key-value store of transactions indexed by their unique keys.
325
- * @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.
326
429
  */
327
430
  type TransactionPool<T extends Transaction> = Record<string, T>;
328
431
  /**
329
- * A utility type that creates a union of all fields that can be safely updated
330
- * on a transaction object via the `updateTxParams` action. This ensures type safety
331
- * and prevents accidental modification of immutable properties.
432
+ * The fields `updateTxParams` accepts: the fields trackers change while a transaction is tracked.
332
433
  */
333
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'>>;
334
435
  /**
335
- * The interface for the base transaction tracking store slice.
336
- * It includes the state and actions for managing the transaction lifecycle.
337
- * @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.
338
439
  */
339
440
  interface IInitializeTxTrackingStore<T extends Transaction> {
340
- /** A pool of all transactions currently being tracked, indexed by `txKey`. */
441
+ /** Every tracked transaction, indexed by `txKey`. Persisted to `localStorage` by `createPulsarStore`. */
341
442
  transactionsPool: TransactionPool<T>;
342
- /** The `txKey` of the most recently added transaction. */
443
+ /** The `txKey` of the transaction added last. */
343
444
  lastAddedTxKey?: string;
344
- /** 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
+ */
345
449
  initialTx?: InitialTransaction;
346
450
  /**
347
- * Adds a new transaction to the tracking pool and marks it as pending.
348
- * @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.
349
459
  */
350
460
  addTxToPool: (tx: T) => Promise<void>;
351
461
  /**
352
- * Updates one or more properties of an existing transaction in the pool.
353
- * @param txKey The key of the transaction to update.
354
- * @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.
355
466
  */
356
467
  updateTxParams: (txKey: string, fields: UpdatableTransactionFields) => void;
357
468
  /**
358
- * Removes a transaction from the tracking pool by its key.
359
- * @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.
360
471
  */
361
472
  removeTxFromPool: (txKey: string) => void;
362
473
  /**
363
- * Closes the tracking modal for a transaction and clears any initial transaction state.
364
- * @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.
365
476
  */
366
477
  closeTxTrackedModal: (txKey?: string) => void;
367
478
  /**
368
- * A selector function to retrieve the key of the last transaction added to the pool.
369
- * @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`.
370
481
  */
371
482
  getLastTxKey: () => string | undefined;
372
483
  /**
373
- * A record of transaction keys that failed to sync with the remote backend (Quasar)
374
- * 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`.
375
486
  */
376
487
  unsyncedTxKeys?: Record<string, boolean>;
377
488
  /**
378
- * Attempts to synchronize any transactions in `unsyncedTxKeys` that have reached a terminal
379
- * 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.
380
495
  */
381
496
  reconcileUnsyncedTransactions: () => Promise<void>;
382
497
  }
383
498
  /**
384
- * The complete interface for the Pulsar transaction tracking store.
385
- * @template T The transaction type.
499
+ * The state and actions of the store created by `createPulsarStore`.
500
+ *
501
+ * @template T - The application transaction type.
386
502
  */
387
503
  type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
388
- /** 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
+ */
389
508
  getAdapter: () => TxAdapter<T> | TxAdapter<T>[];
390
509
  /**
391
- * The primary method for initiating and tracking a new transaction from start to finish.
392
- * 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.
393
514
  *
394
- * @param params The parameters for handling the transaction.
395
- * @param params.actionFunction The async function to execute (e.g., a smart contract write call). Must return a unique key or undefined.
396
- * @param params.params The metadata for the transaction. Title, description, and payload are validated before execution.
397
- * @param params.defaultTracker The default tracker to use if it cannot be determined automatically.
398
- * @param params.beforeTxProcess Optional local preflight callback. When provided, it overrides the global callback from `createPulsarStore`.
399
- * @param params.onSuccess Callback to execute when the transaction is successfully submitted.
400
- * @param params.onError Callback to execute when the transaction fails.
401
- * @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.
402
531
  */
403
532
  executeTxAction: (params: {
404
533
  actionFunction: () => Promise<ActionTxKey | undefined>;
@@ -408,64 +537,83 @@ type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
408
537
  abortOnTxError?: boolean;
409
538
  } & TrackerCallbacks<T>) => Promise<void>;
410
539
  /**
411
- * Initializes trackers for all pending transactions in the pool.
412
- * 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.
413
544
  */
414
545
  initializeTransactionsPool: () => Promise<void>;
415
546
  /**
416
- * Cross-device synchronization bridge.
417
- * Injects remote pending transactions into the local pool and starts their lifecycle trackers.
418
- * 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.
419
553
  */
420
554
  injectExternalPendingTxs: (remoteTxs: T[]) => Promise<void>;
421
555
  };
422
556
  /**
423
- * Represents the structure and behavior of an in-memory pagination system
424
- * for managing transaction history.
557
+ * The pagination state and action of the in-memory history store, as consumed by UI components.
425
558
  */
426
559
  type TxInMemoryPagination = {
427
- /** Indicates whether the store is currently loading transaction history. */
560
+ /** `true` while a history page is loading. */
428
561
  isLoading: boolean;
429
- /** Indicates whether the last loading request ended with an error. */
562
+ /** `true` when the last history request failed. */
430
563
  isError: boolean;
431
- /** Indicates whether more history pages are available. */
564
+ /** `true` when the last loaded page reported a next page. */
432
565
  hasMore: boolean;
433
- /** The current page number in the paginated history. */
566
+ /** The last loaded page number. */
434
567
  currentPage: number;
435
- /** 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
+ */
436
573
  fetchNextPage: (walletAddress: string) => Promise<void>;
437
574
  };
438
575
  /**
439
- * The complete interface for the Pulsar transaction in-memory store.
440
- * 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.
441
578
  *
442
- * @template T The transaction type.
579
+ * @template T - The application transaction type.
443
580
  */
444
581
  type ITxInMemoryStore<T extends Transaction> = {
445
- /** A pool of all transactions currently being tracked and loaded from history, indexed by `txKey`. */
582
+ /** The local and remote transactions, indexed by `txKey`. */
446
583
  transactionsPool: TransactionPool<T>;
447
- /** 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
+ */
448
589
  fetchInitial: (walletAddress: string) => Promise<void>;
449
- /** 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
+ */
450
595
  syncWithLocalPool: (localPool: TransactionPool<T>) => void;
451
596
  } & TxInMemoryPagination;
452
597
  /**
453
- * Parameters used to configure and manage an in-memory transaction store.
598
+ * The configuration of `createTxInMemoryStore`.
454
599
  *
455
- * @template T The transaction type.
600
+ * @template T - The application transaction type.
456
601
  */
457
602
  type ITxInMemoryStoreParameters<T extends Transaction> = {
458
- /** A localTransactionsPool. */
603
+ /** The initial pool, usually `transactionsPool` of the persistent store. */
459
604
  localTransactionsPool: TransactionPool<T>;
460
- /**
461
- * Attempts to synchronize any transactions in `unsyncedTxKeys` that have reached a terminal
462
- * status but failed their initial `onRemoteCreate` call.
463
- */
605
+ /** Called by `fetchInitial` before the first page is loaded, usually the store's `reconcileUnsyncedTransactions`. */
464
606
  reconcileUnsyncedTransactions?: () => Promise<void>;
465
- /** * Callback fired when remote history is successfully fetched.
466
- * 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.
467
611
  */
468
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
+ */
469
617
  getHistory?: ({ page, walletAddress, }: {
470
618
  /**
471
619
  * Page number for pagination.
@@ -473,6 +621,7 @@ type ITxInMemoryStoreParameters<T extends Transaction> = {
473
621
  * @defaultValue `1`
474
622
  */
475
623
  page?: number;
624
+ /** The wallet whose history is requested. */
476
625
  walletAddress: string;
477
626
  }) => Promise<{
478
627
  /** Array of transactions for the current page. */
@@ -491,95 +640,135 @@ type ITxInMemoryStoreParameters<T extends Transaction> = {
491
640
  };
492
641
 
493
642
  /**
494
- * @file This file defines the core Zustand slice for managing the state of transactions. It includes the state,
495
- * 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.
496
645
  */
497
646
 
498
647
  /**
499
- * Creates a Zustand store slice with the core logic for transaction state management.
500
- * 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.
501
650
  *
502
- * @template T The specific transaction type.
503
- * @param options Configuration for the store slice.
504
- * @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`.
505
660
  */
506
661
  declare function initializeTxTrackingStore<T extends Transaction>({ maxTransactions, onRemoteCreate, }: Pick<PulsarAdapter<T>, 'onRemoteCreate'> & {
507
662
  maxTransactions: number;
508
663
  }): StoreSlice<IInitializeTxTrackingStore<T>>;
509
664
 
510
665
  /**
511
- * @file This file contains selector functions for deriving state from the transaction tracking store.
512
- * 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.
513
668
  */
514
669
 
515
670
  /**
516
- * Selects all transactions from the pool and sorts them by their creation timestamp in ascending order.
517
- * @template T - The transaction type.
518
- * @param {TransactionPool<T>} transactionsPool - The entire transaction pool from the store.
519
- * @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.
520
676
  */
521
677
  declare const selectAllTransactions: <T extends Transaction>(transactionsPool: TransactionPool<T>) => T[];
522
678
  /**
523
- * Selects all transactions that are currently in a pending state, sorted chronologically.
524
- * @template T - The transaction type.
525
- * @param {TransactionPool<T>} transactionsPool - The entire transaction pool from the store.
526
- * @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.
527
684
  */
528
685
  declare const selectPendingTransactions: <T extends Transaction>(transactionsPool: TransactionPool<T>) => T[];
529
686
  /**
530
- * Selects a single transaction from the pool by its unique key (`txKey`).
531
- * @template T - The transaction type.
532
- * @param {TransactionPool<T>} transactionsPool - The entire transaction pool from the store.
533
- * @param {string} key - The `txKey` of the transaction to retrieve.
534
- * @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.
535
693
  */
536
694
  declare const selectTxByKey: <T extends Transaction>(transactionsPool: TransactionPool<T>, key: string) => T | undefined;
537
695
  /**
538
- * Selects all transactions initiated by a specific wallet address, sorted chronologically.
539
- * @template T - The transaction type.
540
- * @param {TransactionPool<T>} transactionsPool - The entire transaction pool from the store.
541
- * @param {string} from - The wallet address (`from` address) to filter transactions by.
542
- * @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.
543
702
  */
544
703
  declare const selectAllTransactionsByActiveWallet: <T extends Transaction>(transactionsPool: TransactionPool<T>, from: string) => T[];
545
704
  /**
546
- * Selects all pending transactions for a specific wallet address, sorted chronologically.
547
- * @template T - The transaction type.
548
- * @param {TransactionPool<T>} transactionsPool - The entire transaction pool from the store.
549
- * @param {string} from - The wallet address (`from` address) to filter transactions by.
550
- * @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.
551
711
  */
552
712
  declare const selectPendingTransactionsByActiveWallet: <T extends Transaction>(transactionsPool: TransactionPool<T>, from: string) => T[];
553
713
 
554
714
  /**
555
- * 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.
718
+ *
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.
721
+ *
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`.
556
724
  *
557
- * The store is designed to:
558
- * - keep a local transaction pool in sync with remote history
559
- * - preserve terminal transaction states
560
- * - support paginated history loading
561
- * - avoid duplicated merge logic across store actions
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.
562
727
  *
563
- * @template T The transaction type.
564
- * @param params Store configuration parameters.
565
- * @param params.getHistory Optional remote history fetcher.
566
- * @returns A Zustand vanilla store instance for in-memory transaction management.
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`.
567
736
  */
568
737
  declare function createTxInMemoryStore<T extends Transaction>({ localTransactionsPool, reconcileUnsyncedTransactions, getHistory, onHistoryFetched, }: ITxInMemoryStoreParameters<T>): zustand.StoreApi<ITxInMemoryStore<T>>;
569
738
 
570
739
  /**
571
- * 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.
572
742
  *
573
- * This function configures a Zustand store enhanced with persistence. It combines the core transaction management
574
- * slice with a powerful orchestration logic that leverages chain-specific adapters to handle the entire
575
- * 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.
576
749
  *
577
- * @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()`).
578
761
  *
579
- * @param config Configuration object for creating the store.
580
- * @param config.adapter Adapter or an array of adapters for different chains or transaction types.
581
- * @param options Configuration for the Zustand `persist` middleware.
582
- * @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
+ * ```
583
772
  */
584
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"> & {
585
774
  setState(partial: ITxTrackingStore<T> | Partial<ITxTrackingStore<T>> | ((state: ITxTrackingStore<T>) => ITxTrackingStore<T> | Partial<ITxTrackingStore<T>>), replace?: false | undefined): unknown;
@@ -596,36 +785,36 @@ declare function createPulsarStore<T extends Transaction>({ adapter, maxTransact
596
785
  };
597
786
 
598
787
  /**
599
- * @file This file provides a utility for creating a type-safe, bounded Zustand hook from a vanilla store.
600
- * This pattern is recommended by the official Zustand documentation to ensure full type
601
- * 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.
602
789
  *
603
- * @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}
604
791
  */
605
792
 
606
793
  /**
607
- * A utility type that infers the state shape from a Zustand `StoreApi`.
608
- * It extracts the return type of the `getState` method.
609
- * @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.
610
797
  */
611
798
  type ExtractState<S> = S extends {
612
799
  getState: () => infer T;
613
800
  } ? T : never;
614
801
  /**
615
- * 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.
616
803
  *
617
- * This function takes a vanilla Zustand store instance and returns a React hook
618
- * that is pre-bound to that store. This approach provides a cleaner API and
619
- * enhances type inference, eliminating the need to pass the store instance
620
- * 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.
621
808
  *
622
- * The returned hook supports two signatures:
623
- * 1. `useBoundedStore()`: Selects the entire state.
624
- * 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.
625
812
  *
626
- * @template S - The type of the Zustand store (`StoreApi`).
627
- * @param {S} store - The vanilla Zustand store instance to bind the hook to.
628
- * @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
+ * ```
629
818
  */
630
819
  declare const createBoundedUseStore: <S extends StoreApi<unknown>>(store: S) => {
631
820
  (): ExtractState<S>;
@@ -633,95 +822,206 @@ declare const createBoundedUseStore: <S extends StoreApi<unknown>>(store: S) =>
633
822
  };
634
823
 
635
824
  /**
636
- * @file This file provides a generic utility for creating a polling mechanism to track
637
- * 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.
826
+ */
827
+
828
+ /**
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).
638
859
  */
639
860
 
640
861
  /**
641
- * Defines the parameters for the fetcher function used within the polling tracker.
642
- * The fetcher is the core logic that performs the actual API call.
643
- * @template R The expected type of the successful API response.
644
- * @template T The type of the transaction object being tracked.
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.
645
867
  */
646
868
  type PollingFetcherParams<R, T> = {
647
- /** The transaction object being tracked. */
869
+ /** The tracked transaction, as passed to `initializePollingTracker`. */
648
870
  tx: T;
649
- /** 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
+ */
650
876
  stopPolling: (options?: {
877
+ /** Keep the transaction in the pool. Defaults to `false`. */
651
878
  withoutRemoving?: boolean;
652
879
  }) => void;
653
- /** 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
+ */
654
884
  onSuccess: (response: R) => void;
655
- /** 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
+ */
656
889
  onFailure: (response?: R) => void;
657
- /** 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
+ */
658
894
  onIntervalTick?: (response: R) => void;
659
- /** 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
+ */
660
899
  onReplaced?: (response: R) => void;
661
900
  };
662
901
  /**
663
- * Defines the configuration object for the `initializePollingTracker` function.
664
- * @template R The expected type of the successful API response.
665
- * @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.
666
906
  */
667
- type PollingTrackerConfig<R, T extends Transaction> = {
668
- /** The transaction object to be tracked. It must include `txKey` and `pending` status. */
669
- tx: T & Pick<Transaction, 'txKey' | 'pending'>;
670
- /** 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
+ */
671
915
  fetcher: (params: PollingFetcherParams<R, T>) => Promise<void>;
672
- /** 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
+ */
673
920
  onSuccess: (response: R) => void;
674
- /** 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
+ */
675
926
  onFailure: (response?: R) => void;
676
- /** Optional callback executed once when the tracker is initialized. */
927
+ /** Called once, synchronously, when polling starts. */
677
928
  onInitialize?: () => void;
678
- /** Optional callback for each successful poll. */
929
+ /**
930
+ * Called by the fetcher with intermediate results.
931
+ * @param response - The intermediate result.
932
+ */
679
933
  onIntervalTick?: (response: R) => void;
680
- /** 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
+ */
681
938
  onReplaced?: (response: R) => void;
682
- /** 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
+ */
683
943
  removeTxFromPool?: (txKey: string) => void;
684
- /** The interval (in milliseconds) between polling attempts. Defaults to 5000ms. */
944
+ /** The delay before each attempt, in milliseconds. Defaults to 5000. */
685
945
  pollingInterval?: number;
686
- /** 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. */
687
947
  maxRetries?: number;
688
948
  };
689
949
  /**
690
- * Initializes a generic polling tracker that repeatedly calls a fetcher function
691
- * 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.
692
956
  *
693
- * This function handles the lifecycle of polling, including starting, stopping,
694
- * 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.
695
958
  *
696
- * @template R The expected type of the API response.
697
- * @template T The type of the transaction object.
698
- * @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
+ * ```
699
977
  */
700
- 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;
701
979
 
702
- /** 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. */
703
986
  declare const MAX_TRANSACTION_TITLE_LENGTH = 100;
704
- /** Maximum allowed length for each transaction description string. */
987
+ /** Maximum length, in characters, of each `description` string. */
705
988
  declare const MAX_TRANSACTION_DESCRIPTION_LENGTH = 300;
706
- /** Maximum allowed serialized UTF-8 payload size in bytes. */
989
+ /** Maximum size, in bytes, of the UTF-8 JSON of `payload`. */
707
990
  declare const MAX_TRANSACTION_PAYLOAD_BYTES: number;
708
991
  /**
709
- * 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.
710
993
  */
711
994
  declare class PulsarTransactionValidationError extends Error {
712
- /** The transaction field that failed validation. */
995
+ /** The field that failed, for example `title`, `description[1]` or `payload.amount`. */
713
996
  readonly field: string;
997
+ /**
998
+ * @param field - The field that failed.
999
+ * @param message - The error message.
1000
+ */
714
1001
  constructor(field: string, message: string);
715
1002
  }
716
1003
  /**
717
- * Validates metadata used before a transaction action is executed.
718
- * 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.
719
1014
  */
720
1015
  declare function validateInitialTransactionParams(params: Omit<InitialTransactionParams, 'actionFunction'>): void;
721
1016
  /**
722
- * Validates a complete transaction before it is persisted or synchronized.
723
- * 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.
724
1024
  */
725
1025
  declare function validateTransaction<T extends Transaction>(tx: T): void;
726
1026
 
727
- 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 };