@tuwaio/pulsar-core 0.4.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { OrbitAdapter, BaseAdapter, OrbitGenericAdapter } from '@tuwaio/orbit-core';
1
+ import { TuwaErrorState, OrbitAdapter, BaseAdapter, OrbitGenericAdapter } from '@tuwaio/orbit-core';
2
2
  import * as zustand from 'zustand';
3
3
  import { StoreApi } from 'zustand';
4
4
  import { PersistOptions } from 'zustand/middleware';
@@ -34,13 +34,6 @@ declare enum TransactionStatus {
34
34
  /** The transaction was replaced by another with the same nonce (e.g., a speed-up or cancel). */
35
35
  Replaced = "Replaced"
36
36
  }
37
- /**
38
- * Defines the shape of the identifier for a Gelato transaction task.
39
- */
40
- type GelatoTxKey = {
41
- /** The unique identifier assigned by the Gelato relay service. */
42
- taskId: string;
43
- };
44
37
  /**
45
38
  * A union type representing the unique identifier returned by an `actionFunction`
46
39
  * after a transaction is submitted to the network or a relay service.
@@ -50,10 +43,9 @@ type GelatoTxKey = {
50
43
  *
51
44
  * It can be one of the following:
52
45
  * - A standard `0x...` transaction hash (`Hex`).
53
- * - A structured object from a relay service like Gelato (`GelatoTxKey`).
54
46
  * - A Solana transaction signature (string).
55
47
  */
56
- type ActionTxKey = `0x${string}` | GelatoTxKey | string;
48
+ type ActionTxKey = `0x${string}` | string;
57
49
  /**
58
50
  * The fundamental structure for any transaction being tracked by Pulsar.
59
51
  * This serves as the base upon which chain-specific transaction types are built.
@@ -70,8 +62,8 @@ type BaseTransaction = {
70
62
  * description: ['Swapping...', 'Swapped Successfully', 'Swap Failed', 'Swap Replaced']
71
63
  */
72
64
  description?: string | [string, string, string, string];
73
- /** The error message if the transaction failed. */
74
- errorMessage?: string;
65
+ /** The error state if the transaction failed, containing message and raw error details. */
66
+ error?: TuwaErrorState;
75
67
  /** The on-chain timestamp (in seconds) when the transaction was finalized. */
76
68
  finishedTimestamp?: number;
77
69
  /** The sender's wallet address. */
@@ -186,14 +178,16 @@ type InitialTransactionParams = {
186
178
  withTrackedModal?: boolean;
187
179
  /** The RPC URL to use for the transaction. Required for Solana transactions. */
188
180
  rpcUrl?: string;
181
+ /** The transaction tracker. Required for Gelato transactions. */
182
+ tracker?: TransactionTracker;
189
183
  };
190
184
  /**
191
185
  * Represents a transaction in its temporary, pre-submission state.
192
186
  * This is used for UI feedback while the transaction is being signed and sent.
193
187
  */
194
188
  type InitialTransaction = InitialTransactionParams & {
195
- /** An error message if the initialization fails (e.g., user rejects signature). */
196
- errorMessage?: string;
189
+ /** Normalized error if the initialization fails (e.g., user rejects signature). */
190
+ error?: TuwaErrorState;
197
191
  /** A flag indicating if the transaction is being processed (e.g., waiting for signature). */
198
192
  isInitializing: boolean;
199
193
  /** The `txKey` of the on-chain transaction that this action produced, used for linking the states. */
@@ -211,20 +205,38 @@ interface TrackerCallbacks<T extends Transaction> {
211
205
  onReplaced?: (newTx: T, oldTx: T) => Promise<void> | void;
212
206
  }
213
207
  /**
214
- * @deprecated Use `TrackerCallbacks<T>` instead.
215
- * Defines a callback function to be executed upon a successful transaction.
216
- * @template T The specific transaction type, extending `Transaction`.
208
+ * Callbacks for synchronizing local transaction state with a remote backend.
209
+ * These are injected into the store at creation time.
217
210
  */
218
- type OnSuccessCallback<T extends Transaction> = {
219
- /** Callback to execute when the transaction is successfully submitted. */
220
- onSuccessCallback?: (tx: T) => Promise<void> | void;
221
- };
211
+ interface SyncCallbacks<T extends Transaction> {
212
+ /**
213
+ * Called immediately after a transaction is created locally (added to pool).
214
+ * Use this to POST the active pending transaction to the backend.
215
+ */
216
+ onRemoteCreate?: (tx: T) => Promise<void>;
217
+ }
222
218
  /**
223
219
  * The configuration object containing one or more transaction adapters.
224
220
  * @template T The specific transaction type.
225
221
  */
226
222
  type PulsarAdapter<T extends Transaction> = OrbitGenericAdapter<TxAdapter<T>> & {
227
223
  maxTransactions?: number;
224
+ gelatoApiKey?: string;
225
+ } & SyncCallbacks<T>;
226
+ /**
227
+ * Represents a tracker for a specific transaction tied to an action and a connector.
228
+ *
229
+ * @typedef {Object} CheckTxTracker
230
+ * @property {ActionTxKey} actionTxKey - The key identifying the specific action related to the transaction.
231
+ * @property {string} connectorType - The type of connector used for the transaction (e.g., wallet provider, blockchain interface).
232
+ * @property {TransactionTracker} [tracker] - An optional tracker object that monitors the status and progress of the transaction.
233
+ * @property {string} [gelatoApiKey] - An optional Gelato API key for Gelato relayer integration.
234
+ */
235
+ type CheckTxTracker = {
236
+ actionTxKey: ActionTxKey;
237
+ connectorType: string;
238
+ tracker?: TransactionTracker;
239
+ gelatoApiKey?: string;
228
240
  };
229
241
  /**
230
242
  * Defines the interface for a transaction adapter, which provides chain-specific logic and utilities.
@@ -250,11 +262,9 @@ type TxAdapter<T extends Transaction> = Pick<BaseAdapter, 'getExplorerUrl'> & {
250
262
  checkChainForTx: (chainId: string | number) => Promise<void>;
251
263
  /**
252
264
  * Determines the appropriate tracker and final `txKey` from the result of an action.
253
- * @param actionTxKey The preliminary key returned after an action function is executed.
254
- * @param connectorType The type of connector used for the transaction.
255
265
  * @returns An object containing the final `txKey` and the `TransactionTracker` to be used.
256
266
  */
257
- checkTransactionsTracker: (actionTxKey: ActionTxKey, connectorType: string) => {
267
+ checkTransactionsTracker: ({ actionTxKey, connectorType, tracker }: CheckTxTracker) => {
258
268
  txKey: string;
259
269
  tracker: TransactionTracker;
260
270
  };
@@ -264,6 +274,7 @@ type TxAdapter<T extends Transaction> = Pick<BaseAdapter, 'getExplorerUrl'> & {
264
274
  */
265
275
  checkAndInitializeTrackerInStore: (params: {
266
276
  tx: T;
277
+ gelatoApiKey?: string;
267
278
  } & TrackerCallbacks<T> & Pick<ITxTrackingStore<T>, 'updateTxParams' | 'removeTxFromPool' | 'transactionsPool'>) => Promise<void> | void;
268
279
  /**
269
280
  * Optional: Logic to cancel a pending EVM transaction.
@@ -307,7 +318,7 @@ type TransactionPool<T extends Transaction> = Record<string, T>;
307
318
  * on a transaction object via the `updateTxParams` action. This ensures type safety
308
319
  * and prevents accidental modification of immutable properties.
309
320
  */
310
- type UpdatableTransactionFields = Partial<Pick<EvmTransaction, 'to' | 'nonce' | 'txKey' | 'pending' | 'hash' | 'status' | 'replacedTxHash' | 'errorMessage' | 'finishedTimestamp' | 'isTrackedModalOpen' | 'isError' | 'maxPriorityFeePerGas' | 'maxFeePerGas' | 'input' | 'value'>> & Partial<Pick<SolanaTransaction, 'slot' | 'confirmations' | 'fee' | 'instructions' | 'recentBlockhash' | 'rpcUrl'>>;
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'>>;
311
322
  /**
312
323
  * The interface for the base transaction tracking store slice.
313
324
  * It includes the state and actions for managing the transaction lifecycle.
@@ -391,7 +402,7 @@ type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
391
402
  * @param options Configuration for the store slice.
392
403
  * @returns A Zustand store slice implementing `IInitializeTxTrackingStore`.
393
404
  */
394
- declare function initializeTxTrackingStore<T extends Transaction>({ maxTransactions, }: {
405
+ declare function initializeTxTrackingStore<T extends Transaction>({ maxTransactions, onRemoteCreate, }: Pick<PulsarAdapter<T>, 'onRemoteCreate'> & {
395
406
  maxTransactions: number;
396
407
  }): StoreSlice<IInitializeTxTrackingStore<T>>;
397
408
 
@@ -453,7 +464,7 @@ declare const selectPendingTransactionsByActiveWallet: <T extends Transaction>(t
453
464
  * @param options Configuration for the Zustand `persist` middleware.
454
465
  * @returns A fully configured Zustand store instance.
455
466
  */
456
- declare function createPulsarStore<T extends Transaction>({ adapter, maxTransactions, ...options }: PulsarAdapter<T> & PersistOptions<ITxTrackingStore<T>>): Omit<zustand.StoreApi<ITxTrackingStore<T>>, "setState" | "persist"> & {
467
+ declare function createPulsarStore<T extends Transaction>({ adapter, maxTransactions, onRemoteCreate, gelatoApiKey, ...options }: PulsarAdapter<T> & PersistOptions<ITxTrackingStore<T>>): Omit<zustand.StoreApi<ITxTrackingStore<T>>, "setState" | "persist"> & {
457
468
  setState(partial: ITxTrackingStore<T> | Partial<ITxTrackingStore<T>> | ((state: ITxTrackingStore<T>) => ITxTrackingStore<T> | Partial<ITxTrackingStore<T>>), replace?: false | undefined): unknown;
458
469
  setState(state: ITxTrackingStore<T> | ((state: ITxTrackingStore<T>) => ITxTrackingStore<T>), replace: true): unknown;
459
470
  persist: {
@@ -571,4 +582,4 @@ type PollingTrackerConfig<R, T extends Transaction> = {
571
582
  */
572
583
  declare function initializePollingTracker<R, T extends Transaction>(config: PollingTrackerConfig<R, T>): void;
573
584
 
574
- export { type ActionTxKey, type BaseTransaction, type EvmTransaction, type GelatoTxKey, type IInitializeTxTrackingStore, type ITxTrackingStore, type InitialTransaction, type InitialTransactionParams, type OnSuccessCallback, type PollingFetcherParams, type PollingTrackerConfig, type PulsarAdapter, type SolanaTransaction, type StarknetTransaction, type StoreSlice, type TrackerCallbacks, type Transaction, type TransactionPool, TransactionStatus, TransactionTracker, type TxAdapter, createBoundedUseStore, createPulsarStore, initializePollingTracker, initializeTxTrackingStore, selectAllTransactions, selectAllTransactionsByActiveWallet, selectPendingTransactions, selectPendingTransactionsByActiveWallet, selectTxByKey };
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 };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { OrbitAdapter, BaseAdapter, OrbitGenericAdapter } from '@tuwaio/orbit-core';
1
+ import { TuwaErrorState, OrbitAdapter, BaseAdapter, OrbitGenericAdapter } from '@tuwaio/orbit-core';
2
2
  import * as zustand from 'zustand';
3
3
  import { StoreApi } from 'zustand';
4
4
  import { PersistOptions } from 'zustand/middleware';
@@ -34,13 +34,6 @@ declare enum TransactionStatus {
34
34
  /** The transaction was replaced by another with the same nonce (e.g., a speed-up or cancel). */
35
35
  Replaced = "Replaced"
36
36
  }
37
- /**
38
- * Defines the shape of the identifier for a Gelato transaction task.
39
- */
40
- type GelatoTxKey = {
41
- /** The unique identifier assigned by the Gelato relay service. */
42
- taskId: string;
43
- };
44
37
  /**
45
38
  * A union type representing the unique identifier returned by an `actionFunction`
46
39
  * after a transaction is submitted to the network or a relay service.
@@ -50,10 +43,9 @@ type GelatoTxKey = {
50
43
  *
51
44
  * It can be one of the following:
52
45
  * - A standard `0x...` transaction hash (`Hex`).
53
- * - A structured object from a relay service like Gelato (`GelatoTxKey`).
54
46
  * - A Solana transaction signature (string).
55
47
  */
56
- type ActionTxKey = `0x${string}` | GelatoTxKey | string;
48
+ type ActionTxKey = `0x${string}` | string;
57
49
  /**
58
50
  * The fundamental structure for any transaction being tracked by Pulsar.
59
51
  * This serves as the base upon which chain-specific transaction types are built.
@@ -70,8 +62,8 @@ type BaseTransaction = {
70
62
  * description: ['Swapping...', 'Swapped Successfully', 'Swap Failed', 'Swap Replaced']
71
63
  */
72
64
  description?: string | [string, string, string, string];
73
- /** The error message if the transaction failed. */
74
- errorMessage?: string;
65
+ /** The error state if the transaction failed, containing message and raw error details. */
66
+ error?: TuwaErrorState;
75
67
  /** The on-chain timestamp (in seconds) when the transaction was finalized. */
76
68
  finishedTimestamp?: number;
77
69
  /** The sender's wallet address. */
@@ -186,14 +178,16 @@ type InitialTransactionParams = {
186
178
  withTrackedModal?: boolean;
187
179
  /** The RPC URL to use for the transaction. Required for Solana transactions. */
188
180
  rpcUrl?: string;
181
+ /** The transaction tracker. Required for Gelato transactions. */
182
+ tracker?: TransactionTracker;
189
183
  };
190
184
  /**
191
185
  * Represents a transaction in its temporary, pre-submission state.
192
186
  * This is used for UI feedback while the transaction is being signed and sent.
193
187
  */
194
188
  type InitialTransaction = InitialTransactionParams & {
195
- /** An error message if the initialization fails (e.g., user rejects signature). */
196
- errorMessage?: string;
189
+ /** Normalized error if the initialization fails (e.g., user rejects signature). */
190
+ error?: TuwaErrorState;
197
191
  /** A flag indicating if the transaction is being processed (e.g., waiting for signature). */
198
192
  isInitializing: boolean;
199
193
  /** The `txKey` of the on-chain transaction that this action produced, used for linking the states. */
@@ -211,20 +205,38 @@ interface TrackerCallbacks<T extends Transaction> {
211
205
  onReplaced?: (newTx: T, oldTx: T) => Promise<void> | void;
212
206
  }
213
207
  /**
214
- * @deprecated Use `TrackerCallbacks<T>` instead.
215
- * Defines a callback function to be executed upon a successful transaction.
216
- * @template T The specific transaction type, extending `Transaction`.
208
+ * Callbacks for synchronizing local transaction state with a remote backend.
209
+ * These are injected into the store at creation time.
217
210
  */
218
- type OnSuccessCallback<T extends Transaction> = {
219
- /** Callback to execute when the transaction is successfully submitted. */
220
- onSuccessCallback?: (tx: T) => Promise<void> | void;
221
- };
211
+ interface SyncCallbacks<T extends Transaction> {
212
+ /**
213
+ * Called immediately after a transaction is created locally (added to pool).
214
+ * Use this to POST the active pending transaction to the backend.
215
+ */
216
+ onRemoteCreate?: (tx: T) => Promise<void>;
217
+ }
222
218
  /**
223
219
  * The configuration object containing one or more transaction adapters.
224
220
  * @template T The specific transaction type.
225
221
  */
226
222
  type PulsarAdapter<T extends Transaction> = OrbitGenericAdapter<TxAdapter<T>> & {
227
223
  maxTransactions?: number;
224
+ gelatoApiKey?: string;
225
+ } & SyncCallbacks<T>;
226
+ /**
227
+ * Represents a tracker for a specific transaction tied to an action and a connector.
228
+ *
229
+ * @typedef {Object} CheckTxTracker
230
+ * @property {ActionTxKey} actionTxKey - The key identifying the specific action related to the transaction.
231
+ * @property {string} connectorType - The type of connector used for the transaction (e.g., wallet provider, blockchain interface).
232
+ * @property {TransactionTracker} [tracker] - An optional tracker object that monitors the status and progress of the transaction.
233
+ * @property {string} [gelatoApiKey] - An optional Gelato API key for Gelato relayer integration.
234
+ */
235
+ type CheckTxTracker = {
236
+ actionTxKey: ActionTxKey;
237
+ connectorType: string;
238
+ tracker?: TransactionTracker;
239
+ gelatoApiKey?: string;
228
240
  };
229
241
  /**
230
242
  * Defines the interface for a transaction adapter, which provides chain-specific logic and utilities.
@@ -250,11 +262,9 @@ type TxAdapter<T extends Transaction> = Pick<BaseAdapter, 'getExplorerUrl'> & {
250
262
  checkChainForTx: (chainId: string | number) => Promise<void>;
251
263
  /**
252
264
  * Determines the appropriate tracker and final `txKey` from the result of an action.
253
- * @param actionTxKey The preliminary key returned after an action function is executed.
254
- * @param connectorType The type of connector used for the transaction.
255
265
  * @returns An object containing the final `txKey` and the `TransactionTracker` to be used.
256
266
  */
257
- checkTransactionsTracker: (actionTxKey: ActionTxKey, connectorType: string) => {
267
+ checkTransactionsTracker: ({ actionTxKey, connectorType, tracker }: CheckTxTracker) => {
258
268
  txKey: string;
259
269
  tracker: TransactionTracker;
260
270
  };
@@ -264,6 +274,7 @@ type TxAdapter<T extends Transaction> = Pick<BaseAdapter, 'getExplorerUrl'> & {
264
274
  */
265
275
  checkAndInitializeTrackerInStore: (params: {
266
276
  tx: T;
277
+ gelatoApiKey?: string;
267
278
  } & TrackerCallbacks<T> & Pick<ITxTrackingStore<T>, 'updateTxParams' | 'removeTxFromPool' | 'transactionsPool'>) => Promise<void> | void;
268
279
  /**
269
280
  * Optional: Logic to cancel a pending EVM transaction.
@@ -307,7 +318,7 @@ type TransactionPool<T extends Transaction> = Record<string, T>;
307
318
  * on a transaction object via the `updateTxParams` action. This ensures type safety
308
319
  * and prevents accidental modification of immutable properties.
309
320
  */
310
- type UpdatableTransactionFields = Partial<Pick<EvmTransaction, 'to' | 'nonce' | 'txKey' | 'pending' | 'hash' | 'status' | 'replacedTxHash' | 'errorMessage' | 'finishedTimestamp' | 'isTrackedModalOpen' | 'isError' | 'maxPriorityFeePerGas' | 'maxFeePerGas' | 'input' | 'value'>> & Partial<Pick<SolanaTransaction, 'slot' | 'confirmations' | 'fee' | 'instructions' | 'recentBlockhash' | 'rpcUrl'>>;
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'>>;
311
322
  /**
312
323
  * The interface for the base transaction tracking store slice.
313
324
  * It includes the state and actions for managing the transaction lifecycle.
@@ -391,7 +402,7 @@ type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
391
402
  * @param options Configuration for the store slice.
392
403
  * @returns A Zustand store slice implementing `IInitializeTxTrackingStore`.
393
404
  */
394
- declare function initializeTxTrackingStore<T extends Transaction>({ maxTransactions, }: {
405
+ declare function initializeTxTrackingStore<T extends Transaction>({ maxTransactions, onRemoteCreate, }: Pick<PulsarAdapter<T>, 'onRemoteCreate'> & {
395
406
  maxTransactions: number;
396
407
  }): StoreSlice<IInitializeTxTrackingStore<T>>;
397
408
 
@@ -453,7 +464,7 @@ declare const selectPendingTransactionsByActiveWallet: <T extends Transaction>(t
453
464
  * @param options Configuration for the Zustand `persist` middleware.
454
465
  * @returns A fully configured Zustand store instance.
455
466
  */
456
- declare function createPulsarStore<T extends Transaction>({ adapter, maxTransactions, ...options }: PulsarAdapter<T> & PersistOptions<ITxTrackingStore<T>>): Omit<zustand.StoreApi<ITxTrackingStore<T>>, "setState" | "persist"> & {
467
+ declare function createPulsarStore<T extends Transaction>({ adapter, maxTransactions, onRemoteCreate, gelatoApiKey, ...options }: PulsarAdapter<T> & PersistOptions<ITxTrackingStore<T>>): Omit<zustand.StoreApi<ITxTrackingStore<T>>, "setState" | "persist"> & {
457
468
  setState(partial: ITxTrackingStore<T> | Partial<ITxTrackingStore<T>> | ((state: ITxTrackingStore<T>) => ITxTrackingStore<T> | Partial<ITxTrackingStore<T>>), replace?: false | undefined): unknown;
458
469
  setState(state: ITxTrackingStore<T> | ((state: ITxTrackingStore<T>) => ITxTrackingStore<T>), replace: true): unknown;
459
470
  persist: {
@@ -571,4 +582,4 @@ type PollingTrackerConfig<R, T extends Transaction> = {
571
582
  */
572
583
  declare function initializePollingTracker<R, T extends Transaction>(config: PollingTrackerConfig<R, T>): void;
573
584
 
574
- export { type ActionTxKey, type BaseTransaction, type EvmTransaction, type GelatoTxKey, type IInitializeTxTrackingStore, type ITxTrackingStore, type InitialTransaction, type InitialTransactionParams, type OnSuccessCallback, type PollingFetcherParams, type PollingTrackerConfig, type PulsarAdapter, type SolanaTransaction, type StarknetTransaction, type StoreSlice, type TrackerCallbacks, type Transaction, type TransactionPool, TransactionStatus, TransactionTracker, type TxAdapter, createBoundedUseStore, createPulsarStore, initializePollingTracker, initializeTxTrackingStore, selectAllTransactions, selectAllTransactionsByActiveWallet, selectPendingTransactions, selectPendingTransactionsByActiveWallet, selectTxByKey };
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 };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var immer=require('immer'),orbitCore=require('@tuwaio/orbit-core'),C=require('dayjs'),middleware=require('zustand/middleware'),vanilla=require('zustand/vanilla'),zustand=require('zustand');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var C__default=/*#__PURE__*/_interopDefault(C);function h({maxTransactions:o}){return (t,s)=>({transactionsPool:{},lastAddedTxKey:void 0,initialTx:void 0,addTxToPool:e=>{t(n=>immer.produce(n,r=>{if(r.lastAddedTxKey=e.txKey,e.txKey){if(Object.keys(r.transactionsPool).length>=o){let d=Object.values(r.transactionsPool).sort((l,p)=>l.localTimestamp-p.localTimestamp);if(d.length>0){let l=d[0];delete r.transactionsPool[l.txKey];}}let c={...e,pending:true};r.transactionsPool[e.txKey]=c;}}));},updateTxParams:(e,n)=>{t(r=>immer.produce(r,i=>{let c=i.transactionsPool[e];c&&Object.assign(c,n);}));},removeTxFromPool:e=>{t(n=>immer.produce(n,r=>{delete r.transactionsPool[e];}));},closeTxTrackedModal:e=>{t(n=>immer.produce(n,r=>{if(e&&r.transactionsPool[e]){let i=r.transactionsPool[e];r.transactionsPool[e]={...i,isTrackedModalOpen:false};}r.initialTx=void 0;}));},getLastTxKey:()=>s().lastAddedTxKey})}var b=o=>Object.values(o).sort((t,s)=>Number(t.localTimestamp)-Number(s.localTimestamp)),D=o=>b(o).filter(t=>t.pending),_=(o,t)=>o[t],O=(o,t)=>b(o).filter(s=>s.from.toLowerCase()===t.toLowerCase()),H=(o,t)=>O(o,t).filter(s=>s.pending);function ee({adapter:o,maxTransactions:t=50,...s}){return vanilla.createStore()(middleware.persist((e,n)=>({...h({maxTransactions:t})(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,...n()})));},executeTxAction:async({defaultTracker:r,actionFunction:i,params:c,...d})=>{let{desiredChainID:l,...p}=c,{onSuccess:g,onError:x,onReplaced:P}=d,f=C__default.default().unix();e({initialTx:{...c,actionFunction:i,localTimestamp:f,isInitializing:true}});let T=orbitCore.selectAdapterByKey({adapterKey:p.adapter,adapter:o}),v=a=>{let k=a instanceof Error?a.message:String(a);e(u=>immer.produce(u,m=>{m.initialTx&&(m.initialTx.isInitializing=false,m.initialTx.errorMessage=k);}));};if(!T){let a=new Error("No adapter found for this transaction.");throw v(a),a}try{let{connectorType:a,walletAddress:k}=T.getConnectorInfo();await T.checkChainForTx(l);let u=await i();if(!u){e({initialTx:void 0});return}let{tracker:m,txKey:S}=T.checkTransactionsTracker(u,a),w={...p,connectorType:a,from:k,tracker:m||r,chainId:orbitCore.setChainId(l),localTimestamp:f,txKey:S,hash:m==="ethereum"?u:void 0,pending:!1,isTrackedModalOpen:c.withTrackedModal};n().addTxToPool(w),e(F=>immer.produce(F,A=>{A.initialTx&&(A.initialTx.isInitializing=!1,A.initialTx.lastTxKey=S);}));let R=n().transactionsPool[S];await T.checkAndInitializeTrackerInStore({tx:R,onSuccess:g,onError:x,onReplaced:P,...n()});}catch(a){throw v(a),a}}}),{...s}))}var B=(n=>(n.Ethereum="ethereum",n.Safe="safe",n.Gelato="gelato",n.Solana="solana",n))(B||{}),L=(e=>(e.Failed="Failed",e.Success="Success",e.Replaced="Replaced",e))(L||{});var ie=(o=>t=>zustand.useStore(o,t));var j=5e3,G=10;function se(o){let{tx:t,fetcher:s,onInitialize:e,onSuccess:n,onFailure:r,onIntervalTick:i,onReplaced:c,removeTxFromPool:d,pollingInterval:l=j,maxRetries:p=G}=o;if(!t.pending)return;e?.();let g=p,x=true,P=T=>{x&&(x=false,d&&!T?.withoutRemoving&&d(t.txKey));};(async()=>{for(;x&&g>0;)try{if(await new Promise(T=>setTimeout(T,l)),!x)break;await s({tx:t,stopPolling:P,onSuccess:n,onFailure:r,onIntervalTick:i,onReplaced:c});}catch(T){console.error(`Polling fetcher for txKey ${t.txKey} threw an error:`,T),g--;}g<=0&&(console.warn(`Polling for txKey ${t.txKey} stopped after reaching the maximum number of retries.`),r(),P());})();}exports.TransactionStatus=L;exports.TransactionTracker=B;exports.createBoundedUseStore=ie;exports.createPulsarStore=ee;exports.initializePollingTracker=se;exports.initializeTxTrackingStore=h;exports.selectAllTransactions=b;exports.selectAllTransactionsByActiveWallet=O;exports.selectPendingTransactions=D;exports.selectPendingTransactionsByActiveWallet=H;exports.selectTxByKey=_;
1
+ 'use strict';var immer=require('immer'),orbitCore=require('@tuwaio/orbit-core'),U=require('dayjs'),middleware=require('zustand/middleware'),vanilla=require('zustand/vanilla'),zustand=require('zustand');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var U__default=/*#__PURE__*/_interopDefault(U);function I({maxTransactions:n,onRemoteCreate:e}){return (a,c)=>({transactionsPool:{},lastAddedTxKey:void 0,initialTx:void 0,addTxToPool:t=>{let o={...t,pending:true};a(r=>immer.produce(r,i=>{if(i.lastAddedTxKey=t.txKey,t.txKey){if(Object.keys(i.transactionsPool).length>=n){let l=Object.values(i.transactionsPool).sort((p,d)=>p.localTimestamp-d.localTimestamp);if(l.length>0){let p=l[0];delete i.transactionsPool[p.txKey];}}i.transactionsPool[t.txKey]=o;}})),e&&e(o).catch(r=>console.error("[Pulsar Sync] Create failed:",r));},updateTxParams:(t,o)=>{a(r=>immer.produce(r,i=>{let s=i.transactionsPool[t];s&&Object.assign(s,o);}));},removeTxFromPool:t=>{a(o=>immer.produce(o,r=>{delete r.transactionsPool[t];}));},closeTxTrackedModal:t=>{a(o=>immer.produce(o,r=>{if(t&&r.transactionsPool[t]){let i=r.transactionsPool[t];r.transactionsPool[t]={...i,isTrackedModalOpen:false};}r.initialTx=void 0;}));},getLastTxKey:()=>c().lastAddedTxKey})}var K=n=>Object.values(n).sort((e,a)=>Number(e.localTimestamp)-Number(a.localTimestamp)),W=n=>K(n).filter(e=>e.pending),X=(n,e)=>n[e],z=(n,e)=>K(n).filter(a=>a.from.toLowerCase()===e.toLowerCase()),q=(n,e)=>z(n,e).filter(a=>a.pending);function oe({adapter:n,maxTransactions:e=50,onRemoteCreate:a,gelatoApiKey:c,...t}){return vanilla.createStore()(middleware.persist((o,r)=>({...I({maxTransactions:e,onRemoteCreate:a})(o,r),getAdapter:()=>n,initializeTransactionsPool:async()=>{let i=Object.values(r().transactionsPool).filter(s=>s.pending);await Promise.all(i.map(s=>orbitCore.selectAdapterByKey({adapterKey:s.adapter,adapter:n})?.checkAndInitializeTrackerInStore({tx:s,gelatoApiKey:c,...r()})));},executeTxAction:async({defaultTracker:i,actionFunction:s,params:l,...p})=>{let{desiredChainID:d,tracker:g,...u}=l,{onSuccess:A,onError:x,onReplaced:F}=p,h=U__default.default().unix();o({initialTx:{...l,actionFunction:s,localTimestamp:h,isInitializing:true}});let P=orbitCore.selectAdapterByKey({adapterKey:u.adapter,adapter:n}),v=T=>{o(f=>immer.produce(f,m=>{m.initialTx&&(m.initialTx.isInitializing=false,m.initialTx.error=orbitCore.normalizeError(T));}));};if(!P){let T=new Error("No adapter found for this transaction.");throw v(T),T}try{let{connectorType:T,walletAddress:f}=P.getConnectorInfo();await P.checkChainForTx(d);let m=await s();if(!m){o({initialTx:void 0});return}let{tracker:b,txKey:k}=P.checkTransactionsTracker({actionTxKey:m,connectorType:T,tracker:g,gelatoApiKey:c}),E={...u,connectorType:T,from:f,tracker:b||i,chainId:orbitCore.setChainId(d),localTimestamp:h,txKey:k,hash:b==="ethereum"?m:void 0,pending:!1,isTrackedModalOpen:l.withTrackedModal};r().addTxToPool(E),o(O=>immer.produce(O,S=>{S.initialTx&&(S.initialTx.isInitializing=!1,S.initialTx.lastTxKey=k);}));let C=r().transactionsPool[k];await P.checkAndInitializeTrackerInStore({tx:C,onSuccess:A,onError:x,onReplaced:F,gelatoApiKey:c,...r()});}catch(T){throw v(T),T}}}),{...t}))}var G=(t=>(t.Ethereum="ethereum",t.Safe="safe",t.Gelato="gelato",t.Solana="solana",t))(G||{}),$=(c=>(c.Failed="Failed",c.Success="Success",c.Replaced="Replaced",c))($||{});var Te=(n=>e=>zustand.useStore(n,e));var D=5e3,_=10;function de(n){let{tx:e,fetcher:a,onInitialize:c,onSuccess:t,onFailure:o,onIntervalTick:r,onReplaced:i,removeTxFromPool:s,pollingInterval:l=D,maxRetries:p=_}=n;if(!e.pending)return;c?.();let d=p,g=true,u=x=>{g&&(g=false,s&&!x?.withoutRemoving&&s(e.txKey));};(async()=>{for(;g&&d>0;)try{if(await new Promise(x=>setTimeout(x,l)),!g)break;await a({tx:e,stopPolling:u,onSuccess:t,onFailure:o,onIntervalTick:r,onReplaced:i});}catch(x){console.error(`Polling fetcher for txKey ${e.txKey} threw an error:`,x),d--;}d<=0&&(console.warn(`Polling for txKey ${e.txKey} stopped after reaching the maximum number of retries.`),o(),u());})();}exports.TransactionStatus=$;exports.TransactionTracker=G;exports.createBoundedUseStore=Te;exports.createPulsarStore=oe;exports.initializePollingTracker=de;exports.initializeTxTrackingStore=I;exports.selectAllTransactions=K;exports.selectAllTransactionsByActiveWallet=z;exports.selectPendingTransactions=W;exports.selectPendingTransactionsByActiveWallet=q;exports.selectTxByKey=X;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import {produce}from'immer';import {selectAdapterByKey,setChainId}from'@tuwaio/orbit-core';import C from'dayjs';import {persist}from'zustand/middleware';import {createStore}from'zustand/vanilla';import {useStore}from'zustand';function h({maxTransactions:o}){return (t,s)=>({transactionsPool:{},lastAddedTxKey:void 0,initialTx:void 0,addTxToPool:e=>{t(n=>produce(n,r=>{if(r.lastAddedTxKey=e.txKey,e.txKey){if(Object.keys(r.transactionsPool).length>=o){let d=Object.values(r.transactionsPool).sort((l,p)=>l.localTimestamp-p.localTimestamp);if(d.length>0){let l=d[0];delete r.transactionsPool[l.txKey];}}let c={...e,pending:true};r.transactionsPool[e.txKey]=c;}}));},updateTxParams:(e,n)=>{t(r=>produce(r,i=>{let c=i.transactionsPool[e];c&&Object.assign(c,n);}));},removeTxFromPool:e=>{t(n=>produce(n,r=>{delete r.transactionsPool[e];}));},closeTxTrackedModal:e=>{t(n=>produce(n,r=>{if(e&&r.transactionsPool[e]){let i=r.transactionsPool[e];r.transactionsPool[e]={...i,isTrackedModalOpen:false};}r.initialTx=void 0;}));},getLastTxKey:()=>s().lastAddedTxKey})}var b=o=>Object.values(o).sort((t,s)=>Number(t.localTimestamp)-Number(s.localTimestamp)),D=o=>b(o).filter(t=>t.pending),_=(o,t)=>o[t],O=(o,t)=>b(o).filter(s=>s.from.toLowerCase()===t.toLowerCase()),H=(o,t)=>O(o,t).filter(s=>s.pending);function ee({adapter:o,maxTransactions:t=50,...s}){return createStore()(persist((e,n)=>({...h({maxTransactions:t})(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,...n()})));},executeTxAction:async({defaultTracker:r,actionFunction:i,params:c,...d})=>{let{desiredChainID:l,...p}=c,{onSuccess:g,onError:x,onReplaced:P}=d,f=C().unix();e({initialTx:{...c,actionFunction:i,localTimestamp:f,isInitializing:true}});let T=selectAdapterByKey({adapterKey:p.adapter,adapter:o}),v=a=>{let k=a instanceof Error?a.message:String(a);e(u=>produce(u,m=>{m.initialTx&&(m.initialTx.isInitializing=false,m.initialTx.errorMessage=k);}));};if(!T){let a=new Error("No adapter found for this transaction.");throw v(a),a}try{let{connectorType:a,walletAddress:k}=T.getConnectorInfo();await T.checkChainForTx(l);let u=await i();if(!u){e({initialTx:void 0});return}let{tracker:m,txKey:S}=T.checkTransactionsTracker(u,a),w={...p,connectorType:a,from:k,tracker:m||r,chainId:setChainId(l),localTimestamp:f,txKey:S,hash:m==="ethereum"?u:void 0,pending:!1,isTrackedModalOpen:c.withTrackedModal};n().addTxToPool(w),e(F=>produce(F,A=>{A.initialTx&&(A.initialTx.isInitializing=!1,A.initialTx.lastTxKey=S);}));let R=n().transactionsPool[S];await T.checkAndInitializeTrackerInStore({tx:R,onSuccess:g,onError:x,onReplaced:P,...n()});}catch(a){throw v(a),a}}}),{...s}))}var B=(n=>(n.Ethereum="ethereum",n.Safe="safe",n.Gelato="gelato",n.Solana="solana",n))(B||{}),L=(e=>(e.Failed="Failed",e.Success="Success",e.Replaced="Replaced",e))(L||{});var ie=(o=>t=>useStore(o,t));var j=5e3,G=10;function se(o){let{tx:t,fetcher:s,onInitialize:e,onSuccess:n,onFailure:r,onIntervalTick:i,onReplaced:c,removeTxFromPool:d,pollingInterval:l=j,maxRetries:p=G}=o;if(!t.pending)return;e?.();let g=p,x=true,P=T=>{x&&(x=false,d&&!T?.withoutRemoving&&d(t.txKey));};(async()=>{for(;x&&g>0;)try{if(await new Promise(T=>setTimeout(T,l)),!x)break;await s({tx:t,stopPolling:P,onSuccess:n,onFailure:r,onIntervalTick:i,onReplaced:c});}catch(T){console.error(`Polling fetcher for txKey ${t.txKey} threw an error:`,T),g--;}g<=0&&(console.warn(`Polling for txKey ${t.txKey} stopped after reaching the maximum number of retries.`),r(),P());})();}export{L as TransactionStatus,B as TransactionTracker,ie as createBoundedUseStore,ee as createPulsarStore,se as initializePollingTracker,h as initializeTxTrackingStore,b as selectAllTransactions,O as selectAllTransactionsByActiveWallet,D as selectPendingTransactions,H as selectPendingTransactionsByActiveWallet,_ as selectTxByKey};
1
+ import {produce}from'immer';import {selectAdapterByKey,setChainId,normalizeError}from'@tuwaio/orbit-core';import U from'dayjs';import {persist}from'zustand/middleware';import {createStore}from'zustand/vanilla';import {useStore}from'zustand';function I({maxTransactions:n,onRemoteCreate:e}){return (a,c)=>({transactionsPool:{},lastAddedTxKey:void 0,initialTx:void 0,addTxToPool:t=>{let o={...t,pending:true};a(r=>produce(r,i=>{if(i.lastAddedTxKey=t.txKey,t.txKey){if(Object.keys(i.transactionsPool).length>=n){let l=Object.values(i.transactionsPool).sort((p,d)=>p.localTimestamp-d.localTimestamp);if(l.length>0){let p=l[0];delete i.transactionsPool[p.txKey];}}i.transactionsPool[t.txKey]=o;}})),e&&e(o).catch(r=>console.error("[Pulsar Sync] Create failed:",r));},updateTxParams:(t,o)=>{a(r=>produce(r,i=>{let s=i.transactionsPool[t];s&&Object.assign(s,o);}));},removeTxFromPool:t=>{a(o=>produce(o,r=>{delete r.transactionsPool[t];}));},closeTxTrackedModal:t=>{a(o=>produce(o,r=>{if(t&&r.transactionsPool[t]){let i=r.transactionsPool[t];r.transactionsPool[t]={...i,isTrackedModalOpen:false};}r.initialTx=void 0;}));},getLastTxKey:()=>c().lastAddedTxKey})}var K=n=>Object.values(n).sort((e,a)=>Number(e.localTimestamp)-Number(a.localTimestamp)),W=n=>K(n).filter(e=>e.pending),X=(n,e)=>n[e],z=(n,e)=>K(n).filter(a=>a.from.toLowerCase()===e.toLowerCase()),q=(n,e)=>z(n,e).filter(a=>a.pending);function oe({adapter:n,maxTransactions:e=50,onRemoteCreate:a,gelatoApiKey:c,...t}){return createStore()(persist((o,r)=>({...I({maxTransactions:e,onRemoteCreate:a})(o,r),getAdapter:()=>n,initializeTransactionsPool:async()=>{let i=Object.values(r().transactionsPool).filter(s=>s.pending);await Promise.all(i.map(s=>selectAdapterByKey({adapterKey:s.adapter,adapter:n})?.checkAndInitializeTrackerInStore({tx:s,gelatoApiKey:c,...r()})));},executeTxAction:async({defaultTracker:i,actionFunction:s,params:l,...p})=>{let{desiredChainID:d,tracker:g,...u}=l,{onSuccess:A,onError:x,onReplaced:F}=p,h=U().unix();o({initialTx:{...l,actionFunction:s,localTimestamp:h,isInitializing:true}});let P=selectAdapterByKey({adapterKey:u.adapter,adapter:n}),v=T=>{o(f=>produce(f,m=>{m.initialTx&&(m.initialTx.isInitializing=false,m.initialTx.error=normalizeError(T));}));};if(!P){let T=new Error("No adapter found for this transaction.");throw v(T),T}try{let{connectorType:T,walletAddress:f}=P.getConnectorInfo();await P.checkChainForTx(d);let m=await s();if(!m){o({initialTx:void 0});return}let{tracker:b,txKey:k}=P.checkTransactionsTracker({actionTxKey:m,connectorType:T,tracker:g,gelatoApiKey:c}),E={...u,connectorType:T,from:f,tracker:b||i,chainId:setChainId(d),localTimestamp:h,txKey:k,hash:b==="ethereum"?m:void 0,pending:!1,isTrackedModalOpen:l.withTrackedModal};r().addTxToPool(E),o(O=>produce(O,S=>{S.initialTx&&(S.initialTx.isInitializing=!1,S.initialTx.lastTxKey=k);}));let C=r().transactionsPool[k];await P.checkAndInitializeTrackerInStore({tx:C,onSuccess:A,onError:x,onReplaced:F,gelatoApiKey:c,...r()});}catch(T){throw v(T),T}}}),{...t}))}var G=(t=>(t.Ethereum="ethereum",t.Safe="safe",t.Gelato="gelato",t.Solana="solana",t))(G||{}),$=(c=>(c.Failed="Failed",c.Success="Success",c.Replaced="Replaced",c))($||{});var Te=(n=>e=>useStore(n,e));var D=5e3,_=10;function de(n){let{tx:e,fetcher:a,onInitialize:c,onSuccess:t,onFailure:o,onIntervalTick:r,onReplaced:i,removeTxFromPool:s,pollingInterval:l=D,maxRetries:p=_}=n;if(!e.pending)return;c?.();let d=p,g=true,u=x=>{g&&(g=false,s&&!x?.withoutRemoving&&s(e.txKey));};(async()=>{for(;g&&d>0;)try{if(await new Promise(x=>setTimeout(x,l)),!g)break;await a({tx:e,stopPolling:u,onSuccess:t,onFailure:o,onIntervalTick:r,onReplaced:i});}catch(x){console.error(`Polling fetcher for txKey ${e.txKey} threw an error:`,x),d--;}d<=0&&(console.warn(`Polling for txKey ${e.txKey} stopped after reaching the maximum number of retries.`),o(),u());})();}export{$ as TransactionStatus,G as TransactionTracker,Te as createBoundedUseStore,oe as createPulsarStore,de as initializePollingTracker,I as initializeTxTrackingStore,K as selectAllTransactions,z as selectAllTransactionsByActiveWallet,W as selectPendingTransactions,q as selectPendingTransactionsByActiveWallet,X as selectTxByKey};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuwaio/pulsar-core",
3
- "version": "0.4.1",
3
+ "version": "0.5.1",
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.7",
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.5",
49
+ "@tuwaio/orbit-core": "^0.2.7",
50
50
  "dayjs": "^1.11.19",
51
- "immer": "^11.1.3",
51
+ "immer": "^11.1.4",
52
52
  "tsup": "^8.5.1",
53
53
  "typescript": "^5.9.3",
54
- "zustand": "^5.0.10"
54
+ "zustand": "^5.0.11"
55
55
  },
56
56
  "scripts": {
57
57
  "start": "tsup src/index.ts --watch",