@tuwaio/pulsar-core 0.3.3 → 0.4.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
@@ -1,4 +1,4 @@
1
- import { OrbitAdapter, OrbitGenericAdapter, BaseAdapter } from '@tuwaio/orbit-core';
1
+ import { 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';
@@ -202,6 +202,16 @@ type InitialTransaction = InitialTransactionParams & {
202
202
  localTimestamp: number;
203
203
  };
204
204
  /**
205
+ * Defines the standard callback structure for transaction events.
206
+ * @template T The specific transaction type, extending `Transaction`.
207
+ */
208
+ interface TrackerCallbacks<T extends Transaction> {
209
+ onSuccess?: (tx: T) => Promise<void> | void;
210
+ onError?: (error: unknown, tx?: T) => Promise<void> | void;
211
+ onReplaced?: (newTx: T, oldTx: T) => Promise<void> | void;
212
+ }
213
+ /**
214
+ * @deprecated Use `TrackerCallbacks<T>` instead.
205
215
  * Defines a callback function to be executed upon a successful transaction.
206
216
  * @template T The specific transaction type, extending `Transaction`.
207
217
  */
@@ -213,7 +223,9 @@ type OnSuccessCallback<T extends Transaction> = {
213
223
  * The configuration object containing one or more transaction adapters.
214
224
  * @template T The specific transaction type.
215
225
  */
216
- type PulsarAdapter<T extends Transaction> = OrbitGenericAdapter<TxAdapter<T>>;
226
+ type PulsarAdapter<T extends Transaction> = OrbitGenericAdapter<TxAdapter<T>> & {
227
+ maxTransactions?: number;
228
+ };
217
229
  /**
218
230
  * Defines the interface for a transaction adapter, which provides chain-specific logic and utilities.
219
231
  * @template T The specific transaction type, extending `Transaction`.
@@ -252,7 +264,7 @@ type TxAdapter<T extends Transaction> = Pick<BaseAdapter, 'getExplorerUrl'> & {
252
264
  */
253
265
  checkAndInitializeTrackerInStore: (params: {
254
266
  tx: T;
255
- } & OnSuccessCallback<T> & Pick<ITxTrackingStore<T>, 'updateTxParams' | 'removeTxFromPool' | 'transactionsPool'>) => Promise<void> | void;
267
+ } & TrackerCallbacks<T> & Pick<ITxTrackingStore<T>, 'updateTxParams' | 'removeTxFromPool' | 'transactionsPool'>) => Promise<void> | void;
256
268
  /**
257
269
  * Optional: Logic to cancel a pending EVM transaction.
258
270
  * @param tx The transaction to cancel.
@@ -306,7 +318,7 @@ interface IInitializeTxTrackingStore<T extends Transaction> {
306
318
  transactionsPool: TransactionPool<T>;
307
319
  /** The `txKey` of the most recently added transaction. */
308
320
  lastAddedTxKey?: string;
309
- /** The state for a transaction being initiated, used for UI feedback before it's submitted to the chain. */
321
+ /** The state for a transaction being initiated, used for verify feedback before it's submitted to the chain. */
310
322
  initialTx?: InitialTransaction;
311
323
  /**
312
324
  * Adds a new transaction to the tracking pool and marks it as pending.
@@ -350,13 +362,15 @@ type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
350
362
  * @param params.actionFunction The async function to execute (e.g., a smart contract write call). Must return a unique key or undefined.
351
363
  * @param params.params The metadata for the transaction.
352
364
  * @param params.defaultTracker The default tracker to use if it cannot be determined automatically.
353
- * @param params.onSuccessCallback Callback to execute when the transaction is successfully submitted.
365
+ * @param params.onSuccess Callback to execute when the transaction is successfully submitted.
366
+ * @param params.onError Callback to execute when the transaction fails.
367
+ * @param params.onReplaced Callback to execute when the transaction is replaced.
354
368
  */
355
369
  executeTxAction: (params: {
356
370
  actionFunction: () => Promise<ActionTxKey | undefined>;
357
371
  params: Omit<InitialTransactionParams, 'actionFunction'>;
358
372
  defaultTracker?: TransactionTracker;
359
- } & OnSuccessCallback<T>) => Promise<void>;
373
+ } & TrackerCallbacks<T>) => Promise<void>;
360
374
  /**
361
375
  * Initializes trackers for all pending transactions in the pool.
362
376
  * This is essential for resuming tracking after a page reload or application restart.
@@ -377,7 +391,9 @@ type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
377
391
  * @param options Configuration for the store slice.
378
392
  * @returns A Zustand store slice implementing `IInitializeTxTrackingStore`.
379
393
  */
380
- declare function initializeTxTrackingStore<T extends Transaction>(): StoreSlice<IInitializeTxTrackingStore<T>>;
394
+ declare function initializeTxTrackingStore<T extends Transaction>({ maxTransactions, }: {
395
+ maxTransactions: number;
396
+ }): StoreSlice<IInitializeTxTrackingStore<T>>;
381
397
 
382
398
  /**
383
399
  * @file This file contains selector functions for deriving state from the transaction tracking store.
@@ -437,7 +453,7 @@ declare const selectPendingTransactionsByActiveWallet: <T extends Transaction>(t
437
453
  * @param options Configuration for the Zustand `persist` middleware.
438
454
  * @returns A fully configured Zustand store instance.
439
455
  */
440
- declare function createPulsarStore<T extends Transaction>({ adapter, ...options }: PulsarAdapter<T> & PersistOptions<ITxTrackingStore<T>>): Omit<zustand.StoreApi<ITxTrackingStore<T>>, "setState" | "persist"> & {
456
+ declare function createPulsarStore<T extends Transaction>({ adapter, maxTransactions, ...options }: PulsarAdapter<T> & PersistOptions<ITxTrackingStore<T>>): Omit<zustand.StoreApi<ITxTrackingStore<T>>, "setState" | "persist"> & {
441
457
  setState(partial: ITxTrackingStore<T> | Partial<ITxTrackingStore<T>> | ((state: ITxTrackingStore<T>) => ITxTrackingStore<T> | Partial<ITxTrackingStore<T>>), replace?: false | undefined): unknown;
442
458
  setState(state: ITxTrackingStore<T> | ((state: ITxTrackingStore<T>) => ITxTrackingStore<T>), replace: true): unknown;
443
459
  persist: {
@@ -555,4 +571,4 @@ type PollingTrackerConfig<R, T extends Transaction> = {
555
571
  */
556
572
  declare function initializePollingTracker<R, T extends Transaction>(config: PollingTrackerConfig<R, T>): void;
557
573
 
558
- export { type ActionTxKey, type BaseTransaction, type EvmTransaction, type GelatoTxKey, type IInitializeTxTrackingStore, type ITxTrackingStore, type InitialTransaction, type InitialTransactionParams, type OnSuccessCallback, type PollingTrackerConfig, type PulsarAdapter, type SolanaTransaction, type StarknetTransaction, type StoreSlice, type Transaction, type TransactionPool, TransactionStatus, TransactionTracker, type TxAdapter, createBoundedUseStore, createPulsarStore, initializePollingTracker, initializeTxTrackingStore, selectAllTransactions, selectAllTransactionsByActiveWallet, selectPendingTransactions, selectPendingTransactionsByActiveWallet, selectTxByKey };
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 };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { OrbitAdapter, OrbitGenericAdapter, BaseAdapter } from '@tuwaio/orbit-core';
1
+ import { 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';
@@ -202,6 +202,16 @@ type InitialTransaction = InitialTransactionParams & {
202
202
  localTimestamp: number;
203
203
  };
204
204
  /**
205
+ * Defines the standard callback structure for transaction events.
206
+ * @template T The specific transaction type, extending `Transaction`.
207
+ */
208
+ interface TrackerCallbacks<T extends Transaction> {
209
+ onSuccess?: (tx: T) => Promise<void> | void;
210
+ onError?: (error: unknown, tx?: T) => Promise<void> | void;
211
+ onReplaced?: (newTx: T, oldTx: T) => Promise<void> | void;
212
+ }
213
+ /**
214
+ * @deprecated Use `TrackerCallbacks<T>` instead.
205
215
  * Defines a callback function to be executed upon a successful transaction.
206
216
  * @template T The specific transaction type, extending `Transaction`.
207
217
  */
@@ -213,7 +223,9 @@ type OnSuccessCallback<T extends Transaction> = {
213
223
  * The configuration object containing one or more transaction adapters.
214
224
  * @template T The specific transaction type.
215
225
  */
216
- type PulsarAdapter<T extends Transaction> = OrbitGenericAdapter<TxAdapter<T>>;
226
+ type PulsarAdapter<T extends Transaction> = OrbitGenericAdapter<TxAdapter<T>> & {
227
+ maxTransactions?: number;
228
+ };
217
229
  /**
218
230
  * Defines the interface for a transaction adapter, which provides chain-specific logic and utilities.
219
231
  * @template T The specific transaction type, extending `Transaction`.
@@ -252,7 +264,7 @@ type TxAdapter<T extends Transaction> = Pick<BaseAdapter, 'getExplorerUrl'> & {
252
264
  */
253
265
  checkAndInitializeTrackerInStore: (params: {
254
266
  tx: T;
255
- } & OnSuccessCallback<T> & Pick<ITxTrackingStore<T>, 'updateTxParams' | 'removeTxFromPool' | 'transactionsPool'>) => Promise<void> | void;
267
+ } & TrackerCallbacks<T> & Pick<ITxTrackingStore<T>, 'updateTxParams' | 'removeTxFromPool' | 'transactionsPool'>) => Promise<void> | void;
256
268
  /**
257
269
  * Optional: Logic to cancel a pending EVM transaction.
258
270
  * @param tx The transaction to cancel.
@@ -306,7 +318,7 @@ interface IInitializeTxTrackingStore<T extends Transaction> {
306
318
  transactionsPool: TransactionPool<T>;
307
319
  /** The `txKey` of the most recently added transaction. */
308
320
  lastAddedTxKey?: string;
309
- /** The state for a transaction being initiated, used for UI feedback before it's submitted to the chain. */
321
+ /** The state for a transaction being initiated, used for verify feedback before it's submitted to the chain. */
310
322
  initialTx?: InitialTransaction;
311
323
  /**
312
324
  * Adds a new transaction to the tracking pool and marks it as pending.
@@ -350,13 +362,15 @@ type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
350
362
  * @param params.actionFunction The async function to execute (e.g., a smart contract write call). Must return a unique key or undefined.
351
363
  * @param params.params The metadata for the transaction.
352
364
  * @param params.defaultTracker The default tracker to use if it cannot be determined automatically.
353
- * @param params.onSuccessCallback Callback to execute when the transaction is successfully submitted.
365
+ * @param params.onSuccess Callback to execute when the transaction is successfully submitted.
366
+ * @param params.onError Callback to execute when the transaction fails.
367
+ * @param params.onReplaced Callback to execute when the transaction is replaced.
354
368
  */
355
369
  executeTxAction: (params: {
356
370
  actionFunction: () => Promise<ActionTxKey | undefined>;
357
371
  params: Omit<InitialTransactionParams, 'actionFunction'>;
358
372
  defaultTracker?: TransactionTracker;
359
- } & OnSuccessCallback<T>) => Promise<void>;
373
+ } & TrackerCallbacks<T>) => Promise<void>;
360
374
  /**
361
375
  * Initializes trackers for all pending transactions in the pool.
362
376
  * This is essential for resuming tracking after a page reload or application restart.
@@ -377,7 +391,9 @@ type ITxTrackingStore<T extends Transaction> = IInitializeTxTrackingStore<T> & {
377
391
  * @param options Configuration for the store slice.
378
392
  * @returns A Zustand store slice implementing `IInitializeTxTrackingStore`.
379
393
  */
380
- declare function initializeTxTrackingStore<T extends Transaction>(): StoreSlice<IInitializeTxTrackingStore<T>>;
394
+ declare function initializeTxTrackingStore<T extends Transaction>({ maxTransactions, }: {
395
+ maxTransactions: number;
396
+ }): StoreSlice<IInitializeTxTrackingStore<T>>;
381
397
 
382
398
  /**
383
399
  * @file This file contains selector functions for deriving state from the transaction tracking store.
@@ -437,7 +453,7 @@ declare const selectPendingTransactionsByActiveWallet: <T extends Transaction>(t
437
453
  * @param options Configuration for the Zustand `persist` middleware.
438
454
  * @returns A fully configured Zustand store instance.
439
455
  */
440
- declare function createPulsarStore<T extends Transaction>({ adapter, ...options }: PulsarAdapter<T> & PersistOptions<ITxTrackingStore<T>>): Omit<zustand.StoreApi<ITxTrackingStore<T>>, "setState" | "persist"> & {
456
+ declare function createPulsarStore<T extends Transaction>({ adapter, maxTransactions, ...options }: PulsarAdapter<T> & PersistOptions<ITxTrackingStore<T>>): Omit<zustand.StoreApi<ITxTrackingStore<T>>, "setState" | "persist"> & {
441
457
  setState(partial: ITxTrackingStore<T> | Partial<ITxTrackingStore<T>> | ((state: ITxTrackingStore<T>) => ITxTrackingStore<T> | Partial<ITxTrackingStore<T>>), replace?: false | undefined): unknown;
442
458
  setState(state: ITxTrackingStore<T> | ((state: ITxTrackingStore<T>) => ITxTrackingStore<T>), replace: true): unknown;
443
459
  persist: {
@@ -555,4 +571,4 @@ type PollingTrackerConfig<R, T extends Transaction> = {
555
571
  */
556
572
  declare function initializePollingTracker<R, T extends Transaction>(config: PollingTrackerConfig<R, T>): void;
557
573
 
558
- export { type ActionTxKey, type BaseTransaction, type EvmTransaction, type GelatoTxKey, type IInitializeTxTrackingStore, type ITxTrackingStore, type InitialTransaction, type InitialTransactionParams, type OnSuccessCallback, type PollingTrackerConfig, type PulsarAdapter, type SolanaTransaction, type StarknetTransaction, type StoreSlice, type Transaction, type TransactionPool, TransactionStatus, TransactionTracker, type TxAdapter, createBoundedUseStore, createPulsarStore, initializePollingTracker, initializeTxTrackingStore, selectAllTransactions, selectAllTransactionsByActiveWallet, selectPendingTransactions, selectPendingTransactionsByActiveWallet, selectTxByKey };
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 };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var immer=require('immer'),orbitCore=require('@tuwaio/orbit-core'),R=require('dayjs'),middleware=require('zustand/middleware'),vanilla=require('zustand/vanilla'),zustand=require('zustand');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var R__default=/*#__PURE__*/_interopDefault(R);function S(){return (t,r)=>({transactionsPool:{},lastAddedTxKey:void 0,initialTx:void 0,addTxToPool:e=>{t(o=>immer.produce(o,n=>{if(n.lastAddedTxKey=e.txKey,e.txKey){let i={...e,pending:true};n.transactionsPool[e.txKey]=i;}}));},updateTxParams:(e,o)=>{t(n=>immer.produce(n,i=>{let T=i.transactionsPool[e];T&&Object.assign(T,o);}));},removeTxFromPool:e=>{t(o=>immer.produce(o,n=>{delete n.transactionsPool[e];}));},closeTxTrackedModal:e=>{t(o=>immer.produce(o,n=>{if(e&&n.transactionsPool[e]){let i=n.transactionsPool[e];n.transactionsPool[e]={...i,isTrackedModalOpen:false};}n.initialTx=void 0;}));},getLastTxKey:()=>r().lastAddedTxKey})}var k=t=>Object.values(t).sort((r,e)=>Number(r.localTimestamp)-Number(e.localTimestamp)),G=t=>k(t).filter(r=>r.pending),j=(t,r)=>t[r],K=(t,r)=>k(t).filter(e=>e.from.toLowerCase()===r.toLowerCase()),$=(t,r)=>K(t,r).filter(e=>e.pending);function J({adapter:t,...r}){return vanilla.createStore()(middleware.persist((e,o)=>({...S()(e,o),getAdapter:()=>t,initializeTransactionsPool:async()=>{let n=Object.values(o().transactionsPool).filter(i=>i.pending);await Promise.all(n.map(i=>orbitCore.selectAdapterByKey({adapterKey:i.adapter,adapter:t})?.checkAndInitializeTrackerInStore({tx:i,...o()})));},executeTxAction:async({defaultTracker:n,actionFunction:i,onSuccessCallback:T,params:p})=>{let{desiredChainID:x,...g}=p,m=R__default.default().unix();e({initialTx:{...p,actionFunction:i,localTimestamp:m,isInitializing:true}});let c=orbitCore.selectAdapterByKey({adapterKey:g.adapter,adapter:t}),l=a=>{let u=a instanceof Error?a.message:String(a);e(s=>immer.produce(s,d=>{d.initialTx&&(d.initialTx.isInitializing=false,d.initialTx.errorMessage=u);}));};if(!c){let a=new Error("No adapter found for this transaction.");throw l(a),a}try{let{connectorType:a,walletAddress:u}=c.getConnectorInfo();await c.checkChainForTx(x);let s=await i();if(!s){e({initialTx:void 0});return}let{tracker:d,txKey:f}=c.checkTransactionsTracker(s,a),v={...g,connectorType:a,from:u,tracker:d||n,chainId:orbitCore.setChainId(x),localTimestamp:m,txKey:f,hash:d==="ethereum"?s:void 0,pending:!1,isTrackedModalOpen:p.withTrackedModal};o().addTxToPool(v),e(b=>immer.produce(b,y=>{y.initialTx&&(y.initialTx.isInitializing=!1,y.initialTx.lastTxKey=f);}));let I=o().transactionsPool[f];await c.checkAndInitializeTrackerInStore({tx:I,onSuccessCallback:T,...o()});}catch(a){throw l(a),a}}}),{...r}))}var E=(n=>(n.Ethereum="ethereum",n.Safe="safe",n.Gelato="gelato",n.Solana="solana",n))(E||{}),z=(o=>(o.Failed="Failed",o.Success="Success",o.Replaced="Replaced",o))(z||{});var te=(t=>r=>zustand.useStore(t,r));var M=5e3,B=10;function re(t){let{tx:r,fetcher:e,onInitialize:o,onSuccess:n,onFailure:i,onIntervalTick:T,onReplaced:p,removeTxFromPool:x,pollingInterval:g=M,maxRetries:m=B}=t;if(!r.pending)return;o?.();let c=m,l=true,a=s=>{l&&(l=false,x&&!s?.withoutRemoving&&x(r.txKey));};(async()=>{for(;l&&c>0;)try{if(await new Promise(s=>setTimeout(s,g)),!l)break;await e({tx:r,stopPolling:a,onSuccess:n,onFailure:i,onIntervalTick:T,onReplaced:p});}catch(s){console.error(`Polling fetcher for txKey ${r.txKey} threw an error:`,s),c--;}c<=0&&(console.warn(`Polling for txKey ${r.txKey} stopped after reaching the maximum number of retries.`),i(),a());})();}exports.TransactionStatus=z;exports.TransactionTracker=E;exports.createBoundedUseStore=te;exports.createPulsarStore=J;exports.initializePollingTracker=re;exports.initializeTxTrackingStore=S;exports.selectAllTransactions=k;exports.selectAllTransactionsByActiveWallet=K;exports.selectPendingTransactions=G;exports.selectPendingTransactionsByActiveWallet=$;exports.selectTxByKey=j;
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=_;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import {produce}from'immer';import {selectAdapterByKey,setChainId}from'@tuwaio/orbit-core';import R from'dayjs';import {persist}from'zustand/middleware';import {createStore}from'zustand/vanilla';import {useStore}from'zustand';function S(){return (t,r)=>({transactionsPool:{},lastAddedTxKey:void 0,initialTx:void 0,addTxToPool:e=>{t(o=>produce(o,n=>{if(n.lastAddedTxKey=e.txKey,e.txKey){let i={...e,pending:true};n.transactionsPool[e.txKey]=i;}}));},updateTxParams:(e,o)=>{t(n=>produce(n,i=>{let T=i.transactionsPool[e];T&&Object.assign(T,o);}));},removeTxFromPool:e=>{t(o=>produce(o,n=>{delete n.transactionsPool[e];}));},closeTxTrackedModal:e=>{t(o=>produce(o,n=>{if(e&&n.transactionsPool[e]){let i=n.transactionsPool[e];n.transactionsPool[e]={...i,isTrackedModalOpen:false};}n.initialTx=void 0;}));},getLastTxKey:()=>r().lastAddedTxKey})}var k=t=>Object.values(t).sort((r,e)=>Number(r.localTimestamp)-Number(e.localTimestamp)),G=t=>k(t).filter(r=>r.pending),j=(t,r)=>t[r],K=(t,r)=>k(t).filter(e=>e.from.toLowerCase()===r.toLowerCase()),$=(t,r)=>K(t,r).filter(e=>e.pending);function J({adapter:t,...r}){return createStore()(persist((e,o)=>({...S()(e,o),getAdapter:()=>t,initializeTransactionsPool:async()=>{let n=Object.values(o().transactionsPool).filter(i=>i.pending);await Promise.all(n.map(i=>selectAdapterByKey({adapterKey:i.adapter,adapter:t})?.checkAndInitializeTrackerInStore({tx:i,...o()})));},executeTxAction:async({defaultTracker:n,actionFunction:i,onSuccessCallback:T,params:p})=>{let{desiredChainID:x,...g}=p,m=R().unix();e({initialTx:{...p,actionFunction:i,localTimestamp:m,isInitializing:true}});let c=selectAdapterByKey({adapterKey:g.adapter,adapter:t}),l=a=>{let u=a instanceof Error?a.message:String(a);e(s=>produce(s,d=>{d.initialTx&&(d.initialTx.isInitializing=false,d.initialTx.errorMessage=u);}));};if(!c){let a=new Error("No adapter found for this transaction.");throw l(a),a}try{let{connectorType:a,walletAddress:u}=c.getConnectorInfo();await c.checkChainForTx(x);let s=await i();if(!s){e({initialTx:void 0});return}let{tracker:d,txKey:f}=c.checkTransactionsTracker(s,a),v={...g,connectorType:a,from:u,tracker:d||n,chainId:setChainId(x),localTimestamp:m,txKey:f,hash:d==="ethereum"?s:void 0,pending:!1,isTrackedModalOpen:p.withTrackedModal};o().addTxToPool(v),e(b=>produce(b,y=>{y.initialTx&&(y.initialTx.isInitializing=!1,y.initialTx.lastTxKey=f);}));let I=o().transactionsPool[f];await c.checkAndInitializeTrackerInStore({tx:I,onSuccessCallback:T,...o()});}catch(a){throw l(a),a}}}),{...r}))}var E=(n=>(n.Ethereum="ethereum",n.Safe="safe",n.Gelato="gelato",n.Solana="solana",n))(E||{}),z=(o=>(o.Failed="Failed",o.Success="Success",o.Replaced="Replaced",o))(z||{});var te=(t=>r=>useStore(t,r));var M=5e3,B=10;function re(t){let{tx:r,fetcher:e,onInitialize:o,onSuccess:n,onFailure:i,onIntervalTick:T,onReplaced:p,removeTxFromPool:x,pollingInterval:g=M,maxRetries:m=B}=t;if(!r.pending)return;o?.();let c=m,l=true,a=s=>{l&&(l=false,x&&!s?.withoutRemoving&&x(r.txKey));};(async()=>{for(;l&&c>0;)try{if(await new Promise(s=>setTimeout(s,g)),!l)break;await e({tx:r,stopPolling:a,onSuccess:n,onFailure:i,onIntervalTick:T,onReplaced:p});}catch(s){console.error(`Polling fetcher for txKey ${r.txKey} threw an error:`,s),c--;}c<=0&&(console.warn(`Polling for txKey ${r.txKey} stopped after reaching the maximum number of retries.`),i(),a());})();}export{z as TransactionStatus,E as TransactionTracker,te as createBoundedUseStore,J as createPulsarStore,re as initializePollingTracker,S as initializeTxTrackingStore,k as selectAllTransactions,K as selectAllTransactionsByActiveWallet,G as selectPendingTransactions,$ as selectPendingTransactionsByActiveWallet,j as selectTxByKey};
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};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuwaio/pulsar-core",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",