@tuwaio/pulsar-core 0.5.1 → 0.6.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 +99 -20
- package/dist/index.d.ts +99 -20
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -74,8 +74,8 @@ type BaseTransaction = {
|
|
|
74
74
|
isTrackedModalOpen?: boolean;
|
|
75
75
|
/** The local timestamp (in seconds) when the transaction was initiated by the user. */
|
|
76
76
|
localTimestamp: number;
|
|
77
|
-
/**
|
|
78
|
-
payload?:
|
|
77
|
+
/** Custom data (strings or numbers) to associate with the transaction. */
|
|
78
|
+
payload?: Record<string, string | number>;
|
|
79
79
|
/** A flag indicating if the transaction is still awaiting on-chain confirmation. */
|
|
80
80
|
pending: boolean;
|
|
81
81
|
/** The final on-chain status of the transaction. */
|
|
@@ -97,6 +97,12 @@ type BaseTransaction = {
|
|
|
97
97
|
type: string;
|
|
98
98
|
/** The type of connector used to sign the transaction (e.g., 'injected', 'walletConnect'). */
|
|
99
99
|
connectorType: string;
|
|
100
|
+
/** The number of confirmations required for the transaction to be considered confirmed. */
|
|
101
|
+
requiredConfirmations?: number;
|
|
102
|
+
/** The number of confirmations received. A string value indicates a confirmed transaction, while `null` means it's pending. */
|
|
103
|
+
confirmations?: number | string | null;
|
|
104
|
+
/** The RPC URL to use for the transaction. Required for Solana transactions. */
|
|
105
|
+
rpcUrl?: string;
|
|
100
106
|
};
|
|
101
107
|
/**
|
|
102
108
|
* Represents an EVM-specific transaction, extending the base properties with EVM fields.
|
|
@@ -135,10 +141,6 @@ type SolanaTransaction = BaseTransaction & {
|
|
|
135
141
|
recentBlockhash?: string;
|
|
136
142
|
/** The slot in which the transaction was processed. */
|
|
137
143
|
slot?: number;
|
|
138
|
-
/** The number of confirmations received. A string value indicates a confirmed transaction, while `null` means it's pending. */
|
|
139
|
-
confirmations?: number | string | null;
|
|
140
|
-
/** The RPC URL used to submit and track this transaction. */
|
|
141
|
-
rpcUrl?: string;
|
|
142
144
|
};
|
|
143
145
|
/**
|
|
144
146
|
* Represents a Starknet-specific transaction, extending the base properties.
|
|
@@ -159,26 +161,16 @@ type Transaction = EvmTransaction | SolanaTransaction | StarknetTransaction;
|
|
|
159
161
|
/**
|
|
160
162
|
* Represents the parameters required to initiate a new transaction tracking flow.
|
|
161
163
|
*/
|
|
162
|
-
type InitialTransactionParams = {
|
|
164
|
+
type InitialTransactionParams = Pick<BaseTransaction, 'description' | 'title' | 'type' | 'requiredConfirmations' | 'rpcUrl' | 'payload'> & {
|
|
163
165
|
/** The specific blockchain adapter for this transaction. */
|
|
164
166
|
adapter: OrbitAdapter;
|
|
165
167
|
/** The function that executes the on-chain action (e.g., sending a transaction) and returns a preliminary identifier like a hash. */
|
|
166
168
|
actionFunction: (...args: any[]) => Promise<ActionTxKey | undefined>;
|
|
167
|
-
/** A user-facing description for the transaction. Supports state-specific descriptions. */
|
|
168
|
-
description?: string | [string, string, string, string];
|
|
169
169
|
/** The target chain ID for the transaction. */
|
|
170
170
|
desiredChainID: number | string;
|
|
171
|
-
/** Any custom data to associate with the transaction. */
|
|
172
|
-
payload?: object;
|
|
173
|
-
/** A user-facing title for the transaction. Supports state-specific titles. */
|
|
174
|
-
title?: string | [string, string, string, string];
|
|
175
|
-
/** The application-specific type of the transaction. */
|
|
176
|
-
type: string;
|
|
177
171
|
/** If true, the detailed tracking modal will open automatically upon initiation. */
|
|
178
172
|
withTrackedModal?: boolean;
|
|
179
|
-
/** The
|
|
180
|
-
rpcUrl?: string;
|
|
181
|
-
/** The transaction tracker. Required for Gelato transactions. */
|
|
173
|
+
/** The specific tracker responsible for monitoring this transaction's status. Required for Gelato tracker. */
|
|
182
174
|
tracker?: TransactionTracker;
|
|
183
175
|
};
|
|
184
176
|
/**
|
|
@@ -318,7 +310,7 @@ type TransactionPool<T extends Transaction> = Record<string, T>;
|
|
|
318
310
|
* on a transaction object via the `updateTxParams` action. This ensures type safety
|
|
319
311
|
* and prevents accidental modification of immutable properties.
|
|
320
312
|
*/
|
|
321
|
-
type UpdatableTransactionFields = Partial<Pick<EvmTransaction, 'to' | 'nonce' | 'txKey' | 'pending' | 'hash' | 'status' | 'replacedTxHash' | 'error' | 'finishedTimestamp' | 'isTrackedModalOpen' | 'isError' | 'maxPriorityFeePerGas' | 'maxFeePerGas' | 'input' | 'value'>> & Partial<Pick<SolanaTransaction, 'slot' | 'confirmations' | 'fee' | 'instructions' | 'recentBlockhash' | 'rpcUrl'>>;
|
|
313
|
+
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'>>;
|
|
322
314
|
/**
|
|
323
315
|
* The interface for the base transaction tracking store slice.
|
|
324
316
|
* It includes the state and actions for managing the transaction lifecycle.
|
|
@@ -387,6 +379,77 @@ type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
|
|
|
387
379
|
* This is essential for resuming tracking after a page reload or application restart.
|
|
388
380
|
*/
|
|
389
381
|
initializeTransactionsPool: () => Promise<void>;
|
|
382
|
+
/**
|
|
383
|
+
* Cross-device synchronization bridge.
|
|
384
|
+
* Injects remote pending transactions into the local pool and starts their lifecycle trackers.
|
|
385
|
+
* Also self-heals local pending transactions if the remote DB knows they are terminal.
|
|
386
|
+
*/
|
|
387
|
+
injectExternalPendingTxs: (remoteTxs: T[]) => Promise<void>;
|
|
388
|
+
};
|
|
389
|
+
/**
|
|
390
|
+
* Represents the structure and behavior of an in-memory pagination system
|
|
391
|
+
* for managing transaction history.
|
|
392
|
+
*/
|
|
393
|
+
type TxInMemoryPagination = {
|
|
394
|
+
/** Indicates whether the store is currently loading transaction history. */
|
|
395
|
+
isLoading: boolean;
|
|
396
|
+
/** Indicates whether the last loading request ended with an error. */
|
|
397
|
+
isError: boolean;
|
|
398
|
+
/** Indicates whether more history pages are available. */
|
|
399
|
+
hasMore: boolean;
|
|
400
|
+
/** The current page number in the paginated history. */
|
|
401
|
+
currentPage: number;
|
|
402
|
+
/** Loads the next page of transaction history and appends it to the pool. */
|
|
403
|
+
fetchNextPage: (walletAddress: string) => Promise<void>;
|
|
404
|
+
};
|
|
405
|
+
/**
|
|
406
|
+
* The complete interface for the Pulsar transaction in-memory store.
|
|
407
|
+
* It keeps a paginated remote history in sync with a local transaction pool.
|
|
408
|
+
*
|
|
409
|
+
* @template T The transaction type.
|
|
410
|
+
*/
|
|
411
|
+
type ITxInMemoryStore<T extends Transaction> = {
|
|
412
|
+
/** A pool of all transactions currently being tracked and loaded from history, indexed by `txKey`. */
|
|
413
|
+
transactionsPool: TransactionPool<T>;
|
|
414
|
+
/** Loads the first page of transaction history. */
|
|
415
|
+
fetchInitial: (walletAddress: string) => Promise<void>;
|
|
416
|
+
/** Merges a local transaction pool into the in-memory store. */
|
|
417
|
+
syncWithLocalPool: (localPool: TransactionPool<T>) => void;
|
|
418
|
+
} & TxInMemoryPagination;
|
|
419
|
+
/**
|
|
420
|
+
* Parameters used to configure and manage an in-memory transaction store.
|
|
421
|
+
*
|
|
422
|
+
* @template T The transaction type.
|
|
423
|
+
*/
|
|
424
|
+
type ITxInMemoryStoreParameters<T extends Transaction> = {
|
|
425
|
+
/** A localTransactionsPool. */
|
|
426
|
+
localTransactionsPool: TransactionPool<T>;
|
|
427
|
+
/** * Callback fired when remote history is successfully fetched.
|
|
428
|
+
* Used to inject remote pending transactions into the persistent tracking store.
|
|
429
|
+
*/
|
|
430
|
+
onHistoryFetched?: (remoteTxs: T[]) => void;
|
|
431
|
+
getHistory?: ({ page, walletAddress, }: {
|
|
432
|
+
/**
|
|
433
|
+
* Page number for pagination.
|
|
434
|
+
*
|
|
435
|
+
* @defaultValue `1`
|
|
436
|
+
*/
|
|
437
|
+
page?: number;
|
|
438
|
+
walletAddress: string;
|
|
439
|
+
}) => Promise<{
|
|
440
|
+
/** Array of transactions for the current page. */
|
|
441
|
+
docs: T[];
|
|
442
|
+
/** Total number of transactions matching the query. */
|
|
443
|
+
totalDocs: number;
|
|
444
|
+
/** Total number of available pages. */
|
|
445
|
+
totalPages: number;
|
|
446
|
+
/** Current page number. */
|
|
447
|
+
page: number;
|
|
448
|
+
/** Indicates whether a next page exists. */
|
|
449
|
+
hasNextPage: boolean;
|
|
450
|
+
/** Indicates whether a previous page exists. */
|
|
451
|
+
hasPrevPage: boolean;
|
|
452
|
+
} | null>;
|
|
390
453
|
};
|
|
391
454
|
|
|
392
455
|
/**
|
|
@@ -450,6 +513,22 @@ declare const selectAllTransactionsByActiveWallet: <T extends Transaction>(trans
|
|
|
450
513
|
*/
|
|
451
514
|
declare const selectPendingTransactionsByActiveWallet: <T extends Transaction>(transactionsPool: TransactionPool<T>, from: string) => T[];
|
|
452
515
|
|
|
516
|
+
/**
|
|
517
|
+
* Creates an in-memory transaction store with synchronized local and remote sources.
|
|
518
|
+
*
|
|
519
|
+
* The store is designed to:
|
|
520
|
+
* - keep a local transaction pool in sync with remote history
|
|
521
|
+
* - preserve terminal transaction states
|
|
522
|
+
* - support paginated history loading
|
|
523
|
+
* - avoid duplicated merge logic across store actions
|
|
524
|
+
*
|
|
525
|
+
* @template T The transaction type.
|
|
526
|
+
* @param params Store configuration parameters.
|
|
527
|
+
* @param params.getHistory Optional remote history fetcher.
|
|
528
|
+
* @returns A Zustand vanilla store instance for in-memory transaction management.
|
|
529
|
+
*/
|
|
530
|
+
declare function createTxInMemoryStore<T extends Transaction>({ localTransactionsPool, getHistory, onHistoryFetched, }: ITxInMemoryStoreParameters<T>): zustand.StoreApi<ITxInMemoryStore<T>>;
|
|
531
|
+
|
|
453
532
|
/**
|
|
454
533
|
* Creates the main Pulsar store for transaction tracking.
|
|
455
534
|
*
|
|
@@ -582,4 +661,4 @@ type PollingTrackerConfig<R, T extends Transaction> = {
|
|
|
582
661
|
*/
|
|
583
662
|
declare function initializePollingTracker<R, T extends Transaction>(config: PollingTrackerConfig<R, T>): void;
|
|
584
663
|
|
|
585
|
-
export { type ActionTxKey, type BaseTransaction, type CheckTxTracker, type EvmTransaction, type IInitializeTxTrackingStore, type ITxTrackingStore, type InitialTransaction, type InitialTransactionParams, type PollingFetcherParams, type PollingTrackerConfig, type PulsarAdapter, type SolanaTransaction, type StarknetTransaction, type StoreSlice, type SyncCallbacks, type TrackerCallbacks, type Transaction, type TransactionPool, TransactionStatus, TransactionTracker, type TxAdapter, type UpdatableTransactionFields, createBoundedUseStore, createPulsarStore, initializePollingTracker, initializeTxTrackingStore, selectAllTransactions, selectAllTransactionsByActiveWallet, selectPendingTransactions, selectPendingTransactionsByActiveWallet, selectTxByKey };
|
|
664
|
+
export { type ActionTxKey, type BaseTransaction, type CheckTxTracker, type EvmTransaction, type IInitializeTxTrackingStore, type ITxInMemoryStore, type ITxInMemoryStoreParameters, type ITxTrackingStore, type InitialTransaction, type InitialTransactionParams, type PollingFetcherParams, type PollingTrackerConfig, type PulsarAdapter, 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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -74,8 +74,8 @@ type BaseTransaction = {
|
|
|
74
74
|
isTrackedModalOpen?: boolean;
|
|
75
75
|
/** The local timestamp (in seconds) when the transaction was initiated by the user. */
|
|
76
76
|
localTimestamp: number;
|
|
77
|
-
/**
|
|
78
|
-
payload?:
|
|
77
|
+
/** Custom data (strings or numbers) to associate with the transaction. */
|
|
78
|
+
payload?: Record<string, string | number>;
|
|
79
79
|
/** A flag indicating if the transaction is still awaiting on-chain confirmation. */
|
|
80
80
|
pending: boolean;
|
|
81
81
|
/** The final on-chain status of the transaction. */
|
|
@@ -97,6 +97,12 @@ type BaseTransaction = {
|
|
|
97
97
|
type: string;
|
|
98
98
|
/** The type of connector used to sign the transaction (e.g., 'injected', 'walletConnect'). */
|
|
99
99
|
connectorType: string;
|
|
100
|
+
/** The number of confirmations required for the transaction to be considered confirmed. */
|
|
101
|
+
requiredConfirmations?: number;
|
|
102
|
+
/** The number of confirmations received. A string value indicates a confirmed transaction, while `null` means it's pending. */
|
|
103
|
+
confirmations?: number | string | null;
|
|
104
|
+
/** The RPC URL to use for the transaction. Required for Solana transactions. */
|
|
105
|
+
rpcUrl?: string;
|
|
100
106
|
};
|
|
101
107
|
/**
|
|
102
108
|
* Represents an EVM-specific transaction, extending the base properties with EVM fields.
|
|
@@ -135,10 +141,6 @@ type SolanaTransaction = BaseTransaction & {
|
|
|
135
141
|
recentBlockhash?: string;
|
|
136
142
|
/** The slot in which the transaction was processed. */
|
|
137
143
|
slot?: number;
|
|
138
|
-
/** The number of confirmations received. A string value indicates a confirmed transaction, while `null` means it's pending. */
|
|
139
|
-
confirmations?: number | string | null;
|
|
140
|
-
/** The RPC URL used to submit and track this transaction. */
|
|
141
|
-
rpcUrl?: string;
|
|
142
144
|
};
|
|
143
145
|
/**
|
|
144
146
|
* Represents a Starknet-specific transaction, extending the base properties.
|
|
@@ -159,26 +161,16 @@ type Transaction = EvmTransaction | SolanaTransaction | StarknetTransaction;
|
|
|
159
161
|
/**
|
|
160
162
|
* Represents the parameters required to initiate a new transaction tracking flow.
|
|
161
163
|
*/
|
|
162
|
-
type InitialTransactionParams = {
|
|
164
|
+
type InitialTransactionParams = Pick<BaseTransaction, 'description' | 'title' | 'type' | 'requiredConfirmations' | 'rpcUrl' | 'payload'> & {
|
|
163
165
|
/** The specific blockchain adapter for this transaction. */
|
|
164
166
|
adapter: OrbitAdapter;
|
|
165
167
|
/** The function that executes the on-chain action (e.g., sending a transaction) and returns a preliminary identifier like a hash. */
|
|
166
168
|
actionFunction: (...args: any[]) => Promise<ActionTxKey | undefined>;
|
|
167
|
-
/** A user-facing description for the transaction. Supports state-specific descriptions. */
|
|
168
|
-
description?: string | [string, string, string, string];
|
|
169
169
|
/** The target chain ID for the transaction. */
|
|
170
170
|
desiredChainID: number | string;
|
|
171
|
-
/** Any custom data to associate with the transaction. */
|
|
172
|
-
payload?: object;
|
|
173
|
-
/** A user-facing title for the transaction. Supports state-specific titles. */
|
|
174
|
-
title?: string | [string, string, string, string];
|
|
175
|
-
/** The application-specific type of the transaction. */
|
|
176
|
-
type: string;
|
|
177
171
|
/** If true, the detailed tracking modal will open automatically upon initiation. */
|
|
178
172
|
withTrackedModal?: boolean;
|
|
179
|
-
/** The
|
|
180
|
-
rpcUrl?: string;
|
|
181
|
-
/** The transaction tracker. Required for Gelato transactions. */
|
|
173
|
+
/** The specific tracker responsible for monitoring this transaction's status. Required for Gelato tracker. */
|
|
182
174
|
tracker?: TransactionTracker;
|
|
183
175
|
};
|
|
184
176
|
/**
|
|
@@ -318,7 +310,7 @@ type TransactionPool<T extends Transaction> = Record<string, T>;
|
|
|
318
310
|
* on a transaction object via the `updateTxParams` action. This ensures type safety
|
|
319
311
|
* and prevents accidental modification of immutable properties.
|
|
320
312
|
*/
|
|
321
|
-
type UpdatableTransactionFields = Partial<Pick<EvmTransaction, 'to' | 'nonce' | 'txKey' | 'pending' | 'hash' | 'status' | 'replacedTxHash' | 'error' | 'finishedTimestamp' | 'isTrackedModalOpen' | 'isError' | 'maxPriorityFeePerGas' | 'maxFeePerGas' | 'input' | 'value'>> & Partial<Pick<SolanaTransaction, 'slot' | 'confirmations' | 'fee' | 'instructions' | 'recentBlockhash' | 'rpcUrl'>>;
|
|
313
|
+
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'>>;
|
|
322
314
|
/**
|
|
323
315
|
* The interface for the base transaction tracking store slice.
|
|
324
316
|
* It includes the state and actions for managing the transaction lifecycle.
|
|
@@ -387,6 +379,77 @@ type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
|
|
|
387
379
|
* This is essential for resuming tracking after a page reload or application restart.
|
|
388
380
|
*/
|
|
389
381
|
initializeTransactionsPool: () => Promise<void>;
|
|
382
|
+
/**
|
|
383
|
+
* Cross-device synchronization bridge.
|
|
384
|
+
* Injects remote pending transactions into the local pool and starts their lifecycle trackers.
|
|
385
|
+
* Also self-heals local pending transactions if the remote DB knows they are terminal.
|
|
386
|
+
*/
|
|
387
|
+
injectExternalPendingTxs: (remoteTxs: T[]) => Promise<void>;
|
|
388
|
+
};
|
|
389
|
+
/**
|
|
390
|
+
* Represents the structure and behavior of an in-memory pagination system
|
|
391
|
+
* for managing transaction history.
|
|
392
|
+
*/
|
|
393
|
+
type TxInMemoryPagination = {
|
|
394
|
+
/** Indicates whether the store is currently loading transaction history. */
|
|
395
|
+
isLoading: boolean;
|
|
396
|
+
/** Indicates whether the last loading request ended with an error. */
|
|
397
|
+
isError: boolean;
|
|
398
|
+
/** Indicates whether more history pages are available. */
|
|
399
|
+
hasMore: boolean;
|
|
400
|
+
/** The current page number in the paginated history. */
|
|
401
|
+
currentPage: number;
|
|
402
|
+
/** Loads the next page of transaction history and appends it to the pool. */
|
|
403
|
+
fetchNextPage: (walletAddress: string) => Promise<void>;
|
|
404
|
+
};
|
|
405
|
+
/**
|
|
406
|
+
* The complete interface for the Pulsar transaction in-memory store.
|
|
407
|
+
* It keeps a paginated remote history in sync with a local transaction pool.
|
|
408
|
+
*
|
|
409
|
+
* @template T The transaction type.
|
|
410
|
+
*/
|
|
411
|
+
type ITxInMemoryStore<T extends Transaction> = {
|
|
412
|
+
/** A pool of all transactions currently being tracked and loaded from history, indexed by `txKey`. */
|
|
413
|
+
transactionsPool: TransactionPool<T>;
|
|
414
|
+
/** Loads the first page of transaction history. */
|
|
415
|
+
fetchInitial: (walletAddress: string) => Promise<void>;
|
|
416
|
+
/** Merges a local transaction pool into the in-memory store. */
|
|
417
|
+
syncWithLocalPool: (localPool: TransactionPool<T>) => void;
|
|
418
|
+
} & TxInMemoryPagination;
|
|
419
|
+
/**
|
|
420
|
+
* Parameters used to configure and manage an in-memory transaction store.
|
|
421
|
+
*
|
|
422
|
+
* @template T The transaction type.
|
|
423
|
+
*/
|
|
424
|
+
type ITxInMemoryStoreParameters<T extends Transaction> = {
|
|
425
|
+
/** A localTransactionsPool. */
|
|
426
|
+
localTransactionsPool: TransactionPool<T>;
|
|
427
|
+
/** * Callback fired when remote history is successfully fetched.
|
|
428
|
+
* Used to inject remote pending transactions into the persistent tracking store.
|
|
429
|
+
*/
|
|
430
|
+
onHistoryFetched?: (remoteTxs: T[]) => void;
|
|
431
|
+
getHistory?: ({ page, walletAddress, }: {
|
|
432
|
+
/**
|
|
433
|
+
* Page number for pagination.
|
|
434
|
+
*
|
|
435
|
+
* @defaultValue `1`
|
|
436
|
+
*/
|
|
437
|
+
page?: number;
|
|
438
|
+
walletAddress: string;
|
|
439
|
+
}) => Promise<{
|
|
440
|
+
/** Array of transactions for the current page. */
|
|
441
|
+
docs: T[];
|
|
442
|
+
/** Total number of transactions matching the query. */
|
|
443
|
+
totalDocs: number;
|
|
444
|
+
/** Total number of available pages. */
|
|
445
|
+
totalPages: number;
|
|
446
|
+
/** Current page number. */
|
|
447
|
+
page: number;
|
|
448
|
+
/** Indicates whether a next page exists. */
|
|
449
|
+
hasNextPage: boolean;
|
|
450
|
+
/** Indicates whether a previous page exists. */
|
|
451
|
+
hasPrevPage: boolean;
|
|
452
|
+
} | null>;
|
|
390
453
|
};
|
|
391
454
|
|
|
392
455
|
/**
|
|
@@ -450,6 +513,22 @@ declare const selectAllTransactionsByActiveWallet: <T extends Transaction>(trans
|
|
|
450
513
|
*/
|
|
451
514
|
declare const selectPendingTransactionsByActiveWallet: <T extends Transaction>(transactionsPool: TransactionPool<T>, from: string) => T[];
|
|
452
515
|
|
|
516
|
+
/**
|
|
517
|
+
* Creates an in-memory transaction store with synchronized local and remote sources.
|
|
518
|
+
*
|
|
519
|
+
* The store is designed to:
|
|
520
|
+
* - keep a local transaction pool in sync with remote history
|
|
521
|
+
* - preserve terminal transaction states
|
|
522
|
+
* - support paginated history loading
|
|
523
|
+
* - avoid duplicated merge logic across store actions
|
|
524
|
+
*
|
|
525
|
+
* @template T The transaction type.
|
|
526
|
+
* @param params Store configuration parameters.
|
|
527
|
+
* @param params.getHistory Optional remote history fetcher.
|
|
528
|
+
* @returns A Zustand vanilla store instance for in-memory transaction management.
|
|
529
|
+
*/
|
|
530
|
+
declare function createTxInMemoryStore<T extends Transaction>({ localTransactionsPool, getHistory, onHistoryFetched, }: ITxInMemoryStoreParameters<T>): zustand.StoreApi<ITxInMemoryStore<T>>;
|
|
531
|
+
|
|
453
532
|
/**
|
|
454
533
|
* Creates the main Pulsar store for transaction tracking.
|
|
455
534
|
*
|
|
@@ -582,4 +661,4 @@ type PollingTrackerConfig<R, T extends Transaction> = {
|
|
|
582
661
|
*/
|
|
583
662
|
declare function initializePollingTracker<R, T extends Transaction>(config: PollingTrackerConfig<R, T>): void;
|
|
584
663
|
|
|
585
|
-
export { type ActionTxKey, type BaseTransaction, type CheckTxTracker, type EvmTransaction, type IInitializeTxTrackingStore, type ITxTrackingStore, type InitialTransaction, type InitialTransactionParams, type PollingFetcherParams, type PollingTrackerConfig, type PulsarAdapter, type SolanaTransaction, type StarknetTransaction, type StoreSlice, type SyncCallbacks, type TrackerCallbacks, type Transaction, type TransactionPool, TransactionStatus, TransactionTracker, type TxAdapter, type UpdatableTransactionFields, createBoundedUseStore, createPulsarStore, initializePollingTracker, initializeTxTrackingStore, selectAllTransactions, selectAllTransactionsByActiveWallet, selectPendingTransactions, selectPendingTransactionsByActiveWallet, selectTxByKey };
|
|
664
|
+
export { type ActionTxKey, type BaseTransaction, type CheckTxTracker, type EvmTransaction, type IInitializeTxTrackingStore, type ITxInMemoryStore, type ITxInMemoryStoreParameters, type ITxTrackingStore, type InitialTransaction, type InitialTransactionParams, type PollingFetcherParams, type PollingTrackerConfig, type PulsarAdapter, 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 };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var immer=require('immer'),orbitCore=require('@tuwaio/orbit-core'),
|
|
1
|
+
'use strict';var immer=require('immer'),vanilla=require('zustand/vanilla'),orbitCore=require('@tuwaio/orbit-core'),D=require('dayjs'),middleware=require('zustand/middleware'),zustand=require('zustand');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var D__default=/*#__PURE__*/_interopDefault(D);function E({maxTransactions:o,onRemoteCreate:t}){return (s,p)=>({transactionsPool:{},lastAddedTxKey:void 0,initialTx:void 0,addTxToPool:a=>{let e={...a,pending:true};s(n=>immer.produce(n,r=>{if(r.lastAddedTxKey=a.txKey,a.txKey){if(Object.keys(r.transactionsPool).length>=o){let l=Object.values(r.transactionsPool).sort((T,c)=>T.localTimestamp-c.localTimestamp);if(l.length>0){let T=l[0];delete r.transactionsPool[T.txKey];}}r.transactionsPool[a.txKey]=e;}})),t&&t(e).catch(n=>console.error("[Pulsar Sync] Create failed:",n));},updateTxParams:(a,e)=>{s(n=>immer.produce(n,r=>{let i=r.transactionsPool[a];i&&Object.assign(i,e);}));},removeTxFromPool:a=>{s(e=>immer.produce(e,n=>{delete n.transactionsPool[a];}));},closeTxTrackedModal:a=>{s(e=>immer.produce(e,n=>{if(a&&n.transactionsPool[a]){let r=n.transactionsPool[a];n.transactionsPool[a]={...r,isTrackedModalOpen:false};}n.initialTx=void 0;}));},getLastTxKey:()=>p().lastAddedTxKey})}var F=o=>Object.values(o).sort((t,s)=>Number(t.localTimestamp)-Number(s.localTimestamp)),Y=o=>F(o).filter(t=>t.pending),Z=(o,t)=>o[t],B=(o,t)=>F(o).filter(s=>s.from.toLowerCase()===t.toLowerCase()),ee=(o,t)=>B(o,t).filter(s=>s.pending);var N=(a=>(a.Ethereum="ethereum",a.Safe="safe",a.Gelato="gelato",a.Solana="solana",a))(N||{}),A=(p=>(p.Failed="Failed",p.Success="Success",p.Replaced="Replaced",p))(A||{});var $=o=>o==="Success"||o==="Replaced",M=(o,t)=>{let s=o[t.txKey];return $(s?.status)?false:(o[t.txKey]=t,true)};function Te({localTransactionsPool:o,getHistory:t,onHistoryFetched:s}){immer.setAutoFreeze(false);let p=e=>({isLoading:e,isError:false}),a=e=>e?(s&&queueMicrotask(()=>s(e.docs)),n=>immer.produce(n,r=>{let i=r.transactionsPool;for(let l of e.docs)M(i,l);r.currentPage=e.page,r.hasMore=e.hasNextPage,r.isLoading=false;})):n=>n;return vanilla.createStore()((e,n)=>({transactionsPool:o,isLoading:false,isError:false,hasMore:false,currentPage:1,syncWithLocalPool:r=>{e(i=>immer.produce(i,l=>{let T=l.transactionsPool;for(let c of Object.values(r))M(T,c);}));},fetchInitial:async r=>{if(!(!t||!r)){e(p(true));try{let i=await t({page:1,walletAddress:r});e(a(i));}catch(i){console.error("[Pulsar] Failed to fetch initial transaction history:",i),e({isLoading:false,isError:true});}}},fetchNextPage:async r=>{let{hasMore:i,isLoading:l,currentPage:T}=n();if(!(!t||!i||l||!r)){e(p(true));try{let c=T+1,m=await t({page:c,walletAddress:r});e(a(m));}catch(c){console.error(`[Pulsar] Failed to fetch transaction history page ${T+1}:`,c),e({isLoading:false,isError:true});}}}}))}function Ae({adapter:o,maxTransactions:t=50,onRemoteCreate:s,gelatoApiKey:p,...a}){return vanilla.createStore()(middleware.persist((e,n)=>({...E({maxTransactions:t,onRemoteCreate:s})(e,n),getAdapter:()=>o,initializeTransactionsPool:async()=>{let r=Object.values(n().transactionsPool).filter(i=>i.pending);await Promise.all(r.map(i=>orbitCore.selectAdapterByKey({adapterKey:i.adapter,adapter:o})?.checkAndInitializeTrackerInStore({tx:i,gelatoApiKey:p,...n()})));},injectExternalPendingTxs:async r=>{let l=n().getAdapter(),T=[];e(c=>immer.produce(c,m=>{let g=m.transactionsPool;r.forEach(d=>{let x=g[d.txKey];d.pending&&!x&&(g[d.txKey]=d,T.push(d));let S=d.status==="Success"||d.status==="Failed"||d.status==="Replaced";x?.pending&&S&&(x.status=d.status,x.pending=false,d.txKey&&(x.txKey=d.txKey),d.finishedTimestamp&&(x.finishedTimestamp=d.finishedTimestamp));});})),T.length>0&&await Promise.all(T.map(c=>orbitCore.selectAdapterByKey({adapterKey:c.adapter,adapter:l})?.checkAndInitializeTrackerInStore({tx:c,gelatoApiKey:p,...n()})));},executeTxAction:async({defaultTracker:r,actionFunction:i,params:l,...T})=>{let{desiredChainID:c,tracker:m,...g}=l,{onSuccess:d,onError:x,onReplaced:S}=T,K=D__default.default().unix();e({initialTx:{...l,actionFunction:i,localTimestamp:K,isInitializing:true}});let f=orbitCore.selectAdapterByKey({adapterKey:g.adapter,adapter:o}),w=u=>{e(k=>immer.produce(k,P=>{P.initialTx&&(P.initialTx.isInitializing=false,P.initialTx.error=orbitCore.normalizeError(u));}));};if(!f){let u=new Error("No adapter found for this transaction.");throw w(u),u}try{let{connectorType:u,walletAddress:k}=f.getConnectorInfo();await f.checkChainForTx(c);let P=await i();if(!P){e({initialTx:void 0});return}let{tracker:R,txKey:h}=f.checkTransactionsTracker({actionTxKey:P,connectorType:u,tracker:m,gelatoApiKey:p}),O={...g,connectorType:u,from:k,tracker:R||r,chainId:orbitCore.setChainId(c),localTimestamp:K,txKey:h,hash:R==="ethereum"?P:void 0,pending:!1,isTrackedModalOpen:l.withTrackedModal};n().addTxToPool(O),e(L=>immer.produce(L,I=>{I.initialTx&&(I.initialTx.isInitializing=!1,I.initialTx.lastTxKey=h);}));let z=n().transactionsPool[h];await f.checkAndInitializeTrackerInStore({tx:z,onSuccess:d,onError:x,onReplaced:S,gelatoApiKey:p,...n()});}catch(u){throw w(u),u}}}),{...a}))}var we=(o=>t=>zustand.useStore(o,t));var V=5e3,X=10;function Ee(o){let{tx:t,fetcher:s,onInitialize:p,onSuccess:a,onFailure:e,onIntervalTick:n,onReplaced:r,removeTxFromPool:i,pollingInterval:l=V,maxRetries:T=X}=o;if(!t.pending)return;p?.();let c=T,m=true,g=x=>{m&&(m=false,i&&!x?.withoutRemoving&&i(t.txKey));};(async()=>{for(;m&&c>0;)try{if(await new Promise(x=>setTimeout(x,l)),!m)break;await s({tx:t,stopPolling:g,onSuccess:a,onFailure:e,onIntervalTick:n,onReplaced:r});}catch(x){console.error(`Polling fetcher for txKey ${t.txKey} threw an error:`,x),c--;}c<=0&&(console.warn(`Polling for txKey ${t.txKey} stopped after reaching the maximum number of retries.`),e(),g());})();}exports.TransactionStatus=A;exports.TransactionTracker=N;exports.createBoundedUseStore=we;exports.createPulsarStore=Ae;exports.createTxInMemoryStore=Te;exports.initializePollingTracker=Ee;exports.initializeTxTrackingStore=E;exports.selectAllTransactions=F;exports.selectAllTransactionsByActiveWallet=B;exports.selectPendingTransactions=Y;exports.selectPendingTransactionsByActiveWallet=ee;exports.selectTxByKey=Z;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {produce}from'immer';import {selectAdapterByKey,setChainId,normalizeError}from'@tuwaio/orbit-core';import
|
|
1
|
+
import {produce,setAutoFreeze}from'immer';import {createStore}from'zustand/vanilla';import {selectAdapterByKey,setChainId,normalizeError}from'@tuwaio/orbit-core';import D from'dayjs';import {persist}from'zustand/middleware';import {useStore}from'zustand';function E({maxTransactions:o,onRemoteCreate:t}){return (s,p)=>({transactionsPool:{},lastAddedTxKey:void 0,initialTx:void 0,addTxToPool:a=>{let e={...a,pending:true};s(n=>produce(n,r=>{if(r.lastAddedTxKey=a.txKey,a.txKey){if(Object.keys(r.transactionsPool).length>=o){let l=Object.values(r.transactionsPool).sort((T,c)=>T.localTimestamp-c.localTimestamp);if(l.length>0){let T=l[0];delete r.transactionsPool[T.txKey];}}r.transactionsPool[a.txKey]=e;}})),t&&t(e).catch(n=>console.error("[Pulsar Sync] Create failed:",n));},updateTxParams:(a,e)=>{s(n=>produce(n,r=>{let i=r.transactionsPool[a];i&&Object.assign(i,e);}));},removeTxFromPool:a=>{s(e=>produce(e,n=>{delete n.transactionsPool[a];}));},closeTxTrackedModal:a=>{s(e=>produce(e,n=>{if(a&&n.transactionsPool[a]){let r=n.transactionsPool[a];n.transactionsPool[a]={...r,isTrackedModalOpen:false};}n.initialTx=void 0;}));},getLastTxKey:()=>p().lastAddedTxKey})}var F=o=>Object.values(o).sort((t,s)=>Number(t.localTimestamp)-Number(s.localTimestamp)),Y=o=>F(o).filter(t=>t.pending),Z=(o,t)=>o[t],B=(o,t)=>F(o).filter(s=>s.from.toLowerCase()===t.toLowerCase()),ee=(o,t)=>B(o,t).filter(s=>s.pending);var N=(a=>(a.Ethereum="ethereum",a.Safe="safe",a.Gelato="gelato",a.Solana="solana",a))(N||{}),A=(p=>(p.Failed="Failed",p.Success="Success",p.Replaced="Replaced",p))(A||{});var $=o=>o==="Success"||o==="Replaced",M=(o,t)=>{let s=o[t.txKey];return $(s?.status)?false:(o[t.txKey]=t,true)};function Te({localTransactionsPool:o,getHistory:t,onHistoryFetched:s}){setAutoFreeze(false);let p=e=>({isLoading:e,isError:false}),a=e=>e?(s&&queueMicrotask(()=>s(e.docs)),n=>produce(n,r=>{let i=r.transactionsPool;for(let l of e.docs)M(i,l);r.currentPage=e.page,r.hasMore=e.hasNextPage,r.isLoading=false;})):n=>n;return createStore()((e,n)=>({transactionsPool:o,isLoading:false,isError:false,hasMore:false,currentPage:1,syncWithLocalPool:r=>{e(i=>produce(i,l=>{let T=l.transactionsPool;for(let c of Object.values(r))M(T,c);}));},fetchInitial:async r=>{if(!(!t||!r)){e(p(true));try{let i=await t({page:1,walletAddress:r});e(a(i));}catch(i){console.error("[Pulsar] Failed to fetch initial transaction history:",i),e({isLoading:false,isError:true});}}},fetchNextPage:async r=>{let{hasMore:i,isLoading:l,currentPage:T}=n();if(!(!t||!i||l||!r)){e(p(true));try{let c=T+1,m=await t({page:c,walletAddress:r});e(a(m));}catch(c){console.error(`[Pulsar] Failed to fetch transaction history page ${T+1}:`,c),e({isLoading:false,isError:true});}}}}))}function Ae({adapter:o,maxTransactions:t=50,onRemoteCreate:s,gelatoApiKey:p,...a}){return createStore()(persist((e,n)=>({...E({maxTransactions:t,onRemoteCreate:s})(e,n),getAdapter:()=>o,initializeTransactionsPool:async()=>{let r=Object.values(n().transactionsPool).filter(i=>i.pending);await Promise.all(r.map(i=>selectAdapterByKey({adapterKey:i.adapter,adapter:o})?.checkAndInitializeTrackerInStore({tx:i,gelatoApiKey:p,...n()})));},injectExternalPendingTxs:async r=>{let l=n().getAdapter(),T=[];e(c=>produce(c,m=>{let g=m.transactionsPool;r.forEach(d=>{let x=g[d.txKey];d.pending&&!x&&(g[d.txKey]=d,T.push(d));let S=d.status==="Success"||d.status==="Failed"||d.status==="Replaced";x?.pending&&S&&(x.status=d.status,x.pending=false,d.txKey&&(x.txKey=d.txKey),d.finishedTimestamp&&(x.finishedTimestamp=d.finishedTimestamp));});})),T.length>0&&await Promise.all(T.map(c=>selectAdapterByKey({adapterKey:c.adapter,adapter:l})?.checkAndInitializeTrackerInStore({tx:c,gelatoApiKey:p,...n()})));},executeTxAction:async({defaultTracker:r,actionFunction:i,params:l,...T})=>{let{desiredChainID:c,tracker:m,...g}=l,{onSuccess:d,onError:x,onReplaced:S}=T,K=D().unix();e({initialTx:{...l,actionFunction:i,localTimestamp:K,isInitializing:true}});let f=selectAdapterByKey({adapterKey:g.adapter,adapter:o}),w=u=>{e(k=>produce(k,P=>{P.initialTx&&(P.initialTx.isInitializing=false,P.initialTx.error=normalizeError(u));}));};if(!f){let u=new Error("No adapter found for this transaction.");throw w(u),u}try{let{connectorType:u,walletAddress:k}=f.getConnectorInfo();await f.checkChainForTx(c);let P=await i();if(!P){e({initialTx:void 0});return}let{tracker:R,txKey:h}=f.checkTransactionsTracker({actionTxKey:P,connectorType:u,tracker:m,gelatoApiKey:p}),O={...g,connectorType:u,from:k,tracker:R||r,chainId:setChainId(c),localTimestamp:K,txKey:h,hash:R==="ethereum"?P:void 0,pending:!1,isTrackedModalOpen:l.withTrackedModal};n().addTxToPool(O),e(L=>produce(L,I=>{I.initialTx&&(I.initialTx.isInitializing=!1,I.initialTx.lastTxKey=h);}));let z=n().transactionsPool[h];await f.checkAndInitializeTrackerInStore({tx:z,onSuccess:d,onError:x,onReplaced:S,gelatoApiKey:p,...n()});}catch(u){throw w(u),u}}}),{...a}))}var we=(o=>t=>useStore(o,t));var V=5e3,X=10;function Ee(o){let{tx:t,fetcher:s,onInitialize:p,onSuccess:a,onFailure:e,onIntervalTick:n,onReplaced:r,removeTxFromPool:i,pollingInterval:l=V,maxRetries:T=X}=o;if(!t.pending)return;p?.();let c=T,m=true,g=x=>{m&&(m=false,i&&!x?.withoutRemoving&&i(t.txKey));};(async()=>{for(;m&&c>0;)try{if(await new Promise(x=>setTimeout(x,l)),!m)break;await s({tx:t,stopPolling:g,onSuccess:a,onFailure:e,onIntervalTick:n,onReplaced:r});}catch(x){console.error(`Polling fetcher for txKey ${t.txKey} threw an error:`,x),c--;}c<=0&&(console.warn(`Polling for txKey ${t.txKey} stopped after reaching the maximum number of retries.`),e(),g());})();}export{A as TransactionStatus,N as TransactionTracker,we as createBoundedUseStore,Ae as createPulsarStore,Te as createTxInMemoryStore,Ee as initializePollingTracker,E as initializeTxTrackingStore,F as selectAllTransactions,B as selectAllTransactionsByActiveWallet,Y as selectPendingTransactions,ee as selectPendingTransactionsByActiveWallet,Z as selectTxByKey};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuwaio/pulsar-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Oleksandr Tkach",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -40,18 +40,18 @@
|
|
|
40
40
|
}
|
|
41
41
|
],
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@tuwaio/orbit-core": ">=0.2.
|
|
43
|
+
"@tuwaio/orbit-core": ">=0.2.8",
|
|
44
44
|
"dayjs": "1.x.x",
|
|
45
45
|
"immer": "11.x.x",
|
|
46
46
|
"zustand": "5.x.x"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@tuwaio/orbit-core": "^0.2.
|
|
50
|
-
"dayjs": "^1.11.
|
|
49
|
+
"@tuwaio/orbit-core": "^0.2.8",
|
|
50
|
+
"dayjs": "^1.11.20",
|
|
51
51
|
"immer": "^11.1.4",
|
|
52
52
|
"tsup": "^8.5.1",
|
|
53
|
-
"typescript": "^
|
|
54
|
-
"zustand": "^5.0.
|
|
53
|
+
"typescript": "^6.0.3",
|
|
54
|
+
"zustand": "^5.0.12"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"start": "tsup src/index.ts --watch",
|