@tuwaio/pulsar-evm 0.0.2 → 0.0.3

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,6 +1,6 @@
1
1
  import { InitializePollingTracker, Transaction, ITxTrackingStore, TransactionPool } from '@tuwaio/pulsar-core';
2
2
  import { Config, GetAccountReturnType, GetClientReturnType } from '@wagmi/core';
3
- import { Hex, Chain, GetTransactionReturnType, TransactionReceipt, Client, ReplacementReturnType, WaitForTransactionReceiptParameters, PublicClient } from 'viem';
3
+ import { Hex, Chain, GetTransactionReturnType, TransactionReceipt, Client, ReplacementReturnType, WaitForTransactionReceiptParameters, PublicClient, Address } from 'viem';
4
4
 
5
5
  /**
6
6
  * @file This file implements the transaction tracking logic for meta-transactions relayed via the Gelato Network.
@@ -339,6 +339,46 @@ declare function checkTransactionsTracker(actionTxKey: ActionTxKey, walletType:
339
339
  */
340
340
  declare function createViemClient(chainId: number, chains: Chain[]): PublicClient | undefined;
341
341
 
342
+ /**
343
+ * @file This file contains utility functions for interacting with the Ethereum Name Service (ENS).
344
+ * It provides methods for resolving names to addresses, addresses to names, and fetching avatars.
345
+ */
346
+
347
+ /**
348
+ * Fetches the primary ENS name for a given Ethereum address.
349
+ * Performs the lookup on Ethereum Mainnet.
350
+ *
351
+ * @param {Hex} address - The Ethereum address to look up.
352
+ * @returns {Promise<string | undefined>} The ENS name if found, otherwise undefined.
353
+ */
354
+ declare const getName: (address: Hex) => Promise<string | undefined>;
355
+ /**
356
+ * Fetches the avatar for a given ENS name.
357
+ * If no ENS avatar is set, it generates a unique "blockie" image as a fallback.
358
+ * Performs the lookup on Ethereum Mainnet.
359
+ *
360
+ * @param {string} name - The ENS name (e.g., 'vitalik.eth').
361
+ * @param {string} address - The Ethereum address, used for the blockie fallback.
362
+ * @returns {Promise<string | undefined>} The URL of the avatar image, a base64 blockie, or undefined if an error occurs.
363
+ */
364
+ declare const getAvatar: (name: string) => Promise<string | undefined>;
365
+ /**
366
+ * Fetches the Ethereum address associated with a given ENS name.
367
+ * Performs the lookup on Ethereum Mainnet.
368
+ *
369
+ * @param {string} name - The ENS name to resolve (e.g., 'vitalik.eth').
370
+ * @returns {Promise<Address | undefined>} The associated Ethereum address (lowercase) or undefined if not found.
371
+ */
372
+ declare const getAddress: (name: string) => Promise<Address | undefined>;
373
+ /**
374
+ * A simple heuristic to check if a string could be an ENS name.
375
+ * It works by checking if the string is NOT a valid Ethereum address.
376
+ *
377
+ * @param {string} address - The string to check.
378
+ * @returns {boolean} True if the string is not in a valid address format.
379
+ */
380
+ declare const isEnsName: (address: string) => boolean;
381
+
342
382
  /**
343
383
  * @file This file contains a utility for safely retrieving the active wallet account and viem client.
344
384
  */
@@ -431,4 +471,4 @@ declare function speedUpTxAction<TR, T extends Transaction<TR>>({ config, tx, }:
431
471
  tx: T;
432
472
  }): Promise<Hex>;
433
473
 
434
- export { type ActionTxKey, type EVMTrackerParams, GelatoTaskState, type GelatoTaskStatusResponse, type GelatoTrackerParams, type GelatoTxKey, type SafeTrackerParams, SafeTransactionServiceUrls, type SafeTxStatusResponse, TransactionTracker, cancelTxAction, checkAndInitializeTrackerInStore, checkChainForTx, checkIsGelatoAvailable, checkTransactionsTracker, createViemClient, evmAdapter, evmTracker, evmTrackerForStore, fetchTxFromGelatoAPI, fetchTxFromSafeAPI, gelatoTracker, gelatoTrackerForStore, getActiveWalletAndClient, gnosisSafeLinksHelper, isGelatoTxKey, safeSdkOptions, safeTracker, safeTrackerForStore, selectEvmTxExplorerLink, speedUpTxAction };
474
+ export { type ActionTxKey, type EVMTrackerParams, GelatoTaskState, type GelatoTaskStatusResponse, type GelatoTrackerParams, type GelatoTxKey, type SafeTrackerParams, SafeTransactionServiceUrls, type SafeTxStatusResponse, TransactionTracker, cancelTxAction, checkAndInitializeTrackerInStore, checkChainForTx, checkIsGelatoAvailable, checkTransactionsTracker, createViemClient, evmAdapter, evmTracker, evmTrackerForStore, fetchTxFromGelatoAPI, fetchTxFromSafeAPI, gelatoTracker, gelatoTrackerForStore, getActiveWalletAndClient, getAddress, getAvatar, getName, gnosisSafeLinksHelper, isEnsName, isGelatoTxKey, safeSdkOptions, safeTracker, safeTrackerForStore, selectEvmTxExplorerLink, speedUpTxAction };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { InitializePollingTracker, Transaction, ITxTrackingStore, TransactionPool } from '@tuwaio/pulsar-core';
2
2
  import { Config, GetAccountReturnType, GetClientReturnType } from '@wagmi/core';
3
- import { Hex, Chain, GetTransactionReturnType, TransactionReceipt, Client, ReplacementReturnType, WaitForTransactionReceiptParameters, PublicClient } from 'viem';
3
+ import { Hex, Chain, GetTransactionReturnType, TransactionReceipt, Client, ReplacementReturnType, WaitForTransactionReceiptParameters, PublicClient, Address } from 'viem';
4
4
 
5
5
  /**
6
6
  * @file This file implements the transaction tracking logic for meta-transactions relayed via the Gelato Network.
@@ -339,6 +339,46 @@ declare function checkTransactionsTracker(actionTxKey: ActionTxKey, walletType:
339
339
  */
340
340
  declare function createViemClient(chainId: number, chains: Chain[]): PublicClient | undefined;
341
341
 
342
+ /**
343
+ * @file This file contains utility functions for interacting with the Ethereum Name Service (ENS).
344
+ * It provides methods for resolving names to addresses, addresses to names, and fetching avatars.
345
+ */
346
+
347
+ /**
348
+ * Fetches the primary ENS name for a given Ethereum address.
349
+ * Performs the lookup on Ethereum Mainnet.
350
+ *
351
+ * @param {Hex} address - The Ethereum address to look up.
352
+ * @returns {Promise<string | undefined>} The ENS name if found, otherwise undefined.
353
+ */
354
+ declare const getName: (address: Hex) => Promise<string | undefined>;
355
+ /**
356
+ * Fetches the avatar for a given ENS name.
357
+ * If no ENS avatar is set, it generates a unique "blockie" image as a fallback.
358
+ * Performs the lookup on Ethereum Mainnet.
359
+ *
360
+ * @param {string} name - The ENS name (e.g., 'vitalik.eth').
361
+ * @param {string} address - The Ethereum address, used for the blockie fallback.
362
+ * @returns {Promise<string | undefined>} The URL of the avatar image, a base64 blockie, or undefined if an error occurs.
363
+ */
364
+ declare const getAvatar: (name: string) => Promise<string | undefined>;
365
+ /**
366
+ * Fetches the Ethereum address associated with a given ENS name.
367
+ * Performs the lookup on Ethereum Mainnet.
368
+ *
369
+ * @param {string} name - The ENS name to resolve (e.g., 'vitalik.eth').
370
+ * @returns {Promise<Address | undefined>} The associated Ethereum address (lowercase) or undefined if not found.
371
+ */
372
+ declare const getAddress: (name: string) => Promise<Address | undefined>;
373
+ /**
374
+ * A simple heuristic to check if a string could be an ENS name.
375
+ * It works by checking if the string is NOT a valid Ethereum address.
376
+ *
377
+ * @param {string} address - The string to check.
378
+ * @returns {boolean} True if the string is not in a valid address format.
379
+ */
380
+ declare const isEnsName: (address: string) => boolean;
381
+
342
382
  /**
343
383
  * @file This file contains a utility for safely retrieving the active wallet account and viem client.
344
384
  */
@@ -431,4 +471,4 @@ declare function speedUpTxAction<TR, T extends Transaction<TR>>({ config, tx, }:
431
471
  tx: T;
432
472
  }): Promise<Hex>;
433
473
 
434
- export { type ActionTxKey, type EVMTrackerParams, GelatoTaskState, type GelatoTaskStatusResponse, type GelatoTrackerParams, type GelatoTxKey, type SafeTrackerParams, SafeTransactionServiceUrls, type SafeTxStatusResponse, TransactionTracker, cancelTxAction, checkAndInitializeTrackerInStore, checkChainForTx, checkIsGelatoAvailable, checkTransactionsTracker, createViemClient, evmAdapter, evmTracker, evmTrackerForStore, fetchTxFromGelatoAPI, fetchTxFromSafeAPI, gelatoTracker, gelatoTrackerForStore, getActiveWalletAndClient, gnosisSafeLinksHelper, isGelatoTxKey, safeSdkOptions, safeTracker, safeTrackerForStore, selectEvmTxExplorerLink, speedUpTxAction };
474
+ export { type ActionTxKey, type EVMTrackerParams, GelatoTaskState, type GelatoTaskStatusResponse, type GelatoTrackerParams, type GelatoTxKey, type SafeTrackerParams, SafeTransactionServiceUrls, type SafeTxStatusResponse, TransactionTracker, cancelTxAction, checkAndInitializeTrackerInStore, checkChainForTx, checkIsGelatoAvailable, checkTransactionsTracker, createViemClient, evmAdapter, evmTracker, evmTrackerForStore, fetchTxFromGelatoAPI, fetchTxFromSafeAPI, gelatoTracker, gelatoTrackerForStore, getActiveWalletAndClient, getAddress, getAvatar, getName, gnosisSafeLinksHelper, isEnsName, isGelatoTxKey, safeSdkOptions, safeTracker, safeTrackerForStore, selectEvmTxExplorerLink, speedUpTxAction };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- 'use strict';var pulsarCore=require('@tuwaio/pulsar-core'),viem=require('viem'),actions=require('viem/actions'),core=require('@wagmi/core'),p=require('dayjs'),chains=require('viem/chains');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var p__default=/*#__PURE__*/_interopDefault(p);function I(e,a){let n=a.find(r=>r.id===e);if(n)return viem.createClient({chain:n,transport:core.http()})}async function Z({onInitialize:e,onTxDetailsGot:a,onFinished:n,onFailed:r,onReplaced:i,tx:t,chains:o,retryCount:s,retryTimeout:c,waitForTransactionReceiptParams:h}){let l=s??10,m=I(t.chainId,o);if(e&&e(),t.txKey===viem.zeroHash)throw new Error("Transaction hash is zeroHash");if(!m){let f=new Error(`Could not create a viem client for chainId: ${t.chainId}`);r(f),console.error(f.message);return}for(let f=0;f<l;f++){try{let u=await actions.getTransaction(m,{hash:t.txKey});a(u);let v=!1;try{let k=await actions.waitForTransactionReceipt(m,{hash:u.hash,onReplaced:_=>{v=!0,i(_);},pollingInterval:1e4,...h});if(v)return;await n(u,k,m);}catch(k){r(k),console.error("Error waiting for transaction receipt:",k);}return}catch(u){if(f===l-1){r(u),console.error(`Error tracking EVM transaction after ${l} retries:`,u);return}}await new Promise(u=>setTimeout(u,c??3e3));}}async function P({tx:e,chains:a,transactionsPool:n,updateTxParams:r,onSucceedCallbacks:i}){return await Z({tx:e,chains:a,onInitialize:()=>{r({txKey:e.txKey,hash:e.txKey,pending:e.pending});},onTxDetailsGot:t=>{r({to:t.to??"",input:t.input,value:String(t.value),txKey:e.txKey,pending:e.pending,nonce:t.nonce,hash:t.hash,maxFeePerGas:String(t.maxFeePerGas),maxPriorityFeePerGas:String(t.maxPriorityFeePerGas)});},onFinished:async(t,o,s)=>{let c=await actions.getBlock(s,{blockNumber:o.blockNumber}),h=Number(c.timestamp),l=o.status==="success";r({txKey:e.txKey,status:l?pulsarCore.TransactionStatus.Success:pulsarCore.TransactionStatus.Failed,to:viem.isHex(o.to)?o.to:void 0,nonce:t.nonce,pending:!1,isError:!l,hash:t.hash,finishedTimestamp:h});let m=n[e.txKey];l&&i&&m&&i(m);},onReplaced:t=>{r({txKey:e.txKey,status:pulsarCore.TransactionStatus.Replaced,replacedTxHash:t.transaction.hash,pending:!1});},onFailed:t=>{r({txKey:e.txKey,status:pulsarCore.TransactionStatus.Failed,pending:!1,isError:!0,errorMessage:t instanceof Error?t.message:"Transaction failed or could not be tracked."});}})}function F(e){return e.taskId!==void 0}var te=(o=>(o.CheckPending="CheckPending",o.ExecPending="ExecPending",o.WaitingForConfirmation="WaitingForConfirmation",o.ExecSuccess="ExecSuccess",o.ExecReverted="ExecReverted",o.Cancelled="Cancelled",o))(te||{});function K(e){return e?["CheckPending","ExecPending","WaitingForConfirmation"].includes(e):true}var C=["ExecReverted","Cancelled"];async function ae({tx:e,onSucceed:a,onFailed:n,onIntervalTick:r,clearWatch:i}){let t=await fetch(`https://api.gelato.digital/tasks/status/${e.txKey}/`);if(t.ok){let o=await t.json(),s=K(o.task.taskState);if(o.task.creationDate){let c=p__default.default(o.task.creationDate);if(p__default.default().diff(c,"day")>=1&&s)return i(),t}r?.(o),s||(i(true),o.task.taskState==="ExecSuccess"?a(o):C.includes(o.task.taskState)&&n(o));}return t}async function ne(e){await pulsarCore.initializePollingTracker({...e,fetcher:ae});}async function E({tx:e,transactionsPool:a,updateTxParams:n,onSucceedCallbacks:r,removeTxFromPool:i}){return await ne({tx:e,removeTxFromPool:i,onSucceed:async t=>{n({txKey:e.txKey,status:pulsarCore.TransactionStatus.Success,pending:false,hash:t.task.transactionHash,finishedTimestamp:t.task.executionDate?p__default.default(t.task.executionDate).unix():void 0});let o=a[e.txKey];r&&o&&r(o);},onIntervalTick:async t=>{let o=K(t.task.taskState),s=t.task.taskState==="ExecSuccess";n({txKey:e.txKey,pending:o,status:s?pulsarCore.TransactionStatus.Success:o?void 0:pulsarCore.TransactionStatus.Failed,hash:t.task.transactionHash,finishedTimestamp:t.task.executionDate?p__default.default(t.task.executionDate).unix():void 0,errorMessage:C.includes(t.task.taskState)?t.task.lastCheckMessage:void 0,isError:!o&&!s});},onFailed:t=>{n({txKey:e.txKey,status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:t.task.transactionHash,errorMessage:t.task.lastCheckMessage,finishedTimestamp:t.task.executionDate?p__default.default(t.task.executionDate).unix():void 0});}})}var qe={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},W={[chains.mainnet.id]:"https://app.safe.global/eth:",[chains.goerli.id]:"https://app.safe.global/gor:",[chains.sepolia.id]:"https://app.safe.global/sep:",[chains.optimism.id]:"https://app.safe.global/oeth:",[chains.polygon.id]:"https://app.safe.global/matic:",[chains.arbitrum.id]:"https://app.safe.global/arb1:",[chains.avalanche.id]:"https://app.safe.global/avax:",[chains.bsc.id]:"https://app.safe.global/bnb:",[chains.base.id]:"https://app.safe.global/base:"},b={[chains.mainnet.id]:"https://safe-transaction-mainnet.safe.global/api/v1",[chains.goerli.id]:"https://safe-transaction-goerli.safe.global/api/v1",[chains.sepolia.id]:"https://safe-transaction-sepolia.safe.global/api/v1",[chains.optimism.id]:"https://safe-transaction-optimism.safe.global/api/v1",[chains.polygon.id]:"https://safe-transaction-polygon.safe.global/api/v1",[chains.arbitrum.id]:"https://safe-transaction-arbitrum.safe.global/api/v1",[chains.avalanche.id]:"https://safe-transaction-avalanche.safe.global/api/v1",[chains.bsc.id]:"https://safe-transaction-bsc.safe.global/api/v1",[chains.base.id]:"https://safe-transaction-base.safe.global/api/v1"};async function ie({tx:e,onSucceed:a,onFailed:n,onIntervalTick:r,onReplaced:i,clearWatch:t}){let o=await fetch(`${b[e.chainId]}/multisig-transactions/${e.txKey}/`);if(!o.ok)return o;let s=await o.json(),c=await fetch(`${b[e.chainId]}/safes/${e.from}/multisig-transactions/?nonce=${s.nonce}`);if(!c.ok)return c;let l=(await c.json()).results.find(f=>f.isExecuted);if(l&&l.safeTxHash!==s.safeTxHash)return i?.({...s,replacedHash:l.safeTxHash}),t(true),c;if(s.isExecuted)return s.isSuccessful?a(s):n(s),t(true),o;let m=p__default.default(s.modified);return p__default.default().diff(m,"day")>=1?(t(),o):(r?.(s),o)}async function se(e){await pulsarCore.initializePollingTracker({...e,fetcher:ie});}async function V({tx:e,transactionsPool:a,updateTxParams:n,onSucceedCallbacks:r,removeTxFromPool:i}){return await se({tx:e,removeTxFromPool:i,onSucceed:async t=>{n({txKey:e.txKey,status:pulsarCore.TransactionStatus.Success,pending:false,hash:t.transactionHash,finishedTimestamp:t.executionDate?p__default.default(t.executionDate).unix():void 0});let o=a[e.txKey];r&&o&&r(o);},onIntervalTick:async t=>{n({pending:!t.isExecuted,txKey:e.txKey,hash:t.transactionHash});},onFailed:t=>{n({txKey:e.txKey,status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:t.transactionHash,finishedTimestamp:t.executionDate?p__default.default(t.executionDate).unix():void 0});},onReplaced:t=>{n({txKey:e.txKey,status:pulsarCore.TransactionStatus.Replaced,pending:false,hash:t.transactionHash,replacedTxHash:t.replacedHash??viem.zeroHash,finishedTimestamp:t.executionDate?p__default.default(t.executionDate).unix():void 0});}})}var S=(r=>(r.Ethereum="ethereum",r.Safe="safe",r.Gelato="gelato",r))(S||{});async function B({tracker:e,tx:a,chains:n,...r}){switch(e){case "ethereum":await P({tx:a,chains:n,...r});break;case "gelato":await E({tx:a,...r});break;case "safe":await V({tx:a,...r});break;default:await P({tx:a,chains:n,...r});}}async function U(e,a){let{connector:n,chainId:r}=core.getAccount(a);if(n&&r!==e)try{await core.switchChain(a,{chainId:e});}catch(i){throw console.error("Failed to switch chain:",i),new Error("User rejected chain switch or an error occurred.")}}function j(e,a){if(F(e))return {tracker:"gelato",txKey:e.taskId};if(!viem.isHex(e))throw new Error("Invalid transaction key format. Expected a Hex string or GelatoTxKey object.");return a==="safe"?{tracker:"safe",txKey:e}:{tracker:"ethereum",txKey:e}}function wt(e,a){if(e)return {checkChainForTx:n=>U(n,e),checkTransactionsTracker:(n,r)=>j(n,r),checkAndInitializeTrackerInStore:({tx:n,...r})=>B({tracker:n.tracker,tx:n,chains:a,...r})}}async function Et({config:e,tx:a}){if(a.adapter===pulsarCore.TransactionAdapter.EVM){if(!a.nonce||!a.maxFeePerGas||!a.maxPriorityFeePerGas)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas).");try{if(!e)throw new Error("Wagmi config is not provided.");let n=core.getAccount(e);if(!n.address)throw new Error("No connected account found.");let r=115n,i=100n,t=BigInt(a.maxPriorityFeePerGas)*r/i,o=BigInt(a.maxFeePerGas)*r/i;return await core.sendTransaction(e,{to:n.address,value:0n,chainId:a.chainId,nonce:a.nonce,maxFeePerGas:o,maxPriorityFeePerGas:t})}catch(n){let r=n instanceof Error?n.message:String(n);throw new Error(`Failed to cancel transaction: ${r}`)}}else throw new Error("Failed to cancel transaction: not EVM tx adapter")}var d=null,x=null,Te=300*1e3;async function Gt(e){let a=Date.now();if(d&&x&&a-x<Te)return d.includes(e);try{let n=await fetch("https://relay.gelato.digital/relays/v2");if(!n.ok)return d=null,x=null,!1;let i=(await n.json()).relays.map(Number);return d=i,x=a,i.includes(e)}catch(n){return console.error("Failed to check Gelato service availability:",n),d=null,x=null,false}}function Nt(e){let a=core.getAccount(e),n=core.getClient(e);if(!a.address||!n)throw new Error("Wallet not connected");return {activeWallet:a,walletClient:n}}var Lt=(e,a,n,r)=>{let i=pulsarCore.selectTXByKey(e,n);return i?(o=>{if(i.tracker==="safe"){let c=W[i.chainId];return c?`${c}${i.from}/transactions/tx?id=multisig_${i.from}_${i.txKey}`:""}let s=a.find(c=>c.id===i.chainId);return s?.blockExplorers?.default.url?`${s.blockExplorers.default.url}/tx/${o}`:""})(r||i.adapter===pulsarCore.TransactionAdapter.EVM&&i.hash||i.txKey):""};async function Yt({config:e,tx:a}){if(a.adapter===pulsarCore.TransactionAdapter.EVM){if(!a.nonce||!a.from||!a.to||!a.value||!a.input||!a.maxFeePerGas||!a.maxPriorityFeePerGas)throw new Error("Transaction is missing required fields for speed-up.");try{if(!e)throw new Error("Wagmi config is not provided.");if(!core.getAccount(e).address)throw new Error("No connected account found.");let r=115n,i=100n,t=BigInt(a.maxPriorityFeePerGas)*r/i,o=BigInt(a.maxFeePerGas)*r/i;return await core.sendTransaction(e,{to:a.to,value:BigInt(a.value),data:a.input,chainId:a.chainId,nonce:a.nonce,maxFeePerGas:o,maxPriorityFeePerGas:t})}catch(n){let r=n instanceof Error?n.message:String(n);throw new Error(`Failed to speed up transaction: ${r}`)}}else throw new Error("Failed to speed up transaction: not EVM tx adapter")}
2
- exports.GelatoTaskState=te;exports.SafeTransactionServiceUrls=b;exports.TransactionTracker=S;exports.cancelTxAction=Et;exports.checkAndInitializeTrackerInStore=B;exports.checkChainForTx=U;exports.checkIsGelatoAvailable=Gt;exports.checkTransactionsTracker=j;exports.createViemClient=I;exports.evmAdapter=wt;exports.evmTracker=Z;exports.evmTrackerForStore=P;exports.fetchTxFromGelatoAPI=ae;exports.fetchTxFromSafeAPI=ie;exports.gelatoTracker=ne;exports.gelatoTrackerForStore=E;exports.getActiveWalletAndClient=Nt;exports.gnosisSafeLinksHelper=W;exports.isGelatoTxKey=F;exports.safeSdkOptions=qe;exports.safeTracker=se;exports.safeTrackerForStore=V;exports.selectEvmTxExplorerLink=Lt;exports.speedUpTxAction=Yt;//# sourceMappingURL=index.js.map
1
+ 'use strict';var pulsarCore=require('@tuwaio/pulsar-core'),viem=require('viem'),actions=require('viem/actions'),core=require('@wagmi/core'),p=require('dayjs'),chains=require('viem/chains'),ens=require('viem/ens');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var p__default=/*#__PURE__*/_interopDefault(p);function y(e,t){let r=t.find(n=>n.id===e);if(r)return viem.createClient({chain:r,transport:core.http()})}async function ae({onInitialize:e,onTxDetailsGot:t,onFinished:r,onFailed:n,onReplaced:i,tx:a,chains:o,retryCount:s,retryTimeout:c,waitForTransactionReceiptParams:k}){let l=s??10,d=y(a.chainId,o);if(e&&e(),a.txKey===viem.zeroHash)throw new Error("Transaction hash is zeroHash");if(!d){let m=new Error(`Could not create a viem client for chainId: ${a.chainId}`);n(m),console.error(m.message);return}for(let m=0;m<l;m++){try{let f=await actions.getTransaction(d,{hash:a.txKey});t(f);let E=!1;try{let g=await actions.waitForTransactionReceipt(d,{hash:f.hash,onReplaced:q=>{E=!0,i(q);},pollingInterval:1e4,...k});if(E)return;await r(f,g,d);}catch(g){n(g),console.error("Error waiting for transaction receipt:",g);}return}catch(f){if(m===l-1){n(f),console.error(`Error tracking EVM transaction after ${l} retries:`,f);return}}await new Promise(f=>setTimeout(f,c??3e3));}}async function w({tx:e,chains:t,transactionsPool:r,updateTxParams:n,onSucceedCallbacks:i}){return await ae({tx:e,chains:t,onInitialize:()=>{n({txKey:e.txKey,hash:e.txKey,pending:e.pending});},onTxDetailsGot:a=>{n({to:a.to??"",input:a.input,value:String(a.value),txKey:e.txKey,pending:e.pending,nonce:a.nonce,hash:a.hash,maxFeePerGas:String(a.maxFeePerGas),maxPriorityFeePerGas:String(a.maxPriorityFeePerGas)});},onFinished:async(a,o,s)=>{let c=await actions.getBlock(s,{blockNumber:o.blockNumber}),k=Number(c.timestamp),l=o.status==="success";n({txKey:e.txKey,status:l?pulsarCore.TransactionStatus.Success:pulsarCore.TransactionStatus.Failed,to:viem.isHex(o.to)?o.to:void 0,nonce:a.nonce,pending:!1,isError:!l,hash:a.hash,finishedTimestamp:k});let d=r[e.txKey];l&&i&&d&&i(d);},onReplaced:a=>{n({txKey:e.txKey,status:pulsarCore.TransactionStatus.Replaced,replacedTxHash:a.transaction.hash,pending:!1});},onFailed:a=>{n({txKey:e.txKey,status:pulsarCore.TransactionStatus.Failed,pending:!1,isError:!0,errorMessage:a instanceof Error?a.message:"Transaction failed or could not be tracked."});}})}function F(e){return e.taskId!==void 0}var ne=(o=>(o.CheckPending="CheckPending",o.ExecPending="ExecPending",o.WaitingForConfirmation="WaitingForConfirmation",o.ExecSuccess="ExecSuccess",o.ExecReverted="ExecReverted",o.Cancelled="Cancelled",o))(ne||{});function C(e){return e?["CheckPending","ExecPending","WaitingForConfirmation"].includes(e):true}var K=["ExecReverted","Cancelled"];async function oe({tx:e,onSucceed:t,onFailed:r,onIntervalTick:n,clearWatch:i}){let a=await fetch(`https://api.gelato.digital/tasks/status/${e.txKey}/`);if(a.ok){let o=await a.json(),s=C(o.task.taskState);if(o.task.creationDate){let c=p__default.default(o.task.creationDate);if(p__default.default().diff(c,"day")>=1&&s)return i(),a}n?.(o),s||(i(true),o.task.taskState==="ExecSuccess"?t(o):K.includes(o.task.taskState)&&r(o));}return a}async function ie(e){await pulsarCore.initializePollingTracker({...e,fetcher:oe});}async function R({tx:e,transactionsPool:t,updateTxParams:r,onSucceedCallbacks:n,removeTxFromPool:i}){return await ie({tx:e,removeTxFromPool:i,onSucceed:async a=>{r({txKey:e.txKey,status:pulsarCore.TransactionStatus.Success,pending:false,hash:a.task.transactionHash,finishedTimestamp:a.task.executionDate?p__default.default(a.task.executionDate).unix():void 0});let o=t[e.txKey];n&&o&&n(o);},onIntervalTick:async a=>{let o=C(a.task.taskState),s=a.task.taskState==="ExecSuccess";r({txKey:e.txKey,pending:o,status:s?pulsarCore.TransactionStatus.Success:o?void 0:pulsarCore.TransactionStatus.Failed,hash:a.task.transactionHash,finishedTimestamp:a.task.executionDate?p__default.default(a.task.executionDate).unix():void 0,errorMessage:K.includes(a.task.taskState)?a.task.lastCheckMessage:void 0,isError:!o&&!s});},onFailed:a=>{r({txKey:e.txKey,status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:a.task.transactionHash,errorMessage:a.task.lastCheckMessage,finishedTimestamp:a.task.executionDate?p__default.default(a.task.executionDate).unix():void 0});}})}var tt={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},W={[chains.mainnet.id]:"https://app.safe.global/eth:",[chains.goerli.id]:"https://app.safe.global/gor:",[chains.sepolia.id]:"https://app.safe.global/sep:",[chains.optimism.id]:"https://app.safe.global/oeth:",[chains.polygon.id]:"https://app.safe.global/matic:",[chains.arbitrum.id]:"https://app.safe.global/arb1:",[chains.avalanche.id]:"https://app.safe.global/avax:",[chains.bsc.id]:"https://app.safe.global/bnb:",[chains.base.id]:"https://app.safe.global/base:"},v={[chains.mainnet.id]:"https://safe-transaction-mainnet.safe.global/api/v1",[chains.goerli.id]:"https://safe-transaction-goerli.safe.global/api/v1",[chains.sepolia.id]:"https://safe-transaction-sepolia.safe.global/api/v1",[chains.optimism.id]:"https://safe-transaction-optimism.safe.global/api/v1",[chains.polygon.id]:"https://safe-transaction-polygon.safe.global/api/v1",[chains.arbitrum.id]:"https://safe-transaction-arbitrum.safe.global/api/v1",[chains.avalanche.id]:"https://safe-transaction-avalanche.safe.global/api/v1",[chains.bsc.id]:"https://safe-transaction-bsc.safe.global/api/v1",[chains.base.id]:"https://safe-transaction-base.safe.global/api/v1"};async function le({tx:e,onSucceed:t,onFailed:r,onIntervalTick:n,onReplaced:i,clearWatch:a}){let o=await fetch(`${v[e.chainId]}/multisig-transactions/${e.txKey}/`);if(!o.ok)return o;let s=await o.json(),c=await fetch(`${v[e.chainId]}/safes/${e.from}/multisig-transactions/?nonce=${s.nonce}`);if(!c.ok)return c;let l=(await c.json()).results.find(m=>m.isExecuted);if(l&&l.safeTxHash!==s.safeTxHash)return i?.({...s,replacedHash:l.safeTxHash}),a(true),c;if(s.isExecuted)return s.isSuccessful?t(s):r(s),a(true),o;let d=p__default.default(s.modified);return p__default.default().diff(d,"day")>=1?(a(),o):(n?.(s),o)}async function de(e){await pulsarCore.initializePollingTracker({...e,fetcher:le});}async function U({tx:e,transactionsPool:t,updateTxParams:r,onSucceedCallbacks:n,removeTxFromPool:i}){return await de({tx:e,removeTxFromPool:i,onSucceed:async a=>{r({txKey:e.txKey,status:pulsarCore.TransactionStatus.Success,pending:false,hash:a.transactionHash,finishedTimestamp:a.executionDate?p__default.default(a.executionDate).unix():void 0});let o=t[e.txKey];n&&o&&n(o);},onIntervalTick:async a=>{r({pending:!a.isExecuted,txKey:e.txKey,hash:a.transactionHash});},onFailed:a=>{r({txKey:e.txKey,status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:a.transactionHash,finishedTimestamp:a.executionDate?p__default.default(a.executionDate).unix():void 0});},onReplaced:a=>{r({txKey:e.txKey,status:pulsarCore.TransactionStatus.Replaced,pending:false,hash:a.transactionHash,replacedTxHash:a.replacedHash??viem.zeroHash,finishedTimestamp:a.executionDate?p__default.default(a.executionDate).unix():void 0});}})}var b=(n=>(n.Ethereum="ethereum",n.Safe="safe",n.Gelato="gelato",n))(b||{});async function B({tracker:e,tx:t,chains:r,...n}){switch(e){case "ethereum":await w({tx:t,chains:r,...n});break;case "gelato":await R({tx:t,...n});break;case "safe":await U({tx:t,...n});break;default:await w({tx:t,chains:r,...n});}}async function j(e,t){let{connector:r,chainId:n}=core.getAccount(t);if(r&&n!==e)try{await core.switchChain(t,{chainId:e});}catch(i){throw console.error("Failed to switch chain:",i),new Error("User rejected chain switch or an error occurred.")}}function L(e,t){if(F(e))return {tracker:"gelato",txKey:e.taskId};if(!viem.isHex(e))throw new Error("Invalid transaction key format. Expected a Hex string or GelatoTxKey object.");return t==="safe"?{tracker:"safe",txKey:e}:{tracker:"ethereum",txKey:e}}function Rt(e,t){if(e)return {checkChainForTx:r=>j(r,e),checkTransactionsTracker:(r,n)=>L(r,n),checkAndInitializeTrackerInStore:({tx:r,...n})=>B({tracker:r.tracker,tx:r,chains:t,...n})}}async function Nt({config:e,tx:t}){if(t.adapter===pulsarCore.TransactionAdapter.EVM){if(!t.nonce||!t.maxFeePerGas||!t.maxPriorityFeePerGas)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas).");try{if(!e)throw new Error("Wagmi config is not provided.");let r=core.getAccount(e);if(!r.address)throw new Error("No connected account found.");let n=115n,i=100n,a=BigInt(t.maxPriorityFeePerGas)*n/i,o=BigInt(t.maxFeePerGas)*n/i;return await core.sendTransaction(e,{to:r.address,value:0n,chainId:t.chainId,nonce:t.nonce,maxFeePerGas:o,maxPriorityFeePerGas:a})}catch(r){let n=r instanceof Error?r.message:String(r);throw new Error(`Failed to cancel transaction: ${n}`)}}else throw new Error("Failed to cancel transaction: not EVM tx adapter")}var x=null,h=null,he=300*1e3;async function zt(e){let t=Date.now();if(x&&h&&t-h<he)return x.includes(e);try{let r=await fetch("https://relay.gelato.digital/relays/v2");if(!r.ok)return x=null,h=null,!1;let i=(await r.json()).relays.map(Number);return x=i,h=t,i.includes(e)}catch(r){return console.error("Failed to check Gelato service availability:",r),x=null,h=null,false}}var u=y(chains.mainnet.id,[chains.mainnet]),Ot=async e=>{if(u)try{return await ens.getEnsName(u,{address:e})??void 0}catch(t){console.error("ENS name lookup error:",t);return}},qt=async e=>{if(u)try{return await ens.getEnsAvatar(u,{name:ens.normalize(e)})??void 0}catch(t){console.error("ENS avatar lookup error:",t);return}},Xt=async e=>{if(u)try{let t=await ens.getEnsAddress(u,{name:ens.normalize(e)});return t?t.toLocaleLowerCase():void 0}catch(t){console.error("ENS address lookup error:",t);return}},Jt=e=>!viem.isAddress(e);function ra(e){let t=core.getAccount(e),r=core.getClient(e);if(!t.address||!r)throw new Error("Wallet not connected");return {activeWallet:t,walletClient:r}}var da=(e,t,r,n)=>{let i=pulsarCore.selectTXByKey(e,r);return i?(o=>{if(i.tracker==="safe"){let c=W[i.chainId];return c?`${c}${i.from}/transactions/tx?id=multisig_${i.from}_${i.txKey}`:""}let s=t.find(c=>c.id===i.chainId);return s?.blockExplorers?.default.url?`${s.blockExplorers.default.url}/tx/${o}`:""})(n||i.adapter===pulsarCore.TransactionAdapter.EVM&&i.hash||i.txKey):""};async function xa({config:e,tx:t}){if(t.adapter===pulsarCore.TransactionAdapter.EVM){if(!t.nonce||!t.from||!t.to||!t.value||!t.input||!t.maxFeePerGas||!t.maxPriorityFeePerGas)throw new Error("Transaction is missing required fields for speed-up.");try{if(!e)throw new Error("Wagmi config is not provided.");if(!core.getAccount(e).address)throw new Error("No connected account found.");let n=115n,i=100n,a=BigInt(t.maxPriorityFeePerGas)*n/i,o=BigInt(t.maxFeePerGas)*n/i;return await core.sendTransaction(e,{to:t.to,value:BigInt(t.value),data:t.input,chainId:t.chainId,nonce:t.nonce,maxFeePerGas:o,maxPriorityFeePerGas:a})}catch(r){let n=r instanceof Error?r.message:String(r);throw new Error(`Failed to speed up transaction: ${n}`)}}else throw new Error("Failed to speed up transaction: not EVM tx adapter")}
2
+ exports.GelatoTaskState=ne;exports.SafeTransactionServiceUrls=v;exports.TransactionTracker=b;exports.cancelTxAction=Nt;exports.checkAndInitializeTrackerInStore=B;exports.checkChainForTx=j;exports.checkIsGelatoAvailable=zt;exports.checkTransactionsTracker=L;exports.createViemClient=y;exports.evmAdapter=Rt;exports.evmTracker=ae;exports.evmTrackerForStore=w;exports.fetchTxFromGelatoAPI=oe;exports.fetchTxFromSafeAPI=le;exports.gelatoTracker=ie;exports.gelatoTrackerForStore=R;exports.getActiveWalletAndClient=ra;exports.getAddress=Xt;exports.getAvatar=qt;exports.getName=Ot;exports.gnosisSafeLinksHelper=W;exports.isEnsName=Jt;exports.isGelatoTxKey=F;exports.safeSdkOptions=tt;exports.safeTracker=de;exports.safeTrackerForStore=U;exports.selectEvmTxExplorerLink=da;exports.speedUpTxAction=xa;//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/createViemClient.ts","../src/trackers/evmTracker.ts","../src/trackers/gelatoTracker.ts","../src/utils/safeConstants.ts","../src/trackers/safeTracker.ts","../src/types.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkChainForTx.ts","../src/utils/checkTransactionsTracker.ts","../src/adapters/evmAdapter.ts","../src/utils/cancelTxAction.ts","../src/utils/checkIsGelatoAvailable.ts","../src/utils/getActiveWalletAndClient.ts","../src/utils/selectEvmTxExplorerLink.ts","../src/utils/speedUpTxAction.ts"],"names":["createViemClient","chainId","chains","chain","c","createClient","http","evmTracker","onInitialize","onTxDetailsGot","onFinished","onFailed","onReplaced","tx","retryCount","retryTimeout","waitForTransactionReceiptParams","maxRetries","client","zeroHash","error","i","localTx","getTransaction","txWasReplaced","receipt","waitForTransactionReceipt","replacement","e","resolve","evmTrackerForStore","transactionsPool","updateTxParams","onSucceedCallbacks","txBlock","getBlock","timestamp","isSuccess","TransactionStatus","isHex","updatedTX","isGelatoTxKey","txKey","GelatoTaskState","isGelatoTxPending","gelatoStatus","GELATO_TERMINAL_FAILURE_STATES","fetchTxFromGelatoAPI","onSucceed","onIntervalTick","clearWatch","response","isPending","gelatoCreatedDate","dayjs","gelatoTracker","params","initializePollingTracker","gelatoTrackerForStore","removeTxFromPool","updatedTx","safeSdkOptions","gnosisSafeLinksHelper","mainnet","goerli","sepolia","optimism","polygon","arbitrum","avalanche","bsc","base","SafeTransactionServiceUrls","fetchTxFromSafeAPI","primaryTxResponse","safeStatus","nonceTxsResponse","executedTx","t","modifiedDate","safeTracker","safeTrackerForStore","TransactionTracker","checkAndInitializeTrackerInStore","tracker","rest","checkChainForTx","config","connector","activeChainId","getAccount","switchChain","checkTransactionsTracker","actionTxKey","walletType","evmAdapter","appChains","cancelTxAction","TransactionAdapter","account","gasIncreaseMultiplier","divisor","newPriorityFee","newMaxFee","sendTransaction","errorMessage","cachedRelayChainIds","cacheTimestamp","CACHE_DURATION_MS","checkIsGelatoAvailable","now","supportedChainIds","getActiveWalletAndClient","activeWallet","getWagmiAccount","walletClient","getClient","selectEvmTxExplorerLink","replacedTxHash","selectTXByKey","hash","safeBaseUrl","speedUpTxAction"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @file This file contains a utility function for creating a viem Public Client.\n */\n\nimport { http } from '@wagmi/core';\nimport { Chain, createClient, PublicClient } from 'viem';\n\n/**\n * Creates a viem Public Client for a specific chain.\n * This client is used to interact with the blockchain (e.g., fetch transaction details).\n *\n * @param {number} chainId - The ID of the chain for which to create the client.\n * @param {Chain[]} chains - An array of supported viem Chain objects.\n * @returns {PublicClient | undefined} A viem PublicClient instance if the chain is found in the provided array, otherwise undefined.\n * @ignore\n */\nexport function createViemClient(chainId: number, chains: Chain[]): PublicClient | undefined {\n // Use `find` to get the first matching chain object. It's more direct than `filter`.\n const chain = chains.find((c) => c.id === chainId);\n\n if (chain) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n return createClient({\n chain: chain,\n transport: http(),\n });\n }\n\n // Return undefined if no matching chain was found in the configuration.\n return undefined;\n}\n","/**\n * @file This file contains the tracker implementation for standard EVM transactions.\n * It uses viem's public actions (`getTransaction`, `waitForTransactionReceipt`) to monitor\n * a transaction's lifecycle from submission to finality.\n */\n\nimport { ITxTrackingStore, Transaction, TransactionStatus } from '@tuwaio/pulsar-core';\nimport {\n Chain,\n Client,\n GetTransactionReturnType,\n Hex,\n isHex,\n ReplacementReturnType,\n TransactionReceipt,\n WaitForTransactionReceiptParameters,\n zeroHash,\n} from 'viem';\nimport { getBlock, getTransaction, waitForTransactionReceipt } from 'viem/actions';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { createViemClient } from '../utils/createViemClient';\n\n/**\n * Defines the parameters for the low-level EVM transaction tracker.\n */\nexport type EVMTrackerParams = {\n /** The transaction object to track, requiring at least `chainId` and `txKey` (the transaction hash). */\n tx: Pick<Transaction<TransactionTracker>, 'chainId' | 'txKey'>;\n /** An array of `viem` chain objects supported by the application. */\n chains: Chain[];\n /** Callback executed when the getTransaction info got successfully. */\n onTxDetailsGot: (localTx: GetTransactionReturnType) => void;\n /** Callback executed when the transaction is successfully mined and included in a block. */\n onFinished: (localTx: GetTransactionReturnType, receipt: TransactionReceipt, client: Client) => Promise<void>;\n /** Callback executed when the transaction is replaced (e.g., sped up or cancelled). */\n onReplaced: (replacement: ReplacementReturnType) => void;\n /** Callback executed if an error occurs during tracking or if the transaction fails. */\n onFailed: (error?: unknown) => void;\n /** Optional callback executed once when the tracker starts. */\n onInitialize?: () => void;\n /** The number of times to retry fetching the transaction if it's not found initially. Defaults to 10. */\n retryCount?: number;\n /** The delay (in milliseconds) between retry attempts. Defaults to 3000ms. */\n retryTimeout?: number;\n /** Optional parameters to pass to viem's `waitForTransactionReceipt` function. */\n waitForTransactionReceiptParams?: WaitForTransactionReceiptParameters;\n};\n\n/**\n * A low-level tracker for monitoring a standard EVM transaction by its hash.\n * It retries fetching the transaction and then waits for its receipt.\n *\n * @param {EVMTrackerParams} params - The configuration object for the tracker.\n * @returns {Promise<void>} A promise that resolves when the tracking process is complete (or has terminally failed).\n */\nexport async function evmTracker({\n onInitialize,\n onTxDetailsGot,\n onFinished,\n onFailed,\n onReplaced,\n tx,\n chains,\n retryCount,\n retryTimeout,\n waitForTransactionReceiptParams,\n}: EVMTrackerParams): Promise<void> {\n const maxRetries = retryCount ?? 10;\n const client = createViemClient(tx.chainId as number, chains);\n\n if (onInitialize) {\n onInitialize();\n }\n\n if (tx.txKey === zeroHash) {\n throw new Error('Transaction hash is zeroHash');\n }\n\n if (!client) {\n const error = new Error(`Could not create a viem client for chainId: ${tx.chainId}`);\n onFailed(error);\n console.error(error.message);\n return;\n }\n\n // Retry loop to handle cases where the transaction is not immediately available on the RPC node.\n for (let i = 0; i < maxRetries; i++) {\n try {\n // 1. Attempt to fetch the transaction details.\n const localTx = await getTransaction(client, { hash: tx.txKey as Hex });\n\n onTxDetailsGot(localTx);\n\n let txWasReplaced = false;\n\n try {\n // 2. Wait for the transaction to be mined.\n const receipt = await waitForTransactionReceipt(client, {\n hash: localTx.hash,\n onReplaced: (replacement: ReplacementReturnType) => {\n txWasReplaced = true;\n onReplaced(replacement);\n },\n pollingInterval: 10_000,\n ...waitForTransactionReceiptParams,\n });\n\n // If onReplaced was called, the promise resolves but we should not proceed.\n if (txWasReplaced) {\n return;\n }\n\n // 3. Transaction is mined, call the onFinished callback.\n await onFinished(localTx, receipt, client);\n } catch (e) {\n // Error occurred while waiting for the receipt (e.g., timeout, reverted).\n onFailed(e);\n console.error('Error waiting for transaction receipt:', e);\n }\n\n // Exit the retry loop once the transaction is found and processed.\n return;\n } catch (e) {\n // Error occurred while fetching the initial transaction details.\n if (i === maxRetries - 1) {\n onFailed(e);\n console.error(`Error tracking EVM transaction after ${maxRetries} retries:`, e);\n return;\n }\n }\n // Wait before the next retry.\n await new Promise((resolve) => setTimeout(resolve, retryTimeout ?? 3000));\n }\n}\n\n/**\n * A higher-level wrapper for `evmTracker` that integrates directly with the Zustand store.\n * It provides the necessary callbacks to update the transaction's state in the store.\n *\n * @template T - The application-specific transaction union type.\n */\nexport async function evmTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n chains,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n}: Pick<EVMTrackerParams, 'chains'> &\n Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks'\n > & {\n tx: T;\n }) {\n return await evmTracker({\n tx,\n chains,\n onInitialize: () => {\n updateTxParams({\n txKey: tx.txKey,\n hash: tx.txKey as Hex,\n pending: tx.pending,\n });\n },\n onTxDetailsGot: (localTx) => {\n updateTxParams({\n to: localTx.to ?? '',\n input: localTx.input,\n value: String(localTx.value),\n txKey: tx.txKey,\n pending: tx.pending,\n nonce: localTx.nonce,\n hash: localTx.hash,\n maxFeePerGas: String(localTx.maxFeePerGas),\n maxPriorityFeePerGas: String(localTx.maxPriorityFeePerGas),\n });\n },\n onFinished: async (localTx, receipt, client) => {\n const txBlock = await getBlock(client, { blockNumber: receipt.blockNumber });\n const timestamp = Number(txBlock.timestamp);\n const isSuccess = receipt.status === 'success';\n\n updateTxParams({\n txKey: tx.txKey,\n status: isSuccess ? TransactionStatus.Success : TransactionStatus.Failed,\n to: isHex(receipt.to) ? receipt.to : undefined,\n nonce: localTx.nonce,\n pending: false,\n isError: !isSuccess,\n hash: localTx.hash,\n finishedTimestamp: timestamp,\n });\n\n // After updating the state, retrieve the latest version of the transaction.\n const updatedTX = transactionsPool[tx.txKey];\n if (isSuccess && onSucceedCallbacks && updatedTX) {\n onSucceedCallbacks(updatedTX);\n }\n },\n onReplaced: (replacement) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Replaced,\n replacedTxHash: replacement.transaction.hash,\n pending: false,\n });\n },\n onFailed: (error?: unknown) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage: error instanceof Error ? error.message : 'Transaction failed or could not be tracked.',\n });\n },\n });\n}\n","/**\n * @file This file implements the transaction tracking logic for meta-transactions relayed via the Gelato Network.\n * It uses a polling mechanism to check the status of a Gelato Task ID from the Gelato API.\n */\n\nimport {\n InitializePollingTracker,\n initializePollingTracker,\n ITxTrackingStore,\n Transaction,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Hex } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Defines the shape of the identifier for a Gelato transaction task.\n */\nexport type GelatoTxKey = {\n taskId: string;\n};\n\n/**\n * A type guard to determine if an ActionTxKey is a GelatoTxKey.\n * @param {ActionTxKey} txKey - The transaction key to check.\n * @returns {boolean} True if the key is for a Gelato transaction.\n */\nexport function isGelatoTxKey(txKey: ActionTxKey): txKey is GelatoTxKey {\n return (txKey as GelatoTxKey).taskId !== undefined;\n}\n\n/**\n * Enum representing the possible states of a Gelato task.\n * @see https://docs.gelato.network/developer-services/relay/api/get-task-status\n */\nexport enum GelatoTaskState {\n CheckPending = 'CheckPending',\n ExecPending = 'ExecPending',\n WaitingForConfirmation = 'WaitingForConfirmation',\n ExecSuccess = 'ExecSuccess',\n ExecReverted = 'ExecReverted',\n Cancelled = 'Cancelled',\n}\n\n/**\n * Defines the shape of the response from the Gelato `getTaskStatus` API endpoint.\n */\nexport type GelatoTaskStatusResponse = {\n task: {\n chainId: number;\n taskId: string;\n taskState: GelatoTaskState;\n creationDate?: string;\n executionDate?: string;\n transactionHash?: Hex;\n blockNumber?: number;\n lastCheckMessage?: string;\n };\n};\n\n/**\n * A utility type for the initial Gelato transaction object passed to the tracker.\n */\ntype InitialGelatoTx = Pick<Transaction<TransactionTracker>, 'txKey'> & {\n pending?: boolean;\n};\n\n/**\n * Defines the parameters required for the low-level `gelatoTracker` function.\n */\nexport type GelatoTrackerParams = Pick<\n InitializePollingTracker<GelatoTaskStatusResponse, InitialGelatoTx, TransactionTracker>,\n | 'tx'\n | 'removeTxFromPool'\n | 'onInitialize'\n | 'onSucceed'\n | 'onFailed'\n | 'onIntervalTick'\n | 'pollingInterval'\n | 'retryCount'\n>;\n\n/**\n * Checks if a Gelato task state is considered pending.\n * @param {GelatoTaskState} [gelatoStatus] - The current status of the Gelato task.\n * @returns {boolean} True if the status is pending.\n */\nfunction isGelatoTxPending(gelatoStatus?: GelatoTaskState): boolean {\n if (!gelatoStatus) return true;\n const pendingStates = [\n GelatoTaskState.CheckPending,\n GelatoTaskState.ExecPending,\n GelatoTaskState.WaitingForConfirmation,\n ];\n return pendingStates.includes(gelatoStatus);\n}\n\n/**\n * A set of terminal states that indicate a transaction has failed or been cancelled.\n */\nconst GELATO_TERMINAL_FAILURE_STATES = [GelatoTaskState.ExecReverted, GelatoTaskState.Cancelled];\n\n/**\n * The fetcher function passed to `initializePollingTracker` to get the status of a Gelato task.\n * @param {object} params - The parameters for fetching the transaction status.\n * @returns {Promise<Response>} The raw response from the fetch call.\n */\nexport async function fetchTxFromGelatoAPI({\n tx,\n onSucceed,\n onFailed,\n onIntervalTick,\n clearWatch,\n}: {\n clearWatch: (withoutRemoving?: boolean) => void;\n} & Pick<GelatoTrackerParams, 'onIntervalTick' | 'onSucceed' | 'onFailed' | 'tx'>): Promise<Response> {\n const response = await fetch(`https://api.gelato.digital/tasks/status/${tx.txKey}/`);\n\n if (response.ok) {\n const gelatoStatus = (await response.json()) as GelatoTaskStatusResponse;\n const isPending = isGelatoTxPending(gelatoStatus.task.taskState);\n\n // Safeguard: Stop polling for transactions that have been pending for over a day.\n if (gelatoStatus.task.creationDate) {\n const gelatoCreatedDate = dayjs(gelatoStatus.task.creationDate);\n if (dayjs().diff(gelatoCreatedDate, 'day') >= 1 && isPending) {\n clearWatch(); // Stop polling but don't remove from pool\n return response;\n }\n }\n\n onIntervalTick?.(gelatoStatus);\n\n if (!isPending) {\n clearWatch(true); // Stop polling but keep the transaction for UI feedback\n if (gelatoStatus.task.taskState === GelatoTaskState.ExecSuccess) {\n onSucceed(gelatoStatus);\n } else if (GELATO_TERMINAL_FAILURE_STATES.includes(gelatoStatus.task.taskState)) {\n onFailed(gelatoStatus);\n }\n }\n }\n\n return response;\n}\n\n/**\n * A low-level tracker for monitoring Gelato transactions. It wraps the generic polling\n * tracker with the Gelato-specific fetcher logic.\n *\n * @param {GelatoTrackerParams} params - The configuration object for the tracker.\n * @returns {Promise<void>}\n */\nexport async function gelatoTracker(params: GelatoTrackerParams): Promise<void> {\n await initializePollingTracker({\n ...params,\n fetcher: fetchTxFromGelatoAPI,\n });\n}\n\n/**\n * A higher-level wrapper for `gelatoTracker` that integrates directly with the Zustand store.\n * It provides the necessary callbacks to update the transaction's state in the store.\n *\n * @template T - The application-specific transaction union type.\n */\nexport async function gelatoTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n removeTxFromPool,\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}) {\n return await gelatoTracker({\n tx,\n removeTxFromPool,\n onSucceed: async (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Success,\n pending: false,\n hash: response.task.transactionHash,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n });\n\n const updatedTx = transactionsPool[tx.txKey];\n if (onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onIntervalTick: async (response) => {\n const isPending = isGelatoTxPending(response.task.taskState);\n const isSuccess = response.task.taskState === GelatoTaskState.ExecSuccess;\n\n updateTxParams({\n txKey: tx.txKey,\n pending: isPending,\n status: isSuccess ? TransactionStatus.Success : isPending ? undefined : TransactionStatus.Failed,\n hash: response.task.transactionHash,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n errorMessage: GELATO_TERMINAL_FAILURE_STATES.includes(response.task.taskState)\n ? response.task.lastCheckMessage\n : undefined,\n isError: !isPending && !isSuccess,\n });\n },\n onFailed: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response.task.transactionHash,\n errorMessage: response.task.lastCheckMessage,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n });\n },\n });\n}\n","/**\n * @file This file contains constants related to Safe (formerly Gnosis Safe) configuration,\n * including SDK options, web app URLs, and transaction service API endpoints.\n */\n\nimport { arbitrum, avalanche, base, bsc, goerli, mainnet, optimism, polygon, sepolia } from 'viem/chains';\n\n/**\n * Configuration options for the Safe Apps SDK.\n * This is typically used when integrating with the Safe environment.\n */\nexport const safeSdkOptions = {\n // A list of allowed domains to interact with the Safe Apps SDK.\n allowedDomains: [/gnosis-safe.io$/, /app.safe.global$/, /metissafe.tech$/],\n // A flag to enable or disable debug logging for the SDK.\n debug: false,\n};\n\n/**\n * A mapping of chain IDs to their corresponding Safe web application URL prefixes.\n * Used by selectors like `selectTxExplorerLink` to build correct links for Safe transactions.\n * The prefixes (e.g., 'eth:', 'gor:') are part of the Safe URL scheme.\n * @type {Record<number, string>}\n */\nexport const gnosisSafeLinksHelper: Record<number, string> = {\n [mainnet.id]: 'https://app.safe.global/eth:',\n [goerli.id]: 'https://app.safe.global/gor:',\n [sepolia.id]: 'https://app.safe.global/sep:',\n [optimism.id]: 'https://app.safe.global/oeth:',\n [polygon.id]: 'https://app.safe.global/matic:',\n [arbitrum.id]: 'https://app.safe.global/arb1:',\n [avalanche.id]: 'https://app.safe.global/avax:',\n [bsc.id]: 'https://app.safe.global/bnb:',\n [base.id]: 'https://app.safe.global/base:',\n};\n\n/**\n * A mapping of chain IDs to their corresponding Safe Transaction Service API endpoints.\n * This is used by the `safeTracker` to fetch the status of multisig transactions.\n * @type {Record<number, string>}\n */\nexport const SafeTransactionServiceUrls: Record<number, string> = {\n [mainnet.id]: 'https://safe-transaction-mainnet.safe.global/api/v1',\n [goerli.id]: 'https://safe-transaction-goerli.safe.global/api/v1',\n [sepolia.id]: 'https://safe-transaction-sepolia.safe.global/api/v1',\n [optimism.id]: 'https://safe-transaction-optimism.safe.global/api/v1',\n [polygon.id]: 'https://safe-transaction-polygon.safe.global/api/v1',\n [arbitrum.id]: 'https://safe-transaction-arbitrum.safe.global/api/v1',\n [avalanche.id]: 'https://safe-transaction-avalanche.safe.global/api/v1',\n [bsc.id]: 'https://safe-transaction-bsc.safe.global/api/v1',\n [base.id]: 'https://safe-transaction-base.safe.global/api/v1',\n};\n","/**\n * @file This file implements the transaction tracking logic for Gnosis Safe (now Safe) multisig transactions.\n * It uses a polling mechanism to query the Safe Transaction Service API for the status of a `safeTxHash`.\n */\n\nimport {\n InitializePollingTracker,\n initializePollingTracker,\n ITxTrackingStore,\n Transaction,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Hex, zeroHash } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { SafeTransactionServiceUrls } from '../utils/safeConstants';\n\n/**\n * Defines the shape of the transaction object passed to the Safe tracker.\n */\ntype InitialSafeTx = Pick<Transaction<TransactionTracker>, 'txKey' | 'chainId' | 'from'> & {\n pending?: boolean;\n};\n\n/**\n * Defines the shape of the primary response for a single transaction from the Safe Transaction Service API.\n */\nexport type SafeTxStatusResponse = {\n transactionHash: string;\n safeTxHash: string;\n isExecuted: boolean;\n isSuccessful: boolean | null;\n executionDate: string | null;\n submissionDate: string | null;\n modified: string;\n nonce: number;\n replacedHash?: string; // Custom field for passing replacement info\n};\n\n/**\n * Defines the shape of the response when querying for multiple transactions (e.g., by nonce).\n */\ntype SafeTxSameNonceResponse = {\n count: number;\n results: SafeTxStatusResponse[];\n};\n\n/**\n * Defines the parameters for the low-level `safeTracker` function.\n */\nexport type SafeTrackerParams = Pick<\n InitializePollingTracker<SafeTxStatusResponse, InitialSafeTx, TransactionTracker>,\n | 'tx'\n | 'removeTxFromPool'\n | 'onInitialize'\n | 'onSucceed'\n | 'onFailed'\n | 'onReplaced'\n | 'onIntervalTick'\n | 'pollingInterval'\n | 'retryCount'\n>;\n\n/**\n * The fetcher function passed to `initializePollingTracker` to get the status of a Safe transaction.\n * @returns The raw response from the fetch call.\n */\nexport async function fetchTxFromSafeAPI({\n tx,\n onSucceed,\n onFailed,\n onIntervalTick,\n onReplaced,\n clearWatch,\n}: {\n clearWatch: (withoutRemoving?: boolean) => void;\n} & Pick<SafeTrackerParams, 'onIntervalTick' | 'onSucceed' | 'onFailed' | 'onReplaced' | 'tx'>): Promise<Response> {\n const primaryTxResponse = await fetch(\n `${SafeTransactionServiceUrls[tx.chainId as number]}/multisig-transactions/${tx.txKey}/`,\n );\n\n if (!primaryTxResponse.ok) {\n return primaryTxResponse; // Let the polling tracker handle the retry\n }\n\n const safeStatus = (await primaryTxResponse.json()) as SafeTxStatusResponse;\n\n // Fetch all other transactions with the same nonce to check for replacements.\n const nonceTxsResponse = await fetch(\n `${SafeTransactionServiceUrls[tx.chainId as number]}/safes/${tx.from}/multisig-transactions/?nonce=${safeStatus.nonce}`,\n );\n\n if (!nonceTxsResponse.ok) {\n return nonceTxsResponse; // Let the polling tracker handle the retry\n }\n\n const sameNonceTxs = (await nonceTxsResponse.json()) as SafeTxSameNonceResponse;\n const executedTx = sameNonceTxs.results.find((t) => t.isExecuted);\n\n // Case 1: Another transaction with the same nonce was executed. This one was replaced.\n if (executedTx && executedTx.safeTxHash !== safeStatus.safeTxHash) {\n onReplaced?.({ ...safeStatus, replacedHash: executedTx.safeTxHash });\n clearWatch(true);\n return nonceTxsResponse;\n }\n\n // Case 2: The transaction itself was executed.\n if (safeStatus.isExecuted) {\n if (safeStatus.isSuccessful) {\n onSucceed(safeStatus);\n } else {\n onFailed(safeStatus);\n }\n clearWatch(true);\n return primaryTxResponse;\n }\n\n // Case 3: The transaction is still pending.\n // Safeguard: Stop polling for transactions that have been pending for over a day.\n const modifiedDate = dayjs(safeStatus.modified);\n if (dayjs().diff(modifiedDate, 'day') >= 1) {\n clearWatch(); // Stop polling and remove from pool\n return primaryTxResponse;\n }\n\n // Otherwise, just report the current status and continue polling.\n onIntervalTick?.(safeStatus);\n\n return primaryTxResponse;\n}\n\n/**\n * A low-level tracker for monitoring Safe multisig transactions.\n * It wraps the generic polling tracker with the Safe-specific fetcher logic.\n */\nexport async function safeTracker(params: SafeTrackerParams): Promise<void> {\n await initializePollingTracker<SafeTxStatusResponse, InitialSafeTx, TransactionTracker>({\n ...params,\n fetcher: fetchTxFromSafeAPI,\n });\n}\n\n/**\n * A higher-level wrapper for `safeTracker` that integrates directly with the Zustand store.\n */\nexport async function safeTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n removeTxFromPool,\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}) {\n return await safeTracker({\n tx,\n removeTxFromPool,\n onSucceed: async (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Success,\n pending: false,\n hash: response.transactionHash as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n\n const updatedTx = transactionsPool[tx.txKey];\n if (onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onIntervalTick: async (response) => {\n updateTxParams({\n pending: !response.isExecuted,\n txKey: tx.txKey,\n hash: response.transactionHash as Hex,\n });\n },\n onFailed: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response.transactionHash as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n onReplaced: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Replaced,\n pending: false,\n hash: response.transactionHash as Hex,\n replacedTxHash: (response.replacedHash ?? zeroHash) as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n });\n}\n","/**\n * @file This file defines types and enums specific to the EVM transaction tracking package.\n * It includes identifiers for different tracking strategies and the shape of transaction keys.\n */\n\nimport { Hex } from 'viem';\n\nimport { GelatoTxKey } from './trackers/gelatoTracker';\n\n/**\n * Enum representing the different tracking strategies available for EVM transactions.\n */\nexport enum TransactionTracker {\n /** For standard on-chain EVM transactions tracked by their hash. */\n Ethereum = 'ethereum',\n /** For multi-signature transactions managed by a Safe contract. */\n Safe = 'safe',\n /** For meta-transactions relayed through the Gelato Network. */\n Gelato = 'gelato',\n}\n\n/**\n * Represents the unique identifier returned by an action function after a transaction is submitted.\n * This key is used to determine which tracker should monitor the transaction.\n * It can be a standard transaction hash or a structured key from a relay service like Gelato.\n * @typedef {Hex | GelatoTxKey} ActionTxKey\n */\nexport type ActionTxKey = Hex | GelatoTxKey;\n","/**\n * @file This file contains a utility function that acts as a router to initialize the correct transaction tracker.\n * Based on a transaction's `tracker` property, it delegates the tracking task to the appropriate implementation.\n */\n\nimport { ITxTrackingStore, Transaction } from '@tuwaio/pulsar-core';\nimport { Chain } from 'viem';\n\nimport { evmTrackerForStore } from '../trackers/evmTracker';\nimport { gelatoTrackerForStore } from '../trackers/gelatoTracker';\nimport { safeTrackerForStore } from '../trackers/safeTracker';\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Initializes the appropriate tracker for a given transaction based on its `tracker` type.\n * This function acts as a central router, delegating to the specific tracker implementation\n * (e.g., EVM, Gelato, Safe).\n *\n * @template T - The application-specific transaction union type.\n * @param {object} params - The parameters for initializing the tracker.\n * @param {TransactionTracker} params.tracker - The type of tracker to use for the transaction.\n * @param {T} params.tx - The transaction object to be tracked.\n * @param {Chain[]} params.chains - An array of supported chain objects, required for some trackers (like the EVM tracker).\n * @param {object} params.rest - The rest of the parameters, which are the relevant methods from the Zustand store\n * (`transactionsPool`, `updateTxParams`, `onSucceedCallbacks`, `removeTxFromPool`).\n * @returns {Promise<void>} A promise that resolves once the tracking process has been initiated.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<TransactionTracker>>({\n tracker,\n tx,\n chains,\n ...rest\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n chains: Chain[];\n tx: T;\n tracker: TransactionTracker;\n}): Promise<void> {\n switch (tracker) {\n case TransactionTracker.Ethereum:\n await evmTrackerForStore({\n tx,\n chains,\n ...rest,\n });\n break;\n\n case TransactionTracker.Gelato:\n // The Gelato tracker does not need the `chains` param as it uses its own API endpoints.\n await gelatoTrackerForStore({\n tx,\n ...rest,\n });\n break;\n\n case TransactionTracker.Safe:\n // The Safe tracker also uses its own API endpoints.\n await safeTrackerForStore({\n tx,\n ...rest,\n });\n break;\n\n // The default case handles any unknown or unspecified tracker types as standard EVM transactions.\n default:\n await evmTrackerForStore({\n tx,\n chains,\n ...rest,\n });\n }\n}\n","/**\n * @file This file contains a utility to ensure the user's wallet is connected to the correct chain before proceeding.\n */\n\nimport { Config, switchChain } from '@wagmi/core';\nimport { getAccount } from '@wagmi/core';\n\n/**\n * Checks if the user's wallet is connected to the specified chain. If not, it prompts\n * the user to switch to the correct chain and waits for the operation to complete.\n *\n * @param {number} chainId - The ID of the desired blockchain network.\n * @param {Config} config - The wagmi configuration object.\n * @returns {Promise<void>} A promise that resolves when the wallet is on the correct chain,\n * or rejects if the user cancels the switch or an error occurs.\n * @throws {Error} Throws an error if the user rejects the chain switch or if the switch fails.\n */\nexport async function checkChainForTx(chainId: number, config: Config): Promise<void> {\n const { connector, chainId: activeChainId } = getAccount(config);\n\n // Proceed only if a wallet is connected and it's on the wrong chain.\n if (connector && activeChainId !== chainId) {\n try {\n // Directly await the switchChain call. This pauses execution until the user responds.\n await switchChain(config, { chainId });\n } catch (e) {\n // The user rejected the request or an error occurred.\n console.error('Failed to switch chain:', e);\n throw new Error('User rejected chain switch or an error occurred.');\n }\n }\n}\n","/**\n * @file This file contains a utility function to determine the correct tracker for a transaction\n * based on the key returned by the submission function and the wallet type.\n */\n\nimport { isHex } from 'viem';\n\nimport { isGelatoTxKey } from '../trackers/gelatoTracker';\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Determines which transaction tracker to use based on the format of the transaction key and the wallet type.\n *\n * This function is a critical routing step after a transaction is submitted.\n * It follows a priority order:\n * 1. Checks for a Gelato Task ID.\n * 2. Checks if the wallet type is 'safe'.\n * 3. Defaults to a standard Ethereum tracker.\n *\n * @param {ActionTxKey} actionTxKey - The key returned from the transaction submission function (e.g., a hash or a Gelato task object).\n * @param {string} walletType - The type of the wallet that initiated the action (e.g., 'safe', 'metaMask').\n * @returns {{ tracker: TransactionTracker; txKey: string }} An object containing the determined tracker type and the final string-based transaction key.\n */\nexport function checkTransactionsTracker(\n actionTxKey: ActionTxKey,\n walletType: string,\n): { tracker: TransactionTracker; txKey: string } {\n // 1. Highest priority: Check if the key matches the Gelato task structure.\n if (isGelatoTxKey(actionTxKey)) {\n return {\n tracker: TransactionTracker.Gelato,\n txKey: actionTxKey.taskId,\n };\n }\n\n // At this point, actionTxKey must be a Hex string (transaction hash or SafeTxHash).\n // We can add a check for robustness, although TypeScript should infer this.\n if (!isHex(actionTxKey)) {\n throw new Error('Invalid transaction key format. Expected a Hex string or GelatoTxKey object.');\n }\n\n // 2. Second priority: Check if the transaction came from a Safe wallet.\n if (walletType === 'safe') {\n return {\n tracker: TransactionTracker.Safe,\n txKey: actionTxKey,\n };\n }\n\n // 3. Default: Treat as a standard on-chain Ethereum transaction.\n return {\n tracker: TransactionTracker.Ethereum,\n txKey: actionTxKey,\n };\n}\n","import { ITxTrackingStore, Transaction } from '@tuwaio/pulsar-core';\nimport { Config } from '@wagmi/core';\nimport { Chain } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkChainForTx } from '../utils/checkChainForTx';\nimport { checkTransactionsTracker } from '../utils/checkTransactionsTracker';\n\nexport function evmAdapter<T extends Transaction<TransactionTracker>>(config: Config, appChains: Chain[]) {\n if (config) {\n return {\n checkChainForTx: (chainId: string | number) => checkChainForTx(chainId as number, config),\n checkTransactionsTracker: (actionTxKey: ActionTxKey, walletType: string) =>\n checkTransactionsTracker(actionTxKey, walletType),\n checkAndInitializeTrackerInStore: ({\n tx,\n ...rest\n }: { tx: T } & Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n >) => checkAndInitializeTrackerInStore({ tracker: tx.tracker, tx, chains: appChains, ...rest }),\n };\n }\n}\n","import { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n/**\n * Cancels a pending transaction by sending a new, zero-value transaction to oneself\n * with the same nonce but a higher gas price.\n *\n * @param {object} params - The parameters for the cancellation.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The transaction object to be canceled. Must contain nonce, gas fees, etc.\n *\n * @returns {Promise<Hex>} A promise that resolves with the hash of the new cancellation transaction.\n *\n * @throws {Error} Throws an error if the transaction is missing required fields or if sending fails.\n *\n * @example\n * ```ts\n * import { cancelTxAction } from './cancelTxAction';\n *\n * const handleCancel = async () => {\n * try {\n * const cancelTxHash = await cancelTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Cancellation transaction sent:', cancelTxHash);\n * } catch (error) {\n * console.error('Failed to cancel transaction:', error);\n * }\n * };\n * ```\n */\nexport async function cancelTxAction<T extends Transaction<any>>({\n config,\n tx,\n}: {\n config: Config;\n tx: T;\n}): Promise<Hex> {\n if (tx.adapter === TransactionAdapter.EVM) {\n // Ensure the transaction has all the necessary details for cancellation.\n if (!tx.nonce || !tx.maxFeePerGas || !tx.maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for cancellation (nonce, maxFeePerGas).');\n }\n\n try {\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // Increase gas fees by 15% to ensure the cancellation transaction is prioritized.\n const gasIncreaseMultiplier = 115n; // 115%\n const divisor = 100n;\n const newPriorityFee = (BigInt(tx.maxPriorityFeePerGas) * gasIncreaseMultiplier) / divisor;\n const newMaxFee = (BigInt(tx.maxFeePerGas) * gasIncreaseMultiplier) / divisor;\n\n // Send a zero-value transaction to your own address with the same nonce.\n const hash = await sendTransaction(config, {\n to: account.address,\n value: 0n,\n chainId: tx.chainId as number,\n nonce: tx.nonce,\n maxFeePerGas: newMaxFee,\n maxPriorityFeePerGas: newPriorityFee,\n });\n\n return hash;\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n // Re-throw the error with more context.\n throw new Error(`Failed to cancel transaction: ${errorMessage}`);\n }\n } else {\n throw new Error(`Failed to cancel transaction: not EVM tx adapter`);\n }\n}\n","/**\n * @file This file contains a utility to check if the Gelato Relay service is available for a specific chain.\n */\n\n// --- In-memory cache to store the list of supported chains ---\nlet cachedRelayChainIds: number[] | null = null;\nlet cacheTimestamp: number | null = null;\nconst CACHE_DURATION_MS = 5 * 60 * 1000; // Cache the list for 5 minutes\n\n/**\n * Checks if the Gelato Relay service supports a given chain ID.\n * The result is cached in memory for 5 minutes to avoid excessive network requests.\n *\n * @param {number} chainId - The chain identifier to check.\n * @returns {Promise<boolean>} True if Gelato supports the chain, false otherwise.\n */\nexport async function checkIsGelatoAvailable(chainId: number): Promise<boolean> {\n const now = Date.now();\n\n // 1. Check if a valid cache exists.\n if (cachedRelayChainIds && cacheTimestamp && now - cacheTimestamp < CACHE_DURATION_MS) {\n return cachedRelayChainIds.includes(chainId);\n }\n\n // 2. If no valid cache, fetch from the API.\n try {\n const response = await fetch('https://relay.gelato.digital/relays/v2');\n if (!response.ok) {\n // Clear cache in case of a temporary API failure\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n return false;\n }\n\n const data = (await response.json()) as { relays: string[] };\n const supportedChainIds = data.relays.map(Number);\n\n // 3. Update the cache.\n cachedRelayChainIds = supportedChainIds;\n cacheTimestamp = now;\n\n return supportedChainIds.includes(chainId);\n } catch (e) {\n console.error('Failed to check Gelato service availability:', e);\n // Clear cache on error\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n return false;\n }\n}\n","/**\n * @file This file contains a utility for safely retrieving the active wallet account and viem client.\n */\n\nimport { Config, getClient, GetClientReturnType } from '@wagmi/core';\nimport { getAccount as getWagmiAccount, GetAccountReturnType } from '@wagmi/core';\n\n/**\n * Retrieves the active wallet account and the viem Wallet Client from the wagmi config.\n * It ensures that a wallet is connected by throwing an error if it's not.\n *\n * @param {Config} config - The wagmi configuration object.\n * @returns {{ activeWallet: GetAccountReturnType; walletClient: GetClientReturnType }} An object containing the connected account details and the viem Wallet Client.\n * @throws {Error} Throws an error with the message \"Wallet not connected\" if no wallet is connected or the client is unavailable.\n */\nexport function getActiveWalletAndClient(config: Config): {\n activeWallet: GetAccountReturnType;\n walletClient: GetClientReturnType;\n} {\n const activeWallet = getWagmiAccount(config);\n const walletClient = getClient(config);\n\n // This check is crucial to prevent downstream errors.\n if (!activeWallet.address || !walletClient) {\n throw new Error('Wallet not connected');\n }\n\n return { activeWallet, walletClient };\n}\n","import { selectTXByKey, Transaction, TransactionAdapter, TransactionPool } from '@tuwaio/pulsar-core';\nimport { Chain, Hex } from 'viem';\n\nimport { TransactionTracker } from '../types';\nimport { gnosisSafeLinksHelper } from './safeConstants';\n\n/**\n * Generates a URL to a block explorer for a given transaction.\n * It handles different URL structures for standard EVM transactions and Safe transactions.\n *\n * @template TR - The generic type for the tracker identifier.\n * @template T - The transaction type.\n * @param {TransactionPool<TR, T>} transactionsPool - The entire pool of transactions from the store.\n * @param {Chain[]} chains - An array of supported chain objects from viem.\n * @param {Hex} txKey - The tx key of the transaction for which to generate the link.\n * @param {Hex} [replacedTxHash] - Optional. If provided, the link will be generated for this hash instead of the original.\n * @returns {string} The URL to the transaction on the corresponding block explorer, or an empty string if not found.\n */\nexport const selectEvmTxExplorerLink = <TR, T extends Transaction<TR>>(\n transactionsPool: TransactionPool<TR, T>,\n chains: Chain[],\n txKey: Hex,\n replacedTxHash?: Hex,\n): string => {\n const tx = selectTXByKey(transactionsPool, txKey);\n\n if (!tx) {\n return '';\n }\n\n /**\n * Internal helper to construct the final URL based on the tracker type.\n * @param {string} hash - The transaction hash to include in the URL.\n * @returns {string} The constructed explorer URL.\n */\n const constructUrl = (hash: string): string => {\n // For Safe transactions, generate a link to the Safe web app.\n if (tx.tracker === TransactionTracker.Safe) {\n const safeBaseUrl = gnosisSafeLinksHelper[tx.chainId as number];\n return safeBaseUrl ? `${safeBaseUrl}${tx.from}/transactions/tx?id=multisig_${tx.from}_${tx.txKey}` : '';\n }\n\n // For standard EVM transactions, find the chain's default block explorer.\n const chain = chains.find((chain) => chain.id === tx.chainId);\n\n if (!chain?.blockExplorers?.default.url) {\n // Return empty string if the chain or its explorer URL is not configured.\n return '';\n }\n\n return `${chain.blockExplorers.default.url}/tx/${hash}`;\n };\n\n // Prioritize the replaced hash if it exists, otherwise use the original.\n return constructUrl(replacedTxHash || (tx.adapter === TransactionAdapter.EVM && tx.hash) || tx.txKey);\n};\n","import { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n/**\n * Speeds up a pending transaction by resubmitting it with the same nonce but higher gas fees.\n * This is a common strategy to prevent a transaction from getting stuck.\n *\n * @param {object} params - The parameters required to speed up the transaction.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The original transaction object that needs to be sped up.\n *\n * @returns {Promise<Hex>} A promise that resolves with the hash of the new, speed-up transaction.\n *\n * @throws {Error} Throws an error if the wagmi config is not provided, the account is not found,\n * or if the transaction is missing required fields (`nonce`, `maxFeePerGas`, etc.).\n *\n * @example\n * ```ts\n * import { speedUpTxAction } from './speedUpTxAction';\n *\n * const handleSpeedUp = async () => {\n * try {\n * const newTxHash = await speedUpTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Transaction sped up with new hash:', newTxHash);\n * } catch (error) {\n * console.error('Failed to speed up transaction:', error);\n * }\n * };\n * ```\n */\nexport async function speedUpTxAction<TR, T extends Transaction<TR>>({\n config,\n tx,\n}: {\n config: Config;\n tx: T;\n}): Promise<Hex> {\n if (tx.adapter === TransactionAdapter.EVM) {\n // Ensure all necessary transaction details are present.\n if (!tx.nonce || !tx.from || !tx.to || !tx.value || !tx.input || !tx.maxFeePerGas || !tx.maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for speed-up.');\n }\n\n try {\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // To replace a pending transaction, the new gas fees must be higher.\n // We increase both fees by 15% as a common strategy to ensure replacement.\n const gasIncreaseMultiplier = 115n; // 115%\n const divisor = 100n;\n const newPriorityFee = (BigInt(tx.maxPriorityFeePerGas) * gasIncreaseMultiplier) / divisor;\n const newMaxFee = (BigInt(tx.maxFeePerGas) * gasIncreaseMultiplier) / divisor;\n\n // Resubmit the transaction with the same details but higher gas fees.\n return await sendTransaction(config, {\n to: tx.to as Hex,\n value: BigInt(tx.value),\n data: tx.input as Hex,\n chainId: tx.chainId as number,\n nonce: tx.nonce,\n maxFeePerGas: newMaxFee,\n maxPriorityFeePerGas: newPriorityFee,\n });\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n // Re-throw the error with more context.\n throw new Error(`Failed to speed up transaction: ${errorMessage}`);\n }\n } else {\n throw new Error(`Failed to speed up transaction: not EVM tx adapter`);\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/createViemClient.ts","../src/trackers/evmTracker.ts","../src/trackers/gelatoTracker.ts","../src/utils/safeConstants.ts","../src/trackers/safeTracker.ts","../src/types.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkChainForTx.ts","../src/utils/checkTransactionsTracker.ts","../src/adapters/evmAdapter.ts","../src/utils/cancelTxAction.ts","../src/utils/checkIsGelatoAvailable.ts","../src/utils/ensUtils.ts","../src/utils/getActiveWalletAndClient.ts","../src/utils/selectEvmTxExplorerLink.ts","../src/utils/speedUpTxAction.ts"],"names":["createViemClient","chainId","chains","chain","c","createClient","http","evmTracker","onInitialize","onTxDetailsGot","onFinished","onFailed","onReplaced","tx","retryCount","retryTimeout","waitForTransactionReceiptParams","maxRetries","client","zeroHash","error","i","localTx","getTransaction","txWasReplaced","receipt","waitForTransactionReceipt","replacement","e","resolve","evmTrackerForStore","transactionsPool","updateTxParams","onSucceedCallbacks","txBlock","getBlock","timestamp","isSuccess","TransactionStatus","isHex","updatedTX","isGelatoTxKey","txKey","GelatoTaskState","isGelatoTxPending","gelatoStatus","GELATO_TERMINAL_FAILURE_STATES","fetchTxFromGelatoAPI","onSucceed","onIntervalTick","clearWatch","response","isPending","gelatoCreatedDate","dayjs","gelatoTracker","params","initializePollingTracker","gelatoTrackerForStore","removeTxFromPool","updatedTx","safeSdkOptions","gnosisSafeLinksHelper","mainnet","goerli","sepolia","optimism","polygon","arbitrum","avalanche","bsc","base","SafeTransactionServiceUrls","fetchTxFromSafeAPI","primaryTxResponse","safeStatus","nonceTxsResponse","executedTx","t","modifiedDate","safeTracker","safeTrackerForStore","TransactionTracker","checkAndInitializeTrackerInStore","tracker","rest","checkChainForTx","config","connector","activeChainId","getAccount","switchChain","checkTransactionsTracker","actionTxKey","walletType","evmAdapter","appChains","cancelTxAction","TransactionAdapter","account","gasIncreaseMultiplier","divisor","newPriorityFee","newMaxFee","sendTransaction","errorMessage","cachedRelayChainIds","cacheTimestamp","CACHE_DURATION_MS","checkIsGelatoAvailable","now","supportedChainIds","ensClient","getName","address","getEnsName","getAvatar","name","getEnsAvatar","normalize","getAddress","getEnsAddress","isEnsName","isAddress","getActiveWalletAndClient","activeWallet","getWagmiAccount","walletClient","getClient","selectEvmTxExplorerLink","replacedTxHash","selectTXByKey","hash","safeBaseUrl","speedUpTxAction"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @file This file contains a utility function for creating a viem Public Client.\n */\n\nimport { http } from '@wagmi/core';\nimport { Chain, createClient, PublicClient } from 'viem';\n\n/**\n * Creates a viem Public Client for a specific chain.\n * This client is used to interact with the blockchain (e.g., fetch transaction details).\n *\n * @param {number} chainId - The ID of the chain for which to create the client.\n * @param {Chain[]} chains - An array of supported viem Chain objects.\n * @returns {PublicClient | undefined} A viem PublicClient instance if the chain is found in the provided array, otherwise undefined.\n * @ignore\n */\nexport function createViemClient(chainId: number, chains: Chain[]): PublicClient | undefined {\n // Use `find` to get the first matching chain object. It's more direct than `filter`.\n const chain = chains.find((c) => c.id === chainId);\n\n if (chain) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n return createClient({\n chain: chain,\n transport: http(),\n });\n }\n\n // Return undefined if no matching chain was found in the configuration.\n return undefined;\n}\n","/**\n * @file This file contains the tracker implementation for standard EVM transactions.\n * It uses viem's public actions (`getTransaction`, `waitForTransactionReceipt`) to monitor\n * a transaction's lifecycle from submission to finality.\n */\n\nimport { ITxTrackingStore, Transaction, TransactionStatus } from '@tuwaio/pulsar-core';\nimport {\n Chain,\n Client,\n GetTransactionReturnType,\n Hex,\n isHex,\n ReplacementReturnType,\n TransactionReceipt,\n WaitForTransactionReceiptParameters,\n zeroHash,\n} from 'viem';\nimport { getBlock, getTransaction, waitForTransactionReceipt } from 'viem/actions';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { createViemClient } from '../utils/createViemClient';\n\n/**\n * Defines the parameters for the low-level EVM transaction tracker.\n */\nexport type EVMTrackerParams = {\n /** The transaction object to track, requiring at least `chainId` and `txKey` (the transaction hash). */\n tx: Pick<Transaction<TransactionTracker>, 'chainId' | 'txKey'>;\n /** An array of `viem` chain objects supported by the application. */\n chains: Chain[];\n /** Callback executed when the getTransaction info got successfully. */\n onTxDetailsGot: (localTx: GetTransactionReturnType) => void;\n /** Callback executed when the transaction is successfully mined and included in a block. */\n onFinished: (localTx: GetTransactionReturnType, receipt: TransactionReceipt, client: Client) => Promise<void>;\n /** Callback executed when the transaction is replaced (e.g., sped up or cancelled). */\n onReplaced: (replacement: ReplacementReturnType) => void;\n /** Callback executed if an error occurs during tracking or if the transaction fails. */\n onFailed: (error?: unknown) => void;\n /** Optional callback executed once when the tracker starts. */\n onInitialize?: () => void;\n /** The number of times to retry fetching the transaction if it's not found initially. Defaults to 10. */\n retryCount?: number;\n /** The delay (in milliseconds) between retry attempts. Defaults to 3000ms. */\n retryTimeout?: number;\n /** Optional parameters to pass to viem's `waitForTransactionReceipt` function. */\n waitForTransactionReceiptParams?: WaitForTransactionReceiptParameters;\n};\n\n/**\n * A low-level tracker for monitoring a standard EVM transaction by its hash.\n * It retries fetching the transaction and then waits for its receipt.\n *\n * @param {EVMTrackerParams} params - The configuration object for the tracker.\n * @returns {Promise<void>} A promise that resolves when the tracking process is complete (or has terminally failed).\n */\nexport async function evmTracker({\n onInitialize,\n onTxDetailsGot,\n onFinished,\n onFailed,\n onReplaced,\n tx,\n chains,\n retryCount,\n retryTimeout,\n waitForTransactionReceiptParams,\n}: EVMTrackerParams): Promise<void> {\n const maxRetries = retryCount ?? 10;\n const client = createViemClient(tx.chainId as number, chains);\n\n if (onInitialize) {\n onInitialize();\n }\n\n if (tx.txKey === zeroHash) {\n throw new Error('Transaction hash is zeroHash');\n }\n\n if (!client) {\n const error = new Error(`Could not create a viem client for chainId: ${tx.chainId}`);\n onFailed(error);\n console.error(error.message);\n return;\n }\n\n // Retry loop to handle cases where the transaction is not immediately available on the RPC node.\n for (let i = 0; i < maxRetries; i++) {\n try {\n // 1. Attempt to fetch the transaction details.\n const localTx = await getTransaction(client, { hash: tx.txKey as Hex });\n\n onTxDetailsGot(localTx);\n\n let txWasReplaced = false;\n\n try {\n // 2. Wait for the transaction to be mined.\n const receipt = await waitForTransactionReceipt(client, {\n hash: localTx.hash,\n onReplaced: (replacement: ReplacementReturnType) => {\n txWasReplaced = true;\n onReplaced(replacement);\n },\n pollingInterval: 10_000,\n ...waitForTransactionReceiptParams,\n });\n\n // If onReplaced was called, the promise resolves but we should not proceed.\n if (txWasReplaced) {\n return;\n }\n\n // 3. Transaction is mined, call the onFinished callback.\n await onFinished(localTx, receipt, client);\n } catch (e) {\n // Error occurred while waiting for the receipt (e.g., timeout, reverted).\n onFailed(e);\n console.error('Error waiting for transaction receipt:', e);\n }\n\n // Exit the retry loop once the transaction is found and processed.\n return;\n } catch (e) {\n // Error occurred while fetching the initial transaction details.\n if (i === maxRetries - 1) {\n onFailed(e);\n console.error(`Error tracking EVM transaction after ${maxRetries} retries:`, e);\n return;\n }\n }\n // Wait before the next retry.\n await new Promise((resolve) => setTimeout(resolve, retryTimeout ?? 3000));\n }\n}\n\n/**\n * A higher-level wrapper for `evmTracker` that integrates directly with the Zustand store.\n * It provides the necessary callbacks to update the transaction's state in the store.\n *\n * @template T - The application-specific transaction union type.\n */\nexport async function evmTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n chains,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n}: Pick<EVMTrackerParams, 'chains'> &\n Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks'\n > & {\n tx: T;\n }) {\n return await evmTracker({\n tx,\n chains,\n onInitialize: () => {\n updateTxParams({\n txKey: tx.txKey,\n hash: tx.txKey as Hex,\n pending: tx.pending,\n });\n },\n onTxDetailsGot: (localTx) => {\n updateTxParams({\n to: localTx.to ?? '',\n input: localTx.input,\n value: String(localTx.value),\n txKey: tx.txKey,\n pending: tx.pending,\n nonce: localTx.nonce,\n hash: localTx.hash,\n maxFeePerGas: String(localTx.maxFeePerGas),\n maxPriorityFeePerGas: String(localTx.maxPriorityFeePerGas),\n });\n },\n onFinished: async (localTx, receipt, client) => {\n const txBlock = await getBlock(client, { blockNumber: receipt.blockNumber });\n const timestamp = Number(txBlock.timestamp);\n const isSuccess = receipt.status === 'success';\n\n updateTxParams({\n txKey: tx.txKey,\n status: isSuccess ? TransactionStatus.Success : TransactionStatus.Failed,\n to: isHex(receipt.to) ? receipt.to : undefined,\n nonce: localTx.nonce,\n pending: false,\n isError: !isSuccess,\n hash: localTx.hash,\n finishedTimestamp: timestamp,\n });\n\n // After updating the state, retrieve the latest version of the transaction.\n const updatedTX = transactionsPool[tx.txKey];\n if (isSuccess && onSucceedCallbacks && updatedTX) {\n onSucceedCallbacks(updatedTX);\n }\n },\n onReplaced: (replacement) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Replaced,\n replacedTxHash: replacement.transaction.hash,\n pending: false,\n });\n },\n onFailed: (error?: unknown) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage: error instanceof Error ? error.message : 'Transaction failed or could not be tracked.',\n });\n },\n });\n}\n","/**\n * @file This file implements the transaction tracking logic for meta-transactions relayed via the Gelato Network.\n * It uses a polling mechanism to check the status of a Gelato Task ID from the Gelato API.\n */\n\nimport {\n InitializePollingTracker,\n initializePollingTracker,\n ITxTrackingStore,\n Transaction,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Hex } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Defines the shape of the identifier for a Gelato transaction task.\n */\nexport type GelatoTxKey = {\n taskId: string;\n};\n\n/**\n * A type guard to determine if an ActionTxKey is a GelatoTxKey.\n * @param {ActionTxKey} txKey - The transaction key to check.\n * @returns {boolean} True if the key is for a Gelato transaction.\n */\nexport function isGelatoTxKey(txKey: ActionTxKey): txKey is GelatoTxKey {\n return (txKey as GelatoTxKey).taskId !== undefined;\n}\n\n/**\n * Enum representing the possible states of a Gelato task.\n * @see https://docs.gelato.network/developer-services/relay/api/get-task-status\n */\nexport enum GelatoTaskState {\n CheckPending = 'CheckPending',\n ExecPending = 'ExecPending',\n WaitingForConfirmation = 'WaitingForConfirmation',\n ExecSuccess = 'ExecSuccess',\n ExecReverted = 'ExecReverted',\n Cancelled = 'Cancelled',\n}\n\n/**\n * Defines the shape of the response from the Gelato `getTaskStatus` API endpoint.\n */\nexport type GelatoTaskStatusResponse = {\n task: {\n chainId: number;\n taskId: string;\n taskState: GelatoTaskState;\n creationDate?: string;\n executionDate?: string;\n transactionHash?: Hex;\n blockNumber?: number;\n lastCheckMessage?: string;\n };\n};\n\n/**\n * A utility type for the initial Gelato transaction object passed to the tracker.\n */\ntype InitialGelatoTx = Pick<Transaction<TransactionTracker>, 'txKey'> & {\n pending?: boolean;\n};\n\n/**\n * Defines the parameters required for the low-level `gelatoTracker` function.\n */\nexport type GelatoTrackerParams = Pick<\n InitializePollingTracker<GelatoTaskStatusResponse, InitialGelatoTx, TransactionTracker>,\n | 'tx'\n | 'removeTxFromPool'\n | 'onInitialize'\n | 'onSucceed'\n | 'onFailed'\n | 'onIntervalTick'\n | 'pollingInterval'\n | 'retryCount'\n>;\n\n/**\n * Checks if a Gelato task state is considered pending.\n * @param {GelatoTaskState} [gelatoStatus] - The current status of the Gelato task.\n * @returns {boolean} True if the status is pending.\n */\nfunction isGelatoTxPending(gelatoStatus?: GelatoTaskState): boolean {\n if (!gelatoStatus) return true;\n const pendingStates = [\n GelatoTaskState.CheckPending,\n GelatoTaskState.ExecPending,\n GelatoTaskState.WaitingForConfirmation,\n ];\n return pendingStates.includes(gelatoStatus);\n}\n\n/**\n * A set of terminal states that indicate a transaction has failed or been cancelled.\n */\nconst GELATO_TERMINAL_FAILURE_STATES = [GelatoTaskState.ExecReverted, GelatoTaskState.Cancelled];\n\n/**\n * The fetcher function passed to `initializePollingTracker` to get the status of a Gelato task.\n * @param {object} params - The parameters for fetching the transaction status.\n * @returns {Promise<Response>} The raw response from the fetch call.\n */\nexport async function fetchTxFromGelatoAPI({\n tx,\n onSucceed,\n onFailed,\n onIntervalTick,\n clearWatch,\n}: {\n clearWatch: (withoutRemoving?: boolean) => void;\n} & Pick<GelatoTrackerParams, 'onIntervalTick' | 'onSucceed' | 'onFailed' | 'tx'>): Promise<Response> {\n const response = await fetch(`https://api.gelato.digital/tasks/status/${tx.txKey}/`);\n\n if (response.ok) {\n const gelatoStatus = (await response.json()) as GelatoTaskStatusResponse;\n const isPending = isGelatoTxPending(gelatoStatus.task.taskState);\n\n // Safeguard: Stop polling for transactions that have been pending for over a day.\n if (gelatoStatus.task.creationDate) {\n const gelatoCreatedDate = dayjs(gelatoStatus.task.creationDate);\n if (dayjs().diff(gelatoCreatedDate, 'day') >= 1 && isPending) {\n clearWatch(); // Stop polling but don't remove from pool\n return response;\n }\n }\n\n onIntervalTick?.(gelatoStatus);\n\n if (!isPending) {\n clearWatch(true); // Stop polling but keep the transaction for UI feedback\n if (gelatoStatus.task.taskState === GelatoTaskState.ExecSuccess) {\n onSucceed(gelatoStatus);\n } else if (GELATO_TERMINAL_FAILURE_STATES.includes(gelatoStatus.task.taskState)) {\n onFailed(gelatoStatus);\n }\n }\n }\n\n return response;\n}\n\n/**\n * A low-level tracker for monitoring Gelato transactions. It wraps the generic polling\n * tracker with the Gelato-specific fetcher logic.\n *\n * @param {GelatoTrackerParams} params - The configuration object for the tracker.\n * @returns {Promise<void>}\n */\nexport async function gelatoTracker(params: GelatoTrackerParams): Promise<void> {\n await initializePollingTracker({\n ...params,\n fetcher: fetchTxFromGelatoAPI,\n });\n}\n\n/**\n * A higher-level wrapper for `gelatoTracker` that integrates directly with the Zustand store.\n * It provides the necessary callbacks to update the transaction's state in the store.\n *\n * @template T - The application-specific transaction union type.\n */\nexport async function gelatoTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n removeTxFromPool,\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}) {\n return await gelatoTracker({\n tx,\n removeTxFromPool,\n onSucceed: async (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Success,\n pending: false,\n hash: response.task.transactionHash,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n });\n\n const updatedTx = transactionsPool[tx.txKey];\n if (onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onIntervalTick: async (response) => {\n const isPending = isGelatoTxPending(response.task.taskState);\n const isSuccess = response.task.taskState === GelatoTaskState.ExecSuccess;\n\n updateTxParams({\n txKey: tx.txKey,\n pending: isPending,\n status: isSuccess ? TransactionStatus.Success : isPending ? undefined : TransactionStatus.Failed,\n hash: response.task.transactionHash,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n errorMessage: GELATO_TERMINAL_FAILURE_STATES.includes(response.task.taskState)\n ? response.task.lastCheckMessage\n : undefined,\n isError: !isPending && !isSuccess,\n });\n },\n onFailed: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response.task.transactionHash,\n errorMessage: response.task.lastCheckMessage,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n });\n },\n });\n}\n","/**\n * @file This file contains constants related to Safe (formerly Gnosis Safe) configuration,\n * including SDK options, web app URLs, and transaction service API endpoints.\n */\n\nimport { arbitrum, avalanche, base, bsc, goerli, mainnet, optimism, polygon, sepolia } from 'viem/chains';\n\n/**\n * Configuration options for the Safe Apps SDK.\n * This is typically used when integrating with the Safe environment.\n */\nexport const safeSdkOptions = {\n // A list of allowed domains to interact with the Safe Apps SDK.\n allowedDomains: [/gnosis-safe.io$/, /app.safe.global$/, /metissafe.tech$/],\n // A flag to enable or disable debug logging for the SDK.\n debug: false,\n};\n\n/**\n * A mapping of chain IDs to their corresponding Safe web application URL prefixes.\n * Used by selectors like `selectTxExplorerLink` to build correct links for Safe transactions.\n * The prefixes (e.g., 'eth:', 'gor:') are part of the Safe URL scheme.\n * @type {Record<number, string>}\n */\nexport const gnosisSafeLinksHelper: Record<number, string> = {\n [mainnet.id]: 'https://app.safe.global/eth:',\n [goerli.id]: 'https://app.safe.global/gor:',\n [sepolia.id]: 'https://app.safe.global/sep:',\n [optimism.id]: 'https://app.safe.global/oeth:',\n [polygon.id]: 'https://app.safe.global/matic:',\n [arbitrum.id]: 'https://app.safe.global/arb1:',\n [avalanche.id]: 'https://app.safe.global/avax:',\n [bsc.id]: 'https://app.safe.global/bnb:',\n [base.id]: 'https://app.safe.global/base:',\n};\n\n/**\n * A mapping of chain IDs to their corresponding Safe Transaction Service API endpoints.\n * This is used by the `safeTracker` to fetch the status of multisig transactions.\n * @type {Record<number, string>}\n */\nexport const SafeTransactionServiceUrls: Record<number, string> = {\n [mainnet.id]: 'https://safe-transaction-mainnet.safe.global/api/v1',\n [goerli.id]: 'https://safe-transaction-goerli.safe.global/api/v1',\n [sepolia.id]: 'https://safe-transaction-sepolia.safe.global/api/v1',\n [optimism.id]: 'https://safe-transaction-optimism.safe.global/api/v1',\n [polygon.id]: 'https://safe-transaction-polygon.safe.global/api/v1',\n [arbitrum.id]: 'https://safe-transaction-arbitrum.safe.global/api/v1',\n [avalanche.id]: 'https://safe-transaction-avalanche.safe.global/api/v1',\n [bsc.id]: 'https://safe-transaction-bsc.safe.global/api/v1',\n [base.id]: 'https://safe-transaction-base.safe.global/api/v1',\n};\n","/**\n * @file This file implements the transaction tracking logic for Gnosis Safe (now Safe) multisig transactions.\n * It uses a polling mechanism to query the Safe Transaction Service API for the status of a `safeTxHash`.\n */\n\nimport {\n InitializePollingTracker,\n initializePollingTracker,\n ITxTrackingStore,\n Transaction,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Hex, zeroHash } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { SafeTransactionServiceUrls } from '../utils/safeConstants';\n\n/**\n * Defines the shape of the transaction object passed to the Safe tracker.\n */\ntype InitialSafeTx = Pick<Transaction<TransactionTracker>, 'txKey' | 'chainId' | 'from'> & {\n pending?: boolean;\n};\n\n/**\n * Defines the shape of the primary response for a single transaction from the Safe Transaction Service API.\n */\nexport type SafeTxStatusResponse = {\n transactionHash: string;\n safeTxHash: string;\n isExecuted: boolean;\n isSuccessful: boolean | null;\n executionDate: string | null;\n submissionDate: string | null;\n modified: string;\n nonce: number;\n replacedHash?: string; // Custom field for passing replacement info\n};\n\n/**\n * Defines the shape of the response when querying for multiple transactions (e.g., by nonce).\n */\ntype SafeTxSameNonceResponse = {\n count: number;\n results: SafeTxStatusResponse[];\n};\n\n/**\n * Defines the parameters for the low-level `safeTracker` function.\n */\nexport type SafeTrackerParams = Pick<\n InitializePollingTracker<SafeTxStatusResponse, InitialSafeTx, TransactionTracker>,\n | 'tx'\n | 'removeTxFromPool'\n | 'onInitialize'\n | 'onSucceed'\n | 'onFailed'\n | 'onReplaced'\n | 'onIntervalTick'\n | 'pollingInterval'\n | 'retryCount'\n>;\n\n/**\n * The fetcher function passed to `initializePollingTracker` to get the status of a Safe transaction.\n * @returns The raw response from the fetch call.\n */\nexport async function fetchTxFromSafeAPI({\n tx,\n onSucceed,\n onFailed,\n onIntervalTick,\n onReplaced,\n clearWatch,\n}: {\n clearWatch: (withoutRemoving?: boolean) => void;\n} & Pick<SafeTrackerParams, 'onIntervalTick' | 'onSucceed' | 'onFailed' | 'onReplaced' | 'tx'>): Promise<Response> {\n const primaryTxResponse = await fetch(\n `${SafeTransactionServiceUrls[tx.chainId as number]}/multisig-transactions/${tx.txKey}/`,\n );\n\n if (!primaryTxResponse.ok) {\n return primaryTxResponse; // Let the polling tracker handle the retry\n }\n\n const safeStatus = (await primaryTxResponse.json()) as SafeTxStatusResponse;\n\n // Fetch all other transactions with the same nonce to check for replacements.\n const nonceTxsResponse = await fetch(\n `${SafeTransactionServiceUrls[tx.chainId as number]}/safes/${tx.from}/multisig-transactions/?nonce=${safeStatus.nonce}`,\n );\n\n if (!nonceTxsResponse.ok) {\n return nonceTxsResponse; // Let the polling tracker handle the retry\n }\n\n const sameNonceTxs = (await nonceTxsResponse.json()) as SafeTxSameNonceResponse;\n const executedTx = sameNonceTxs.results.find((t) => t.isExecuted);\n\n // Case 1: Another transaction with the same nonce was executed. This one was replaced.\n if (executedTx && executedTx.safeTxHash !== safeStatus.safeTxHash) {\n onReplaced?.({ ...safeStatus, replacedHash: executedTx.safeTxHash });\n clearWatch(true);\n return nonceTxsResponse;\n }\n\n // Case 2: The transaction itself was executed.\n if (safeStatus.isExecuted) {\n if (safeStatus.isSuccessful) {\n onSucceed(safeStatus);\n } else {\n onFailed(safeStatus);\n }\n clearWatch(true);\n return primaryTxResponse;\n }\n\n // Case 3: The transaction is still pending.\n // Safeguard: Stop polling for transactions that have been pending for over a day.\n const modifiedDate = dayjs(safeStatus.modified);\n if (dayjs().diff(modifiedDate, 'day') >= 1) {\n clearWatch(); // Stop polling and remove from pool\n return primaryTxResponse;\n }\n\n // Otherwise, just report the current status and continue polling.\n onIntervalTick?.(safeStatus);\n\n return primaryTxResponse;\n}\n\n/**\n * A low-level tracker for monitoring Safe multisig transactions.\n * It wraps the generic polling tracker with the Safe-specific fetcher logic.\n */\nexport async function safeTracker(params: SafeTrackerParams): Promise<void> {\n await initializePollingTracker<SafeTxStatusResponse, InitialSafeTx, TransactionTracker>({\n ...params,\n fetcher: fetchTxFromSafeAPI,\n });\n}\n\n/**\n * A higher-level wrapper for `safeTracker` that integrates directly with the Zustand store.\n */\nexport async function safeTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n removeTxFromPool,\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}) {\n return await safeTracker({\n tx,\n removeTxFromPool,\n onSucceed: async (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Success,\n pending: false,\n hash: response.transactionHash as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n\n const updatedTx = transactionsPool[tx.txKey];\n if (onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onIntervalTick: async (response) => {\n updateTxParams({\n pending: !response.isExecuted,\n txKey: tx.txKey,\n hash: response.transactionHash as Hex,\n });\n },\n onFailed: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response.transactionHash as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n onReplaced: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Replaced,\n pending: false,\n hash: response.transactionHash as Hex,\n replacedTxHash: (response.replacedHash ?? zeroHash) as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n });\n}\n","/**\n * @file This file defines types and enums specific to the EVM transaction tracking package.\n * It includes identifiers for different tracking strategies and the shape of transaction keys.\n */\n\nimport { Hex } from 'viem';\n\nimport { GelatoTxKey } from './trackers/gelatoTracker';\n\n/**\n * Enum representing the different tracking strategies available for EVM transactions.\n */\nexport enum TransactionTracker {\n /** For standard on-chain EVM transactions tracked by their hash. */\n Ethereum = 'ethereum',\n /** For multi-signature transactions managed by a Safe contract. */\n Safe = 'safe',\n /** For meta-transactions relayed through the Gelato Network. */\n Gelato = 'gelato',\n}\n\n/**\n * Represents the unique identifier returned by an action function after a transaction is submitted.\n * This key is used to determine which tracker should monitor the transaction.\n * It can be a standard transaction hash or a structured key from a relay service like Gelato.\n * @typedef {Hex | GelatoTxKey} ActionTxKey\n */\nexport type ActionTxKey = Hex | GelatoTxKey;\n","/**\n * @file This file contains a utility function that acts as a router to initialize the correct transaction tracker.\n * Based on a transaction's `tracker` property, it delegates the tracking task to the appropriate implementation.\n */\n\nimport { ITxTrackingStore, Transaction } from '@tuwaio/pulsar-core';\nimport { Chain } from 'viem';\n\nimport { evmTrackerForStore } from '../trackers/evmTracker';\nimport { gelatoTrackerForStore } from '../trackers/gelatoTracker';\nimport { safeTrackerForStore } from '../trackers/safeTracker';\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Initializes the appropriate tracker for a given transaction based on its `tracker` type.\n * This function acts as a central router, delegating to the specific tracker implementation\n * (e.g., EVM, Gelato, Safe).\n *\n * @template T - The application-specific transaction union type.\n * @param {object} params - The parameters for initializing the tracker.\n * @param {TransactionTracker} params.tracker - The type of tracker to use for the transaction.\n * @param {T} params.tx - The transaction object to be tracked.\n * @param {Chain[]} params.chains - An array of supported chain objects, required for some trackers (like the EVM tracker).\n * @param {object} params.rest - The rest of the parameters, which are the relevant methods from the Zustand store\n * (`transactionsPool`, `updateTxParams`, `onSucceedCallbacks`, `removeTxFromPool`).\n * @returns {Promise<void>} A promise that resolves once the tracking process has been initiated.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<TransactionTracker>>({\n tracker,\n tx,\n chains,\n ...rest\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n chains: Chain[];\n tx: T;\n tracker: TransactionTracker;\n}): Promise<void> {\n switch (tracker) {\n case TransactionTracker.Ethereum:\n await evmTrackerForStore({\n tx,\n chains,\n ...rest,\n });\n break;\n\n case TransactionTracker.Gelato:\n // The Gelato tracker does not need the `chains` param as it uses its own API endpoints.\n await gelatoTrackerForStore({\n tx,\n ...rest,\n });\n break;\n\n case TransactionTracker.Safe:\n // The Safe tracker also uses its own API endpoints.\n await safeTrackerForStore({\n tx,\n ...rest,\n });\n break;\n\n // The default case handles any unknown or unspecified tracker types as standard EVM transactions.\n default:\n await evmTrackerForStore({\n tx,\n chains,\n ...rest,\n });\n }\n}\n","/**\n * @file This file contains a utility to ensure the user's wallet is connected to the correct chain before proceeding.\n */\n\nimport { Config, switchChain } from '@wagmi/core';\nimport { getAccount } from '@wagmi/core';\n\n/**\n * Checks if the user's wallet is connected to the specified chain. If not, it prompts\n * the user to switch to the correct chain and waits for the operation to complete.\n *\n * @param {number} chainId - The ID of the desired blockchain network.\n * @param {Config} config - The wagmi configuration object.\n * @returns {Promise<void>} A promise that resolves when the wallet is on the correct chain,\n * or rejects if the user cancels the switch or an error occurs.\n * @throws {Error} Throws an error if the user rejects the chain switch or if the switch fails.\n */\nexport async function checkChainForTx(chainId: number, config: Config): Promise<void> {\n const { connector, chainId: activeChainId } = getAccount(config);\n\n // Proceed only if a wallet is connected and it's on the wrong chain.\n if (connector && activeChainId !== chainId) {\n try {\n // Directly await the switchChain call. This pauses execution until the user responds.\n await switchChain(config, { chainId });\n } catch (e) {\n // The user rejected the request or an error occurred.\n console.error('Failed to switch chain:', e);\n throw new Error('User rejected chain switch or an error occurred.');\n }\n }\n}\n","/**\n * @file This file contains a utility function to determine the correct tracker for a transaction\n * based on the key returned by the submission function and the wallet type.\n */\n\nimport { isHex } from 'viem';\n\nimport { isGelatoTxKey } from '../trackers/gelatoTracker';\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Determines which transaction tracker to use based on the format of the transaction key and the wallet type.\n *\n * This function is a critical routing step after a transaction is submitted.\n * It follows a priority order:\n * 1. Checks for a Gelato Task ID.\n * 2. Checks if the wallet type is 'safe'.\n * 3. Defaults to a standard Ethereum tracker.\n *\n * @param {ActionTxKey} actionTxKey - The key returned from the transaction submission function (e.g., a hash or a Gelato task object).\n * @param {string} walletType - The type of the wallet that initiated the action (e.g., 'safe', 'metaMask').\n * @returns {{ tracker: TransactionTracker; txKey: string }} An object containing the determined tracker type and the final string-based transaction key.\n */\nexport function checkTransactionsTracker(\n actionTxKey: ActionTxKey,\n walletType: string,\n): { tracker: TransactionTracker; txKey: string } {\n // 1. Highest priority: Check if the key matches the Gelato task structure.\n if (isGelatoTxKey(actionTxKey)) {\n return {\n tracker: TransactionTracker.Gelato,\n txKey: actionTxKey.taskId,\n };\n }\n\n // At this point, actionTxKey must be a Hex string (transaction hash or SafeTxHash).\n // We can add a check for robustness, although TypeScript should infer this.\n if (!isHex(actionTxKey)) {\n throw new Error('Invalid transaction key format. Expected a Hex string or GelatoTxKey object.');\n }\n\n // 2. Second priority: Check if the transaction came from a Safe wallet.\n if (walletType === 'safe') {\n return {\n tracker: TransactionTracker.Safe,\n txKey: actionTxKey,\n };\n }\n\n // 3. Default: Treat as a standard on-chain Ethereum transaction.\n return {\n tracker: TransactionTracker.Ethereum,\n txKey: actionTxKey,\n };\n}\n","import { ITxTrackingStore, Transaction } from '@tuwaio/pulsar-core';\nimport { Config } from '@wagmi/core';\nimport { Chain } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkChainForTx } from '../utils/checkChainForTx';\nimport { checkTransactionsTracker } from '../utils/checkTransactionsTracker';\n\nexport function evmAdapter<T extends Transaction<TransactionTracker>>(config: Config, appChains: Chain[]) {\n if (config) {\n return {\n checkChainForTx: (chainId: string | number) => checkChainForTx(chainId as number, config),\n checkTransactionsTracker: (actionTxKey: ActionTxKey, walletType: string) =>\n checkTransactionsTracker(actionTxKey, walletType),\n checkAndInitializeTrackerInStore: ({\n tx,\n ...rest\n }: { tx: T } & Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n >) => checkAndInitializeTrackerInStore({ tracker: tx.tracker, tx, chains: appChains, ...rest }),\n };\n }\n}\n","import { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n/**\n * Cancels a pending transaction by sending a new, zero-value transaction to oneself\n * with the same nonce but a higher gas price.\n *\n * @param {object} params - The parameters for the cancellation.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The transaction object to be canceled. Must contain nonce, gas fees, etc.\n *\n * @returns {Promise<Hex>} A promise that resolves with the hash of the new cancellation transaction.\n *\n * @throws {Error} Throws an error if the transaction is missing required fields or if sending fails.\n *\n * @example\n * ```ts\n * import { cancelTxAction } from './cancelTxAction';\n *\n * const handleCancel = async () => {\n * try {\n * const cancelTxHash = await cancelTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Cancellation transaction sent:', cancelTxHash);\n * } catch (error) {\n * console.error('Failed to cancel transaction:', error);\n * }\n * };\n * ```\n */\nexport async function cancelTxAction<T extends Transaction<any>>({\n config,\n tx,\n}: {\n config: Config;\n tx: T;\n}): Promise<Hex> {\n if (tx.adapter === TransactionAdapter.EVM) {\n // Ensure the transaction has all the necessary details for cancellation.\n if (!tx.nonce || !tx.maxFeePerGas || !tx.maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for cancellation (nonce, maxFeePerGas).');\n }\n\n try {\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // Increase gas fees by 15% to ensure the cancellation transaction is prioritized.\n const gasIncreaseMultiplier = 115n; // 115%\n const divisor = 100n;\n const newPriorityFee = (BigInt(tx.maxPriorityFeePerGas) * gasIncreaseMultiplier) / divisor;\n const newMaxFee = (BigInt(tx.maxFeePerGas) * gasIncreaseMultiplier) / divisor;\n\n // Send a zero-value transaction to your own address with the same nonce.\n const hash = await sendTransaction(config, {\n to: account.address,\n value: 0n,\n chainId: tx.chainId as number,\n nonce: tx.nonce,\n maxFeePerGas: newMaxFee,\n maxPriorityFeePerGas: newPriorityFee,\n });\n\n return hash;\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n // Re-throw the error with more context.\n throw new Error(`Failed to cancel transaction: ${errorMessage}`);\n }\n } else {\n throw new Error(`Failed to cancel transaction: not EVM tx adapter`);\n }\n}\n","/**\n * @file This file contains a utility to check if the Gelato Relay service is available for a specific chain.\n */\n\n// --- In-memory cache to store the list of supported chains ---\nlet cachedRelayChainIds: number[] | null = null;\nlet cacheTimestamp: number | null = null;\nconst CACHE_DURATION_MS = 5 * 60 * 1000; // Cache the list for 5 minutes\n\n/**\n * Checks if the Gelato Relay service supports a given chain ID.\n * The result is cached in memory for 5 minutes to avoid excessive network requests.\n *\n * @param {number} chainId - The chain identifier to check.\n * @returns {Promise<boolean>} True if Gelato supports the chain, false otherwise.\n */\nexport async function checkIsGelatoAvailable(chainId: number): Promise<boolean> {\n const now = Date.now();\n\n // 1. Check if a valid cache exists.\n if (cachedRelayChainIds && cacheTimestamp && now - cacheTimestamp < CACHE_DURATION_MS) {\n return cachedRelayChainIds.includes(chainId);\n }\n\n // 2. If no valid cache, fetch from the API.\n try {\n const response = await fetch('https://relay.gelato.digital/relays/v2');\n if (!response.ok) {\n // Clear cache in case of a temporary API failure\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n return false;\n }\n\n const data = (await response.json()) as { relays: string[] };\n const supportedChainIds = data.relays.map(Number);\n\n // 3. Update the cache.\n cachedRelayChainIds = supportedChainIds;\n cacheTimestamp = now;\n\n return supportedChainIds.includes(chainId);\n } catch (e) {\n console.error('Failed to check Gelato service availability:', e);\n // Clear cache on error\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n return false;\n }\n}\n","/**\n * @file This file contains utility functions for interacting with the Ethereum Name Service (ENS).\n * It provides methods for resolving names to addresses, addresses to names, and fetching avatars.\n */\n\nimport { Address, Hex, isAddress } from 'viem';\nimport { mainnet } from 'viem/chains';\nimport { getEnsAddress, getEnsAvatar, getEnsName, normalize } from 'viem/ens';\n\nimport { createViemClient } from './createViemClient';\n\n// Create a single, shared viem client for all ENS lookups to improve performance.\n// ENS lookups are typically done against Ethereum Mainnet regardless of the connected chain.\nconst ensClient = createViemClient(mainnet.id, [mainnet]);\n\n/**\n * Fetches the primary ENS name for a given Ethereum address.\n * Performs the lookup on Ethereum Mainnet.\n *\n * @param {Hex} address - The Ethereum address to look up.\n * @returns {Promise<string | undefined>} The ENS name if found, otherwise undefined.\n */\nexport const getName = async (address: Hex): Promise<string | undefined> => {\n if (!ensClient) return undefined;\n try {\n const name = await getEnsName(ensClient, { address });\n return name ?? undefined;\n } catch (error) {\n console.error('ENS name lookup error:', error);\n return undefined;\n }\n};\n\n/**\n * Fetches the avatar for a given ENS name.\n * If no ENS avatar is set, it generates a unique \"blockie\" image as a fallback.\n * Performs the lookup on Ethereum Mainnet.\n *\n * @param {string} name - The ENS name (e.g., 'vitalik.eth').\n * @param {string} address - The Ethereum address, used for the blockie fallback.\n * @returns {Promise<string | undefined>} The URL of the avatar image, a base64 blockie, or undefined if an error occurs.\n */\nexport const getAvatar = async (name: string): Promise<string | undefined> => {\n if (!ensClient) return undefined;\n try {\n const avatarUrl = await getEnsAvatar(ensClient, { name: normalize(name) });\n return avatarUrl ?? undefined;\n } catch (error) {\n console.error('ENS avatar lookup error:', error);\n return undefined;\n }\n};\n\n/**\n * Fetches the Ethereum address associated with a given ENS name.\n * Performs the lookup on Ethereum Mainnet.\n *\n * @param {string} name - The ENS name to resolve (e.g., 'vitalik.eth').\n * @returns {Promise<Address | undefined>} The associated Ethereum address (lowercase) or undefined if not found.\n */\nexport const getAddress = async (name: string): Promise<Address | undefined> => {\n if (!ensClient) return undefined;\n try {\n const address = await getEnsAddress(ensClient, { name: normalize(name) });\n return address ? (address.toLocaleLowerCase() as Address) : undefined;\n } catch (error) {\n console.error('ENS address lookup error:', error);\n return undefined;\n }\n};\n\n/**\n * A simple heuristic to check if a string could be an ENS name.\n * It works by checking if the string is NOT a valid Ethereum address.\n *\n * @param {string} address - The string to check.\n * @returns {boolean} True if the string is not in a valid address format.\n */\nexport const isEnsName = (address: string): boolean => !isAddress(address);\n","/**\n * @file This file contains a utility for safely retrieving the active wallet account and viem client.\n */\n\nimport { Config, getClient, GetClientReturnType } from '@wagmi/core';\nimport { getAccount as getWagmiAccount, GetAccountReturnType } from '@wagmi/core';\n\n/**\n * Retrieves the active wallet account and the viem Wallet Client from the wagmi config.\n * It ensures that a wallet is connected by throwing an error if it's not.\n *\n * @param {Config} config - The wagmi configuration object.\n * @returns {{ activeWallet: GetAccountReturnType; walletClient: GetClientReturnType }} An object containing the connected account details and the viem Wallet Client.\n * @throws {Error} Throws an error with the message \"Wallet not connected\" if no wallet is connected or the client is unavailable.\n */\nexport function getActiveWalletAndClient(config: Config): {\n activeWallet: GetAccountReturnType;\n walletClient: GetClientReturnType;\n} {\n const activeWallet = getWagmiAccount(config);\n const walletClient = getClient(config);\n\n // This check is crucial to prevent downstream errors.\n if (!activeWallet.address || !walletClient) {\n throw new Error('Wallet not connected');\n }\n\n return { activeWallet, walletClient };\n}\n","import { selectTXByKey, Transaction, TransactionAdapter, TransactionPool } from '@tuwaio/pulsar-core';\nimport { Chain, Hex } from 'viem';\n\nimport { TransactionTracker } from '../types';\nimport { gnosisSafeLinksHelper } from './safeConstants';\n\n/**\n * Generates a URL to a block explorer for a given transaction.\n * It handles different URL structures for standard EVM transactions and Safe transactions.\n *\n * @template TR - The generic type for the tracker identifier.\n * @template T - The transaction type.\n * @param {TransactionPool<TR, T>} transactionsPool - The entire pool of transactions from the store.\n * @param {Chain[]} chains - An array of supported chain objects from viem.\n * @param {Hex} txKey - The tx key of the transaction for which to generate the link.\n * @param {Hex} [replacedTxHash] - Optional. If provided, the link will be generated for this hash instead of the original.\n * @returns {string} The URL to the transaction on the corresponding block explorer, or an empty string if not found.\n */\nexport const selectEvmTxExplorerLink = <TR, T extends Transaction<TR>>(\n transactionsPool: TransactionPool<TR, T>,\n chains: Chain[],\n txKey: Hex,\n replacedTxHash?: Hex,\n): string => {\n const tx = selectTXByKey(transactionsPool, txKey);\n\n if (!tx) {\n return '';\n }\n\n /**\n * Internal helper to construct the final URL based on the tracker type.\n * @param {string} hash - The transaction hash to include in the URL.\n * @returns {string} The constructed explorer URL.\n */\n const constructUrl = (hash: string): string => {\n // For Safe transactions, generate a link to the Safe web app.\n if (tx.tracker === TransactionTracker.Safe) {\n const safeBaseUrl = gnosisSafeLinksHelper[tx.chainId as number];\n return safeBaseUrl ? `${safeBaseUrl}${tx.from}/transactions/tx?id=multisig_${tx.from}_${tx.txKey}` : '';\n }\n\n // For standard EVM transactions, find the chain's default block explorer.\n const chain = chains.find((chain) => chain.id === tx.chainId);\n\n if (!chain?.blockExplorers?.default.url) {\n // Return empty string if the chain or its explorer URL is not configured.\n return '';\n }\n\n return `${chain.blockExplorers.default.url}/tx/${hash}`;\n };\n\n // Prioritize the replaced hash if it exists, otherwise use the original.\n return constructUrl(replacedTxHash || (tx.adapter === TransactionAdapter.EVM && tx.hash) || tx.txKey);\n};\n","import { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n/**\n * Speeds up a pending transaction by resubmitting it with the same nonce but higher gas fees.\n * This is a common strategy to prevent a transaction from getting stuck.\n *\n * @param {object} params - The parameters required to speed up the transaction.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The original transaction object that needs to be sped up.\n *\n * @returns {Promise<Hex>} A promise that resolves with the hash of the new, speed-up transaction.\n *\n * @throws {Error} Throws an error if the wagmi config is not provided, the account is not found,\n * or if the transaction is missing required fields (`nonce`, `maxFeePerGas`, etc.).\n *\n * @example\n * ```ts\n * import { speedUpTxAction } from './speedUpTxAction';\n *\n * const handleSpeedUp = async () => {\n * try {\n * const newTxHash = await speedUpTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Transaction sped up with new hash:', newTxHash);\n * } catch (error) {\n * console.error('Failed to speed up transaction:', error);\n * }\n * };\n * ```\n */\nexport async function speedUpTxAction<TR, T extends Transaction<TR>>({\n config,\n tx,\n}: {\n config: Config;\n tx: T;\n}): Promise<Hex> {\n if (tx.adapter === TransactionAdapter.EVM) {\n // Ensure all necessary transaction details are present.\n if (!tx.nonce || !tx.from || !tx.to || !tx.value || !tx.input || !tx.maxFeePerGas || !tx.maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for speed-up.');\n }\n\n try {\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // To replace a pending transaction, the new gas fees must be higher.\n // We increase both fees by 15% as a common strategy to ensure replacement.\n const gasIncreaseMultiplier = 115n; // 115%\n const divisor = 100n;\n const newPriorityFee = (BigInt(tx.maxPriorityFeePerGas) * gasIncreaseMultiplier) / divisor;\n const newMaxFee = (BigInt(tx.maxFeePerGas) * gasIncreaseMultiplier) / divisor;\n\n // Resubmit the transaction with the same details but higher gas fees.\n return await sendTransaction(config, {\n to: tx.to as Hex,\n value: BigInt(tx.value),\n data: tx.input as Hex,\n chainId: tx.chainId as number,\n nonce: tx.nonce,\n maxFeePerGas: newMaxFee,\n maxPriorityFeePerGas: newPriorityFee,\n });\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n // Re-throw the error with more context.\n throw new Error(`Failed to speed up transaction: ${errorMessage}`);\n }\n } else {\n throw new Error(`Failed to speed up transaction: not EVM tx adapter`);\n }\n}\n"]}
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import {TransactionStatus,initializePollingTracker,TransactionAdapter,selectTXByKey}from'@tuwaio/pulsar-core';import {createClient,zeroHash,isHex}from'viem';import {getTransaction,waitForTransactionReceipt,getBlock}from'viem/actions';import {http,getAccount,switchChain,sendTransaction,getClient}from'@wagmi/core';import p from'dayjs';import {base,bsc,avalanche,arbitrum,polygon,optimism,sepolia,goerli,mainnet}from'viem/chains';function I(e,a){let n=a.find(r=>r.id===e);if(n)return createClient({chain:n,transport:http()})}async function Z({onInitialize:e,onTxDetailsGot:a,onFinished:n,onFailed:r,onReplaced:i,tx:t,chains:o,retryCount:s,retryTimeout:c,waitForTransactionReceiptParams:h}){let l=s??10,m=I(t.chainId,o);if(e&&e(),t.txKey===zeroHash)throw new Error("Transaction hash is zeroHash");if(!m){let f=new Error(`Could not create a viem client for chainId: ${t.chainId}`);r(f),console.error(f.message);return}for(let f=0;f<l;f++){try{let u=await getTransaction(m,{hash:t.txKey});a(u);let v=!1;try{let k=await waitForTransactionReceipt(m,{hash:u.hash,onReplaced:_=>{v=!0,i(_);},pollingInterval:1e4,...h});if(v)return;await n(u,k,m);}catch(k){r(k),console.error("Error waiting for transaction receipt:",k);}return}catch(u){if(f===l-1){r(u),console.error(`Error tracking EVM transaction after ${l} retries:`,u);return}}await new Promise(u=>setTimeout(u,c??3e3));}}async function P({tx:e,chains:a,transactionsPool:n,updateTxParams:r,onSucceedCallbacks:i}){return await Z({tx:e,chains:a,onInitialize:()=>{r({txKey:e.txKey,hash:e.txKey,pending:e.pending});},onTxDetailsGot:t=>{r({to:t.to??"",input:t.input,value:String(t.value),txKey:e.txKey,pending:e.pending,nonce:t.nonce,hash:t.hash,maxFeePerGas:String(t.maxFeePerGas),maxPriorityFeePerGas:String(t.maxPriorityFeePerGas)});},onFinished:async(t,o,s)=>{let c=await getBlock(s,{blockNumber:o.blockNumber}),h=Number(c.timestamp),l=o.status==="success";r({txKey:e.txKey,status:l?TransactionStatus.Success:TransactionStatus.Failed,to:isHex(o.to)?o.to:void 0,nonce:t.nonce,pending:!1,isError:!l,hash:t.hash,finishedTimestamp:h});let m=n[e.txKey];l&&i&&m&&i(m);},onReplaced:t=>{r({txKey:e.txKey,status:TransactionStatus.Replaced,replacedTxHash:t.transaction.hash,pending:!1});},onFailed:t=>{r({txKey:e.txKey,status:TransactionStatus.Failed,pending:!1,isError:!0,errorMessage:t instanceof Error?t.message:"Transaction failed or could not be tracked."});}})}function F(e){return e.taskId!==void 0}var te=(o=>(o.CheckPending="CheckPending",o.ExecPending="ExecPending",o.WaitingForConfirmation="WaitingForConfirmation",o.ExecSuccess="ExecSuccess",o.ExecReverted="ExecReverted",o.Cancelled="Cancelled",o))(te||{});function K(e){return e?["CheckPending","ExecPending","WaitingForConfirmation"].includes(e):true}var C=["ExecReverted","Cancelled"];async function ae({tx:e,onSucceed:a,onFailed:n,onIntervalTick:r,clearWatch:i}){let t=await fetch(`https://api.gelato.digital/tasks/status/${e.txKey}/`);if(t.ok){let o=await t.json(),s=K(o.task.taskState);if(o.task.creationDate){let c=p(o.task.creationDate);if(p().diff(c,"day")>=1&&s)return i(),t}r?.(o),s||(i(true),o.task.taskState==="ExecSuccess"?a(o):C.includes(o.task.taskState)&&n(o));}return t}async function ne(e){await initializePollingTracker({...e,fetcher:ae});}async function E({tx:e,transactionsPool:a,updateTxParams:n,onSucceedCallbacks:r,removeTxFromPool:i}){return await ne({tx:e,removeTxFromPool:i,onSucceed:async t=>{n({txKey:e.txKey,status:TransactionStatus.Success,pending:false,hash:t.task.transactionHash,finishedTimestamp:t.task.executionDate?p(t.task.executionDate).unix():void 0});let o=a[e.txKey];r&&o&&r(o);},onIntervalTick:async t=>{let o=K(t.task.taskState),s=t.task.taskState==="ExecSuccess";n({txKey:e.txKey,pending:o,status:s?TransactionStatus.Success:o?void 0:TransactionStatus.Failed,hash:t.task.transactionHash,finishedTimestamp:t.task.executionDate?p(t.task.executionDate).unix():void 0,errorMessage:C.includes(t.task.taskState)?t.task.lastCheckMessage:void 0,isError:!o&&!s});},onFailed:t=>{n({txKey:e.txKey,status:TransactionStatus.Failed,pending:false,isError:true,hash:t.task.transactionHash,errorMessage:t.task.lastCheckMessage,finishedTimestamp:t.task.executionDate?p(t.task.executionDate).unix():void 0});}})}var qe={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},W={[mainnet.id]:"https://app.safe.global/eth:",[goerli.id]:"https://app.safe.global/gor:",[sepolia.id]:"https://app.safe.global/sep:",[optimism.id]:"https://app.safe.global/oeth:",[polygon.id]:"https://app.safe.global/matic:",[arbitrum.id]:"https://app.safe.global/arb1:",[avalanche.id]:"https://app.safe.global/avax:",[bsc.id]:"https://app.safe.global/bnb:",[base.id]:"https://app.safe.global/base:"},b={[mainnet.id]:"https://safe-transaction-mainnet.safe.global/api/v1",[goerli.id]:"https://safe-transaction-goerli.safe.global/api/v1",[sepolia.id]:"https://safe-transaction-sepolia.safe.global/api/v1",[optimism.id]:"https://safe-transaction-optimism.safe.global/api/v1",[polygon.id]:"https://safe-transaction-polygon.safe.global/api/v1",[arbitrum.id]:"https://safe-transaction-arbitrum.safe.global/api/v1",[avalanche.id]:"https://safe-transaction-avalanche.safe.global/api/v1",[bsc.id]:"https://safe-transaction-bsc.safe.global/api/v1",[base.id]:"https://safe-transaction-base.safe.global/api/v1"};async function ie({tx:e,onSucceed:a,onFailed:n,onIntervalTick:r,onReplaced:i,clearWatch:t}){let o=await fetch(`${b[e.chainId]}/multisig-transactions/${e.txKey}/`);if(!o.ok)return o;let s=await o.json(),c=await fetch(`${b[e.chainId]}/safes/${e.from}/multisig-transactions/?nonce=${s.nonce}`);if(!c.ok)return c;let l=(await c.json()).results.find(f=>f.isExecuted);if(l&&l.safeTxHash!==s.safeTxHash)return i?.({...s,replacedHash:l.safeTxHash}),t(true),c;if(s.isExecuted)return s.isSuccessful?a(s):n(s),t(true),o;let m=p(s.modified);return p().diff(m,"day")>=1?(t(),o):(r?.(s),o)}async function se(e){await initializePollingTracker({...e,fetcher:ie});}async function V({tx:e,transactionsPool:a,updateTxParams:n,onSucceedCallbacks:r,removeTxFromPool:i}){return await se({tx:e,removeTxFromPool:i,onSucceed:async t=>{n({txKey:e.txKey,status:TransactionStatus.Success,pending:false,hash:t.transactionHash,finishedTimestamp:t.executionDate?p(t.executionDate).unix():void 0});let o=a[e.txKey];r&&o&&r(o);},onIntervalTick:async t=>{n({pending:!t.isExecuted,txKey:e.txKey,hash:t.transactionHash});},onFailed:t=>{n({txKey:e.txKey,status:TransactionStatus.Failed,pending:false,isError:true,hash:t.transactionHash,finishedTimestamp:t.executionDate?p(t.executionDate).unix():void 0});},onReplaced:t=>{n({txKey:e.txKey,status:TransactionStatus.Replaced,pending:false,hash:t.transactionHash,replacedTxHash:t.replacedHash??zeroHash,finishedTimestamp:t.executionDate?p(t.executionDate).unix():void 0});}})}var S=(r=>(r.Ethereum="ethereum",r.Safe="safe",r.Gelato="gelato",r))(S||{});async function B({tracker:e,tx:a,chains:n,...r}){switch(e){case "ethereum":await P({tx:a,chains:n,...r});break;case "gelato":await E({tx:a,...r});break;case "safe":await V({tx:a,...r});break;default:await P({tx:a,chains:n,...r});}}async function U(e,a){let{connector:n,chainId:r}=getAccount(a);if(n&&r!==e)try{await switchChain(a,{chainId:e});}catch(i){throw console.error("Failed to switch chain:",i),new Error("User rejected chain switch or an error occurred.")}}function j(e,a){if(F(e))return {tracker:"gelato",txKey:e.taskId};if(!isHex(e))throw new Error("Invalid transaction key format. Expected a Hex string or GelatoTxKey object.");return a==="safe"?{tracker:"safe",txKey:e}:{tracker:"ethereum",txKey:e}}function wt(e,a){if(e)return {checkChainForTx:n=>U(n,e),checkTransactionsTracker:(n,r)=>j(n,r),checkAndInitializeTrackerInStore:({tx:n,...r})=>B({tracker:n.tracker,tx:n,chains:a,...r})}}async function Et({config:e,tx:a}){if(a.adapter===TransactionAdapter.EVM){if(!a.nonce||!a.maxFeePerGas||!a.maxPriorityFeePerGas)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas).");try{if(!e)throw new Error("Wagmi config is not provided.");let n=getAccount(e);if(!n.address)throw new Error("No connected account found.");let r=115n,i=100n,t=BigInt(a.maxPriorityFeePerGas)*r/i,o=BigInt(a.maxFeePerGas)*r/i;return await sendTransaction(e,{to:n.address,value:0n,chainId:a.chainId,nonce:a.nonce,maxFeePerGas:o,maxPriorityFeePerGas:t})}catch(n){let r=n instanceof Error?n.message:String(n);throw new Error(`Failed to cancel transaction: ${r}`)}}else throw new Error("Failed to cancel transaction: not EVM tx adapter")}var d=null,x=null,Te=300*1e3;async function Gt(e){let a=Date.now();if(d&&x&&a-x<Te)return d.includes(e);try{let n=await fetch("https://relay.gelato.digital/relays/v2");if(!n.ok)return d=null,x=null,!1;let i=(await n.json()).relays.map(Number);return d=i,x=a,i.includes(e)}catch(n){return console.error("Failed to check Gelato service availability:",n),d=null,x=null,false}}function Nt(e){let a=getAccount(e),n=getClient(e);if(!a.address||!n)throw new Error("Wallet not connected");return {activeWallet:a,walletClient:n}}var Lt=(e,a,n,r)=>{let i=selectTXByKey(e,n);return i?(o=>{if(i.tracker==="safe"){let c=W[i.chainId];return c?`${c}${i.from}/transactions/tx?id=multisig_${i.from}_${i.txKey}`:""}let s=a.find(c=>c.id===i.chainId);return s?.blockExplorers?.default.url?`${s.blockExplorers.default.url}/tx/${o}`:""})(r||i.adapter===TransactionAdapter.EVM&&i.hash||i.txKey):""};async function Yt({config:e,tx:a}){if(a.adapter===TransactionAdapter.EVM){if(!a.nonce||!a.from||!a.to||!a.value||!a.input||!a.maxFeePerGas||!a.maxPriorityFeePerGas)throw new Error("Transaction is missing required fields for speed-up.");try{if(!e)throw new Error("Wagmi config is not provided.");if(!getAccount(e).address)throw new Error("No connected account found.");let r=115n,i=100n,t=BigInt(a.maxPriorityFeePerGas)*r/i,o=BigInt(a.maxFeePerGas)*r/i;return await sendTransaction(e,{to:a.to,value:BigInt(a.value),data:a.input,chainId:a.chainId,nonce:a.nonce,maxFeePerGas:o,maxPriorityFeePerGas:t})}catch(n){let r=n instanceof Error?n.message:String(n);throw new Error(`Failed to speed up transaction: ${r}`)}}else throw new Error("Failed to speed up transaction: not EVM tx adapter")}
2
- export{te as GelatoTaskState,b as SafeTransactionServiceUrls,S as TransactionTracker,Et as cancelTxAction,B as checkAndInitializeTrackerInStore,U as checkChainForTx,Gt as checkIsGelatoAvailable,j as checkTransactionsTracker,I as createViemClient,wt as evmAdapter,Z as evmTracker,P as evmTrackerForStore,ae as fetchTxFromGelatoAPI,ie as fetchTxFromSafeAPI,ne as gelatoTracker,E as gelatoTrackerForStore,Nt as getActiveWalletAndClient,W as gnosisSafeLinksHelper,F as isGelatoTxKey,qe as safeSdkOptions,se as safeTracker,V as safeTrackerForStore,Lt as selectEvmTxExplorerLink,Yt as speedUpTxAction};//# sourceMappingURL=index.mjs.map
1
+ import {TransactionStatus,initializePollingTracker,TransactionAdapter,selectTXByKey}from'@tuwaio/pulsar-core';import {createClient,zeroHash,isHex,isAddress}from'viem';import {getTransaction,waitForTransactionReceipt,getBlock}from'viem/actions';import {http,getAccount,switchChain,sendTransaction,getClient}from'@wagmi/core';import p from'dayjs';import {base,bsc,avalanche,arbitrum,polygon,optimism,sepolia,goerli,mainnet}from'viem/chains';import {getEnsName,getEnsAvatar,normalize,getEnsAddress}from'viem/ens';function y(e,t){let r=t.find(n=>n.id===e);if(r)return createClient({chain:r,transport:http()})}async function ae({onInitialize:e,onTxDetailsGot:t,onFinished:r,onFailed:n,onReplaced:i,tx:a,chains:o,retryCount:s,retryTimeout:c,waitForTransactionReceiptParams:k}){let l=s??10,d=y(a.chainId,o);if(e&&e(),a.txKey===zeroHash)throw new Error("Transaction hash is zeroHash");if(!d){let m=new Error(`Could not create a viem client for chainId: ${a.chainId}`);n(m),console.error(m.message);return}for(let m=0;m<l;m++){try{let f=await getTransaction(d,{hash:a.txKey});t(f);let E=!1;try{let g=await waitForTransactionReceipt(d,{hash:f.hash,onReplaced:q=>{E=!0,i(q);},pollingInterval:1e4,...k});if(E)return;await r(f,g,d);}catch(g){n(g),console.error("Error waiting for transaction receipt:",g);}return}catch(f){if(m===l-1){n(f),console.error(`Error tracking EVM transaction after ${l} retries:`,f);return}}await new Promise(f=>setTimeout(f,c??3e3));}}async function w({tx:e,chains:t,transactionsPool:r,updateTxParams:n,onSucceedCallbacks:i}){return await ae({tx:e,chains:t,onInitialize:()=>{n({txKey:e.txKey,hash:e.txKey,pending:e.pending});},onTxDetailsGot:a=>{n({to:a.to??"",input:a.input,value:String(a.value),txKey:e.txKey,pending:e.pending,nonce:a.nonce,hash:a.hash,maxFeePerGas:String(a.maxFeePerGas),maxPriorityFeePerGas:String(a.maxPriorityFeePerGas)});},onFinished:async(a,o,s)=>{let c=await getBlock(s,{blockNumber:o.blockNumber}),k=Number(c.timestamp),l=o.status==="success";n({txKey:e.txKey,status:l?TransactionStatus.Success:TransactionStatus.Failed,to:isHex(o.to)?o.to:void 0,nonce:a.nonce,pending:!1,isError:!l,hash:a.hash,finishedTimestamp:k});let d=r[e.txKey];l&&i&&d&&i(d);},onReplaced:a=>{n({txKey:e.txKey,status:TransactionStatus.Replaced,replacedTxHash:a.transaction.hash,pending:!1});},onFailed:a=>{n({txKey:e.txKey,status:TransactionStatus.Failed,pending:!1,isError:!0,errorMessage:a instanceof Error?a.message:"Transaction failed or could not be tracked."});}})}function F(e){return e.taskId!==void 0}var ne=(o=>(o.CheckPending="CheckPending",o.ExecPending="ExecPending",o.WaitingForConfirmation="WaitingForConfirmation",o.ExecSuccess="ExecSuccess",o.ExecReverted="ExecReverted",o.Cancelled="Cancelled",o))(ne||{});function C(e){return e?["CheckPending","ExecPending","WaitingForConfirmation"].includes(e):true}var K=["ExecReverted","Cancelled"];async function oe({tx:e,onSucceed:t,onFailed:r,onIntervalTick:n,clearWatch:i}){let a=await fetch(`https://api.gelato.digital/tasks/status/${e.txKey}/`);if(a.ok){let o=await a.json(),s=C(o.task.taskState);if(o.task.creationDate){let c=p(o.task.creationDate);if(p().diff(c,"day")>=1&&s)return i(),a}n?.(o),s||(i(true),o.task.taskState==="ExecSuccess"?t(o):K.includes(o.task.taskState)&&r(o));}return a}async function ie(e){await initializePollingTracker({...e,fetcher:oe});}async function R({tx:e,transactionsPool:t,updateTxParams:r,onSucceedCallbacks:n,removeTxFromPool:i}){return await ie({tx:e,removeTxFromPool:i,onSucceed:async a=>{r({txKey:e.txKey,status:TransactionStatus.Success,pending:false,hash:a.task.transactionHash,finishedTimestamp:a.task.executionDate?p(a.task.executionDate).unix():void 0});let o=t[e.txKey];n&&o&&n(o);},onIntervalTick:async a=>{let o=C(a.task.taskState),s=a.task.taskState==="ExecSuccess";r({txKey:e.txKey,pending:o,status:s?TransactionStatus.Success:o?void 0:TransactionStatus.Failed,hash:a.task.transactionHash,finishedTimestamp:a.task.executionDate?p(a.task.executionDate).unix():void 0,errorMessage:K.includes(a.task.taskState)?a.task.lastCheckMessage:void 0,isError:!o&&!s});},onFailed:a=>{r({txKey:e.txKey,status:TransactionStatus.Failed,pending:false,isError:true,hash:a.task.transactionHash,errorMessage:a.task.lastCheckMessage,finishedTimestamp:a.task.executionDate?p(a.task.executionDate).unix():void 0});}})}var tt={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},W={[mainnet.id]:"https://app.safe.global/eth:",[goerli.id]:"https://app.safe.global/gor:",[sepolia.id]:"https://app.safe.global/sep:",[optimism.id]:"https://app.safe.global/oeth:",[polygon.id]:"https://app.safe.global/matic:",[arbitrum.id]:"https://app.safe.global/arb1:",[avalanche.id]:"https://app.safe.global/avax:",[bsc.id]:"https://app.safe.global/bnb:",[base.id]:"https://app.safe.global/base:"},v={[mainnet.id]:"https://safe-transaction-mainnet.safe.global/api/v1",[goerli.id]:"https://safe-transaction-goerli.safe.global/api/v1",[sepolia.id]:"https://safe-transaction-sepolia.safe.global/api/v1",[optimism.id]:"https://safe-transaction-optimism.safe.global/api/v1",[polygon.id]:"https://safe-transaction-polygon.safe.global/api/v1",[arbitrum.id]:"https://safe-transaction-arbitrum.safe.global/api/v1",[avalanche.id]:"https://safe-transaction-avalanche.safe.global/api/v1",[bsc.id]:"https://safe-transaction-bsc.safe.global/api/v1",[base.id]:"https://safe-transaction-base.safe.global/api/v1"};async function le({tx:e,onSucceed:t,onFailed:r,onIntervalTick:n,onReplaced:i,clearWatch:a}){let o=await fetch(`${v[e.chainId]}/multisig-transactions/${e.txKey}/`);if(!o.ok)return o;let s=await o.json(),c=await fetch(`${v[e.chainId]}/safes/${e.from}/multisig-transactions/?nonce=${s.nonce}`);if(!c.ok)return c;let l=(await c.json()).results.find(m=>m.isExecuted);if(l&&l.safeTxHash!==s.safeTxHash)return i?.({...s,replacedHash:l.safeTxHash}),a(true),c;if(s.isExecuted)return s.isSuccessful?t(s):r(s),a(true),o;let d=p(s.modified);return p().diff(d,"day")>=1?(a(),o):(n?.(s),o)}async function de(e){await initializePollingTracker({...e,fetcher:le});}async function U({tx:e,transactionsPool:t,updateTxParams:r,onSucceedCallbacks:n,removeTxFromPool:i}){return await de({tx:e,removeTxFromPool:i,onSucceed:async a=>{r({txKey:e.txKey,status:TransactionStatus.Success,pending:false,hash:a.transactionHash,finishedTimestamp:a.executionDate?p(a.executionDate).unix():void 0});let o=t[e.txKey];n&&o&&n(o);},onIntervalTick:async a=>{r({pending:!a.isExecuted,txKey:e.txKey,hash:a.transactionHash});},onFailed:a=>{r({txKey:e.txKey,status:TransactionStatus.Failed,pending:false,isError:true,hash:a.transactionHash,finishedTimestamp:a.executionDate?p(a.executionDate).unix():void 0});},onReplaced:a=>{r({txKey:e.txKey,status:TransactionStatus.Replaced,pending:false,hash:a.transactionHash,replacedTxHash:a.replacedHash??zeroHash,finishedTimestamp:a.executionDate?p(a.executionDate).unix():void 0});}})}var b=(n=>(n.Ethereum="ethereum",n.Safe="safe",n.Gelato="gelato",n))(b||{});async function B({tracker:e,tx:t,chains:r,...n}){switch(e){case "ethereum":await w({tx:t,chains:r,...n});break;case "gelato":await R({tx:t,...n});break;case "safe":await U({tx:t,...n});break;default:await w({tx:t,chains:r,...n});}}async function j(e,t){let{connector:r,chainId:n}=getAccount(t);if(r&&n!==e)try{await switchChain(t,{chainId:e});}catch(i){throw console.error("Failed to switch chain:",i),new Error("User rejected chain switch or an error occurred.")}}function L(e,t){if(F(e))return {tracker:"gelato",txKey:e.taskId};if(!isHex(e))throw new Error("Invalid transaction key format. Expected a Hex string or GelatoTxKey object.");return t==="safe"?{tracker:"safe",txKey:e}:{tracker:"ethereum",txKey:e}}function Rt(e,t){if(e)return {checkChainForTx:r=>j(r,e),checkTransactionsTracker:(r,n)=>L(r,n),checkAndInitializeTrackerInStore:({tx:r,...n})=>B({tracker:r.tracker,tx:r,chains:t,...n})}}async function Nt({config:e,tx:t}){if(t.adapter===TransactionAdapter.EVM){if(!t.nonce||!t.maxFeePerGas||!t.maxPriorityFeePerGas)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas).");try{if(!e)throw new Error("Wagmi config is not provided.");let r=getAccount(e);if(!r.address)throw new Error("No connected account found.");let n=115n,i=100n,a=BigInt(t.maxPriorityFeePerGas)*n/i,o=BigInt(t.maxFeePerGas)*n/i;return await sendTransaction(e,{to:r.address,value:0n,chainId:t.chainId,nonce:t.nonce,maxFeePerGas:o,maxPriorityFeePerGas:a})}catch(r){let n=r instanceof Error?r.message:String(r);throw new Error(`Failed to cancel transaction: ${n}`)}}else throw new Error("Failed to cancel transaction: not EVM tx adapter")}var x=null,h=null,he=300*1e3;async function zt(e){let t=Date.now();if(x&&h&&t-h<he)return x.includes(e);try{let r=await fetch("https://relay.gelato.digital/relays/v2");if(!r.ok)return x=null,h=null,!1;let i=(await r.json()).relays.map(Number);return x=i,h=t,i.includes(e)}catch(r){return console.error("Failed to check Gelato service availability:",r),x=null,h=null,false}}var u=y(mainnet.id,[mainnet]),Ot=async e=>{if(u)try{return await getEnsName(u,{address:e})??void 0}catch(t){console.error("ENS name lookup error:",t);return}},qt=async e=>{if(u)try{return await getEnsAvatar(u,{name:normalize(e)})??void 0}catch(t){console.error("ENS avatar lookup error:",t);return}},Xt=async e=>{if(u)try{let t=await getEnsAddress(u,{name:normalize(e)});return t?t.toLocaleLowerCase():void 0}catch(t){console.error("ENS address lookup error:",t);return}},Jt=e=>!isAddress(e);function ra(e){let t=getAccount(e),r=getClient(e);if(!t.address||!r)throw new Error("Wallet not connected");return {activeWallet:t,walletClient:r}}var da=(e,t,r,n)=>{let i=selectTXByKey(e,r);return i?(o=>{if(i.tracker==="safe"){let c=W[i.chainId];return c?`${c}${i.from}/transactions/tx?id=multisig_${i.from}_${i.txKey}`:""}let s=t.find(c=>c.id===i.chainId);return s?.blockExplorers?.default.url?`${s.blockExplorers.default.url}/tx/${o}`:""})(n||i.adapter===TransactionAdapter.EVM&&i.hash||i.txKey):""};async function xa({config:e,tx:t}){if(t.adapter===TransactionAdapter.EVM){if(!t.nonce||!t.from||!t.to||!t.value||!t.input||!t.maxFeePerGas||!t.maxPriorityFeePerGas)throw new Error("Transaction is missing required fields for speed-up.");try{if(!e)throw new Error("Wagmi config is not provided.");if(!getAccount(e).address)throw new Error("No connected account found.");let n=115n,i=100n,a=BigInt(t.maxPriorityFeePerGas)*n/i,o=BigInt(t.maxFeePerGas)*n/i;return await sendTransaction(e,{to:t.to,value:BigInt(t.value),data:t.input,chainId:t.chainId,nonce:t.nonce,maxFeePerGas:o,maxPriorityFeePerGas:a})}catch(r){let n=r instanceof Error?r.message:String(r);throw new Error(`Failed to speed up transaction: ${n}`)}}else throw new Error("Failed to speed up transaction: not EVM tx adapter")}
2
+ export{ne as GelatoTaskState,v as SafeTransactionServiceUrls,b as TransactionTracker,Nt as cancelTxAction,B as checkAndInitializeTrackerInStore,j as checkChainForTx,zt as checkIsGelatoAvailable,L as checkTransactionsTracker,y as createViemClient,Rt as evmAdapter,ae as evmTracker,w as evmTrackerForStore,oe as fetchTxFromGelatoAPI,le as fetchTxFromSafeAPI,ie as gelatoTracker,R as gelatoTrackerForStore,ra as getActiveWalletAndClient,Xt as getAddress,qt as getAvatar,Ot as getName,W as gnosisSafeLinksHelper,Jt as isEnsName,F as isGelatoTxKey,tt as safeSdkOptions,de as safeTracker,U as safeTrackerForStore,da as selectEvmTxExplorerLink,xa as speedUpTxAction};//# sourceMappingURL=index.mjs.map
3
3
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/createViemClient.ts","../src/trackers/evmTracker.ts","../src/trackers/gelatoTracker.ts","../src/utils/safeConstants.ts","../src/trackers/safeTracker.ts","../src/types.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkChainForTx.ts","../src/utils/checkTransactionsTracker.ts","../src/adapters/evmAdapter.ts","../src/utils/cancelTxAction.ts","../src/utils/checkIsGelatoAvailable.ts","../src/utils/getActiveWalletAndClient.ts","../src/utils/selectEvmTxExplorerLink.ts","../src/utils/speedUpTxAction.ts"],"names":["createViemClient","chainId","chains","chain","c","createClient","http","evmTracker","onInitialize","onTxDetailsGot","onFinished","onFailed","onReplaced","tx","retryCount","retryTimeout","waitForTransactionReceiptParams","maxRetries","client","zeroHash","error","i","localTx","getTransaction","txWasReplaced","receipt","waitForTransactionReceipt","replacement","e","resolve","evmTrackerForStore","transactionsPool","updateTxParams","onSucceedCallbacks","txBlock","getBlock","timestamp","isSuccess","TransactionStatus","isHex","updatedTX","isGelatoTxKey","txKey","GelatoTaskState","isGelatoTxPending","gelatoStatus","GELATO_TERMINAL_FAILURE_STATES","fetchTxFromGelatoAPI","onSucceed","onIntervalTick","clearWatch","response","isPending","gelatoCreatedDate","dayjs","gelatoTracker","params","initializePollingTracker","gelatoTrackerForStore","removeTxFromPool","updatedTx","safeSdkOptions","gnosisSafeLinksHelper","mainnet","goerli","sepolia","optimism","polygon","arbitrum","avalanche","bsc","base","SafeTransactionServiceUrls","fetchTxFromSafeAPI","primaryTxResponse","safeStatus","nonceTxsResponse","executedTx","t","modifiedDate","safeTracker","safeTrackerForStore","TransactionTracker","checkAndInitializeTrackerInStore","tracker","rest","checkChainForTx","config","connector","activeChainId","getAccount","switchChain","checkTransactionsTracker","actionTxKey","walletType","evmAdapter","appChains","cancelTxAction","TransactionAdapter","account","gasIncreaseMultiplier","divisor","newPriorityFee","newMaxFee","sendTransaction","errorMessage","cachedRelayChainIds","cacheTimestamp","CACHE_DURATION_MS","checkIsGelatoAvailable","now","supportedChainIds","getActiveWalletAndClient","activeWallet","getWagmiAccount","walletClient","getClient","selectEvmTxExplorerLink","replacedTxHash","selectTXByKey","hash","safeBaseUrl","speedUpTxAction"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @file This file contains a utility function for creating a viem Public Client.\n */\n\nimport { http } from '@wagmi/core';\nimport { Chain, createClient, PublicClient } from 'viem';\n\n/**\n * Creates a viem Public Client for a specific chain.\n * This client is used to interact with the blockchain (e.g., fetch transaction details).\n *\n * @param {number} chainId - The ID of the chain for which to create the client.\n * @param {Chain[]} chains - An array of supported viem Chain objects.\n * @returns {PublicClient | undefined} A viem PublicClient instance if the chain is found in the provided array, otherwise undefined.\n * @ignore\n */\nexport function createViemClient(chainId: number, chains: Chain[]): PublicClient | undefined {\n // Use `find` to get the first matching chain object. It's more direct than `filter`.\n const chain = chains.find((c) => c.id === chainId);\n\n if (chain) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n return createClient({\n chain: chain,\n transport: http(),\n });\n }\n\n // Return undefined if no matching chain was found in the configuration.\n return undefined;\n}\n","/**\n * @file This file contains the tracker implementation for standard EVM transactions.\n * It uses viem's public actions (`getTransaction`, `waitForTransactionReceipt`) to monitor\n * a transaction's lifecycle from submission to finality.\n */\n\nimport { ITxTrackingStore, Transaction, TransactionStatus } from '@tuwaio/pulsar-core';\nimport {\n Chain,\n Client,\n GetTransactionReturnType,\n Hex,\n isHex,\n ReplacementReturnType,\n TransactionReceipt,\n WaitForTransactionReceiptParameters,\n zeroHash,\n} from 'viem';\nimport { getBlock, getTransaction, waitForTransactionReceipt } from 'viem/actions';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { createViemClient } from '../utils/createViemClient';\n\n/**\n * Defines the parameters for the low-level EVM transaction tracker.\n */\nexport type EVMTrackerParams = {\n /** The transaction object to track, requiring at least `chainId` and `txKey` (the transaction hash). */\n tx: Pick<Transaction<TransactionTracker>, 'chainId' | 'txKey'>;\n /** An array of `viem` chain objects supported by the application. */\n chains: Chain[];\n /** Callback executed when the getTransaction info got successfully. */\n onTxDetailsGot: (localTx: GetTransactionReturnType) => void;\n /** Callback executed when the transaction is successfully mined and included in a block. */\n onFinished: (localTx: GetTransactionReturnType, receipt: TransactionReceipt, client: Client) => Promise<void>;\n /** Callback executed when the transaction is replaced (e.g., sped up or cancelled). */\n onReplaced: (replacement: ReplacementReturnType) => void;\n /** Callback executed if an error occurs during tracking or if the transaction fails. */\n onFailed: (error?: unknown) => void;\n /** Optional callback executed once when the tracker starts. */\n onInitialize?: () => void;\n /** The number of times to retry fetching the transaction if it's not found initially. Defaults to 10. */\n retryCount?: number;\n /** The delay (in milliseconds) between retry attempts. Defaults to 3000ms. */\n retryTimeout?: number;\n /** Optional parameters to pass to viem's `waitForTransactionReceipt` function. */\n waitForTransactionReceiptParams?: WaitForTransactionReceiptParameters;\n};\n\n/**\n * A low-level tracker for monitoring a standard EVM transaction by its hash.\n * It retries fetching the transaction and then waits for its receipt.\n *\n * @param {EVMTrackerParams} params - The configuration object for the tracker.\n * @returns {Promise<void>} A promise that resolves when the tracking process is complete (or has terminally failed).\n */\nexport async function evmTracker({\n onInitialize,\n onTxDetailsGot,\n onFinished,\n onFailed,\n onReplaced,\n tx,\n chains,\n retryCount,\n retryTimeout,\n waitForTransactionReceiptParams,\n}: EVMTrackerParams): Promise<void> {\n const maxRetries = retryCount ?? 10;\n const client = createViemClient(tx.chainId as number, chains);\n\n if (onInitialize) {\n onInitialize();\n }\n\n if (tx.txKey === zeroHash) {\n throw new Error('Transaction hash is zeroHash');\n }\n\n if (!client) {\n const error = new Error(`Could not create a viem client for chainId: ${tx.chainId}`);\n onFailed(error);\n console.error(error.message);\n return;\n }\n\n // Retry loop to handle cases where the transaction is not immediately available on the RPC node.\n for (let i = 0; i < maxRetries; i++) {\n try {\n // 1. Attempt to fetch the transaction details.\n const localTx = await getTransaction(client, { hash: tx.txKey as Hex });\n\n onTxDetailsGot(localTx);\n\n let txWasReplaced = false;\n\n try {\n // 2. Wait for the transaction to be mined.\n const receipt = await waitForTransactionReceipt(client, {\n hash: localTx.hash,\n onReplaced: (replacement: ReplacementReturnType) => {\n txWasReplaced = true;\n onReplaced(replacement);\n },\n pollingInterval: 10_000,\n ...waitForTransactionReceiptParams,\n });\n\n // If onReplaced was called, the promise resolves but we should not proceed.\n if (txWasReplaced) {\n return;\n }\n\n // 3. Transaction is mined, call the onFinished callback.\n await onFinished(localTx, receipt, client);\n } catch (e) {\n // Error occurred while waiting for the receipt (e.g., timeout, reverted).\n onFailed(e);\n console.error('Error waiting for transaction receipt:', e);\n }\n\n // Exit the retry loop once the transaction is found and processed.\n return;\n } catch (e) {\n // Error occurred while fetching the initial transaction details.\n if (i === maxRetries - 1) {\n onFailed(e);\n console.error(`Error tracking EVM transaction after ${maxRetries} retries:`, e);\n return;\n }\n }\n // Wait before the next retry.\n await new Promise((resolve) => setTimeout(resolve, retryTimeout ?? 3000));\n }\n}\n\n/**\n * A higher-level wrapper for `evmTracker` that integrates directly with the Zustand store.\n * It provides the necessary callbacks to update the transaction's state in the store.\n *\n * @template T - The application-specific transaction union type.\n */\nexport async function evmTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n chains,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n}: Pick<EVMTrackerParams, 'chains'> &\n Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks'\n > & {\n tx: T;\n }) {\n return await evmTracker({\n tx,\n chains,\n onInitialize: () => {\n updateTxParams({\n txKey: tx.txKey,\n hash: tx.txKey as Hex,\n pending: tx.pending,\n });\n },\n onTxDetailsGot: (localTx) => {\n updateTxParams({\n to: localTx.to ?? '',\n input: localTx.input,\n value: String(localTx.value),\n txKey: tx.txKey,\n pending: tx.pending,\n nonce: localTx.nonce,\n hash: localTx.hash,\n maxFeePerGas: String(localTx.maxFeePerGas),\n maxPriorityFeePerGas: String(localTx.maxPriorityFeePerGas),\n });\n },\n onFinished: async (localTx, receipt, client) => {\n const txBlock = await getBlock(client, { blockNumber: receipt.blockNumber });\n const timestamp = Number(txBlock.timestamp);\n const isSuccess = receipt.status === 'success';\n\n updateTxParams({\n txKey: tx.txKey,\n status: isSuccess ? TransactionStatus.Success : TransactionStatus.Failed,\n to: isHex(receipt.to) ? receipt.to : undefined,\n nonce: localTx.nonce,\n pending: false,\n isError: !isSuccess,\n hash: localTx.hash,\n finishedTimestamp: timestamp,\n });\n\n // After updating the state, retrieve the latest version of the transaction.\n const updatedTX = transactionsPool[tx.txKey];\n if (isSuccess && onSucceedCallbacks && updatedTX) {\n onSucceedCallbacks(updatedTX);\n }\n },\n onReplaced: (replacement) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Replaced,\n replacedTxHash: replacement.transaction.hash,\n pending: false,\n });\n },\n onFailed: (error?: unknown) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage: error instanceof Error ? error.message : 'Transaction failed or could not be tracked.',\n });\n },\n });\n}\n","/**\n * @file This file implements the transaction tracking logic for meta-transactions relayed via the Gelato Network.\n * It uses a polling mechanism to check the status of a Gelato Task ID from the Gelato API.\n */\n\nimport {\n InitializePollingTracker,\n initializePollingTracker,\n ITxTrackingStore,\n Transaction,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Hex } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Defines the shape of the identifier for a Gelato transaction task.\n */\nexport type GelatoTxKey = {\n taskId: string;\n};\n\n/**\n * A type guard to determine if an ActionTxKey is a GelatoTxKey.\n * @param {ActionTxKey} txKey - The transaction key to check.\n * @returns {boolean} True if the key is for a Gelato transaction.\n */\nexport function isGelatoTxKey(txKey: ActionTxKey): txKey is GelatoTxKey {\n return (txKey as GelatoTxKey).taskId !== undefined;\n}\n\n/**\n * Enum representing the possible states of a Gelato task.\n * @see https://docs.gelato.network/developer-services/relay/api/get-task-status\n */\nexport enum GelatoTaskState {\n CheckPending = 'CheckPending',\n ExecPending = 'ExecPending',\n WaitingForConfirmation = 'WaitingForConfirmation',\n ExecSuccess = 'ExecSuccess',\n ExecReverted = 'ExecReverted',\n Cancelled = 'Cancelled',\n}\n\n/**\n * Defines the shape of the response from the Gelato `getTaskStatus` API endpoint.\n */\nexport type GelatoTaskStatusResponse = {\n task: {\n chainId: number;\n taskId: string;\n taskState: GelatoTaskState;\n creationDate?: string;\n executionDate?: string;\n transactionHash?: Hex;\n blockNumber?: number;\n lastCheckMessage?: string;\n };\n};\n\n/**\n * A utility type for the initial Gelato transaction object passed to the tracker.\n */\ntype InitialGelatoTx = Pick<Transaction<TransactionTracker>, 'txKey'> & {\n pending?: boolean;\n};\n\n/**\n * Defines the parameters required for the low-level `gelatoTracker` function.\n */\nexport type GelatoTrackerParams = Pick<\n InitializePollingTracker<GelatoTaskStatusResponse, InitialGelatoTx, TransactionTracker>,\n | 'tx'\n | 'removeTxFromPool'\n | 'onInitialize'\n | 'onSucceed'\n | 'onFailed'\n | 'onIntervalTick'\n | 'pollingInterval'\n | 'retryCount'\n>;\n\n/**\n * Checks if a Gelato task state is considered pending.\n * @param {GelatoTaskState} [gelatoStatus] - The current status of the Gelato task.\n * @returns {boolean} True if the status is pending.\n */\nfunction isGelatoTxPending(gelatoStatus?: GelatoTaskState): boolean {\n if (!gelatoStatus) return true;\n const pendingStates = [\n GelatoTaskState.CheckPending,\n GelatoTaskState.ExecPending,\n GelatoTaskState.WaitingForConfirmation,\n ];\n return pendingStates.includes(gelatoStatus);\n}\n\n/**\n * A set of terminal states that indicate a transaction has failed or been cancelled.\n */\nconst GELATO_TERMINAL_FAILURE_STATES = [GelatoTaskState.ExecReverted, GelatoTaskState.Cancelled];\n\n/**\n * The fetcher function passed to `initializePollingTracker` to get the status of a Gelato task.\n * @param {object} params - The parameters for fetching the transaction status.\n * @returns {Promise<Response>} The raw response from the fetch call.\n */\nexport async function fetchTxFromGelatoAPI({\n tx,\n onSucceed,\n onFailed,\n onIntervalTick,\n clearWatch,\n}: {\n clearWatch: (withoutRemoving?: boolean) => void;\n} & Pick<GelatoTrackerParams, 'onIntervalTick' | 'onSucceed' | 'onFailed' | 'tx'>): Promise<Response> {\n const response = await fetch(`https://api.gelato.digital/tasks/status/${tx.txKey}/`);\n\n if (response.ok) {\n const gelatoStatus = (await response.json()) as GelatoTaskStatusResponse;\n const isPending = isGelatoTxPending(gelatoStatus.task.taskState);\n\n // Safeguard: Stop polling for transactions that have been pending for over a day.\n if (gelatoStatus.task.creationDate) {\n const gelatoCreatedDate = dayjs(gelatoStatus.task.creationDate);\n if (dayjs().diff(gelatoCreatedDate, 'day') >= 1 && isPending) {\n clearWatch(); // Stop polling but don't remove from pool\n return response;\n }\n }\n\n onIntervalTick?.(gelatoStatus);\n\n if (!isPending) {\n clearWatch(true); // Stop polling but keep the transaction for UI feedback\n if (gelatoStatus.task.taskState === GelatoTaskState.ExecSuccess) {\n onSucceed(gelatoStatus);\n } else if (GELATO_TERMINAL_FAILURE_STATES.includes(gelatoStatus.task.taskState)) {\n onFailed(gelatoStatus);\n }\n }\n }\n\n return response;\n}\n\n/**\n * A low-level tracker for monitoring Gelato transactions. It wraps the generic polling\n * tracker with the Gelato-specific fetcher logic.\n *\n * @param {GelatoTrackerParams} params - The configuration object for the tracker.\n * @returns {Promise<void>}\n */\nexport async function gelatoTracker(params: GelatoTrackerParams): Promise<void> {\n await initializePollingTracker({\n ...params,\n fetcher: fetchTxFromGelatoAPI,\n });\n}\n\n/**\n * A higher-level wrapper for `gelatoTracker` that integrates directly with the Zustand store.\n * It provides the necessary callbacks to update the transaction's state in the store.\n *\n * @template T - The application-specific transaction union type.\n */\nexport async function gelatoTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n removeTxFromPool,\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}) {\n return await gelatoTracker({\n tx,\n removeTxFromPool,\n onSucceed: async (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Success,\n pending: false,\n hash: response.task.transactionHash,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n });\n\n const updatedTx = transactionsPool[tx.txKey];\n if (onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onIntervalTick: async (response) => {\n const isPending = isGelatoTxPending(response.task.taskState);\n const isSuccess = response.task.taskState === GelatoTaskState.ExecSuccess;\n\n updateTxParams({\n txKey: tx.txKey,\n pending: isPending,\n status: isSuccess ? TransactionStatus.Success : isPending ? undefined : TransactionStatus.Failed,\n hash: response.task.transactionHash,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n errorMessage: GELATO_TERMINAL_FAILURE_STATES.includes(response.task.taskState)\n ? response.task.lastCheckMessage\n : undefined,\n isError: !isPending && !isSuccess,\n });\n },\n onFailed: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response.task.transactionHash,\n errorMessage: response.task.lastCheckMessage,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n });\n },\n });\n}\n","/**\n * @file This file contains constants related to Safe (formerly Gnosis Safe) configuration,\n * including SDK options, web app URLs, and transaction service API endpoints.\n */\n\nimport { arbitrum, avalanche, base, bsc, goerli, mainnet, optimism, polygon, sepolia } from 'viem/chains';\n\n/**\n * Configuration options for the Safe Apps SDK.\n * This is typically used when integrating with the Safe environment.\n */\nexport const safeSdkOptions = {\n // A list of allowed domains to interact with the Safe Apps SDK.\n allowedDomains: [/gnosis-safe.io$/, /app.safe.global$/, /metissafe.tech$/],\n // A flag to enable or disable debug logging for the SDK.\n debug: false,\n};\n\n/**\n * A mapping of chain IDs to their corresponding Safe web application URL prefixes.\n * Used by selectors like `selectTxExplorerLink` to build correct links for Safe transactions.\n * The prefixes (e.g., 'eth:', 'gor:') are part of the Safe URL scheme.\n * @type {Record<number, string>}\n */\nexport const gnosisSafeLinksHelper: Record<number, string> = {\n [mainnet.id]: 'https://app.safe.global/eth:',\n [goerli.id]: 'https://app.safe.global/gor:',\n [sepolia.id]: 'https://app.safe.global/sep:',\n [optimism.id]: 'https://app.safe.global/oeth:',\n [polygon.id]: 'https://app.safe.global/matic:',\n [arbitrum.id]: 'https://app.safe.global/arb1:',\n [avalanche.id]: 'https://app.safe.global/avax:',\n [bsc.id]: 'https://app.safe.global/bnb:',\n [base.id]: 'https://app.safe.global/base:',\n};\n\n/**\n * A mapping of chain IDs to their corresponding Safe Transaction Service API endpoints.\n * This is used by the `safeTracker` to fetch the status of multisig transactions.\n * @type {Record<number, string>}\n */\nexport const SafeTransactionServiceUrls: Record<number, string> = {\n [mainnet.id]: 'https://safe-transaction-mainnet.safe.global/api/v1',\n [goerli.id]: 'https://safe-transaction-goerli.safe.global/api/v1',\n [sepolia.id]: 'https://safe-transaction-sepolia.safe.global/api/v1',\n [optimism.id]: 'https://safe-transaction-optimism.safe.global/api/v1',\n [polygon.id]: 'https://safe-transaction-polygon.safe.global/api/v1',\n [arbitrum.id]: 'https://safe-transaction-arbitrum.safe.global/api/v1',\n [avalanche.id]: 'https://safe-transaction-avalanche.safe.global/api/v1',\n [bsc.id]: 'https://safe-transaction-bsc.safe.global/api/v1',\n [base.id]: 'https://safe-transaction-base.safe.global/api/v1',\n};\n","/**\n * @file This file implements the transaction tracking logic for Gnosis Safe (now Safe) multisig transactions.\n * It uses a polling mechanism to query the Safe Transaction Service API for the status of a `safeTxHash`.\n */\n\nimport {\n InitializePollingTracker,\n initializePollingTracker,\n ITxTrackingStore,\n Transaction,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Hex, zeroHash } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { SafeTransactionServiceUrls } from '../utils/safeConstants';\n\n/**\n * Defines the shape of the transaction object passed to the Safe tracker.\n */\ntype InitialSafeTx = Pick<Transaction<TransactionTracker>, 'txKey' | 'chainId' | 'from'> & {\n pending?: boolean;\n};\n\n/**\n * Defines the shape of the primary response for a single transaction from the Safe Transaction Service API.\n */\nexport type SafeTxStatusResponse = {\n transactionHash: string;\n safeTxHash: string;\n isExecuted: boolean;\n isSuccessful: boolean | null;\n executionDate: string | null;\n submissionDate: string | null;\n modified: string;\n nonce: number;\n replacedHash?: string; // Custom field for passing replacement info\n};\n\n/**\n * Defines the shape of the response when querying for multiple transactions (e.g., by nonce).\n */\ntype SafeTxSameNonceResponse = {\n count: number;\n results: SafeTxStatusResponse[];\n};\n\n/**\n * Defines the parameters for the low-level `safeTracker` function.\n */\nexport type SafeTrackerParams = Pick<\n InitializePollingTracker<SafeTxStatusResponse, InitialSafeTx, TransactionTracker>,\n | 'tx'\n | 'removeTxFromPool'\n | 'onInitialize'\n | 'onSucceed'\n | 'onFailed'\n | 'onReplaced'\n | 'onIntervalTick'\n | 'pollingInterval'\n | 'retryCount'\n>;\n\n/**\n * The fetcher function passed to `initializePollingTracker` to get the status of a Safe transaction.\n * @returns The raw response from the fetch call.\n */\nexport async function fetchTxFromSafeAPI({\n tx,\n onSucceed,\n onFailed,\n onIntervalTick,\n onReplaced,\n clearWatch,\n}: {\n clearWatch: (withoutRemoving?: boolean) => void;\n} & Pick<SafeTrackerParams, 'onIntervalTick' | 'onSucceed' | 'onFailed' | 'onReplaced' | 'tx'>): Promise<Response> {\n const primaryTxResponse = await fetch(\n `${SafeTransactionServiceUrls[tx.chainId as number]}/multisig-transactions/${tx.txKey}/`,\n );\n\n if (!primaryTxResponse.ok) {\n return primaryTxResponse; // Let the polling tracker handle the retry\n }\n\n const safeStatus = (await primaryTxResponse.json()) as SafeTxStatusResponse;\n\n // Fetch all other transactions with the same nonce to check for replacements.\n const nonceTxsResponse = await fetch(\n `${SafeTransactionServiceUrls[tx.chainId as number]}/safes/${tx.from}/multisig-transactions/?nonce=${safeStatus.nonce}`,\n );\n\n if (!nonceTxsResponse.ok) {\n return nonceTxsResponse; // Let the polling tracker handle the retry\n }\n\n const sameNonceTxs = (await nonceTxsResponse.json()) as SafeTxSameNonceResponse;\n const executedTx = sameNonceTxs.results.find((t) => t.isExecuted);\n\n // Case 1: Another transaction with the same nonce was executed. This one was replaced.\n if (executedTx && executedTx.safeTxHash !== safeStatus.safeTxHash) {\n onReplaced?.({ ...safeStatus, replacedHash: executedTx.safeTxHash });\n clearWatch(true);\n return nonceTxsResponse;\n }\n\n // Case 2: The transaction itself was executed.\n if (safeStatus.isExecuted) {\n if (safeStatus.isSuccessful) {\n onSucceed(safeStatus);\n } else {\n onFailed(safeStatus);\n }\n clearWatch(true);\n return primaryTxResponse;\n }\n\n // Case 3: The transaction is still pending.\n // Safeguard: Stop polling for transactions that have been pending for over a day.\n const modifiedDate = dayjs(safeStatus.modified);\n if (dayjs().diff(modifiedDate, 'day') >= 1) {\n clearWatch(); // Stop polling and remove from pool\n return primaryTxResponse;\n }\n\n // Otherwise, just report the current status and continue polling.\n onIntervalTick?.(safeStatus);\n\n return primaryTxResponse;\n}\n\n/**\n * A low-level tracker for monitoring Safe multisig transactions.\n * It wraps the generic polling tracker with the Safe-specific fetcher logic.\n */\nexport async function safeTracker(params: SafeTrackerParams): Promise<void> {\n await initializePollingTracker<SafeTxStatusResponse, InitialSafeTx, TransactionTracker>({\n ...params,\n fetcher: fetchTxFromSafeAPI,\n });\n}\n\n/**\n * A higher-level wrapper for `safeTracker` that integrates directly with the Zustand store.\n */\nexport async function safeTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n removeTxFromPool,\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}) {\n return await safeTracker({\n tx,\n removeTxFromPool,\n onSucceed: async (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Success,\n pending: false,\n hash: response.transactionHash as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n\n const updatedTx = transactionsPool[tx.txKey];\n if (onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onIntervalTick: async (response) => {\n updateTxParams({\n pending: !response.isExecuted,\n txKey: tx.txKey,\n hash: response.transactionHash as Hex,\n });\n },\n onFailed: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response.transactionHash as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n onReplaced: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Replaced,\n pending: false,\n hash: response.transactionHash as Hex,\n replacedTxHash: (response.replacedHash ?? zeroHash) as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n });\n}\n","/**\n * @file This file defines types and enums specific to the EVM transaction tracking package.\n * It includes identifiers for different tracking strategies and the shape of transaction keys.\n */\n\nimport { Hex } from 'viem';\n\nimport { GelatoTxKey } from './trackers/gelatoTracker';\n\n/**\n * Enum representing the different tracking strategies available for EVM transactions.\n */\nexport enum TransactionTracker {\n /** For standard on-chain EVM transactions tracked by their hash. */\n Ethereum = 'ethereum',\n /** For multi-signature transactions managed by a Safe contract. */\n Safe = 'safe',\n /** For meta-transactions relayed through the Gelato Network. */\n Gelato = 'gelato',\n}\n\n/**\n * Represents the unique identifier returned by an action function after a transaction is submitted.\n * This key is used to determine which tracker should monitor the transaction.\n * It can be a standard transaction hash or a structured key from a relay service like Gelato.\n * @typedef {Hex | GelatoTxKey} ActionTxKey\n */\nexport type ActionTxKey = Hex | GelatoTxKey;\n","/**\n * @file This file contains a utility function that acts as a router to initialize the correct transaction tracker.\n * Based on a transaction's `tracker` property, it delegates the tracking task to the appropriate implementation.\n */\n\nimport { ITxTrackingStore, Transaction } from '@tuwaio/pulsar-core';\nimport { Chain } from 'viem';\n\nimport { evmTrackerForStore } from '../trackers/evmTracker';\nimport { gelatoTrackerForStore } from '../trackers/gelatoTracker';\nimport { safeTrackerForStore } from '../trackers/safeTracker';\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Initializes the appropriate tracker for a given transaction based on its `tracker` type.\n * This function acts as a central router, delegating to the specific tracker implementation\n * (e.g., EVM, Gelato, Safe).\n *\n * @template T - The application-specific transaction union type.\n * @param {object} params - The parameters for initializing the tracker.\n * @param {TransactionTracker} params.tracker - The type of tracker to use for the transaction.\n * @param {T} params.tx - The transaction object to be tracked.\n * @param {Chain[]} params.chains - An array of supported chain objects, required for some trackers (like the EVM tracker).\n * @param {object} params.rest - The rest of the parameters, which are the relevant methods from the Zustand store\n * (`transactionsPool`, `updateTxParams`, `onSucceedCallbacks`, `removeTxFromPool`).\n * @returns {Promise<void>} A promise that resolves once the tracking process has been initiated.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<TransactionTracker>>({\n tracker,\n tx,\n chains,\n ...rest\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n chains: Chain[];\n tx: T;\n tracker: TransactionTracker;\n}): Promise<void> {\n switch (tracker) {\n case TransactionTracker.Ethereum:\n await evmTrackerForStore({\n tx,\n chains,\n ...rest,\n });\n break;\n\n case TransactionTracker.Gelato:\n // The Gelato tracker does not need the `chains` param as it uses its own API endpoints.\n await gelatoTrackerForStore({\n tx,\n ...rest,\n });\n break;\n\n case TransactionTracker.Safe:\n // The Safe tracker also uses its own API endpoints.\n await safeTrackerForStore({\n tx,\n ...rest,\n });\n break;\n\n // The default case handles any unknown or unspecified tracker types as standard EVM transactions.\n default:\n await evmTrackerForStore({\n tx,\n chains,\n ...rest,\n });\n }\n}\n","/**\n * @file This file contains a utility to ensure the user's wallet is connected to the correct chain before proceeding.\n */\n\nimport { Config, switchChain } from '@wagmi/core';\nimport { getAccount } from '@wagmi/core';\n\n/**\n * Checks if the user's wallet is connected to the specified chain. If not, it prompts\n * the user to switch to the correct chain and waits for the operation to complete.\n *\n * @param {number} chainId - The ID of the desired blockchain network.\n * @param {Config} config - The wagmi configuration object.\n * @returns {Promise<void>} A promise that resolves when the wallet is on the correct chain,\n * or rejects if the user cancels the switch or an error occurs.\n * @throws {Error} Throws an error if the user rejects the chain switch or if the switch fails.\n */\nexport async function checkChainForTx(chainId: number, config: Config): Promise<void> {\n const { connector, chainId: activeChainId } = getAccount(config);\n\n // Proceed only if a wallet is connected and it's on the wrong chain.\n if (connector && activeChainId !== chainId) {\n try {\n // Directly await the switchChain call. This pauses execution until the user responds.\n await switchChain(config, { chainId });\n } catch (e) {\n // The user rejected the request or an error occurred.\n console.error('Failed to switch chain:', e);\n throw new Error('User rejected chain switch or an error occurred.');\n }\n }\n}\n","/**\n * @file This file contains a utility function to determine the correct tracker for a transaction\n * based on the key returned by the submission function and the wallet type.\n */\n\nimport { isHex } from 'viem';\n\nimport { isGelatoTxKey } from '../trackers/gelatoTracker';\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Determines which transaction tracker to use based on the format of the transaction key and the wallet type.\n *\n * This function is a critical routing step after a transaction is submitted.\n * It follows a priority order:\n * 1. Checks for a Gelato Task ID.\n * 2. Checks if the wallet type is 'safe'.\n * 3. Defaults to a standard Ethereum tracker.\n *\n * @param {ActionTxKey} actionTxKey - The key returned from the transaction submission function (e.g., a hash or a Gelato task object).\n * @param {string} walletType - The type of the wallet that initiated the action (e.g., 'safe', 'metaMask').\n * @returns {{ tracker: TransactionTracker; txKey: string }} An object containing the determined tracker type and the final string-based transaction key.\n */\nexport function checkTransactionsTracker(\n actionTxKey: ActionTxKey,\n walletType: string,\n): { tracker: TransactionTracker; txKey: string } {\n // 1. Highest priority: Check if the key matches the Gelato task structure.\n if (isGelatoTxKey(actionTxKey)) {\n return {\n tracker: TransactionTracker.Gelato,\n txKey: actionTxKey.taskId,\n };\n }\n\n // At this point, actionTxKey must be a Hex string (transaction hash or SafeTxHash).\n // We can add a check for robustness, although TypeScript should infer this.\n if (!isHex(actionTxKey)) {\n throw new Error('Invalid transaction key format. Expected a Hex string or GelatoTxKey object.');\n }\n\n // 2. Second priority: Check if the transaction came from a Safe wallet.\n if (walletType === 'safe') {\n return {\n tracker: TransactionTracker.Safe,\n txKey: actionTxKey,\n };\n }\n\n // 3. Default: Treat as a standard on-chain Ethereum transaction.\n return {\n tracker: TransactionTracker.Ethereum,\n txKey: actionTxKey,\n };\n}\n","import { ITxTrackingStore, Transaction } from '@tuwaio/pulsar-core';\nimport { Config } from '@wagmi/core';\nimport { Chain } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkChainForTx } from '../utils/checkChainForTx';\nimport { checkTransactionsTracker } from '../utils/checkTransactionsTracker';\n\nexport function evmAdapter<T extends Transaction<TransactionTracker>>(config: Config, appChains: Chain[]) {\n if (config) {\n return {\n checkChainForTx: (chainId: string | number) => checkChainForTx(chainId as number, config),\n checkTransactionsTracker: (actionTxKey: ActionTxKey, walletType: string) =>\n checkTransactionsTracker(actionTxKey, walletType),\n checkAndInitializeTrackerInStore: ({\n tx,\n ...rest\n }: { tx: T } & Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n >) => checkAndInitializeTrackerInStore({ tracker: tx.tracker, tx, chains: appChains, ...rest }),\n };\n }\n}\n","import { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n/**\n * Cancels a pending transaction by sending a new, zero-value transaction to oneself\n * with the same nonce but a higher gas price.\n *\n * @param {object} params - The parameters for the cancellation.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The transaction object to be canceled. Must contain nonce, gas fees, etc.\n *\n * @returns {Promise<Hex>} A promise that resolves with the hash of the new cancellation transaction.\n *\n * @throws {Error} Throws an error if the transaction is missing required fields or if sending fails.\n *\n * @example\n * ```ts\n * import { cancelTxAction } from './cancelTxAction';\n *\n * const handleCancel = async () => {\n * try {\n * const cancelTxHash = await cancelTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Cancellation transaction sent:', cancelTxHash);\n * } catch (error) {\n * console.error('Failed to cancel transaction:', error);\n * }\n * };\n * ```\n */\nexport async function cancelTxAction<T extends Transaction<any>>({\n config,\n tx,\n}: {\n config: Config;\n tx: T;\n}): Promise<Hex> {\n if (tx.adapter === TransactionAdapter.EVM) {\n // Ensure the transaction has all the necessary details for cancellation.\n if (!tx.nonce || !tx.maxFeePerGas || !tx.maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for cancellation (nonce, maxFeePerGas).');\n }\n\n try {\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // Increase gas fees by 15% to ensure the cancellation transaction is prioritized.\n const gasIncreaseMultiplier = 115n; // 115%\n const divisor = 100n;\n const newPriorityFee = (BigInt(tx.maxPriorityFeePerGas) * gasIncreaseMultiplier) / divisor;\n const newMaxFee = (BigInt(tx.maxFeePerGas) * gasIncreaseMultiplier) / divisor;\n\n // Send a zero-value transaction to your own address with the same nonce.\n const hash = await sendTransaction(config, {\n to: account.address,\n value: 0n,\n chainId: tx.chainId as number,\n nonce: tx.nonce,\n maxFeePerGas: newMaxFee,\n maxPriorityFeePerGas: newPriorityFee,\n });\n\n return hash;\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n // Re-throw the error with more context.\n throw new Error(`Failed to cancel transaction: ${errorMessage}`);\n }\n } else {\n throw new Error(`Failed to cancel transaction: not EVM tx adapter`);\n }\n}\n","/**\n * @file This file contains a utility to check if the Gelato Relay service is available for a specific chain.\n */\n\n// --- In-memory cache to store the list of supported chains ---\nlet cachedRelayChainIds: number[] | null = null;\nlet cacheTimestamp: number | null = null;\nconst CACHE_DURATION_MS = 5 * 60 * 1000; // Cache the list for 5 minutes\n\n/**\n * Checks if the Gelato Relay service supports a given chain ID.\n * The result is cached in memory for 5 minutes to avoid excessive network requests.\n *\n * @param {number} chainId - The chain identifier to check.\n * @returns {Promise<boolean>} True if Gelato supports the chain, false otherwise.\n */\nexport async function checkIsGelatoAvailable(chainId: number): Promise<boolean> {\n const now = Date.now();\n\n // 1. Check if a valid cache exists.\n if (cachedRelayChainIds && cacheTimestamp && now - cacheTimestamp < CACHE_DURATION_MS) {\n return cachedRelayChainIds.includes(chainId);\n }\n\n // 2. If no valid cache, fetch from the API.\n try {\n const response = await fetch('https://relay.gelato.digital/relays/v2');\n if (!response.ok) {\n // Clear cache in case of a temporary API failure\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n return false;\n }\n\n const data = (await response.json()) as { relays: string[] };\n const supportedChainIds = data.relays.map(Number);\n\n // 3. Update the cache.\n cachedRelayChainIds = supportedChainIds;\n cacheTimestamp = now;\n\n return supportedChainIds.includes(chainId);\n } catch (e) {\n console.error('Failed to check Gelato service availability:', e);\n // Clear cache on error\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n return false;\n }\n}\n","/**\n * @file This file contains a utility for safely retrieving the active wallet account and viem client.\n */\n\nimport { Config, getClient, GetClientReturnType } from '@wagmi/core';\nimport { getAccount as getWagmiAccount, GetAccountReturnType } from '@wagmi/core';\n\n/**\n * Retrieves the active wallet account and the viem Wallet Client from the wagmi config.\n * It ensures that a wallet is connected by throwing an error if it's not.\n *\n * @param {Config} config - The wagmi configuration object.\n * @returns {{ activeWallet: GetAccountReturnType; walletClient: GetClientReturnType }} An object containing the connected account details and the viem Wallet Client.\n * @throws {Error} Throws an error with the message \"Wallet not connected\" if no wallet is connected or the client is unavailable.\n */\nexport function getActiveWalletAndClient(config: Config): {\n activeWallet: GetAccountReturnType;\n walletClient: GetClientReturnType;\n} {\n const activeWallet = getWagmiAccount(config);\n const walletClient = getClient(config);\n\n // This check is crucial to prevent downstream errors.\n if (!activeWallet.address || !walletClient) {\n throw new Error('Wallet not connected');\n }\n\n return { activeWallet, walletClient };\n}\n","import { selectTXByKey, Transaction, TransactionAdapter, TransactionPool } from '@tuwaio/pulsar-core';\nimport { Chain, Hex } from 'viem';\n\nimport { TransactionTracker } from '../types';\nimport { gnosisSafeLinksHelper } from './safeConstants';\n\n/**\n * Generates a URL to a block explorer for a given transaction.\n * It handles different URL structures for standard EVM transactions and Safe transactions.\n *\n * @template TR - The generic type for the tracker identifier.\n * @template T - The transaction type.\n * @param {TransactionPool<TR, T>} transactionsPool - The entire pool of transactions from the store.\n * @param {Chain[]} chains - An array of supported chain objects from viem.\n * @param {Hex} txKey - The tx key of the transaction for which to generate the link.\n * @param {Hex} [replacedTxHash] - Optional. If provided, the link will be generated for this hash instead of the original.\n * @returns {string} The URL to the transaction on the corresponding block explorer, or an empty string if not found.\n */\nexport const selectEvmTxExplorerLink = <TR, T extends Transaction<TR>>(\n transactionsPool: TransactionPool<TR, T>,\n chains: Chain[],\n txKey: Hex,\n replacedTxHash?: Hex,\n): string => {\n const tx = selectTXByKey(transactionsPool, txKey);\n\n if (!tx) {\n return '';\n }\n\n /**\n * Internal helper to construct the final URL based on the tracker type.\n * @param {string} hash - The transaction hash to include in the URL.\n * @returns {string} The constructed explorer URL.\n */\n const constructUrl = (hash: string): string => {\n // For Safe transactions, generate a link to the Safe web app.\n if (tx.tracker === TransactionTracker.Safe) {\n const safeBaseUrl = gnosisSafeLinksHelper[tx.chainId as number];\n return safeBaseUrl ? `${safeBaseUrl}${tx.from}/transactions/tx?id=multisig_${tx.from}_${tx.txKey}` : '';\n }\n\n // For standard EVM transactions, find the chain's default block explorer.\n const chain = chains.find((chain) => chain.id === tx.chainId);\n\n if (!chain?.blockExplorers?.default.url) {\n // Return empty string if the chain or its explorer URL is not configured.\n return '';\n }\n\n return `${chain.blockExplorers.default.url}/tx/${hash}`;\n };\n\n // Prioritize the replaced hash if it exists, otherwise use the original.\n return constructUrl(replacedTxHash || (tx.adapter === TransactionAdapter.EVM && tx.hash) || tx.txKey);\n};\n","import { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n/**\n * Speeds up a pending transaction by resubmitting it with the same nonce but higher gas fees.\n * This is a common strategy to prevent a transaction from getting stuck.\n *\n * @param {object} params - The parameters required to speed up the transaction.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The original transaction object that needs to be sped up.\n *\n * @returns {Promise<Hex>} A promise that resolves with the hash of the new, speed-up transaction.\n *\n * @throws {Error} Throws an error if the wagmi config is not provided, the account is not found,\n * or if the transaction is missing required fields (`nonce`, `maxFeePerGas`, etc.).\n *\n * @example\n * ```ts\n * import { speedUpTxAction } from './speedUpTxAction';\n *\n * const handleSpeedUp = async () => {\n * try {\n * const newTxHash = await speedUpTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Transaction sped up with new hash:', newTxHash);\n * } catch (error) {\n * console.error('Failed to speed up transaction:', error);\n * }\n * };\n * ```\n */\nexport async function speedUpTxAction<TR, T extends Transaction<TR>>({\n config,\n tx,\n}: {\n config: Config;\n tx: T;\n}): Promise<Hex> {\n if (tx.adapter === TransactionAdapter.EVM) {\n // Ensure all necessary transaction details are present.\n if (!tx.nonce || !tx.from || !tx.to || !tx.value || !tx.input || !tx.maxFeePerGas || !tx.maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for speed-up.');\n }\n\n try {\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // To replace a pending transaction, the new gas fees must be higher.\n // We increase both fees by 15% as a common strategy to ensure replacement.\n const gasIncreaseMultiplier = 115n; // 115%\n const divisor = 100n;\n const newPriorityFee = (BigInt(tx.maxPriorityFeePerGas) * gasIncreaseMultiplier) / divisor;\n const newMaxFee = (BigInt(tx.maxFeePerGas) * gasIncreaseMultiplier) / divisor;\n\n // Resubmit the transaction with the same details but higher gas fees.\n return await sendTransaction(config, {\n to: tx.to as Hex,\n value: BigInt(tx.value),\n data: tx.input as Hex,\n chainId: tx.chainId as number,\n nonce: tx.nonce,\n maxFeePerGas: newMaxFee,\n maxPriorityFeePerGas: newPriorityFee,\n });\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n // Re-throw the error with more context.\n throw new Error(`Failed to speed up transaction: ${errorMessage}`);\n }\n } else {\n throw new Error(`Failed to speed up transaction: not EVM tx adapter`);\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/createViemClient.ts","../src/trackers/evmTracker.ts","../src/trackers/gelatoTracker.ts","../src/utils/safeConstants.ts","../src/trackers/safeTracker.ts","../src/types.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkChainForTx.ts","../src/utils/checkTransactionsTracker.ts","../src/adapters/evmAdapter.ts","../src/utils/cancelTxAction.ts","../src/utils/checkIsGelatoAvailable.ts","../src/utils/ensUtils.ts","../src/utils/getActiveWalletAndClient.ts","../src/utils/selectEvmTxExplorerLink.ts","../src/utils/speedUpTxAction.ts"],"names":["createViemClient","chainId","chains","chain","c","createClient","http","evmTracker","onInitialize","onTxDetailsGot","onFinished","onFailed","onReplaced","tx","retryCount","retryTimeout","waitForTransactionReceiptParams","maxRetries","client","zeroHash","error","i","localTx","getTransaction","txWasReplaced","receipt","waitForTransactionReceipt","replacement","e","resolve","evmTrackerForStore","transactionsPool","updateTxParams","onSucceedCallbacks","txBlock","getBlock","timestamp","isSuccess","TransactionStatus","isHex","updatedTX","isGelatoTxKey","txKey","GelatoTaskState","isGelatoTxPending","gelatoStatus","GELATO_TERMINAL_FAILURE_STATES","fetchTxFromGelatoAPI","onSucceed","onIntervalTick","clearWatch","response","isPending","gelatoCreatedDate","dayjs","gelatoTracker","params","initializePollingTracker","gelatoTrackerForStore","removeTxFromPool","updatedTx","safeSdkOptions","gnosisSafeLinksHelper","mainnet","goerli","sepolia","optimism","polygon","arbitrum","avalanche","bsc","base","SafeTransactionServiceUrls","fetchTxFromSafeAPI","primaryTxResponse","safeStatus","nonceTxsResponse","executedTx","t","modifiedDate","safeTracker","safeTrackerForStore","TransactionTracker","checkAndInitializeTrackerInStore","tracker","rest","checkChainForTx","config","connector","activeChainId","getAccount","switchChain","checkTransactionsTracker","actionTxKey","walletType","evmAdapter","appChains","cancelTxAction","TransactionAdapter","account","gasIncreaseMultiplier","divisor","newPriorityFee","newMaxFee","sendTransaction","errorMessage","cachedRelayChainIds","cacheTimestamp","CACHE_DURATION_MS","checkIsGelatoAvailable","now","supportedChainIds","ensClient","getName","address","getEnsName","getAvatar","name","getEnsAvatar","normalize","getAddress","getEnsAddress","isEnsName","isAddress","getActiveWalletAndClient","activeWallet","getWagmiAccount","walletClient","getClient","selectEvmTxExplorerLink","replacedTxHash","selectTXByKey","hash","safeBaseUrl","speedUpTxAction"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @file This file contains a utility function for creating a viem Public Client.\n */\n\nimport { http } from '@wagmi/core';\nimport { Chain, createClient, PublicClient } from 'viem';\n\n/**\n * Creates a viem Public Client for a specific chain.\n * This client is used to interact with the blockchain (e.g., fetch transaction details).\n *\n * @param {number} chainId - The ID of the chain for which to create the client.\n * @param {Chain[]} chains - An array of supported viem Chain objects.\n * @returns {PublicClient | undefined} A viem PublicClient instance if the chain is found in the provided array, otherwise undefined.\n * @ignore\n */\nexport function createViemClient(chainId: number, chains: Chain[]): PublicClient | undefined {\n // Use `find` to get the first matching chain object. It's more direct than `filter`.\n const chain = chains.find((c) => c.id === chainId);\n\n if (chain) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n return createClient({\n chain: chain,\n transport: http(),\n });\n }\n\n // Return undefined if no matching chain was found in the configuration.\n return undefined;\n}\n","/**\n * @file This file contains the tracker implementation for standard EVM transactions.\n * It uses viem's public actions (`getTransaction`, `waitForTransactionReceipt`) to monitor\n * a transaction's lifecycle from submission to finality.\n */\n\nimport { ITxTrackingStore, Transaction, TransactionStatus } from '@tuwaio/pulsar-core';\nimport {\n Chain,\n Client,\n GetTransactionReturnType,\n Hex,\n isHex,\n ReplacementReturnType,\n TransactionReceipt,\n WaitForTransactionReceiptParameters,\n zeroHash,\n} from 'viem';\nimport { getBlock, getTransaction, waitForTransactionReceipt } from 'viem/actions';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { createViemClient } from '../utils/createViemClient';\n\n/**\n * Defines the parameters for the low-level EVM transaction tracker.\n */\nexport type EVMTrackerParams = {\n /** The transaction object to track, requiring at least `chainId` and `txKey` (the transaction hash). */\n tx: Pick<Transaction<TransactionTracker>, 'chainId' | 'txKey'>;\n /** An array of `viem` chain objects supported by the application. */\n chains: Chain[];\n /** Callback executed when the getTransaction info got successfully. */\n onTxDetailsGot: (localTx: GetTransactionReturnType) => void;\n /** Callback executed when the transaction is successfully mined and included in a block. */\n onFinished: (localTx: GetTransactionReturnType, receipt: TransactionReceipt, client: Client) => Promise<void>;\n /** Callback executed when the transaction is replaced (e.g., sped up or cancelled). */\n onReplaced: (replacement: ReplacementReturnType) => void;\n /** Callback executed if an error occurs during tracking or if the transaction fails. */\n onFailed: (error?: unknown) => void;\n /** Optional callback executed once when the tracker starts. */\n onInitialize?: () => void;\n /** The number of times to retry fetching the transaction if it's not found initially. Defaults to 10. */\n retryCount?: number;\n /** The delay (in milliseconds) between retry attempts. Defaults to 3000ms. */\n retryTimeout?: number;\n /** Optional parameters to pass to viem's `waitForTransactionReceipt` function. */\n waitForTransactionReceiptParams?: WaitForTransactionReceiptParameters;\n};\n\n/**\n * A low-level tracker for monitoring a standard EVM transaction by its hash.\n * It retries fetching the transaction and then waits for its receipt.\n *\n * @param {EVMTrackerParams} params - The configuration object for the tracker.\n * @returns {Promise<void>} A promise that resolves when the tracking process is complete (or has terminally failed).\n */\nexport async function evmTracker({\n onInitialize,\n onTxDetailsGot,\n onFinished,\n onFailed,\n onReplaced,\n tx,\n chains,\n retryCount,\n retryTimeout,\n waitForTransactionReceiptParams,\n}: EVMTrackerParams): Promise<void> {\n const maxRetries = retryCount ?? 10;\n const client = createViemClient(tx.chainId as number, chains);\n\n if (onInitialize) {\n onInitialize();\n }\n\n if (tx.txKey === zeroHash) {\n throw new Error('Transaction hash is zeroHash');\n }\n\n if (!client) {\n const error = new Error(`Could not create a viem client for chainId: ${tx.chainId}`);\n onFailed(error);\n console.error(error.message);\n return;\n }\n\n // Retry loop to handle cases where the transaction is not immediately available on the RPC node.\n for (let i = 0; i < maxRetries; i++) {\n try {\n // 1. Attempt to fetch the transaction details.\n const localTx = await getTransaction(client, { hash: tx.txKey as Hex });\n\n onTxDetailsGot(localTx);\n\n let txWasReplaced = false;\n\n try {\n // 2. Wait for the transaction to be mined.\n const receipt = await waitForTransactionReceipt(client, {\n hash: localTx.hash,\n onReplaced: (replacement: ReplacementReturnType) => {\n txWasReplaced = true;\n onReplaced(replacement);\n },\n pollingInterval: 10_000,\n ...waitForTransactionReceiptParams,\n });\n\n // If onReplaced was called, the promise resolves but we should not proceed.\n if (txWasReplaced) {\n return;\n }\n\n // 3. Transaction is mined, call the onFinished callback.\n await onFinished(localTx, receipt, client);\n } catch (e) {\n // Error occurred while waiting for the receipt (e.g., timeout, reverted).\n onFailed(e);\n console.error('Error waiting for transaction receipt:', e);\n }\n\n // Exit the retry loop once the transaction is found and processed.\n return;\n } catch (e) {\n // Error occurred while fetching the initial transaction details.\n if (i === maxRetries - 1) {\n onFailed(e);\n console.error(`Error tracking EVM transaction after ${maxRetries} retries:`, e);\n return;\n }\n }\n // Wait before the next retry.\n await new Promise((resolve) => setTimeout(resolve, retryTimeout ?? 3000));\n }\n}\n\n/**\n * A higher-level wrapper for `evmTracker` that integrates directly with the Zustand store.\n * It provides the necessary callbacks to update the transaction's state in the store.\n *\n * @template T - The application-specific transaction union type.\n */\nexport async function evmTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n chains,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n}: Pick<EVMTrackerParams, 'chains'> &\n Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks'\n > & {\n tx: T;\n }) {\n return await evmTracker({\n tx,\n chains,\n onInitialize: () => {\n updateTxParams({\n txKey: tx.txKey,\n hash: tx.txKey as Hex,\n pending: tx.pending,\n });\n },\n onTxDetailsGot: (localTx) => {\n updateTxParams({\n to: localTx.to ?? '',\n input: localTx.input,\n value: String(localTx.value),\n txKey: tx.txKey,\n pending: tx.pending,\n nonce: localTx.nonce,\n hash: localTx.hash,\n maxFeePerGas: String(localTx.maxFeePerGas),\n maxPriorityFeePerGas: String(localTx.maxPriorityFeePerGas),\n });\n },\n onFinished: async (localTx, receipt, client) => {\n const txBlock = await getBlock(client, { blockNumber: receipt.blockNumber });\n const timestamp = Number(txBlock.timestamp);\n const isSuccess = receipt.status === 'success';\n\n updateTxParams({\n txKey: tx.txKey,\n status: isSuccess ? TransactionStatus.Success : TransactionStatus.Failed,\n to: isHex(receipt.to) ? receipt.to : undefined,\n nonce: localTx.nonce,\n pending: false,\n isError: !isSuccess,\n hash: localTx.hash,\n finishedTimestamp: timestamp,\n });\n\n // After updating the state, retrieve the latest version of the transaction.\n const updatedTX = transactionsPool[tx.txKey];\n if (isSuccess && onSucceedCallbacks && updatedTX) {\n onSucceedCallbacks(updatedTX);\n }\n },\n onReplaced: (replacement) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Replaced,\n replacedTxHash: replacement.transaction.hash,\n pending: false,\n });\n },\n onFailed: (error?: unknown) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage: error instanceof Error ? error.message : 'Transaction failed or could not be tracked.',\n });\n },\n });\n}\n","/**\n * @file This file implements the transaction tracking logic for meta-transactions relayed via the Gelato Network.\n * It uses a polling mechanism to check the status of a Gelato Task ID from the Gelato API.\n */\n\nimport {\n InitializePollingTracker,\n initializePollingTracker,\n ITxTrackingStore,\n Transaction,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Hex } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Defines the shape of the identifier for a Gelato transaction task.\n */\nexport type GelatoTxKey = {\n taskId: string;\n};\n\n/**\n * A type guard to determine if an ActionTxKey is a GelatoTxKey.\n * @param {ActionTxKey} txKey - The transaction key to check.\n * @returns {boolean} True if the key is for a Gelato transaction.\n */\nexport function isGelatoTxKey(txKey: ActionTxKey): txKey is GelatoTxKey {\n return (txKey as GelatoTxKey).taskId !== undefined;\n}\n\n/**\n * Enum representing the possible states of a Gelato task.\n * @see https://docs.gelato.network/developer-services/relay/api/get-task-status\n */\nexport enum GelatoTaskState {\n CheckPending = 'CheckPending',\n ExecPending = 'ExecPending',\n WaitingForConfirmation = 'WaitingForConfirmation',\n ExecSuccess = 'ExecSuccess',\n ExecReverted = 'ExecReverted',\n Cancelled = 'Cancelled',\n}\n\n/**\n * Defines the shape of the response from the Gelato `getTaskStatus` API endpoint.\n */\nexport type GelatoTaskStatusResponse = {\n task: {\n chainId: number;\n taskId: string;\n taskState: GelatoTaskState;\n creationDate?: string;\n executionDate?: string;\n transactionHash?: Hex;\n blockNumber?: number;\n lastCheckMessage?: string;\n };\n};\n\n/**\n * A utility type for the initial Gelato transaction object passed to the tracker.\n */\ntype InitialGelatoTx = Pick<Transaction<TransactionTracker>, 'txKey'> & {\n pending?: boolean;\n};\n\n/**\n * Defines the parameters required for the low-level `gelatoTracker` function.\n */\nexport type GelatoTrackerParams = Pick<\n InitializePollingTracker<GelatoTaskStatusResponse, InitialGelatoTx, TransactionTracker>,\n | 'tx'\n | 'removeTxFromPool'\n | 'onInitialize'\n | 'onSucceed'\n | 'onFailed'\n | 'onIntervalTick'\n | 'pollingInterval'\n | 'retryCount'\n>;\n\n/**\n * Checks if a Gelato task state is considered pending.\n * @param {GelatoTaskState} [gelatoStatus] - The current status of the Gelato task.\n * @returns {boolean} True if the status is pending.\n */\nfunction isGelatoTxPending(gelatoStatus?: GelatoTaskState): boolean {\n if (!gelatoStatus) return true;\n const pendingStates = [\n GelatoTaskState.CheckPending,\n GelatoTaskState.ExecPending,\n GelatoTaskState.WaitingForConfirmation,\n ];\n return pendingStates.includes(gelatoStatus);\n}\n\n/**\n * A set of terminal states that indicate a transaction has failed or been cancelled.\n */\nconst GELATO_TERMINAL_FAILURE_STATES = [GelatoTaskState.ExecReverted, GelatoTaskState.Cancelled];\n\n/**\n * The fetcher function passed to `initializePollingTracker` to get the status of a Gelato task.\n * @param {object} params - The parameters for fetching the transaction status.\n * @returns {Promise<Response>} The raw response from the fetch call.\n */\nexport async function fetchTxFromGelatoAPI({\n tx,\n onSucceed,\n onFailed,\n onIntervalTick,\n clearWatch,\n}: {\n clearWatch: (withoutRemoving?: boolean) => void;\n} & Pick<GelatoTrackerParams, 'onIntervalTick' | 'onSucceed' | 'onFailed' | 'tx'>): Promise<Response> {\n const response = await fetch(`https://api.gelato.digital/tasks/status/${tx.txKey}/`);\n\n if (response.ok) {\n const gelatoStatus = (await response.json()) as GelatoTaskStatusResponse;\n const isPending = isGelatoTxPending(gelatoStatus.task.taskState);\n\n // Safeguard: Stop polling for transactions that have been pending for over a day.\n if (gelatoStatus.task.creationDate) {\n const gelatoCreatedDate = dayjs(gelatoStatus.task.creationDate);\n if (dayjs().diff(gelatoCreatedDate, 'day') >= 1 && isPending) {\n clearWatch(); // Stop polling but don't remove from pool\n return response;\n }\n }\n\n onIntervalTick?.(gelatoStatus);\n\n if (!isPending) {\n clearWatch(true); // Stop polling but keep the transaction for UI feedback\n if (gelatoStatus.task.taskState === GelatoTaskState.ExecSuccess) {\n onSucceed(gelatoStatus);\n } else if (GELATO_TERMINAL_FAILURE_STATES.includes(gelatoStatus.task.taskState)) {\n onFailed(gelatoStatus);\n }\n }\n }\n\n return response;\n}\n\n/**\n * A low-level tracker for monitoring Gelato transactions. It wraps the generic polling\n * tracker with the Gelato-specific fetcher logic.\n *\n * @param {GelatoTrackerParams} params - The configuration object for the tracker.\n * @returns {Promise<void>}\n */\nexport async function gelatoTracker(params: GelatoTrackerParams): Promise<void> {\n await initializePollingTracker({\n ...params,\n fetcher: fetchTxFromGelatoAPI,\n });\n}\n\n/**\n * A higher-level wrapper for `gelatoTracker` that integrates directly with the Zustand store.\n * It provides the necessary callbacks to update the transaction's state in the store.\n *\n * @template T - The application-specific transaction union type.\n */\nexport async function gelatoTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n removeTxFromPool,\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}) {\n return await gelatoTracker({\n tx,\n removeTxFromPool,\n onSucceed: async (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Success,\n pending: false,\n hash: response.task.transactionHash,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n });\n\n const updatedTx = transactionsPool[tx.txKey];\n if (onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onIntervalTick: async (response) => {\n const isPending = isGelatoTxPending(response.task.taskState);\n const isSuccess = response.task.taskState === GelatoTaskState.ExecSuccess;\n\n updateTxParams({\n txKey: tx.txKey,\n pending: isPending,\n status: isSuccess ? TransactionStatus.Success : isPending ? undefined : TransactionStatus.Failed,\n hash: response.task.transactionHash,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n errorMessage: GELATO_TERMINAL_FAILURE_STATES.includes(response.task.taskState)\n ? response.task.lastCheckMessage\n : undefined,\n isError: !isPending && !isSuccess,\n });\n },\n onFailed: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response.task.transactionHash,\n errorMessage: response.task.lastCheckMessage,\n finishedTimestamp: response.task.executionDate ? dayjs(response.task.executionDate).unix() : undefined,\n });\n },\n });\n}\n","/**\n * @file This file contains constants related to Safe (formerly Gnosis Safe) configuration,\n * including SDK options, web app URLs, and transaction service API endpoints.\n */\n\nimport { arbitrum, avalanche, base, bsc, goerli, mainnet, optimism, polygon, sepolia } from 'viem/chains';\n\n/**\n * Configuration options for the Safe Apps SDK.\n * This is typically used when integrating with the Safe environment.\n */\nexport const safeSdkOptions = {\n // A list of allowed domains to interact with the Safe Apps SDK.\n allowedDomains: [/gnosis-safe.io$/, /app.safe.global$/, /metissafe.tech$/],\n // A flag to enable or disable debug logging for the SDK.\n debug: false,\n};\n\n/**\n * A mapping of chain IDs to their corresponding Safe web application URL prefixes.\n * Used by selectors like `selectTxExplorerLink` to build correct links for Safe transactions.\n * The prefixes (e.g., 'eth:', 'gor:') are part of the Safe URL scheme.\n * @type {Record<number, string>}\n */\nexport const gnosisSafeLinksHelper: Record<number, string> = {\n [mainnet.id]: 'https://app.safe.global/eth:',\n [goerli.id]: 'https://app.safe.global/gor:',\n [sepolia.id]: 'https://app.safe.global/sep:',\n [optimism.id]: 'https://app.safe.global/oeth:',\n [polygon.id]: 'https://app.safe.global/matic:',\n [arbitrum.id]: 'https://app.safe.global/arb1:',\n [avalanche.id]: 'https://app.safe.global/avax:',\n [bsc.id]: 'https://app.safe.global/bnb:',\n [base.id]: 'https://app.safe.global/base:',\n};\n\n/**\n * A mapping of chain IDs to their corresponding Safe Transaction Service API endpoints.\n * This is used by the `safeTracker` to fetch the status of multisig transactions.\n * @type {Record<number, string>}\n */\nexport const SafeTransactionServiceUrls: Record<number, string> = {\n [mainnet.id]: 'https://safe-transaction-mainnet.safe.global/api/v1',\n [goerli.id]: 'https://safe-transaction-goerli.safe.global/api/v1',\n [sepolia.id]: 'https://safe-transaction-sepolia.safe.global/api/v1',\n [optimism.id]: 'https://safe-transaction-optimism.safe.global/api/v1',\n [polygon.id]: 'https://safe-transaction-polygon.safe.global/api/v1',\n [arbitrum.id]: 'https://safe-transaction-arbitrum.safe.global/api/v1',\n [avalanche.id]: 'https://safe-transaction-avalanche.safe.global/api/v1',\n [bsc.id]: 'https://safe-transaction-bsc.safe.global/api/v1',\n [base.id]: 'https://safe-transaction-base.safe.global/api/v1',\n};\n","/**\n * @file This file implements the transaction tracking logic for Gnosis Safe (now Safe) multisig transactions.\n * It uses a polling mechanism to query the Safe Transaction Service API for the status of a `safeTxHash`.\n */\n\nimport {\n InitializePollingTracker,\n initializePollingTracker,\n ITxTrackingStore,\n Transaction,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Hex, zeroHash } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { SafeTransactionServiceUrls } from '../utils/safeConstants';\n\n/**\n * Defines the shape of the transaction object passed to the Safe tracker.\n */\ntype InitialSafeTx = Pick<Transaction<TransactionTracker>, 'txKey' | 'chainId' | 'from'> & {\n pending?: boolean;\n};\n\n/**\n * Defines the shape of the primary response for a single transaction from the Safe Transaction Service API.\n */\nexport type SafeTxStatusResponse = {\n transactionHash: string;\n safeTxHash: string;\n isExecuted: boolean;\n isSuccessful: boolean | null;\n executionDate: string | null;\n submissionDate: string | null;\n modified: string;\n nonce: number;\n replacedHash?: string; // Custom field for passing replacement info\n};\n\n/**\n * Defines the shape of the response when querying for multiple transactions (e.g., by nonce).\n */\ntype SafeTxSameNonceResponse = {\n count: number;\n results: SafeTxStatusResponse[];\n};\n\n/**\n * Defines the parameters for the low-level `safeTracker` function.\n */\nexport type SafeTrackerParams = Pick<\n InitializePollingTracker<SafeTxStatusResponse, InitialSafeTx, TransactionTracker>,\n | 'tx'\n | 'removeTxFromPool'\n | 'onInitialize'\n | 'onSucceed'\n | 'onFailed'\n | 'onReplaced'\n | 'onIntervalTick'\n | 'pollingInterval'\n | 'retryCount'\n>;\n\n/**\n * The fetcher function passed to `initializePollingTracker` to get the status of a Safe transaction.\n * @returns The raw response from the fetch call.\n */\nexport async function fetchTxFromSafeAPI({\n tx,\n onSucceed,\n onFailed,\n onIntervalTick,\n onReplaced,\n clearWatch,\n}: {\n clearWatch: (withoutRemoving?: boolean) => void;\n} & Pick<SafeTrackerParams, 'onIntervalTick' | 'onSucceed' | 'onFailed' | 'onReplaced' | 'tx'>): Promise<Response> {\n const primaryTxResponse = await fetch(\n `${SafeTransactionServiceUrls[tx.chainId as number]}/multisig-transactions/${tx.txKey}/`,\n );\n\n if (!primaryTxResponse.ok) {\n return primaryTxResponse; // Let the polling tracker handle the retry\n }\n\n const safeStatus = (await primaryTxResponse.json()) as SafeTxStatusResponse;\n\n // Fetch all other transactions with the same nonce to check for replacements.\n const nonceTxsResponse = await fetch(\n `${SafeTransactionServiceUrls[tx.chainId as number]}/safes/${tx.from}/multisig-transactions/?nonce=${safeStatus.nonce}`,\n );\n\n if (!nonceTxsResponse.ok) {\n return nonceTxsResponse; // Let the polling tracker handle the retry\n }\n\n const sameNonceTxs = (await nonceTxsResponse.json()) as SafeTxSameNonceResponse;\n const executedTx = sameNonceTxs.results.find((t) => t.isExecuted);\n\n // Case 1: Another transaction with the same nonce was executed. This one was replaced.\n if (executedTx && executedTx.safeTxHash !== safeStatus.safeTxHash) {\n onReplaced?.({ ...safeStatus, replacedHash: executedTx.safeTxHash });\n clearWatch(true);\n return nonceTxsResponse;\n }\n\n // Case 2: The transaction itself was executed.\n if (safeStatus.isExecuted) {\n if (safeStatus.isSuccessful) {\n onSucceed(safeStatus);\n } else {\n onFailed(safeStatus);\n }\n clearWatch(true);\n return primaryTxResponse;\n }\n\n // Case 3: The transaction is still pending.\n // Safeguard: Stop polling for transactions that have been pending for over a day.\n const modifiedDate = dayjs(safeStatus.modified);\n if (dayjs().diff(modifiedDate, 'day') >= 1) {\n clearWatch(); // Stop polling and remove from pool\n return primaryTxResponse;\n }\n\n // Otherwise, just report the current status and continue polling.\n onIntervalTick?.(safeStatus);\n\n return primaryTxResponse;\n}\n\n/**\n * A low-level tracker for monitoring Safe multisig transactions.\n * It wraps the generic polling tracker with the Safe-specific fetcher logic.\n */\nexport async function safeTracker(params: SafeTrackerParams): Promise<void> {\n await initializePollingTracker<SafeTxStatusResponse, InitialSafeTx, TransactionTracker>({\n ...params,\n fetcher: fetchTxFromSafeAPI,\n });\n}\n\n/**\n * A higher-level wrapper for `safeTracker` that integrates directly with the Zustand store.\n */\nexport async function safeTrackerForStore<T extends Transaction<TransactionTracker>>({\n tx,\n transactionsPool,\n updateTxParams,\n onSucceedCallbacks,\n removeTxFromPool,\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}) {\n return await safeTracker({\n tx,\n removeTxFromPool,\n onSucceed: async (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Success,\n pending: false,\n hash: response.transactionHash as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n\n const updatedTx = transactionsPool[tx.txKey];\n if (onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onIntervalTick: async (response) => {\n updateTxParams({\n pending: !response.isExecuted,\n txKey: tx.txKey,\n hash: response.transactionHash as Hex,\n });\n },\n onFailed: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response.transactionHash as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n onReplaced: (response) => {\n updateTxParams({\n txKey: tx.txKey,\n status: TransactionStatus.Replaced,\n pending: false,\n hash: response.transactionHash as Hex,\n replacedTxHash: (response.replacedHash ?? zeroHash) as Hex,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n });\n}\n","/**\n * @file This file defines types and enums specific to the EVM transaction tracking package.\n * It includes identifiers for different tracking strategies and the shape of transaction keys.\n */\n\nimport { Hex } from 'viem';\n\nimport { GelatoTxKey } from './trackers/gelatoTracker';\n\n/**\n * Enum representing the different tracking strategies available for EVM transactions.\n */\nexport enum TransactionTracker {\n /** For standard on-chain EVM transactions tracked by their hash. */\n Ethereum = 'ethereum',\n /** For multi-signature transactions managed by a Safe contract. */\n Safe = 'safe',\n /** For meta-transactions relayed through the Gelato Network. */\n Gelato = 'gelato',\n}\n\n/**\n * Represents the unique identifier returned by an action function after a transaction is submitted.\n * This key is used to determine which tracker should monitor the transaction.\n * It can be a standard transaction hash or a structured key from a relay service like Gelato.\n * @typedef {Hex | GelatoTxKey} ActionTxKey\n */\nexport type ActionTxKey = Hex | GelatoTxKey;\n","/**\n * @file This file contains a utility function that acts as a router to initialize the correct transaction tracker.\n * Based on a transaction's `tracker` property, it delegates the tracking task to the appropriate implementation.\n */\n\nimport { ITxTrackingStore, Transaction } from '@tuwaio/pulsar-core';\nimport { Chain } from 'viem';\n\nimport { evmTrackerForStore } from '../trackers/evmTracker';\nimport { gelatoTrackerForStore } from '../trackers/gelatoTracker';\nimport { safeTrackerForStore } from '../trackers/safeTracker';\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Initializes the appropriate tracker for a given transaction based on its `tracker` type.\n * This function acts as a central router, delegating to the specific tracker implementation\n * (e.g., EVM, Gelato, Safe).\n *\n * @template T - The application-specific transaction union type.\n * @param {object} params - The parameters for initializing the tracker.\n * @param {TransactionTracker} params.tracker - The type of tracker to use for the transaction.\n * @param {T} params.tx - The transaction object to be tracked.\n * @param {Chain[]} params.chains - An array of supported chain objects, required for some trackers (like the EVM tracker).\n * @param {object} params.rest - The rest of the parameters, which are the relevant methods from the Zustand store\n * (`transactionsPool`, `updateTxParams`, `onSucceedCallbacks`, `removeTxFromPool`).\n * @returns {Promise<void>} A promise that resolves once the tracking process has been initiated.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<TransactionTracker>>({\n tracker,\n tx,\n chains,\n ...rest\n}: Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n chains: Chain[];\n tx: T;\n tracker: TransactionTracker;\n}): Promise<void> {\n switch (tracker) {\n case TransactionTracker.Ethereum:\n await evmTrackerForStore({\n tx,\n chains,\n ...rest,\n });\n break;\n\n case TransactionTracker.Gelato:\n // The Gelato tracker does not need the `chains` param as it uses its own API endpoints.\n await gelatoTrackerForStore({\n tx,\n ...rest,\n });\n break;\n\n case TransactionTracker.Safe:\n // The Safe tracker also uses its own API endpoints.\n await safeTrackerForStore({\n tx,\n ...rest,\n });\n break;\n\n // The default case handles any unknown or unspecified tracker types as standard EVM transactions.\n default:\n await evmTrackerForStore({\n tx,\n chains,\n ...rest,\n });\n }\n}\n","/**\n * @file This file contains a utility to ensure the user's wallet is connected to the correct chain before proceeding.\n */\n\nimport { Config, switchChain } from '@wagmi/core';\nimport { getAccount } from '@wagmi/core';\n\n/**\n * Checks if the user's wallet is connected to the specified chain. If not, it prompts\n * the user to switch to the correct chain and waits for the operation to complete.\n *\n * @param {number} chainId - The ID of the desired blockchain network.\n * @param {Config} config - The wagmi configuration object.\n * @returns {Promise<void>} A promise that resolves when the wallet is on the correct chain,\n * or rejects if the user cancels the switch or an error occurs.\n * @throws {Error} Throws an error if the user rejects the chain switch or if the switch fails.\n */\nexport async function checkChainForTx(chainId: number, config: Config): Promise<void> {\n const { connector, chainId: activeChainId } = getAccount(config);\n\n // Proceed only if a wallet is connected and it's on the wrong chain.\n if (connector && activeChainId !== chainId) {\n try {\n // Directly await the switchChain call. This pauses execution until the user responds.\n await switchChain(config, { chainId });\n } catch (e) {\n // The user rejected the request or an error occurred.\n console.error('Failed to switch chain:', e);\n throw new Error('User rejected chain switch or an error occurred.');\n }\n }\n}\n","/**\n * @file This file contains a utility function to determine the correct tracker for a transaction\n * based on the key returned by the submission function and the wallet type.\n */\n\nimport { isHex } from 'viem';\n\nimport { isGelatoTxKey } from '../trackers/gelatoTracker';\nimport { ActionTxKey, TransactionTracker } from '../types';\n\n/**\n * Determines which transaction tracker to use based on the format of the transaction key and the wallet type.\n *\n * This function is a critical routing step after a transaction is submitted.\n * It follows a priority order:\n * 1. Checks for a Gelato Task ID.\n * 2. Checks if the wallet type is 'safe'.\n * 3. Defaults to a standard Ethereum tracker.\n *\n * @param {ActionTxKey} actionTxKey - The key returned from the transaction submission function (e.g., a hash or a Gelato task object).\n * @param {string} walletType - The type of the wallet that initiated the action (e.g., 'safe', 'metaMask').\n * @returns {{ tracker: TransactionTracker; txKey: string }} An object containing the determined tracker type and the final string-based transaction key.\n */\nexport function checkTransactionsTracker(\n actionTxKey: ActionTxKey,\n walletType: string,\n): { tracker: TransactionTracker; txKey: string } {\n // 1. Highest priority: Check if the key matches the Gelato task structure.\n if (isGelatoTxKey(actionTxKey)) {\n return {\n tracker: TransactionTracker.Gelato,\n txKey: actionTxKey.taskId,\n };\n }\n\n // At this point, actionTxKey must be a Hex string (transaction hash or SafeTxHash).\n // We can add a check for robustness, although TypeScript should infer this.\n if (!isHex(actionTxKey)) {\n throw new Error('Invalid transaction key format. Expected a Hex string or GelatoTxKey object.');\n }\n\n // 2. Second priority: Check if the transaction came from a Safe wallet.\n if (walletType === 'safe') {\n return {\n tracker: TransactionTracker.Safe,\n txKey: actionTxKey,\n };\n }\n\n // 3. Default: Treat as a standard on-chain Ethereum transaction.\n return {\n tracker: TransactionTracker.Ethereum,\n txKey: actionTxKey,\n };\n}\n","import { ITxTrackingStore, Transaction } from '@tuwaio/pulsar-core';\nimport { Config } from '@wagmi/core';\nimport { Chain } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkChainForTx } from '../utils/checkChainForTx';\nimport { checkTransactionsTracker } from '../utils/checkTransactionsTracker';\n\nexport function evmAdapter<T extends Transaction<TransactionTracker>>(config: Config, appChains: Chain[]) {\n if (config) {\n return {\n checkChainForTx: (chainId: string | number) => checkChainForTx(chainId as number, config),\n checkTransactionsTracker: (actionTxKey: ActionTxKey, walletType: string) =>\n checkTransactionsTracker(actionTxKey, walletType),\n checkAndInitializeTrackerInStore: ({\n tx,\n ...rest\n }: { tx: T } & Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n >) => checkAndInitializeTrackerInStore({ tracker: tx.tracker, tx, chains: appChains, ...rest }),\n };\n }\n}\n","import { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n/**\n * Cancels a pending transaction by sending a new, zero-value transaction to oneself\n * with the same nonce but a higher gas price.\n *\n * @param {object} params - The parameters for the cancellation.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The transaction object to be canceled. Must contain nonce, gas fees, etc.\n *\n * @returns {Promise<Hex>} A promise that resolves with the hash of the new cancellation transaction.\n *\n * @throws {Error} Throws an error if the transaction is missing required fields or if sending fails.\n *\n * @example\n * ```ts\n * import { cancelTxAction } from './cancelTxAction';\n *\n * const handleCancel = async () => {\n * try {\n * const cancelTxHash = await cancelTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Cancellation transaction sent:', cancelTxHash);\n * } catch (error) {\n * console.error('Failed to cancel transaction:', error);\n * }\n * };\n * ```\n */\nexport async function cancelTxAction<T extends Transaction<any>>({\n config,\n tx,\n}: {\n config: Config;\n tx: T;\n}): Promise<Hex> {\n if (tx.adapter === TransactionAdapter.EVM) {\n // Ensure the transaction has all the necessary details for cancellation.\n if (!tx.nonce || !tx.maxFeePerGas || !tx.maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for cancellation (nonce, maxFeePerGas).');\n }\n\n try {\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // Increase gas fees by 15% to ensure the cancellation transaction is prioritized.\n const gasIncreaseMultiplier = 115n; // 115%\n const divisor = 100n;\n const newPriorityFee = (BigInt(tx.maxPriorityFeePerGas) * gasIncreaseMultiplier) / divisor;\n const newMaxFee = (BigInt(tx.maxFeePerGas) * gasIncreaseMultiplier) / divisor;\n\n // Send a zero-value transaction to your own address with the same nonce.\n const hash = await sendTransaction(config, {\n to: account.address,\n value: 0n,\n chainId: tx.chainId as number,\n nonce: tx.nonce,\n maxFeePerGas: newMaxFee,\n maxPriorityFeePerGas: newPriorityFee,\n });\n\n return hash;\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n // Re-throw the error with more context.\n throw new Error(`Failed to cancel transaction: ${errorMessage}`);\n }\n } else {\n throw new Error(`Failed to cancel transaction: not EVM tx adapter`);\n }\n}\n","/**\n * @file This file contains a utility to check if the Gelato Relay service is available for a specific chain.\n */\n\n// --- In-memory cache to store the list of supported chains ---\nlet cachedRelayChainIds: number[] | null = null;\nlet cacheTimestamp: number | null = null;\nconst CACHE_DURATION_MS = 5 * 60 * 1000; // Cache the list for 5 minutes\n\n/**\n * Checks if the Gelato Relay service supports a given chain ID.\n * The result is cached in memory for 5 minutes to avoid excessive network requests.\n *\n * @param {number} chainId - The chain identifier to check.\n * @returns {Promise<boolean>} True if Gelato supports the chain, false otherwise.\n */\nexport async function checkIsGelatoAvailable(chainId: number): Promise<boolean> {\n const now = Date.now();\n\n // 1. Check if a valid cache exists.\n if (cachedRelayChainIds && cacheTimestamp && now - cacheTimestamp < CACHE_DURATION_MS) {\n return cachedRelayChainIds.includes(chainId);\n }\n\n // 2. If no valid cache, fetch from the API.\n try {\n const response = await fetch('https://relay.gelato.digital/relays/v2');\n if (!response.ok) {\n // Clear cache in case of a temporary API failure\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n return false;\n }\n\n const data = (await response.json()) as { relays: string[] };\n const supportedChainIds = data.relays.map(Number);\n\n // 3. Update the cache.\n cachedRelayChainIds = supportedChainIds;\n cacheTimestamp = now;\n\n return supportedChainIds.includes(chainId);\n } catch (e) {\n console.error('Failed to check Gelato service availability:', e);\n // Clear cache on error\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n return false;\n }\n}\n","/**\n * @file This file contains utility functions for interacting with the Ethereum Name Service (ENS).\n * It provides methods for resolving names to addresses, addresses to names, and fetching avatars.\n */\n\nimport { Address, Hex, isAddress } from 'viem';\nimport { mainnet } from 'viem/chains';\nimport { getEnsAddress, getEnsAvatar, getEnsName, normalize } from 'viem/ens';\n\nimport { createViemClient } from './createViemClient';\n\n// Create a single, shared viem client for all ENS lookups to improve performance.\n// ENS lookups are typically done against Ethereum Mainnet regardless of the connected chain.\nconst ensClient = createViemClient(mainnet.id, [mainnet]);\n\n/**\n * Fetches the primary ENS name for a given Ethereum address.\n * Performs the lookup on Ethereum Mainnet.\n *\n * @param {Hex} address - The Ethereum address to look up.\n * @returns {Promise<string | undefined>} The ENS name if found, otherwise undefined.\n */\nexport const getName = async (address: Hex): Promise<string | undefined> => {\n if (!ensClient) return undefined;\n try {\n const name = await getEnsName(ensClient, { address });\n return name ?? undefined;\n } catch (error) {\n console.error('ENS name lookup error:', error);\n return undefined;\n }\n};\n\n/**\n * Fetches the avatar for a given ENS name.\n * If no ENS avatar is set, it generates a unique \"blockie\" image as a fallback.\n * Performs the lookup on Ethereum Mainnet.\n *\n * @param {string} name - The ENS name (e.g., 'vitalik.eth').\n * @param {string} address - The Ethereum address, used for the blockie fallback.\n * @returns {Promise<string | undefined>} The URL of the avatar image, a base64 blockie, or undefined if an error occurs.\n */\nexport const getAvatar = async (name: string): Promise<string | undefined> => {\n if (!ensClient) return undefined;\n try {\n const avatarUrl = await getEnsAvatar(ensClient, { name: normalize(name) });\n return avatarUrl ?? undefined;\n } catch (error) {\n console.error('ENS avatar lookup error:', error);\n return undefined;\n }\n};\n\n/**\n * Fetches the Ethereum address associated with a given ENS name.\n * Performs the lookup on Ethereum Mainnet.\n *\n * @param {string} name - The ENS name to resolve (e.g., 'vitalik.eth').\n * @returns {Promise<Address | undefined>} The associated Ethereum address (lowercase) or undefined if not found.\n */\nexport const getAddress = async (name: string): Promise<Address | undefined> => {\n if (!ensClient) return undefined;\n try {\n const address = await getEnsAddress(ensClient, { name: normalize(name) });\n return address ? (address.toLocaleLowerCase() as Address) : undefined;\n } catch (error) {\n console.error('ENS address lookup error:', error);\n return undefined;\n }\n};\n\n/**\n * A simple heuristic to check if a string could be an ENS name.\n * It works by checking if the string is NOT a valid Ethereum address.\n *\n * @param {string} address - The string to check.\n * @returns {boolean} True if the string is not in a valid address format.\n */\nexport const isEnsName = (address: string): boolean => !isAddress(address);\n","/**\n * @file This file contains a utility for safely retrieving the active wallet account and viem client.\n */\n\nimport { Config, getClient, GetClientReturnType } from '@wagmi/core';\nimport { getAccount as getWagmiAccount, GetAccountReturnType } from '@wagmi/core';\n\n/**\n * Retrieves the active wallet account and the viem Wallet Client from the wagmi config.\n * It ensures that a wallet is connected by throwing an error if it's not.\n *\n * @param {Config} config - The wagmi configuration object.\n * @returns {{ activeWallet: GetAccountReturnType; walletClient: GetClientReturnType }} An object containing the connected account details and the viem Wallet Client.\n * @throws {Error} Throws an error with the message \"Wallet not connected\" if no wallet is connected or the client is unavailable.\n */\nexport function getActiveWalletAndClient(config: Config): {\n activeWallet: GetAccountReturnType;\n walletClient: GetClientReturnType;\n} {\n const activeWallet = getWagmiAccount(config);\n const walletClient = getClient(config);\n\n // This check is crucial to prevent downstream errors.\n if (!activeWallet.address || !walletClient) {\n throw new Error('Wallet not connected');\n }\n\n return { activeWallet, walletClient };\n}\n","import { selectTXByKey, Transaction, TransactionAdapter, TransactionPool } from '@tuwaio/pulsar-core';\nimport { Chain, Hex } from 'viem';\n\nimport { TransactionTracker } from '../types';\nimport { gnosisSafeLinksHelper } from './safeConstants';\n\n/**\n * Generates a URL to a block explorer for a given transaction.\n * It handles different URL structures for standard EVM transactions and Safe transactions.\n *\n * @template TR - The generic type for the tracker identifier.\n * @template T - The transaction type.\n * @param {TransactionPool<TR, T>} transactionsPool - The entire pool of transactions from the store.\n * @param {Chain[]} chains - An array of supported chain objects from viem.\n * @param {Hex} txKey - The tx key of the transaction for which to generate the link.\n * @param {Hex} [replacedTxHash] - Optional. If provided, the link will be generated for this hash instead of the original.\n * @returns {string} The URL to the transaction on the corresponding block explorer, or an empty string if not found.\n */\nexport const selectEvmTxExplorerLink = <TR, T extends Transaction<TR>>(\n transactionsPool: TransactionPool<TR, T>,\n chains: Chain[],\n txKey: Hex,\n replacedTxHash?: Hex,\n): string => {\n const tx = selectTXByKey(transactionsPool, txKey);\n\n if (!tx) {\n return '';\n }\n\n /**\n * Internal helper to construct the final URL based on the tracker type.\n * @param {string} hash - The transaction hash to include in the URL.\n * @returns {string} The constructed explorer URL.\n */\n const constructUrl = (hash: string): string => {\n // For Safe transactions, generate a link to the Safe web app.\n if (tx.tracker === TransactionTracker.Safe) {\n const safeBaseUrl = gnosisSafeLinksHelper[tx.chainId as number];\n return safeBaseUrl ? `${safeBaseUrl}${tx.from}/transactions/tx?id=multisig_${tx.from}_${tx.txKey}` : '';\n }\n\n // For standard EVM transactions, find the chain's default block explorer.\n const chain = chains.find((chain) => chain.id === tx.chainId);\n\n if (!chain?.blockExplorers?.default.url) {\n // Return empty string if the chain or its explorer URL is not configured.\n return '';\n }\n\n return `${chain.blockExplorers.default.url}/tx/${hash}`;\n };\n\n // Prioritize the replaced hash if it exists, otherwise use the original.\n return constructUrl(replacedTxHash || (tx.adapter === TransactionAdapter.EVM && tx.hash) || tx.txKey);\n};\n","import { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n/**\n * Speeds up a pending transaction by resubmitting it with the same nonce but higher gas fees.\n * This is a common strategy to prevent a transaction from getting stuck.\n *\n * @param {object} params - The parameters required to speed up the transaction.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The original transaction object that needs to be sped up.\n *\n * @returns {Promise<Hex>} A promise that resolves with the hash of the new, speed-up transaction.\n *\n * @throws {Error} Throws an error if the wagmi config is not provided, the account is not found,\n * or if the transaction is missing required fields (`nonce`, `maxFeePerGas`, etc.).\n *\n * @example\n * ```ts\n * import { speedUpTxAction } from './speedUpTxAction';\n *\n * const handleSpeedUp = async () => {\n * try {\n * const newTxHash = await speedUpTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Transaction sped up with new hash:', newTxHash);\n * } catch (error) {\n * console.error('Failed to speed up transaction:', error);\n * }\n * };\n * ```\n */\nexport async function speedUpTxAction<TR, T extends Transaction<TR>>({\n config,\n tx,\n}: {\n config: Config;\n tx: T;\n}): Promise<Hex> {\n if (tx.adapter === TransactionAdapter.EVM) {\n // Ensure all necessary transaction details are present.\n if (!tx.nonce || !tx.from || !tx.to || !tx.value || !tx.input || !tx.maxFeePerGas || !tx.maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for speed-up.');\n }\n\n try {\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // To replace a pending transaction, the new gas fees must be higher.\n // We increase both fees by 15% as a common strategy to ensure replacement.\n const gasIncreaseMultiplier = 115n; // 115%\n const divisor = 100n;\n const newPriorityFee = (BigInt(tx.maxPriorityFeePerGas) * gasIncreaseMultiplier) / divisor;\n const newMaxFee = (BigInt(tx.maxFeePerGas) * gasIncreaseMultiplier) / divisor;\n\n // Resubmit the transaction with the same details but higher gas fees.\n return await sendTransaction(config, {\n to: tx.to as Hex,\n value: BigInt(tx.value),\n data: tx.input as Hex,\n chainId: tx.chainId as number,\n nonce: tx.nonce,\n maxFeePerGas: newMaxFee,\n maxPriorityFeePerGas: newPriorityFee,\n });\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n // Re-throw the error with more context.\n throw new Error(`Failed to speed up transaction: ${errorMessage}`);\n }\n } else {\n throw new Error(`Failed to speed up transaction: not EVM tx adapter`);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuwaio/pulsar-evm",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",