@tuwaio/pulsar-evm 0.0.13 → 0.0.14
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.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var pulsarCore=require('@tuwaio/pulsar-core'),core=require('@wagmi/core'),viem=require('viem'),actions=require('viem/actions'),h=require('dayjs'),chains=require('viem/chains'),ens=require('viem/ens');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var h__default=/*#__PURE__*/_interopDefault(h);var T=(o=>(o.Ethereum="ethereum",o.Safe="safe",o.Gelato="gelato",o))(T||{});var P=1.15;async function v({config:e,tx:r}){if(r.adapter!==pulsarCore.TransactionAdapter.EVM)throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${r.adapter}'.`);let{nonce:t,maxFeePerGas:o,maxPriorityFeePerGas:i,chainId:a}=r;if(t===void 0||!o||!i)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).");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 s=BigInt(Math.ceil(Number(i)*P)),c=BigInt(Math.ceil(Number(o)*P));return await core.sendTransaction(e,{to:n.address,value:0n,chainId:a,nonce:t,maxFeePerGas:c,maxPriorityFeePerGas:s})}catch(n){let s=n instanceof Error?n.message:String(n);throw new Error(`Failed to cancel transaction: ${s}`)}}function g(e,r){let t=r.find(o=>o.id===e);if(t)return viem.createPublicClient({chain:t,transport:viem.http()});console.warn(`createViemClient: No chain configuration found for chainId ${e}. A client could not be created.`);}var xe=10,ge=3e3;async function ke(e){let{tx:r,chains:t,onInitialize:o,onTxDetailsFetched:i,onSuccess:a,onFailure:n,onReplaced:s,retryCount:c=xe,retryTimeout:u=ge,waitForTransactionReceiptParams:p}=e;if(o?.(),r.txKey===viem.zeroHash)return n(new Error("Transaction hash cannot be the zero hash."));let l=g(r.chainId,t);if(!l)return n(new Error(`Could not create a viem client for chainId: ${r.chainId}`));let f=null;for(let d=0;d<c;d++)try{f=await actions.getTransaction(l,{hash:r.txKey}),i(f);break}catch(x){if(d===c-1)return console.error(`EVM tracker failed to fetch tx ${r.txKey} after ${c} retries:`,x),n(x);await new Promise(E=>setTimeout(E,u));}if(!f)return n(new Error("Transaction details could not be fetched."));try{let d=!1,x=await actions.waitForTransactionReceipt(l,{hash:f.hash,onReplaced:E=>{d=!0,s(E);},...p});if(d)return;await a(f,x,l);}catch(d){console.error(`Error waiting for receipt for tx ${r.txKey}:`,d),n(d);}}async function S(e){let{tx:r,chains:t,transactionsPool:o,updateTxParams:i,onSucceedCallbacks:a}=e;return ke({tx:r,chains:t,onInitialize:()=>{i(r.txKey,{hash:r.txKey});},onTxDetailsFetched:n=>{i(r.txKey,{to:n.to??void 0,input:n.input,value:n.value?.toString(),nonce:n.nonce,maxFeePerGas:n.maxFeePerGas?.toString(),maxPriorityFeePerGas:n.maxPriorityFeePerGas?.toString()});},onSuccess:async(n,s,c)=>{let u=await actions.getBlock(c,{blockNumber:s.blockNumber}),p=Number(u.timestamp),l=s.status==="success";i(r.txKey,{status:l?pulsarCore.TransactionStatus.Success:pulsarCore.TransactionStatus.Failed,isError:!l,pending:false,finishedTimestamp:p});let f=o[r.txKey];l&&a&&f&&a(f);},onReplaced:n=>{i(r.txKey,{status:pulsarCore.TransactionStatus.Replaced,replacedTxHash:n.transaction.hash,pending:false});},onFailure:n=>{i(r.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,errorMessage:n instanceof Error?n.message:"Transaction failed or could not be tracked."});}})}function R(e){return typeof e=="object"&&e!==null&&"taskId"in e}var be=(s=>(s.CheckPending="CheckPending",s.ExecPending="ExecPending",s.WaitingForConfirmation="WaitingForConfirmation",s.ExecSuccess="ExecSuccess",s.ExecReverted="ExecReverted",s.Cancelled="Cancelled",s.NotFound="NotFound",s))(be||{}),we="https://api.gelato.digital/tasks/status/",F=new Set(["ExecReverted","Cancelled","NotFound"]);function Ee(e){return e!=="ExecSuccess"&&!F.has(e)}var Se=async({tx:e,stopPolling:r,onSuccess:t,onFailure:o,onIntervalTick:i})=>{let a=await fetch(`${we}${e.txKey}`);if(!a.ok){if(a.status===404){o();return}throw new Error(`Gelato API responded with status: ${a.status}`)}let n=await a.json(),{taskState:s,creationDate:c}=n.task;if(i?.(n),c&&h__default.default().diff(h__default.default(c),"day")>=1&&Ee(s)){r({withoutRemoving:true});return}s==="ExecSuccess"?t(n):F.has(s)&&o(n);};function I({tx:e,transactionsPool:r,updateTxParams:t,onSucceedCallbacks:o,removeTxFromPool:i}){return pulsarCore.initializePollingTracker({tx:e,fetcher:Se,removeTxFromPool:i,onSuccess:a=>{t(e.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:a.task.transactionHash,finishedTimestamp:a.task.executionDate?h__default.default(a.task.executionDate).unix():void 0});let n=r[e.txKey];o&&n&&o(n);},onIntervalTick:a=>{t(e.txKey,{hash:a.task.transactionHash});},onFailure:a=>{t(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:a?.task.transactionHash,errorMessage:a?.task.lastCheckMessage??"Transaction failed or was not found.",finishedTimestamp:a?.task.executionDate?h__default.default(a.task.executionDate).unix():void 0});}})}var bt={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},O={[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.polygon.id]:"https://app.safe.global/matic:",[chains.arbitrum.id]:"https://app.safe.global/arb1:",[chains.aurora.id]:"https://app.safe.global/aurora:",[chains.avalanche.id]:"https://app.safe.global/avax:",[chains.base.id]:"https://app.safe.global/base:",[chains.boba.id]:"https://app.safe.global/boba:",[chains.bsc.id]:"https://app.safe.global/bnb:",[chains.celo.id]:"https://app.safe.global/celo:",[chains.gnosis.id]:"https://app.safe.global/gno:",[chains.optimism.id]:"https://app.safe.global/oeth:",[chains.polygonZkEvm.id]:"https://app.safe.global/zkevm:",[chains.zksync.id]:"https://app.safe.global/zksync:"},q={[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.polygon.id]:"https://safe-transaction-polygon.safe.global/api/v1",[chains.arbitrum.id]:"https://safe-transaction-arbitrum.safe.global/api/v1",[chains.aurora.id]:"https://safe-transaction-aurora.safe.global/api/v1",[chains.avalanche.id]:"https://safe-transaction-avalanche.safe.global/api/v1",[chains.base.id]:"https://safe-transaction-base.safe.global/api/v1",[chains.boba.id]:"https://safe-transaction-boba.safe.global/api/v1",[chains.bsc.id]:"https://safe-transaction-bsc.safe.global/api/v1",[chains.celo.id]:"https://safe-transaction-celo.safe.global/api/v1",[chains.gnosis.id]:"https://safe-transaction-gnosis-chain.safe.global/api/v1",[chains.optimism.id]:"https://safe-transaction-optimism.safe.global/api/v1",[chains.polygonZkEvm.id]:"https://safe-transaction-zkevm.safe.global/api/v1",[chains.zksync.id]:"https://safe-transaction-zksync.safe.global/api/v1"};var ve=async({tx:e,stopPolling:r,onSuccess:t,onFailure:o,onReplaced:i,onIntervalTick:a})=>{let n=q[e.chainId];if(!n)throw new Error(`Safe Transaction Service URL not found for chainId: ${e.chainId}`);let s=await fetch(`${n}/multisig-transactions/${e.txKey}/`);if(!s.ok)throw s.status===404&&o(),new Error(`Safe API responded with status: ${s.status}`);let c=await s.json();if(a?.(c),c.isExecuted){c.isSuccessful?t(c):o(c);return}let u=await fetch(`${n}/safes/${e.from}/multisig-transactions/?nonce=${c.nonce}`);if(!u.ok)throw new Error(`Safe API (nonce check) responded with status: ${u.status}`);let l=(await u.json()).results.find(f=>f.isExecuted);if(l){i?.(l);return}h__default.default().diff(h__default.default(c.submissionDate),"day")>=1&&r({withoutRemoving:true});};function J({tx:e,transactionsPool:r,updateTxParams:t,onSucceedCallbacks:o,removeTxFromPool:i}){return pulsarCore.initializePollingTracker({tx:e,fetcher:ve,removeTxFromPool:i,onSuccess:a=>{t(e.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:a.transactionHash??void 0,finishedTimestamp:a.executionDate?h__default.default(a.executionDate).unix():void 0});let n=r[e.txKey];o&&n&&o(n);},onIntervalTick:a=>{t(e.txKey,{hash:a.transactionHash??void 0});},onFailure:a=>{t(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:a?.transactionHash??void 0,errorMessage:a?"Safe transaction failed or was rejected.":"Transaction not found.",finishedTimestamp:a?.executionDate?h__default.default(a.executionDate).unix():void 0});},onReplaced:a=>{t(e.txKey,{status:pulsarCore.TransactionStatus.Replaced,pending:false,hash:e.adapter===pulsarCore.TransactionAdapter.EVM?e.hash:viem.zeroHash,replacedTxHash:a.safeTxHash??viem.zeroHash,finishedTimestamp:a.executionDate?h__default.default(a.executionDate).unix():void 0});}})}async function Z({tracker:e,tx:r,chains:t,...o}){switch(e){case "ethereum":return S({tx:r,chains:t,...o});case "gelato":return I({tx:r,...o});case "safe":return J({tx:r,...o});default:return console.warn(`Unknown tracker type: '${e}'. Falling back to default EVM tracker.`),S({tx:r,chains:t,...o})}}async function Q(e,r){let{connector:t,chainId:o}=core.getAccount(r);if(t&&o!==e)try{await core.switchChain(r,{chainId:e});}catch(i){throw i.cause?.name==="UserRejectedRequestError"?new Error("User rejected the request to switch network."):(console.error("Failed to switch network:",i),new Error("An error occurred while switching the network."))}}function X(e,r){if(R(e))return {tracker:"gelato",txKey:e.taskId};if(!viem.isHex(e))throw new Error(`Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(e)}`);return r?.toLowerCase()==="safe"?{tracker:"safe",txKey:e}:{tracker:"ethereum",txKey:e}}var m=g(chains.mainnet.id,[chains.mainnet]),re=async e=>{if(!m)return null;try{return await ens.getEnsName(m,{address:e})}catch(r){return console.error(`ENS name lookup failed for address ${e}:`,r),null}},ae=async e=>{if(!m)return null;try{return await ens.getEnsAvatar(m,{name:ens.normalize(e)})}catch(r){return console.error(`ENS avatar lookup failed for name ${e}:`,r),null}},Qt=async e=>{if(!m)return null;try{let r=await ens.getEnsAddress(m,{name:ens.normalize(e)});return r?r.toLowerCase():null}catch(r){return console.error(`ENS address lookup failed for name ${e}:`,r),null}},Xt=e=>e.includes(".")&&!viem.isAddress(e);var ne=(e,r,t,o)=>{let i=pulsarCore.selectTxByKey(e,t);if(!i)return "";if(i.tracker==="safe"){let c=O[i.chainId];return c?`${c}${i.from}/transactions/tx?id=multisig_${i.from}_${i.txKey}`:""}let n=r.find(c=>c.id===i.chainId)?.blockExplorers?.default.url;if(!n)return "";let s=o||(i.adapter===pulsarCore.TransactionAdapter.EVM?i.hash:i.txKey);return s?`${n}/tx/${s}`:""};var oe=1.15;async function ie({config:e,tx:r}){if(r.adapter!==pulsarCore.TransactionAdapter.EVM)throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${r.adapter}'.`);let{nonce:t,from:o,to:i,value:a,input:n,maxFeePerGas:s,maxPriorityFeePerGas:c,chainId:u}=r;if(t===void 0||!o||!i||!a||!s||!c)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 l=BigInt(Math.ceil(Number(c)*oe)),f=BigInt(Math.ceil(Number(s)*oe));return await core.sendTransaction(e,{to:i,value:BigInt(a),data:n||"0x",chainId:u,nonce:t,maxFeePerGas:f,maxPriorityFeePerGas:l})}catch(p){let l=p instanceof Error?p.message:String(p);throw new Error(`Failed to speed up transaction: ${l}`)}}function Cr(e,r){if(!e)throw new Error("EVM adapter requires a wagmi config object.");return {key:pulsarCore.TransactionAdapter.EVM,getWalletInfo:()=>{let t=core.getAccount(e);return {walletAddress:t.address??viem.zeroAddress,walletType:t.connector?.name?.toLowerCase()??"unknown"}},checkChainForTx:t=>Q(t,e),checkTransactionsTracker:(t,o)=>X(t,o),checkAndInitializeTrackerInStore:({tx:t,...o})=>Z({tracker:t.tracker,tx:t,chains:r,...o}),getExplorerUrl:()=>{let{chain:t}=core.getAccount(e);return t?.blockExplorers?.default.url},getExplorerTxUrl:(t,o,i)=>ne(t,r,o,i),getName:t=>re(t),getAvatar:t=>ae(t),cancelTxAction:t=>v({config:e,tx:t}),speedUpTxAction:t=>ie({config:e,tx:t}),retryTxAction:async({onClose:t,txKey:o,handleTransaction:i,tx:a})=>{if(t(o),!i){console.error("Retry failed: handleTransaction function is not provided.");return}await i({actionFunction:()=>a.actionFunction({config:e,...a.payload}),params:a,defaultTracker:"ethereum"});}}}var b=null,w=null,Le=300*1e3,Ve="https://relay.gelato.digital/relays/v2/supported-chains";async function Fr(e){let r=Date.now();if(b&&w&&r-w<Le)return b.includes(e);try{let t=await fetch(Ve);if(!t.ok)throw new Error(`Gelato API responded with status: ${t.status}`);let i=(await t.json()).chains.map(Number);return b=i,w=r,i.includes(e)}catch(t){return console.error("Failed to fetch Gelato supported chains:",t),b=null,w=null,false}}function Mr(e){let r=core.getAccount(e),t=core.getClient(e);if(!r.address)throw new Error("getActiveWalletAndClient failed: No connected wallet address found.");if(!t)throw new Error("getActiveWalletAndClient failed: Wallet client is unavailable.");return {activeWallet:r,walletClient:t}}
|
|
2
|
-
exports.GelatoTaskState=
|
|
1
|
+
'use strict';var pulsarCore=require('@tuwaio/pulsar-core'),core=require('@wagmi/core'),viem=require('viem'),actions=require('viem/actions'),h=require('dayjs'),chains=require('viem/chains'),ens=require('viem/ens');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var h__default=/*#__PURE__*/_interopDefault(h);var T=(o=>(o.Ethereum="ethereum",o.Safe="safe",o.Gelato="gelato",o))(T||{});var A=1.15;async function R({config:e,tx:t}){if(t.adapter!==pulsarCore.TransactionAdapter.EVM)throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${t.adapter}'.`);let{nonce:r,maxFeePerGas:o,maxPriorityFeePerGas:i,chainId:a}=t;if(r===void 0||!o||!i)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).");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 s=BigInt(Math.ceil(Number(i)*A)),c=BigInt(Math.ceil(Number(o)*A));return await core.sendTransaction(e,{to:n.address,value:0n,chainId:a,nonce:r,maxFeePerGas:c,maxPriorityFeePerGas:s})}catch(n){let s=n instanceof Error?n.message:String(n);throw new Error(`Failed to cancel transaction: ${s}`)}}function g(e,t){let r=t.find(o=>o.id===e);if(r)return viem.createPublicClient({chain:r,transport:viem.http()});console.warn(`createViemClient: No chain configuration found for chainId ${e}. A client could not be created.`);}var xe=10,ge=3e3;async function ke(e){let{tx:t,chains:r,onInitialize:o,onTxDetailsFetched:i,onSuccess:a,onFailure:n,onReplaced:s,retryCount:c=xe,retryTimeout:f=ge,waitForTransactionReceiptParams:p}=e;if(o?.(),t.txKey===viem.zeroHash)return n(new Error("Transaction hash cannot be the zero hash."));let l=g(t.chainId,r);if(!l)return n(new Error(`Could not create a viem client for chainId: ${t.chainId}`));let u=null;for(let d=0;d<c;d++)try{u=await actions.getTransaction(l,{hash:t.txKey}),i(u);break}catch(x){if(d===c-1)return console.error(`EVM tracker failed to fetch tx ${t.txKey} after ${c} retries:`,x),n(x);await new Promise(E=>setTimeout(E,f));}if(!u)return n(new Error("Transaction details could not be fetched."));try{let d=!1,x=await actions.waitForTransactionReceipt(l,{hash:u.hash,onReplaced:E=>{d=!0,s(E);},...p});if(d)return;await a(u,x,l);}catch(d){console.error(`Error waiting for receipt for tx ${t.txKey}:`,d),n(d);}}async function S(e){let{tx:t,chains:r,transactionsPool:o,updateTxParams:i,onSucceedCallbacks:a}=e;return ke({tx:t,chains:r,onInitialize:()=>{i(t.txKey,{hash:t.txKey});},onTxDetailsFetched:n=>{i(t.txKey,{to:n.to??void 0,input:n.input,value:n.value?.toString(),nonce:n.nonce,maxFeePerGas:n.maxFeePerGas?.toString(),maxPriorityFeePerGas:n.maxPriorityFeePerGas?.toString()});},onSuccess:async(n,s,c)=>{let f=await actions.getBlock(c,{blockNumber:s.blockNumber}),p=Number(f.timestamp),l=s.status==="success";i(t.txKey,{status:l?pulsarCore.TransactionStatus.Success:pulsarCore.TransactionStatus.Failed,isError:!l,pending:false,finishedTimestamp:p});let u=o[t.txKey];l&&a&&u&&a(u);},onReplaced:n=>{i(t.txKey,{status:pulsarCore.TransactionStatus.Replaced,replacedTxHash:n.transaction.hash,pending:false});},onFailure:n=>{i(t.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,errorMessage:n instanceof Error?n.message:"Transaction failed or could not be tracked."});}})}function C(e){return typeof e=="object"&&e!==null&&"taskId"in e}var we=(s=>(s.CheckPending="CheckPending",s.ExecPending="ExecPending",s.WaitingForConfirmation="WaitingForConfirmation",s.ExecSuccess="ExecSuccess",s.ExecReverted="ExecReverted",s.Cancelled="Cancelled",s.NotFound="NotFound",s))(we||{}),be="https://api.gelato.digital/tasks/status/",F=new Set(["ExecReverted","Cancelled","NotFound"]);function Ee(e){return e!=="ExecSuccess"&&!F.has(e)}var Se=async({tx:e,stopPolling:t,onSuccess:r,onFailure:o,onIntervalTick:i})=>{let a=await fetch(`${be}${e.txKey}`);if(!a.ok){if(a.status===404){o(),t({withoutRemoving:true});return}throw new Error(`Gelato API responded with status: ${a.status}`)}let n=await a.json(),{taskState:s,creationDate:c}=n.task;if(i?.(n),c&&h__default.default().diff(h__default.default(c),"day")>=1&&Ee(s)){t({withoutRemoving:true});return}s==="ExecSuccess"?(r(n),t({withoutRemoving:true})):F.has(s)&&(o(n),t({withoutRemoving:true}));};function I({tx:e,transactionsPool:t,updateTxParams:r,onSucceedCallbacks:o,removeTxFromPool:i}){return pulsarCore.initializePollingTracker({tx:e,fetcher:Se,removeTxFromPool:i,onSuccess:a=>{r(e.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:a.task.transactionHash,finishedTimestamp:a.task.executionDate?h__default.default(a.task.executionDate).unix():void 0});let n=t[e.txKey];o&&n&&o(n);},onIntervalTick:a=>{r(e.txKey,{hash:a.task.transactionHash});},onFailure:a=>{r(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:a?.task.transactionHash,errorMessage:a?.task.lastCheckMessage??"Transaction failed or was not found.",finishedTimestamp:a?.task.executionDate?h__default.default(a.task.executionDate).unix():void 0});}})}var wt={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},O={[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.polygon.id]:"https://app.safe.global/matic:",[chains.arbitrum.id]:"https://app.safe.global/arb1:",[chains.aurora.id]:"https://app.safe.global/aurora:",[chains.avalanche.id]:"https://app.safe.global/avax:",[chains.base.id]:"https://app.safe.global/base:",[chains.boba.id]:"https://app.safe.global/boba:",[chains.bsc.id]:"https://app.safe.global/bnb:",[chains.celo.id]:"https://app.safe.global/celo:",[chains.gnosis.id]:"https://app.safe.global/gno:",[chains.optimism.id]:"https://app.safe.global/oeth:",[chains.polygonZkEvm.id]:"https://app.safe.global/zkevm:",[chains.zksync.id]:"https://app.safe.global/zksync:"},q={[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.polygon.id]:"https://safe-transaction-polygon.safe.global/api/v1",[chains.arbitrum.id]:"https://safe-transaction-arbitrum.safe.global/api/v1",[chains.aurora.id]:"https://safe-transaction-aurora.safe.global/api/v1",[chains.avalanche.id]:"https://safe-transaction-avalanche.safe.global/api/v1",[chains.base.id]:"https://safe-transaction-base.safe.global/api/v1",[chains.boba.id]:"https://safe-transaction-boba.safe.global/api/v1",[chains.bsc.id]:"https://safe-transaction-bsc.safe.global/api/v1",[chains.celo.id]:"https://safe-transaction-celo.safe.global/api/v1",[chains.gnosis.id]:"https://safe-transaction-gnosis-chain.safe.global/api/v1",[chains.optimism.id]:"https://safe-transaction-optimism.safe.global/api/v1",[chains.polygonZkEvm.id]:"https://safe-transaction-zkevm.safe.global/api/v1",[chains.zksync.id]:"https://safe-transaction-zksync.safe.global/api/v1"};var Re=async({tx:e,stopPolling:t,onSuccess:r,onFailure:o,onReplaced:i,onIntervalTick:a})=>{let n=q[e.chainId];if(!n)throw new Error(`Safe Transaction Service URL not found for chainId: ${e.chainId}`);let s=await fetch(`${n}/multisig-transactions/${e.txKey}/`);if(!s.ok)throw s.status===404&&(o(),t({withoutRemoving:true})),new Error(`Safe API responded with status: ${s.status}`);let c=await s.json();if(a?.(c),c.isExecuted){c.isSuccessful?r(c):o(c),t({withoutRemoving:true});return}let f=await fetch(`${n}/safes/${e.from}/multisig-transactions/?nonce=${c.nonce}`);if(!f.ok)throw new Error(`Safe API (nonce check) responded with status: ${f.status}`);let l=(await f.json()).results.find(u=>u.isExecuted);if(l){i?.(l),t({withoutRemoving:true});return}h__default.default().diff(h__default.default(c.submissionDate),"day")>=1&&t({withoutRemoving:true});};function J({tx:e,transactionsPool:t,updateTxParams:r,onSucceedCallbacks:o,removeTxFromPool:i}){return pulsarCore.initializePollingTracker({tx:e,fetcher:Re,removeTxFromPool:i,onSuccess:a=>{r(e.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:a.transactionHash??void 0,finishedTimestamp:a.executionDate?h__default.default(a.executionDate).unix():void 0});let n=t[e.txKey];o&&n&&o(n);},onIntervalTick:a=>{r(e.txKey,{hash:a.transactionHash??void 0});},onFailure:a=>{r(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:a?.transactionHash??void 0,errorMessage:a?"Safe transaction failed or was rejected.":"Transaction not found.",finishedTimestamp:a?.executionDate?h__default.default(a.executionDate).unix():void 0});},onReplaced:a=>{r(e.txKey,{status:pulsarCore.TransactionStatus.Replaced,pending:false,hash:e.adapter===pulsarCore.TransactionAdapter.EVM?e.hash:viem.zeroHash,replacedTxHash:a.safeTxHash??viem.zeroHash,finishedTimestamp:a.executionDate?h__default.default(a.executionDate).unix():void 0});}})}async function Z({tracker:e,tx:t,chains:r,...o}){switch(e){case "ethereum":return S({tx:t,chains:r,...o});case "gelato":return I({tx:t,...o});case "safe":return J({tx:t,...o});default:return console.warn(`Unknown tracker type: '${e}'. Falling back to default EVM tracker.`),S({tx:t,chains:r,...o})}}async function Q(e,t){let{connector:r,chainId:o}=core.getAccount(t);if(r&&o!==e)try{await core.switchChain(t,{chainId:e});}catch(i){throw i.cause?.name==="UserRejectedRequestError"?new Error("User rejected the request to switch network."):(console.error("Failed to switch network:",i),new Error("An error occurred while switching the network."))}}function X(e,t){if(C(e))return {tracker:"gelato",txKey:e.taskId};if(!viem.isHex(e))throw new Error(`Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(e)}`);return t?.toLowerCase()==="safe"?{tracker:"safe",txKey:e}:{tracker:"ethereum",txKey:e}}var m=g(chains.mainnet.id,[chains.mainnet]),re=async e=>{if(!m)return null;try{return await ens.getEnsName(m,{address:e})}catch(t){return console.error(`ENS name lookup failed for address ${e}:`,t),null}},ae=async e=>{if(!m)return null;try{return await ens.getEnsAvatar(m,{name:ens.normalize(e)})}catch(t){return console.error(`ENS avatar lookup failed for name ${e}:`,t),null}},Qt=async e=>{if(!m)return null;try{let t=await ens.getEnsAddress(m,{name:ens.normalize(e)});return t?t.toLowerCase():null}catch(t){return console.error(`ENS address lookup failed for name ${e}:`,t),null}},Xt=e=>e.includes(".")&&!viem.isAddress(e);var ne=(e,t,r,o)=>{let i=pulsarCore.selectTxByKey(e,r);if(!i)return "";if(i.tracker==="safe"){let c=O[i.chainId];return c?`${c}${i.from}/transactions/tx?id=multisig_${i.from}_${i.txKey}`:""}let n=t.find(c=>c.id===i.chainId)?.blockExplorers?.default.url;if(!n)return "";let s=o||(i.adapter===pulsarCore.TransactionAdapter.EVM?i.hash:i.txKey);return s?`${n}/tx/${s}`:""};var oe=1.15;async function ie({config:e,tx:t}){if(t.adapter!==pulsarCore.TransactionAdapter.EVM)throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${t.adapter}'.`);let{nonce:r,from:o,to:i,value:a,input:n,maxFeePerGas:s,maxPriorityFeePerGas:c,chainId:f}=t;if(r===void 0||!o||!i||!a||!s||!c)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 l=BigInt(Math.ceil(Number(c)*oe)),u=BigInt(Math.ceil(Number(s)*oe));return await core.sendTransaction(e,{to:i,value:BigInt(a),data:n||"0x",chainId:f,nonce:r,maxFeePerGas:u,maxPriorityFeePerGas:l})}catch(p){let l=p instanceof Error?p.message:String(p);throw new Error(`Failed to speed up transaction: ${l}`)}}function Pr(e,t){if(!e)throw new Error("EVM adapter requires a wagmi config object.");return {key:pulsarCore.TransactionAdapter.EVM,getWalletInfo:()=>{let r=core.getAccount(e);return {walletAddress:r.address??viem.zeroAddress,walletType:r.connector?.name?.toLowerCase()??"unknown"}},checkChainForTx:r=>Q(r,e),checkTransactionsTracker:(r,o)=>X(r,o),checkAndInitializeTrackerInStore:({tx:r,...o})=>Z({tracker:r.tracker,tx:r,chains:t,...o}),getExplorerUrl:()=>{let{chain:r}=core.getAccount(e);return r?.blockExplorers?.default.url},getExplorerTxUrl:(r,o,i)=>ne(r,t,o,i),getName:r=>re(r),getAvatar:r=>ae(r),cancelTxAction:r=>R({config:e,tx:r}),speedUpTxAction:r=>ie({config:e,tx:r}),retryTxAction:async({onClose:r,txKey:o,handleTransaction:i,tx:a})=>{if(r(o),!i){console.error("Retry failed: handleTransaction function is not provided.");return}await i({actionFunction:()=>a.actionFunction({config:e,...a.payload}),params:a,defaultTracker:"ethereum"});}}}var w=null,b=null,Le=300*1e3,Ve="https://relay.gelato.digital/relays/v2/supported-chains";async function Fr(e){let t=Date.now();if(w&&b&&t-b<Le)return w.includes(e);try{let r=await fetch(Ve);if(!r.ok)throw new Error(`Gelato API responded with status: ${r.status}`);let i=(await r.json()).chains.map(Number);return w=i,b=t,i.includes(e)}catch(r){return console.error("Failed to fetch Gelato supported chains:",r),w=null,b=null,false}}function Mr(e){let t=core.getAccount(e),r=core.getClient(e);if(!t.address)throw new Error("getActiveWalletAndClient failed: No connected wallet address found.");if(!r)throw new Error("getActiveWalletAndClient failed: Wallet client is unavailable.");return {activeWallet:t,walletClient:r}}
|
|
2
|
+
exports.GelatoTaskState=we;exports.SafeTransactionServiceUrls=q;exports.TransactionTracker=T;exports.cancelTxAction=R;exports.checkAndInitializeTrackerInStore=Z;exports.checkChainForTx=Q;exports.checkIsGelatoAvailable=Fr;exports.checkTransactionsTracker=X;exports.createViemClient=g;exports.evmAdapter=Pr;exports.evmTracker=ke;exports.evmTrackerForStore=S;exports.gelatoFetcher=Se;exports.gelatoTrackerForStore=I;exports.getActiveWalletAndClient=Mr;exports.getAddress=Qt;exports.getAvatar=ae;exports.getName=re;exports.gnosisSafeLinksHelper=O;exports.isEnsName=Xt;exports.isGelatoTxKey=C;exports.safeFetcher=Re;exports.safeSdkOptions=wt;exports.safeTrackerForStore=J;exports.selectEvmTxExplorerLink=ne;exports.speedUpTxAction=ie;//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/utils/cancelTxAction.ts","../src/utils/createViemClient.ts","../src/trackers/evmTracker.ts","../src/trackers/gelatoTracker.ts","../src/utils/safeConstants.ts","../src/trackers/safeTracker.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkChainForTx.ts","../src/utils/checkTransactionsTracker.ts","../src/utils/ensUtils.ts","../src/utils/selectEvmTxExplorerLink.ts","../src/utils/speedUpTxAction.ts","../src/adapters/evmAdapter.ts","../src/utils/checkIsGelatoAvailable.ts","../src/utils/getActiveWalletAndClient.ts"],"names":["TransactionTracker","GAS_INCREASE_PERCENTAGE","cancelTxAction","config","tx","TransactionAdapter","nonce","maxFeePerGas","maxPriorityFeePerGas","chainId","account","getAccount","newPriorityFee","newMaxFee","sendTransaction","e","errorMessage","createViemClient","chains","chain","c","createPublicClient","http","DEFAULT_RETRY_COUNT","DEFAULT_RETRY_TIMEOUT_MS","evmTracker","params","onInitialize","onTxDetailsFetched","onSuccess","onFailure","onReplaced","retryCount","retryTimeout","waitForTransactionReceiptParams","zeroHash","client","txDetails","i","getTransaction","error","resolve","wasReplaced","receipt","waitForTransactionReceipt","replacement","evmTrackerForStore","transactionsPool","updateTxParams","onSucceedCallbacks","block","getBlock","timestamp","isSuccess","TransactionStatus","updatedTx","isGelatoTxKey","txKey","GelatoTaskState","GELATO_API_BASE_URL","GELATO_TERMINAL_FAILURE_STATES","isGelatoTxPending","gelatoStatus","gelatoFetcher","stopPolling","onIntervalTick","response","data","taskState","creationDate","dayjs","gelatoTrackerForStore","removeTxFromPool","initializePollingTracker","safeSdkOptions","gnosisSafeLinksHelper","mainnet","goerli","sepolia","polygon","arbitrum","aurora","avalanche","base","boba","bsc","celo","gnosis","optimism","polygonZkEvm","zksync","SafeTransactionServiceUrls","safeFetcher","baseUrl","primaryTxResponse","safeStatus","nonceTxsResponse","executedTx","t","safeTrackerForStore","checkAndInitializeTrackerInStore","tracker","rest","checkChainForTx","connector","activeChainId","switchChain","checkTransactionsTracker","actionTxKey","walletType","isHex","ensClient","getName","address","getEnsName","getAvatar","name","getEnsAvatar","normalize","getAddress","getEnsAddress","isEnsName","nameOrAddress","isAddress","selectEvmTxExplorerLink","replacedTxHash","selectTxByKey","safeBaseUrl","explorerUrl","hash","speedUpTxAction","from","to","value","input","evmAdapter","appChains","activeWallet","zeroAddress","onClose","handleTransaction","cachedRelayChainIds","cacheTimestamp","CACHE_DURATION_MS","GELATO_API_URL","checkIsGelatoAvailable","now","supportedChainIds","getActiveWalletAndClient","getWagmiAccount","walletClient","getClient"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @file This file defines types and enums specific to the EVM (Ethereum Virtual Machine) adapter.\n * It includes identifiers for different tracking strategies and the shape of transaction keys\n * used within the EVM ecosystem.\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 * Each tracker corresponds to a specific method of monitoring a transaction's lifecycle.\n */\nexport enum TransactionTracker {\n /** For standard on-chain EVM transactions tracked by their hash. */\n Ethereum = 'ethereum',\n /** For multi-signature transactions managed and executed via a Safe contract. */\n Safe = 'safe',\n /** For meta-transactions relayed and executed by the Gelato Network. */\n Gelato = 'gelato',\n}\n\n/**\n * A union type representing the unique identifier returned by an `actionFunction`\n * after a transaction is submitted to the network or a relay service.\n *\n * This key is crucial for the EVM adapter to determine which tracker should\n * monitor the transaction.\n *\n * It can be one of the following:\n * - A standard `0x...` transaction hash (`Hex`).\n * - A structured object from a relay service like Gelato (`GelatoTxKey`).\n */\nexport type ActionTxKey = Hex | GelatoTxKey;\n","/**\n * @file This file contains a utility function for canceling a pending EVM transaction.\n */\n\nimport { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n// A common strategy is to increase gas by at least 10% to ensure replacement.\n// We use 15% for a higher chance of success.\nconst GAS_INCREASE_PERCENTAGE = 1.15;\n\n/**\n * Cancels a pending EVM transaction by sending a new, zero-value transaction to oneself\n * with the same nonce but higher gas fees. This effectively replaces the original transaction.\n *\n * @template T - The transaction type, which must be a valid EVM transaction.\n *\n * @param {object} params - The parameters required to cancel the transaction.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The original transaction object to be canceled. It must contain the nonce and gas fee fields.\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:\n * - The transaction is not an EVM transaction.\n * - The transaction is missing required fields (`nonce`, `maxFeePerGas`, etc.).\n * - The wagmi config is not provided.\n * - No connected account is found.\n * - The `sendTransaction` call fails.\n *\n * @example\n * ```ts\n * const handleCancel = async (stuckTransaction) => {\n * try {\n * const cancelTxHash = await cancelTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Cancellation transaction sent with hash:', cancelTxHash);\n * // You should now update your state to track this new transaction.\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 // 1. Validate the transaction type\n if (tx.adapter !== TransactionAdapter.EVM) {\n throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${tx.adapter}'.`);\n }\n\n // 2. Ensure all necessary transaction details are present.\n const { nonce, maxFeePerGas, maxPriorityFeePerGas, chainId } = tx;\n\n if (nonce === undefined || !maxFeePerGas || !maxPriorityFeePerGas) {\n throw new Error(\n 'Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).',\n );\n }\n\n try {\n // 3. Verify wagmi configuration and connected account\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // 4. Calculate new gas fees.\n const newPriorityFee = BigInt(Math.ceil(Number(maxPriorityFeePerGas) * GAS_INCREASE_PERCENTAGE));\n const newMaxFee = BigInt(Math.ceil(Number(maxFeePerGas) * GAS_INCREASE_PERCENTAGE));\n\n // 5. Send a zero-value transaction to your own address with the same nonce and higher gas.\n return await sendTransaction(config, {\n to: account.address,\n value: 0n,\n chainId: chainId as number,\n nonce: 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 for easier debugging.\n throw new Error(`Failed to cancel transaction: ${errorMessage}`);\n }\n}\n","/**\n * @file This file contains a utility function for creating a viem Public Client.\n */\n\nimport { createPublicClient, http } from 'viem';\nimport { Chain } from 'viem/chains';\n\n/**\n * Creates a viem Public Client for a specific chain.\n *\n * This client is used for read-only interactions with the blockchain, such as fetching\n * transaction receipts or reading contract state, without needing a wallet connection.\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 *\n * @returns {import('viem').PublicClient | undefined} A viem PublicClient instance if a matching chain is found, otherwise undefined.\n * It will also log a warning to the console if the chain is not configured.\n */\nexport function createViemClient(chainId: number, chains: Chain[]): import('viem').PublicClient | undefined {\n const chain = chains.find((c) => c.id === chainId);\n\n if (chain) {\n return createPublicClient({\n chain: chain,\n transport: http(),\n });\n }\n\n // Log a warning for easier debugging if a chain configuration is missing.\n console.warn(`createViemClient: No chain configuration found for chainId ${chainId}. A client could not be created.`);\n\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 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\nconst DEFAULT_RETRY_COUNT = 10;\nconst DEFAULT_RETRY_TIMEOUT_MS = 3000;\n\n/**\n * Defines the parameters for the low-level EVM transaction tracker.\n */\nexport type EVMTrackerParams = {\n tx: Pick<Transaction<TransactionTracker>, 'chainId' | 'txKey'>;\n chains: Chain[];\n onTxDetailsFetched: (txDetails: GetTransactionReturnType) => void;\n onSuccess: (txDetails: GetTransactionReturnType, receipt: TransactionReceipt, client: Client) => Promise<void>;\n onReplaced: (replacement: ReplacementReturnType) => void;\n onFailure: (error?: unknown) => void;\n onInitialize?: () => void;\n retryCount?: number;\n retryTimeout?: number;\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 to determine the final status.\n *\n * @param {EVMTrackerParams} params - The configuration object for the tracker.\n */\nexport async function evmTracker(params: EVMTrackerParams): Promise<void> {\n const {\n tx,\n chains,\n onInitialize,\n onTxDetailsFetched,\n onSuccess,\n onFailure,\n onReplaced,\n retryCount = DEFAULT_RETRY_COUNT,\n retryTimeout = DEFAULT_RETRY_TIMEOUT_MS,\n waitForTransactionReceiptParams,\n } = params;\n\n onInitialize?.();\n\n if (tx.txKey === zeroHash) {\n return onFailure(new Error('Transaction hash cannot be the zero hash.'));\n }\n\n const client = createViemClient(tx.chainId as number, chains);\n if (!client) {\n return onFailure(new Error(`Could not create a viem client for chainId: ${tx.chainId}`));\n }\n\n let txDetails: GetTransactionReturnType | null = null;\n\n // 1. Retry loop to fetch the transaction details.\n // This handles cases where the transaction is not immediately available on the RPC node.\n for (let i = 0; i < retryCount; i++) {\n try {\n txDetails = await getTransaction(client, { hash: tx.txKey as Hex });\n onTxDetailsFetched(txDetails);\n break; // Exit loop on success\n } catch (error) {\n if (i === retryCount - 1) {\n console.error(`EVM tracker failed to fetch tx ${tx.txKey} after ${retryCount} retries:`, error);\n return onFailure(error);\n }\n await new Promise((resolve) => setTimeout(resolve, retryTimeout));\n }\n }\n\n if (!txDetails) {\n // This should theoretically not be reached if the loop completes, but it's a good safeguard.\n return onFailure(new Error('Transaction details could not be fetched.'));\n }\n\n // 2. Wait for the transaction to be mined and get the receipt.\n try {\n let wasReplaced = false;\n const receipt = await waitForTransactionReceipt(client, {\n hash: txDetails.hash,\n onReplaced: (replacement) => {\n wasReplaced = true;\n onReplaced(replacement);\n },\n ...waitForTransactionReceiptParams,\n });\n\n // If onReplaced was called, the promise resolves but we should not proceed to onSuccess.\n if (wasReplaced) {\n return;\n }\n\n // 3. Transaction is mined, call the onSuccess callback.\n await onSuccess(txDetails, receipt, client);\n } catch (error) {\n console.error(`Error waiting for receipt for tx ${tx.txKey}:`, error);\n onFailure(error);\n }\n}\n\n/**\n * A higher-level wrapper for `evmTracker` that integrates directly with the Pulsar store.\n * It provides the necessary callbacks to update a transaction's state throughout its lifecycle.\n *\n * @template T - The application-specific transaction type.\n */\nexport async function evmTrackerForStore<T extends Transaction<TransactionTracker>>(\n params: Pick<EVMTrackerParams, 'chains'> &\n Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks'\n > & { tx: T },\n) {\n const { tx, chains, transactionsPool, updateTxParams, onSucceedCallbacks } = params;\n\n return evmTracker({\n tx,\n chains,\n onInitialize: () => {\n // Set the initial hash, which is the same as the txKey for this tracker.\n updateTxParams(tx.txKey, { hash: tx.txKey as Hex });\n },\n onTxDetailsFetched: (txDetails) => {\n // Once we fetch details from the node, update the transaction with more info.\n updateTxParams(tx.txKey, {\n to: txDetails.to ?? undefined,\n input: txDetails.input,\n value: txDetails.value?.toString(),\n nonce: txDetails.nonce,\n maxFeePerGas: txDetails.maxFeePerGas?.toString(),\n maxPriorityFeePerGas: txDetails.maxPriorityFeePerGas?.toString(),\n });\n },\n onSuccess: async (txDetails, receipt, client) => {\n const block = await getBlock(client, { blockNumber: receipt.blockNumber });\n const timestamp = Number(block.timestamp);\n const isSuccess = receipt.status === 'success';\n\n updateTxParams(tx.txKey, {\n status: isSuccess ? TransactionStatus.Success : TransactionStatus.Failed,\n isError: !isSuccess,\n pending: false,\n finishedTimestamp: timestamp,\n });\n\n // After the final state update, retrieve the latest version of the transaction\n // and trigger the global success callback if applicable.\n const updatedTx = transactionsPool[tx.txKey];\n if (isSuccess && onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onReplaced: (replacement) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Replaced,\n replacedTxHash: replacement.transaction.hash,\n pending: false,\n });\n },\n onFailure: (error) => {\n updateTxParams(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 ITxTrackingStore,\n PollingTrackerConfig,\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// 1. TYPES AND TYPE GUARDS\n// =================================================================================================\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 typeof txKey === 'object' && txKey !== null && 'taskId' in txKey;\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 NotFound = 'NotFound',\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\nconst GELATO_API_BASE_URL = 'https://api.gelato.digital/tasks/status/';\n\n// =================================================================================================\n// 2. HELPER FUNCTIONS\n// =================================================================================================\n\nconst GELATO_TERMINAL_FAILURE_STATES = new Set([\n GelatoTaskState.ExecReverted,\n GelatoTaskState.Cancelled,\n GelatoTaskState.NotFound,\n]);\n\nfunction isGelatoTxPending(gelatoStatus: GelatoTaskState): boolean {\n return gelatoStatus !== GelatoTaskState.ExecSuccess && !GELATO_TERMINAL_FAILURE_STATES.has(gelatoStatus);\n}\n\n// =================================================================================================\n// 3. FETCHER IMPLEMENTATION\n// =================================================================================================\n\n/**\n * A reusable fetcher function for `initializePollingTracker` that queries the Gelato API for a task's status.\n * It handles the logic for interpreting Gelato's task states and calls the appropriate polling callbacks.\n */\nexport const gelatoFetcher: PollingTrackerConfig<\n GelatoTaskStatusResponse,\n Transaction<TransactionTracker>,\n TransactionTracker\n>['fetcher'] = async ({ tx, stopPolling, onSuccess, onFailure, onIntervalTick }) => {\n const response = await fetch(`${GELATO_API_BASE_URL}${tx.txKey}`);\n\n if (!response.ok) {\n if (response.status === 404) {\n onFailure(); // Treat 404 as a terminal failure.\n return;\n }\n // For other errors, let the polling tracker's retry mechanism handle it.\n throw new Error(`Gelato API responded with status: ${response.status}`);\n }\n\n const data = (await response.json()) as GelatoTaskStatusResponse;\n const { taskState, creationDate } = data.task;\n\n onIntervalTick?.(data);\n\n // Safeguard: Stop polling for tasks that have been pending for over a day.\n if (creationDate && dayjs().diff(dayjs(creationDate), 'day') >= 1 && isGelatoTxPending(taskState)) {\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // Check for terminal states to stop the polling.\n if (taskState === GelatoTaskState.ExecSuccess) {\n onSuccess(data);\n } else if (GELATO_TERMINAL_FAILURE_STATES.has(taskState)) {\n onFailure(data);\n }\n};\n\n// =================================================================================================\n// 4. STORE-CONNECTED TRACKER\n// =================================================================================================\n\n/**\n * A higher-level wrapper that integrates the Gelato polling logic with the Pulsar store.\n * It uses the generic `gelatoFetcher` and provides store-specific callbacks.\n *\n * @template T - The application-specific transaction type.\n */\nexport 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 initializePollingTracker<GelatoTaskStatusResponse, T, TransactionTracker>({\n tx,\n fetcher: gelatoFetcher, // Use the exported, reusable fetcher\n removeTxFromPool,\n onSuccess: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: 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: (response) => {\n updateTxParams(tx.txKey, {\n hash: response.task.transactionHash,\n });\n },\n onFailure: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response?.task.transactionHash,\n errorMessage: response?.task.lastCheckMessage ?? 'Transaction failed or was not found.',\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 for various chains.\n */\n\nimport {\n arbitrum,\n aurora,\n avalanche,\n base,\n boba,\n bsc,\n celo,\n gnosis,\n goerli,\n mainnet,\n optimism,\n polygon,\n polygonZkEvm,\n sepolia,\n zksync,\n} 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 [polygon.id]: 'https://app.safe.global/matic:',\n [arbitrum.id]: 'https://app.safe.global/arb1:',\n [aurora.id]: 'https://app.safe.global/aurora:',\n [avalanche.id]: 'https://app.safe.global/avax:',\n [base.id]: 'https://app.safe.global/base:',\n [boba.id]: 'https://app.safe.global/boba:',\n [bsc.id]: 'https://app.safe.global/bnb:',\n [celo.id]: 'https://app.safe.global/celo:',\n [gnosis.id]: 'https://app.safe.global/gno:',\n [optimism.id]: 'https://app.safe.global/oeth:',\n [polygonZkEvm.id]: 'https://app.safe.global/zkevm:',\n [zksync.id]: 'https://app.safe.global/zksync:',\n};\n\n/**\n * A comprehensive 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 from the correct service.\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 [polygon.id]: 'https://safe-transaction-polygon.safe.global/api/v1',\n [arbitrum.id]: 'https://safe-transaction-arbitrum.safe.global/api/v1',\n [aurora.id]: 'https://safe-transaction-aurora.safe.global/api/v1',\n [avalanche.id]: 'https://safe-transaction-avalanche.safe.global/api/v1',\n [base.id]: 'https://safe-transaction-base.safe.global/api/v1',\n [boba.id]: 'https://safe-transaction-boba.safe.global/api/v1',\n [bsc.id]: 'https://safe-transaction-bsc.safe.global/api/v1',\n [celo.id]: 'https://safe-transaction-celo.safe.global/api/v1',\n [gnosis.id]: 'https://safe-transaction-gnosis-chain.safe.global/api/v1',\n [optimism.id]: 'https://safe-transaction-optimism.safe.global/api/v1',\n [polygonZkEvm.id]: 'https://safe-transaction-zkevm.safe.global/api/v1',\n [zksync.id]: 'https://safe-transaction-zksync.safe.global/api/v1',\n};\n","/**\n * @file This file implements the transaction tracking logic for Safe (formerly Gnosis 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 ITxTrackingStore,\n PollingTrackerConfig,\n Transaction,\n TransactionAdapter,\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// 1. TYPES\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: Hex | null;\n safeTxHash: Hex;\n isExecuted: boolean;\n isSuccessful: boolean | null;\n executionDate: string | null;\n submissionDate: string;\n modified: string;\n nonce: number;\n};\n\n/**\n * The response shape when querying for multiple transactions (e.g., by nonce).\n */\ntype SafeTxSameNonceResponse = {\n count: number;\n results: SafeTxStatusResponse[];\n};\n\n// =================================================================================================\n// 2. FETCHER IMPLEMENTATION\n// =================================================================================================\n\n/**\n * A reusable fetcher for `initializePollingTracker` that queries the Safe Transaction Service API.\n * It handles the complex logic of detecting executed, failed, and replaced multisig transactions.\n */\nexport const safeFetcher: PollingTrackerConfig<\n SafeTxStatusResponse,\n Transaction<TransactionTracker>,\n TransactionTracker\n>['fetcher'] = async ({ tx, stopPolling, onSuccess, onFailure, onReplaced, onIntervalTick }) => {\n const baseUrl = SafeTransactionServiceUrls[tx.chainId as number];\n if (!baseUrl) {\n throw new Error(`Safe Transaction Service URL not found for chainId: ${tx.chainId}`);\n }\n\n // 1. Fetch the status of the primary transaction.\n const primaryTxResponse = await fetch(`${baseUrl}/multisig-transactions/${tx.txKey}/`);\n if (!primaryTxResponse.ok) {\n // Treat 404 as a terminal failure (transaction is lost).\n if (primaryTxResponse.status === 404) {\n onFailure();\n }\n throw new Error(`Safe API responded with status: ${primaryTxResponse.status}`);\n }\n const safeStatus = (await primaryTxResponse.json()) as SafeTxStatusResponse;\n onIntervalTick?.(safeStatus);\n\n // 2. Check if the primary transaction itself has been executed.\n if (safeStatus.isExecuted) {\n if (safeStatus.isSuccessful) {\n onSuccess(safeStatus);\n } else {\n onFailure(safeStatus);\n }\n return;\n }\n\n // 3. If still pending, check for replacements.\n // This is necessary because another transaction with the same nonce might have been executed.\n const nonceTxsResponse = await fetch(`${baseUrl}/safes/${tx.from}/multisig-transactions/?nonce=${safeStatus.nonce}`);\n if (!nonceTxsResponse.ok) {\n throw new Error(`Safe API (nonce check) responded with status: ${nonceTxsResponse.status}`);\n }\n const sameNonceTxs = (await nonceTxsResponse.json()) as SafeTxSameNonceResponse;\n const executedTx = sameNonceTxs.results.find((t) => t.isExecuted);\n\n if (executedTx) {\n // If an executed transaction exists and it's not ours, our transaction was replaced.\n onReplaced?.(executedTx);\n return;\n }\n\n // 4. Safeguard: Stop polling for very old pending transactions.\n if (dayjs().diff(dayjs(safeStatus.submissionDate), 'day') >= 1) {\n stopPolling({ withoutRemoving: true });\n }\n};\n\n// =================================================================================================\n// 3. STORE-CONNECTED TRACKER\n// =================================================================================================\n\n/**\n * A higher-level wrapper that integrates the Safe polling logic with the Pulsar store.\n * It uses the generic `safeFetcher` and provides store-specific callbacks.\n *\n * @template T - The application-specific transaction type.\n */\nexport 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 initializePollingTracker<SafeTxStatusResponse, T, TransactionTracker>({\n tx,\n fetcher: safeFetcher,\n removeTxFromPool,\n onSuccess: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: false,\n hash: response.transactionHash ?? undefined,\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: (response) => {\n // Only update fields that might change while pending.\n updateTxParams(tx.txKey, {\n hash: response.transactionHash ?? undefined,\n });\n },\n onFailure: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response?.transactionHash ?? undefined,\n errorMessage: response ? 'Safe transaction failed or was rejected.' : 'Transaction not found.',\n finishedTimestamp: response?.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n onReplaced: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Replaced,\n pending: false,\n hash: tx.adapter === TransactionAdapter.EVM ? tx.hash : zeroHash,\n // The `replacedTxHash` is the `safeTxHash` of the transaction that was executed instead.\n replacedTxHash: response.safeTxHash ?? zeroHash,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n });\n}\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 * The parameters required to initialize a tracker.\n * @template T - The application-specific transaction type.\n */\ntype InitializeTrackerParams<T extends Transaction<TransactionTracker>> = Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n chains: Chain[];\n tx: T;\n tracker: TransactionTracker;\n};\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., standard EVM, Gelato, or Safe).\n *\n * @template T - The application-specific transaction type, extending the base `Transaction`.\n * @param {InitializeTrackerParams<T>} params - The parameters for initializing the tracker.\n * @returns {Promise<void>} A promise that resolves once the tracking process has been successfully initiated.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<TransactionTracker>>({\n tracker,\n tx,\n chains,\n ...rest\n}: InitializeTrackerParams<T>): Promise<void> {\n switch (tracker) {\n case TransactionTracker.Ethereum:\n return evmTrackerForStore({ tx, chains, ...rest });\n\n case TransactionTracker.Gelato:\n // The Gelato tracker does not need the `chains` param as it uses its own API endpoints.\n return gelatoTrackerForStore({ tx, ...rest });\n\n case TransactionTracker.Safe:\n // The Safe tracker also uses its own API endpoints.\n return safeTrackerForStore({ tx, ...rest });\n\n // The default case handles any unknown or unspecified tracker types.\n // It logs a warning and treats them as standard EVM transactions.\n default:\n console.warn(`Unknown tracker type: '${tracker}'. Falling back to default EVM tracker.`);\n return evmTrackerForStore({ tx, chains, ...rest });\n }\n}\n","/**\n * @file This file contains a utility to ensure the user's wallet is connected to the correct chain before proceeding with a transaction.\n */\n\nimport { Config, getAccount, switchChain } 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.\n *\n * This function is a crucial prerequisite for any action that requires a specific network.\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 * It rejects if the user cancels the switch or if another error occurs.\n *\n * @throws {Error} Throws a specific error if the user rejects the chain switch or if the switch fails for other reasons.\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 is on a different chain than required.\n if (connector && activeChainId !== chainId) {\n try {\n // Pause execution and wait for the user to confirm the chain switch in their wallet.\n await switchChain(config, { chainId });\n } catch (error) {\n // Provide a more specific error message based on the type of error.\n // This helps in distinguishing user rejection from other issues.\n if ((error as any).cause?.name === 'UserRejectedRequestError') {\n throw new Error('User rejected the request to switch network.');\n }\n console.error('Failed to switch network:', error);\n throw new Error('An error occurred while switching the network.');\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. It inspects\n * the key returned by the `actionFunction` and the wallet type to decide the tracking strategy.\n * The logic follows a specific priority:\n * 1. Checks for a Gelato Task ID structure.\n * 2. Checks if the wallet type indicates a Safe transaction.\n * 3. Defaults to the standard on-chain EVM hash 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', 'injected').\n *\n * @returns {{ tracker: TransactionTracker; txKey: string }} An object containing the determined tracker type and the final string-based transaction key.\n *\n * @throws {Error} Throws an error if the `actionTxKey` is not a valid Hex string after failing the Gelato check.\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 (e.g., a transaction hash or SafeTxHash).\n // This check adds robustness in case of type mismatches.\n if (!isHex(actionTxKey)) {\n throw new Error(\n `Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(\n actionTxKey,\n )}`,\n );\n }\n\n // 2. Second priority: Check if the transaction came from a Safe wallet.\n // The check is case-insensitive for robustness.\n if (walletType?.toLowerCase() === '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","/**\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 * all specifically targeting the Ethereum Mainnet where ENS is deployed.\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// A single, shared viem client for all ENS lookups.\n// ENS lookups are always performed against Ethereum Mainnet, regardless of the app's connected chain.\nconst ensClient = createViemClient(mainnet.id, [mainnet]);\n\n/**\n * Fetches the primary ENS name for a given Ethereum address from the Ethereum Mainnet.\n *\n * @param {Hex} address - The Ethereum address to look up.\n * @returns {Promise<string | null>} The ENS name if found, otherwise null.\n */\nexport const getName = async (address: Hex): Promise<string | null> => {\n if (!ensClient) return null;\n try {\n // getEnsName returns the name or null if not found.\n return await getEnsName(ensClient, { address });\n } catch (error) {\n console.error(`ENS name lookup failed for address ${address}:`, error);\n return null;\n }\n};\n\n/**\n * Fetches the avatar URL for a given ENS name from the Ethereum Mainnet.\n *\n * @param {string} name - The ENS name (e.g., 'vitalik.eth').\n * @returns {Promise<string | null>} The URL of the avatar image if found, otherwise null.\n */\nexport const getAvatar = async (name: string): Promise<string | null> => {\n if (!ensClient) return null;\n try {\n // getEnsAvatar returns the URL or null if not found.\n return await getEnsAvatar(ensClient, { name: normalize(name) });\n } catch (error) {\n console.error(`ENS avatar lookup failed for name ${name}:`, error);\n return null;\n }\n};\n\n/**\n * Fetches the Ethereum address associated with a given ENS name from the Ethereum Mainnet.\n *\n * @param {string} name - The ENS name to resolve (e.g., 'vitalik.eth').\n * @returns {Promise<Address | null>} The associated Ethereum address (lowercase) or null if not found.\n */\nexport const getAddress = async (name: string): Promise<Address | null> => {\n if (!ensClient) return null;\n try {\n const address = await getEnsAddress(ensClient, { name: normalize(name) });\n // viem returns the address or null. We ensure it's lowercase if it exists.\n return address ? (address.toLowerCase() as Address) : null;\n } catch (error) {\n console.error(`ENS address lookup failed for name ${name}:`, error);\n return null;\n }\n};\n\n/**\n * A heuristic to check if a string is likely an ENS name.\n *\n * This is not a foolproof validation but a quick check. A valid ENS name\n * must contain at least one dot and should not be a valid Ethereum address.\n *\n * @param {string} nameOrAddress - The string to check.\n * @returns {boolean} True if the string is likely an ENS name.\n *\n * @example\n * isEnsName('vitalik.eth') // true\n * isEnsName('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045') // false\n * isEnsName('notanaddress') // false (doesn't contain a dot)\n */\nexport const isEnsName = (nameOrAddress: string): boolean => {\n return nameOrAddress.includes('.') && !isAddress(nameOrAddress);\n};\n","/**\n * @file This file contains a selector utility for generating a block explorer URL for a given EVM transaction.\n */\n\nimport { 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 or Safe UI for a given transaction.\n * It handles different URL structures for standard EVM transactions and Safe multi-sig transactions.\n *\n * @template TR - The generic type for the tracker identifier.\n * @template T - The transaction type.\n *\n * @param {TransactionPool<TR, T>} transactionsPool - The entire pool of transactions from the store.\n * @param {Chain[]} chains - An array of supported chain objects, typically from `viem/chains`.\n * @param {Hex} txKey - The unique key (`txKey`) of the transaction for which to generate the link.\n * @param {Hex} [replacedTxHash] - Optional. If this is a speed-up/cancel transaction, this is the hash of the new transaction.\n *\n * @returns {string} The full URL to the transaction on the corresponding block explorer or Safe app,\n * or an empty string if the transaction or required chain configuration is 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 // Handle Safe transactions, which link to the Safe web app instead of a block explorer.\n if (tx.tracker === TransactionTracker.Safe) {\n const safeBaseUrl = gnosisSafeLinksHelper[tx.chainId as number];\n if (!safeBaseUrl) return '';\n\n return `${safeBaseUrl}${tx.from}/transactions/tx?id=multisig_${tx.from}_${tx.txKey}`;\n }\n\n // Handle standard EVM transactions.\n const chain = chains.find((c) => c.id === tx.chainId);\n const explorerUrl = chain?.blockExplorers?.default.url;\n\n if (!explorerUrl) {\n // Return empty string if the chain or its explorer URL is not configured.\n return '';\n }\n\n // Determine the correct hash to display. Prioritize the replaced hash for speed-up/cancel transactions.\n const hash = replacedTxHash || (tx.adapter === TransactionAdapter.EVM ? tx.hash : tx.txKey);\n\n if (!hash) return '';\n\n return `${explorerUrl}/tx/${hash}`;\n};\n","/**\n * @file This file contains a utility function for speeding up a pending EVM transaction.\n */\n\nimport { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n// A common strategy is to increase gas by at least 10% to ensure replacement.\n// We use 15% for a higher chance of success.\nconst GAS_INCREASE_PERCENTAGE = 1.15;\n\n/**\n * Speeds up a pending EVM transaction by resubmitting it with the same nonce but higher gas fees.\n * This function is designed to work with wagmi's configuration and actions.\n *\n * @template TR - The type of the tracker identifier.\n * @template T - The transaction type, which must be a valid EVM transaction.\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. It must contain all necessary EVM fields.\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:\n * - The transaction is not an EVM transaction.\n * - The transaction is missing required fields (`nonce`, `from`, `to`, `value`, `maxFeePerGas`, etc.).\n * - The wagmi config is not provided.\n * - No connected account is found.\n * - The `sendTransaction` call fails for any reason.\n *\n * @example\n * ```ts\n * const handleSpeedUp = async (stuckTransaction) => {\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 * // You should now update your state to track this new transaction hash.\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 // 1. Validate the transaction type\n if (tx.adapter !== TransactionAdapter.EVM) {\n throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${tx.adapter}'.`);\n }\n\n // 2. Ensure all necessary transaction details are present.\n const { nonce, from, to, value, input, maxFeePerGas, maxPriorityFeePerGas, chainId } = tx;\n\n if (nonce === undefined || !from || !to || !value || !maxFeePerGas || !maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for speed-up.');\n }\n\n try {\n // 3. Verify wagmi configuration and connected account\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // 4. Calculate new gas fees.\n // We increase both fees to ensure the new transaction replaces the old one.\n // Using floating point for calculation and converting back to BigInt at the end.\n const newPriorityFee = BigInt(Math.ceil(Number(maxPriorityFeePerGas) * GAS_INCREASE_PERCENTAGE));\n const newMaxFee = BigInt(Math.ceil(Number(maxFeePerGas) * GAS_INCREASE_PERCENTAGE));\n\n // 5. Resubmit the transaction with the same details but higher gas fees.\n return await sendTransaction(config, {\n to: to as Hex,\n value: BigInt(value),\n data: (input as Hex) || '0x',\n chainId: chainId as number,\n nonce: 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 for easier debugging.\n throw new Error(`Failed to speed up transaction: ${errorMessage}`);\n }\n}\n","/**\n * @file This file contains the factory function for creating the EVM (Ethereum Virtual Machine) transaction adapter.\n * This adapter encapsulates all the logic required to interact with EVM-based chains using wagmi.\n */\n\nimport { Transaction, TransactionAdapter, TxAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount } from '@wagmi/core';\nimport { Chain, zeroAddress } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { cancelTxAction } from '../utils/cancelTxAction';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkChainForTx } from '../utils/checkChainForTx';\nimport { checkTransactionsTracker } from '../utils/checkTransactionsTracker';\nimport { getAvatar, getName } from '../utils/ensUtils';\nimport { selectEvmTxExplorerLink } from '../utils/selectEvmTxExplorerLink';\nimport { speedUpTxAction } from '../utils/speedUpTxAction';\n\n/**\n * Creates an EVM-specific transaction adapter.\n *\n * This function acts as a constructor for the EVM adapter, bundling all the necessary\n * chain-specific utilities (like checking chain, ENS resolution, speeding up transactions, etc.)\n * into a single object that conforms to the `TxAdapter` interface.\n *\n * @template T - The application-specific transaction type.\n * @param {Config} config - The wagmi configuration object.\n * @param {Chain[]} appChains - An array of viem `Chain` objects supported by the application.\n *\n * @returns {TxAdapter<TransactionTracker, T, ActionTxKey>} The configured EVM transaction adapter.\n *\n * @throws {Error} Throws an error if the wagmi `config` is not provided.\n */\nexport function evmAdapter<T extends Transaction<TransactionTracker>>(\n config: Config,\n appChains: Chain[],\n): TxAdapter<TransactionTracker, T, ActionTxKey> {\n if (!config) {\n throw new Error('EVM adapter requires a wagmi config object.');\n }\n\n return {\n key: TransactionAdapter.EVM,\n\n // --- Core Methods ---\n getWalletInfo: () => {\n const activeWallet = getAccount(config);\n return {\n walletAddress: activeWallet.address ?? zeroAddress,\n walletType: activeWallet.connector?.name?.toLowerCase() ?? 'unknown',\n };\n },\n checkChainForTx: (chainId: string | number) => checkChainForTx(chainId as number, config),\n checkTransactionsTracker: (actionTxKey, walletType) => checkTransactionsTracker(actionTxKey, walletType),\n checkAndInitializeTrackerInStore: ({ tx, ...rest }) =>\n checkAndInitializeTrackerInStore({ tracker: tx.tracker, tx, chains: appChains, ...rest }),\n\n // --- UI & Explorer Methods ---\n getExplorerUrl: () => {\n const { chain } = getAccount(config);\n return chain?.blockExplorers?.default.url;\n },\n getExplorerTxUrl: (transactionsPool, txKey, replacedTxHash) =>\n selectEvmTxExplorerLink(transactionsPool, appChains, txKey as `0x${string}`, replacedTxHash as `0x${string}`),\n getName: (address: string) => getName(address as `0x${string}`),\n getAvatar: (name: string) => getAvatar(name),\n\n // --- Optional Actions ---\n cancelTxAction: (tx) => cancelTxAction({ config, tx }),\n speedUpTxAction: (tx) => speedUpTxAction({ config, tx }),\n retryTxAction: async ({ onClose, txKey, handleTransaction, tx }) => {\n onClose(txKey);\n\n if (!handleTransaction) {\n console.error('Retry failed: handleTransaction function is not provided.');\n return;\n }\n\n await handleTransaction({\n actionFunction: () => tx.actionFunction({ config, ...tx.payload }),\n params: tx,\n defaultTracker: TransactionTracker.Ethereum,\n });\n },\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\nconst GELATO_API_URL = 'https://relay.gelato.digital/relays/v2/supported-chains';\n\n/**\n * Checks if the Gelato Relay service supports a given chain ID.\n *\n * This function fetches the list of supported chain IDs from the Gelato API and\n * caches the result in memory for 5 minutes to reduce network requests.\n *\n * @param {number} chainId - The chain identifier to check.\n * @returns {Promise<boolean>} A promise that resolves to `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, non-expired 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 the list from the Gelato API.\n try {\n const response = await fetch(GELATO_API_URL);\n\n if (!response.ok) {\n throw new Error(`Gelato API responded with status: ${response.status}`);\n }\n\n const data = (await response.json()) as { chains: string[] };\n // The endpoint returns an array of strings, which we convert to numbers.\n const supportedChainIds = data.chains.map(Number);\n\n // 3. Update the cache with the new data and timestamp.\n cachedRelayChainIds = supportedChainIds;\n cacheTimestamp = now;\n\n return supportedChainIds.includes(chainId);\n } catch (error) {\n console.error('Failed to fetch Gelato supported chains:', error);\n\n // In case of an error, clear the cache to allow for a retry on the next call.\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n\n return false;\n }\n}\n","/**\n * @file This file contains a utility for safely retrieving the active wallet account and the viem wallet client from wagmi.\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 * This function acts as a safeguard, ensuring that a wallet is connected before\n * attempting any on-chain actions.\n *\n * @param {Config} config - The wagmi configuration object.\n *\n * @returns {{ activeWallet: GetAccountReturnType; walletClient: NonNullable<GetClientReturnType> }}\n * An object containing the connected account details and the viem Wallet Client.\n * The return types are guaranteed to be non-nullable.\n *\n * @throws {Error} Throws an error if the wallet is not connected, the address is missing,\n * or the viem client is unavailable.\n */\nexport function getActiveWalletAndClient(config: Config): {\n activeWallet: GetAccountReturnType;\n walletClient: NonNullable<GetClientReturnType>;\n} {\n const activeWallet = getWagmiAccount(config);\n const walletClient = getClient(config);\n\n // This check is a crucial guard clause to prevent downstream errors.\n if (!activeWallet.address) {\n throw new Error('getActiveWalletAndClient failed: No connected wallet address found.');\n }\n\n if (!walletClient) {\n throw new Error('getActiveWalletAndClient failed: Wallet client is unavailable.');\n }\n\n return { activeWallet, walletClient };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/utils/cancelTxAction.ts","../src/utils/createViemClient.ts","../src/trackers/evmTracker.ts","../src/trackers/gelatoTracker.ts","../src/utils/safeConstants.ts","../src/trackers/safeTracker.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkChainForTx.ts","../src/utils/checkTransactionsTracker.ts","../src/utils/ensUtils.ts","../src/utils/selectEvmTxExplorerLink.ts","../src/utils/speedUpTxAction.ts","../src/adapters/evmAdapter.ts","../src/utils/checkIsGelatoAvailable.ts","../src/utils/getActiveWalletAndClient.ts"],"names":["TransactionTracker","GAS_INCREASE_PERCENTAGE","cancelTxAction","config","tx","TransactionAdapter","nonce","maxFeePerGas","maxPriorityFeePerGas","chainId","account","getAccount","newPriorityFee","newMaxFee","sendTransaction","e","errorMessage","createViemClient","chains","chain","c","createPublicClient","http","DEFAULT_RETRY_COUNT","DEFAULT_RETRY_TIMEOUT_MS","evmTracker","params","onInitialize","onTxDetailsFetched","onSuccess","onFailure","onReplaced","retryCount","retryTimeout","waitForTransactionReceiptParams","zeroHash","client","txDetails","i","getTransaction","error","resolve","wasReplaced","receipt","waitForTransactionReceipt","replacement","evmTrackerForStore","transactionsPool","updateTxParams","onSucceedCallbacks","block","getBlock","timestamp","isSuccess","TransactionStatus","updatedTx","isGelatoTxKey","txKey","GelatoTaskState","GELATO_API_BASE_URL","GELATO_TERMINAL_FAILURE_STATES","isGelatoTxPending","gelatoStatus","gelatoFetcher","stopPolling","onIntervalTick","response","data","taskState","creationDate","dayjs","gelatoTrackerForStore","removeTxFromPool","initializePollingTracker","safeSdkOptions","gnosisSafeLinksHelper","mainnet","goerli","sepolia","polygon","arbitrum","aurora","avalanche","base","boba","bsc","celo","gnosis","optimism","polygonZkEvm","zksync","SafeTransactionServiceUrls","safeFetcher","baseUrl","primaryTxResponse","safeStatus","nonceTxsResponse","executedTx","t","safeTrackerForStore","checkAndInitializeTrackerInStore","tracker","rest","checkChainForTx","connector","activeChainId","switchChain","checkTransactionsTracker","actionTxKey","walletType","isHex","ensClient","getName","address","getEnsName","getAvatar","name","getEnsAvatar","normalize","getAddress","getEnsAddress","isEnsName","nameOrAddress","isAddress","selectEvmTxExplorerLink","replacedTxHash","selectTxByKey","safeBaseUrl","explorerUrl","hash","speedUpTxAction","from","to","value","input","evmAdapter","appChains","activeWallet","zeroAddress","onClose","handleTransaction","cachedRelayChainIds","cacheTimestamp","CACHE_DURATION_MS","GELATO_API_URL","checkIsGelatoAvailable","now","supportedChainIds","getActiveWalletAndClient","getWagmiAccount","walletClient","getClient"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @file This file defines types and enums specific to the EVM (Ethereum Virtual Machine) adapter.\n * It includes identifiers for different tracking strategies and the shape of transaction keys\n * used within the EVM ecosystem.\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 * Each tracker corresponds to a specific method of monitoring a transaction's lifecycle.\n */\nexport enum TransactionTracker {\n /** For standard on-chain EVM transactions tracked by their hash. */\n Ethereum = 'ethereum',\n /** For multi-signature transactions managed and executed via a Safe contract. */\n Safe = 'safe',\n /** For meta-transactions relayed and executed by the Gelato Network. */\n Gelato = 'gelato',\n}\n\n/**\n * A union type representing the unique identifier returned by an `actionFunction`\n * after a transaction is submitted to the network or a relay service.\n *\n * This key is crucial for the EVM adapter to determine which tracker should\n * monitor the transaction.\n *\n * It can be one of the following:\n * - A standard `0x...` transaction hash (`Hex`).\n * - A structured object from a relay service like Gelato (`GelatoTxKey`).\n */\nexport type ActionTxKey = Hex | GelatoTxKey;\n","/**\n * @file This file contains a utility function for canceling a pending EVM transaction.\n */\n\nimport { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n// A common strategy is to increase gas by at least 10% to ensure replacement.\n// We use 15% for a higher chance of success.\nconst GAS_INCREASE_PERCENTAGE = 1.15;\n\n/**\n * Cancels a pending EVM transaction by sending a new, zero-value transaction to oneself\n * with the same nonce but higher gas fees. This effectively replaces the original transaction.\n *\n * @template T - The transaction type, which must be a valid EVM transaction.\n *\n * @param {object} params - The parameters required to cancel the transaction.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The original transaction object to be canceled. It must contain the nonce and gas fee fields.\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:\n * - The transaction is not an EVM transaction.\n * - The transaction is missing required fields (`nonce`, `maxFeePerGas`, etc.).\n * - The wagmi config is not provided.\n * - No connected account is found.\n * - The `sendTransaction` call fails.\n *\n * @example\n * ```ts\n * const handleCancel = async (stuckTransaction) => {\n * try {\n * const cancelTxHash = await cancelTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Cancellation transaction sent with hash:', cancelTxHash);\n * // You should now update your state to track this new transaction.\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 // 1. Validate the transaction type\n if (tx.adapter !== TransactionAdapter.EVM) {\n throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${tx.adapter}'.`);\n }\n\n // 2. Ensure all necessary transaction details are present.\n const { nonce, maxFeePerGas, maxPriorityFeePerGas, chainId } = tx;\n\n if (nonce === undefined || !maxFeePerGas || !maxPriorityFeePerGas) {\n throw new Error(\n 'Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).',\n );\n }\n\n try {\n // 3. Verify wagmi configuration and connected account\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // 4. Calculate new gas fees.\n const newPriorityFee = BigInt(Math.ceil(Number(maxPriorityFeePerGas) * GAS_INCREASE_PERCENTAGE));\n const newMaxFee = BigInt(Math.ceil(Number(maxFeePerGas) * GAS_INCREASE_PERCENTAGE));\n\n // 5. Send a zero-value transaction to your own address with the same nonce and higher gas.\n return await sendTransaction(config, {\n to: account.address,\n value: 0n,\n chainId: chainId as number,\n nonce: 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 for easier debugging.\n throw new Error(`Failed to cancel transaction: ${errorMessage}`);\n }\n}\n","/**\n * @file This file contains a utility function for creating a viem Public Client.\n */\n\nimport { createPublicClient, http } from 'viem';\nimport { Chain } from 'viem/chains';\n\n/**\n * Creates a viem Public Client for a specific chain.\n *\n * This client is used for read-only interactions with the blockchain, such as fetching\n * transaction receipts or reading contract state, without needing a wallet connection.\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 *\n * @returns {import('viem').PublicClient | undefined} A viem PublicClient instance if a matching chain is found, otherwise undefined.\n * It will also log a warning to the console if the chain is not configured.\n */\nexport function createViemClient(chainId: number, chains: Chain[]): import('viem').PublicClient | undefined {\n const chain = chains.find((c) => c.id === chainId);\n\n if (chain) {\n return createPublicClient({\n chain: chain,\n transport: http(),\n });\n }\n\n // Log a warning for easier debugging if a chain configuration is missing.\n console.warn(`createViemClient: No chain configuration found for chainId ${chainId}. A client could not be created.`);\n\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 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\nconst DEFAULT_RETRY_COUNT = 10;\nconst DEFAULT_RETRY_TIMEOUT_MS = 3000;\n\n/**\n * Defines the parameters for the low-level EVM transaction tracker.\n */\nexport type EVMTrackerParams = {\n tx: Pick<Transaction<TransactionTracker>, 'chainId' | 'txKey'>;\n chains: Chain[];\n onTxDetailsFetched: (txDetails: GetTransactionReturnType) => void;\n onSuccess: (txDetails: GetTransactionReturnType, receipt: TransactionReceipt, client: Client) => Promise<void>;\n onReplaced: (replacement: ReplacementReturnType) => void;\n onFailure: (error?: unknown) => void;\n onInitialize?: () => void;\n retryCount?: number;\n retryTimeout?: number;\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 to determine the final status.\n *\n * @param {EVMTrackerParams} params - The configuration object for the tracker.\n */\nexport async function evmTracker(params: EVMTrackerParams): Promise<void> {\n const {\n tx,\n chains,\n onInitialize,\n onTxDetailsFetched,\n onSuccess,\n onFailure,\n onReplaced,\n retryCount = DEFAULT_RETRY_COUNT,\n retryTimeout = DEFAULT_RETRY_TIMEOUT_MS,\n waitForTransactionReceiptParams,\n } = params;\n\n onInitialize?.();\n\n if (tx.txKey === zeroHash) {\n return onFailure(new Error('Transaction hash cannot be the zero hash.'));\n }\n\n const client = createViemClient(tx.chainId as number, chains);\n if (!client) {\n return onFailure(new Error(`Could not create a viem client for chainId: ${tx.chainId}`));\n }\n\n let txDetails: GetTransactionReturnType | null = null;\n\n // 1. Retry loop to fetch the transaction details.\n // This handles cases where the transaction is not immediately available on the RPC node.\n for (let i = 0; i < retryCount; i++) {\n try {\n txDetails = await getTransaction(client, { hash: tx.txKey as Hex });\n onTxDetailsFetched(txDetails);\n break; // Exit loop on success\n } catch (error) {\n if (i === retryCount - 1) {\n console.error(`EVM tracker failed to fetch tx ${tx.txKey} after ${retryCount} retries:`, error);\n return onFailure(error);\n }\n await new Promise((resolve) => setTimeout(resolve, retryTimeout));\n }\n }\n\n if (!txDetails) {\n // This should theoretically not be reached if the loop completes, but it's a good safeguard.\n return onFailure(new Error('Transaction details could not be fetched.'));\n }\n\n // 2. Wait for the transaction to be mined and get the receipt.\n try {\n let wasReplaced = false;\n const receipt = await waitForTransactionReceipt(client, {\n hash: txDetails.hash,\n onReplaced: (replacement) => {\n wasReplaced = true;\n onReplaced(replacement);\n },\n ...waitForTransactionReceiptParams,\n });\n\n // If onReplaced was called, the promise resolves but we should not proceed to onSuccess.\n if (wasReplaced) {\n return;\n }\n\n // 3. Transaction is mined, call the onSuccess callback.\n await onSuccess(txDetails, receipt, client);\n } catch (error) {\n console.error(`Error waiting for receipt for tx ${tx.txKey}:`, error);\n onFailure(error);\n }\n}\n\n/**\n * A higher-level wrapper for `evmTracker` that integrates directly with the Pulsar store.\n * It provides the necessary callbacks to update a transaction's state throughout its lifecycle.\n *\n * @template T - The application-specific transaction type.\n */\nexport async function evmTrackerForStore<T extends Transaction<TransactionTracker>>(\n params: Pick<EVMTrackerParams, 'chains'> &\n Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks'\n > & { tx: T },\n) {\n const { tx, chains, transactionsPool, updateTxParams, onSucceedCallbacks } = params;\n\n return evmTracker({\n tx,\n chains,\n onInitialize: () => {\n // Set the initial hash, which is the same as the txKey for this tracker.\n updateTxParams(tx.txKey, { hash: tx.txKey as Hex });\n },\n onTxDetailsFetched: (txDetails) => {\n // Once we fetch details from the node, update the transaction with more info.\n updateTxParams(tx.txKey, {\n to: txDetails.to ?? undefined,\n input: txDetails.input,\n value: txDetails.value?.toString(),\n nonce: txDetails.nonce,\n maxFeePerGas: txDetails.maxFeePerGas?.toString(),\n maxPriorityFeePerGas: txDetails.maxPriorityFeePerGas?.toString(),\n });\n },\n onSuccess: async (txDetails, receipt, client) => {\n const block = await getBlock(client, { blockNumber: receipt.blockNumber });\n const timestamp = Number(block.timestamp);\n const isSuccess = receipt.status === 'success';\n\n updateTxParams(tx.txKey, {\n status: isSuccess ? TransactionStatus.Success : TransactionStatus.Failed,\n isError: !isSuccess,\n pending: false,\n finishedTimestamp: timestamp,\n });\n\n // After the final state update, retrieve the latest version of the transaction\n // and trigger the global success callback if applicable.\n const updatedTx = transactionsPool[tx.txKey];\n if (isSuccess && onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onReplaced: (replacement) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Replaced,\n replacedTxHash: replacement.transaction.hash,\n pending: false,\n });\n },\n onFailure: (error) => {\n updateTxParams(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 ITxTrackingStore,\n PollingTrackerConfig,\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// 1. TYPES AND TYPE GUARDS\n// =================================================================================================\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 typeof txKey === 'object' && txKey !== null && 'taskId' in txKey;\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 NotFound = 'NotFound',\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\nconst GELATO_API_BASE_URL = 'https://api.gelato.digital/tasks/status/';\n\n// =================================================================================================\n// 2. HELPER FUNCTIONS\n// =================================================================================================\n\nconst GELATO_TERMINAL_FAILURE_STATES = new Set([\n GelatoTaskState.ExecReverted,\n GelatoTaskState.Cancelled,\n GelatoTaskState.NotFound,\n]);\n\nfunction isGelatoTxPending(gelatoStatus: GelatoTaskState): boolean {\n return gelatoStatus !== GelatoTaskState.ExecSuccess && !GELATO_TERMINAL_FAILURE_STATES.has(gelatoStatus);\n}\n\n// =================================================================================================\n// 3. FETCHER IMPLEMENTATION\n// =================================================================================================\n\n/**\n * A reusable fetcher function for `initializePollingTracker` that queries the Gelato API for a task's status.\n * It handles the logic for interpreting Gelato's task states and calls the appropriate polling callbacks.\n */\nexport const gelatoFetcher: PollingTrackerConfig<\n GelatoTaskStatusResponse,\n Transaction<TransactionTracker>,\n TransactionTracker\n>['fetcher'] = async ({ tx, stopPolling, onSuccess, onFailure, onIntervalTick }) => {\n const response = await fetch(`${GELATO_API_BASE_URL}${tx.txKey}`);\n\n if (!response.ok) {\n if (response.status === 404) {\n onFailure(); // Treat 404 as a terminal failure.\n stopPolling({ withoutRemoving: true });\n return;\n }\n // For other errors, let the polling tracker's retry mechanism handle it.\n throw new Error(`Gelato API responded with status: ${response.status}`);\n }\n\n const data = (await response.json()) as GelatoTaskStatusResponse;\n const { taskState, creationDate } = data.task;\n\n onIntervalTick?.(data);\n\n // Safeguard: Stop polling for tasks that have been pending for over a day.\n if (creationDate && dayjs().diff(dayjs(creationDate), 'day') >= 1 && isGelatoTxPending(taskState)) {\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // Check for terminal states to stop the polling.\n if (taskState === GelatoTaskState.ExecSuccess) {\n onSuccess(data);\n stopPolling({ withoutRemoving: true });\n } else if (GELATO_TERMINAL_FAILURE_STATES.has(taskState)) {\n onFailure(data);\n stopPolling({ withoutRemoving: true });\n }\n};\n\n// =================================================================================================\n// 4. STORE-CONNECTED TRACKER\n// =================================================================================================\n\n/**\n * A higher-level wrapper that integrates the Gelato polling logic with the Pulsar store.\n * It uses the generic `gelatoFetcher` and provides store-specific callbacks.\n *\n * @template T - The application-specific transaction type.\n */\nexport 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 initializePollingTracker<GelatoTaskStatusResponse, T, TransactionTracker>({\n tx,\n fetcher: gelatoFetcher, // Use the exported, reusable fetcher\n removeTxFromPool,\n onSuccess: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: 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: (response) => {\n updateTxParams(tx.txKey, {\n hash: response.task.transactionHash,\n });\n },\n onFailure: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response?.task.transactionHash,\n errorMessage: response?.task.lastCheckMessage ?? 'Transaction failed or was not found.',\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 for various chains.\n */\n\nimport {\n arbitrum,\n aurora,\n avalanche,\n base,\n boba,\n bsc,\n celo,\n gnosis,\n goerli,\n mainnet,\n optimism,\n polygon,\n polygonZkEvm,\n sepolia,\n zksync,\n} 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 [polygon.id]: 'https://app.safe.global/matic:',\n [arbitrum.id]: 'https://app.safe.global/arb1:',\n [aurora.id]: 'https://app.safe.global/aurora:',\n [avalanche.id]: 'https://app.safe.global/avax:',\n [base.id]: 'https://app.safe.global/base:',\n [boba.id]: 'https://app.safe.global/boba:',\n [bsc.id]: 'https://app.safe.global/bnb:',\n [celo.id]: 'https://app.safe.global/celo:',\n [gnosis.id]: 'https://app.safe.global/gno:',\n [optimism.id]: 'https://app.safe.global/oeth:',\n [polygonZkEvm.id]: 'https://app.safe.global/zkevm:',\n [zksync.id]: 'https://app.safe.global/zksync:',\n};\n\n/**\n * A comprehensive 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 from the correct service.\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 [polygon.id]: 'https://safe-transaction-polygon.safe.global/api/v1',\n [arbitrum.id]: 'https://safe-transaction-arbitrum.safe.global/api/v1',\n [aurora.id]: 'https://safe-transaction-aurora.safe.global/api/v1',\n [avalanche.id]: 'https://safe-transaction-avalanche.safe.global/api/v1',\n [base.id]: 'https://safe-transaction-base.safe.global/api/v1',\n [boba.id]: 'https://safe-transaction-boba.safe.global/api/v1',\n [bsc.id]: 'https://safe-transaction-bsc.safe.global/api/v1',\n [celo.id]: 'https://safe-transaction-celo.safe.global/api/v1',\n [gnosis.id]: 'https://safe-transaction-gnosis-chain.safe.global/api/v1',\n [optimism.id]: 'https://safe-transaction-optimism.safe.global/api/v1',\n [polygonZkEvm.id]: 'https://safe-transaction-zkevm.safe.global/api/v1',\n [zksync.id]: 'https://safe-transaction-zksync.safe.global/api/v1',\n};\n","/**\n * @file This file implements the transaction tracking logic for Safe (formerly Gnosis 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 ITxTrackingStore,\n PollingTrackerConfig,\n Transaction,\n TransactionAdapter,\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// 1. TYPES\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: Hex | null;\n safeTxHash: Hex;\n isExecuted: boolean;\n isSuccessful: boolean | null;\n executionDate: string | null;\n submissionDate: string;\n modified: string;\n nonce: number;\n};\n\n/**\n * The response shape when querying for multiple transactions (e.g., by nonce).\n */\ntype SafeTxSameNonceResponse = {\n count: number;\n results: SafeTxStatusResponse[];\n};\n\n// =================================================================================================\n// 2. FETCHER IMPLEMENTATION\n// =================================================================================================\n\n/**\n * A reusable fetcher for `initializePollingTracker` that queries the Safe Transaction Service API.\n * It handles the complex logic of detecting executed, failed, and replaced multisig transactions.\n */\nexport const safeFetcher: PollingTrackerConfig<\n SafeTxStatusResponse,\n Transaction<TransactionTracker>,\n TransactionTracker\n>['fetcher'] = async ({ tx, stopPolling, onSuccess, onFailure, onReplaced, onIntervalTick }) => {\n const baseUrl = SafeTransactionServiceUrls[tx.chainId as number];\n if (!baseUrl) {\n throw new Error(`Safe Transaction Service URL not found for chainId: ${tx.chainId}`);\n }\n\n // 1. Fetch the status of the primary transaction.\n const primaryTxResponse = await fetch(`${baseUrl}/multisig-transactions/${tx.txKey}/`);\n if (!primaryTxResponse.ok) {\n // Treat 404 as a terminal failure (transaction is lost).\n if (primaryTxResponse.status === 404) {\n onFailure();\n stopPolling({ withoutRemoving: true });\n }\n throw new Error(`Safe API responded with status: ${primaryTxResponse.status}`);\n }\n const safeStatus = (await primaryTxResponse.json()) as SafeTxStatusResponse;\n onIntervalTick?.(safeStatus);\n\n // 2. Check if the primary transaction itself has been executed.\n if (safeStatus.isExecuted) {\n if (safeStatus.isSuccessful) {\n onSuccess(safeStatus);\n } else {\n onFailure(safeStatus);\n }\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // 3. If still pending, check for replacements.\n // This is necessary because another transaction with the same nonce might have been executed.\n const nonceTxsResponse = await fetch(`${baseUrl}/safes/${tx.from}/multisig-transactions/?nonce=${safeStatus.nonce}`);\n if (!nonceTxsResponse.ok) {\n throw new Error(`Safe API (nonce check) responded with status: ${nonceTxsResponse.status}`);\n }\n const sameNonceTxs = (await nonceTxsResponse.json()) as SafeTxSameNonceResponse;\n const executedTx = sameNonceTxs.results.find((t) => t.isExecuted);\n\n if (executedTx) {\n // If an executed transaction exists and it's not ours, our transaction was replaced.\n onReplaced?.(executedTx);\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // 4. Safeguard: Stop polling for very old pending transactions.\n if (dayjs().diff(dayjs(safeStatus.submissionDate), 'day') >= 1) {\n stopPolling({ withoutRemoving: true });\n }\n};\n\n// =================================================================================================\n// 3. STORE-CONNECTED TRACKER\n// =================================================================================================\n\n/**\n * A higher-level wrapper that integrates the Safe polling logic with the Pulsar store.\n * It uses the generic `safeFetcher` and provides store-specific callbacks.\n *\n * @template T - The application-specific transaction type.\n */\nexport 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 initializePollingTracker<SafeTxStatusResponse, T, TransactionTracker>({\n tx,\n fetcher: safeFetcher,\n removeTxFromPool,\n onSuccess: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: false,\n hash: response.transactionHash ?? undefined,\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: (response) => {\n // Only update fields that might change while pending.\n updateTxParams(tx.txKey, {\n hash: response.transactionHash ?? undefined,\n });\n },\n onFailure: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response?.transactionHash ?? undefined,\n errorMessage: response ? 'Safe transaction failed or was rejected.' : 'Transaction not found.',\n finishedTimestamp: response?.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n onReplaced: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Replaced,\n pending: false,\n hash: tx.adapter === TransactionAdapter.EVM ? tx.hash : zeroHash,\n // The `replacedTxHash` is the `safeTxHash` of the transaction that was executed instead.\n replacedTxHash: response.safeTxHash ?? zeroHash,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n });\n}\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 * The parameters required to initialize a tracker.\n * @template T - The application-specific transaction type.\n */\ntype InitializeTrackerParams<T extends Transaction<TransactionTracker>> = Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n chains: Chain[];\n tx: T;\n tracker: TransactionTracker;\n};\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., standard EVM, Gelato, or Safe).\n *\n * @template T - The application-specific transaction type, extending the base `Transaction`.\n * @param {InitializeTrackerParams<T>} params - The parameters for initializing the tracker.\n * @returns {Promise<void>} A promise that resolves once the tracking process has been successfully initiated.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<TransactionTracker>>({\n tracker,\n tx,\n chains,\n ...rest\n}: InitializeTrackerParams<T>): Promise<void> {\n switch (tracker) {\n case TransactionTracker.Ethereum:\n return evmTrackerForStore({ tx, chains, ...rest });\n\n case TransactionTracker.Gelato:\n // The Gelato tracker does not need the `chains` param as it uses its own API endpoints.\n return gelatoTrackerForStore({ tx, ...rest });\n\n case TransactionTracker.Safe:\n // The Safe tracker also uses its own API endpoints.\n return safeTrackerForStore({ tx, ...rest });\n\n // The default case handles any unknown or unspecified tracker types.\n // It logs a warning and treats them as standard EVM transactions.\n default:\n console.warn(`Unknown tracker type: '${tracker}'. Falling back to default EVM tracker.`);\n return evmTrackerForStore({ tx, chains, ...rest });\n }\n}\n","/**\n * @file This file contains a utility to ensure the user's wallet is connected to the correct chain before proceeding with a transaction.\n */\n\nimport { Config, getAccount, switchChain } 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.\n *\n * This function is a crucial prerequisite for any action that requires a specific network.\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 * It rejects if the user cancels the switch or if another error occurs.\n *\n * @throws {Error} Throws a specific error if the user rejects the chain switch or if the switch fails for other reasons.\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 is on a different chain than required.\n if (connector && activeChainId !== chainId) {\n try {\n // Pause execution and wait for the user to confirm the chain switch in their wallet.\n await switchChain(config, { chainId });\n } catch (error) {\n // Provide a more specific error message based on the type of error.\n // This helps in distinguishing user rejection from other issues.\n if ((error as any).cause?.name === 'UserRejectedRequestError') {\n throw new Error('User rejected the request to switch network.');\n }\n console.error('Failed to switch network:', error);\n throw new Error('An error occurred while switching the network.');\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. It inspects\n * the key returned by the `actionFunction` and the wallet type to decide the tracking strategy.\n * The logic follows a specific priority:\n * 1. Checks for a Gelato Task ID structure.\n * 2. Checks if the wallet type indicates a Safe transaction.\n * 3. Defaults to the standard on-chain EVM hash 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', 'injected').\n *\n * @returns {{ tracker: TransactionTracker; txKey: string }} An object containing the determined tracker type and the final string-based transaction key.\n *\n * @throws {Error} Throws an error if the `actionTxKey` is not a valid Hex string after failing the Gelato check.\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 (e.g., a transaction hash or SafeTxHash).\n // This check adds robustness in case of type mismatches.\n if (!isHex(actionTxKey)) {\n throw new Error(\n `Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(\n actionTxKey,\n )}`,\n );\n }\n\n // 2. Second priority: Check if the transaction came from a Safe wallet.\n // The check is case-insensitive for robustness.\n if (walletType?.toLowerCase() === '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","/**\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 * all specifically targeting the Ethereum Mainnet where ENS is deployed.\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// A single, shared viem client for all ENS lookups.\n// ENS lookups are always performed against Ethereum Mainnet, regardless of the app's connected chain.\nconst ensClient = createViemClient(mainnet.id, [mainnet]);\n\n/**\n * Fetches the primary ENS name for a given Ethereum address from the Ethereum Mainnet.\n *\n * @param {Hex} address - The Ethereum address to look up.\n * @returns {Promise<string | null>} The ENS name if found, otherwise null.\n */\nexport const getName = async (address: Hex): Promise<string | null> => {\n if (!ensClient) return null;\n try {\n // getEnsName returns the name or null if not found.\n return await getEnsName(ensClient, { address });\n } catch (error) {\n console.error(`ENS name lookup failed for address ${address}:`, error);\n return null;\n }\n};\n\n/**\n * Fetches the avatar URL for a given ENS name from the Ethereum Mainnet.\n *\n * @param {string} name - The ENS name (e.g., 'vitalik.eth').\n * @returns {Promise<string | null>} The URL of the avatar image if found, otherwise null.\n */\nexport const getAvatar = async (name: string): Promise<string | null> => {\n if (!ensClient) return null;\n try {\n // getEnsAvatar returns the URL or null if not found.\n return await getEnsAvatar(ensClient, { name: normalize(name) });\n } catch (error) {\n console.error(`ENS avatar lookup failed for name ${name}:`, error);\n return null;\n }\n};\n\n/**\n * Fetches the Ethereum address associated with a given ENS name from the Ethereum Mainnet.\n *\n * @param {string} name - The ENS name to resolve (e.g., 'vitalik.eth').\n * @returns {Promise<Address | null>} The associated Ethereum address (lowercase) or null if not found.\n */\nexport const getAddress = async (name: string): Promise<Address | null> => {\n if (!ensClient) return null;\n try {\n const address = await getEnsAddress(ensClient, { name: normalize(name) });\n // viem returns the address or null. We ensure it's lowercase if it exists.\n return address ? (address.toLowerCase() as Address) : null;\n } catch (error) {\n console.error(`ENS address lookup failed for name ${name}:`, error);\n return null;\n }\n};\n\n/**\n * A heuristic to check if a string is likely an ENS name.\n *\n * This is not a foolproof validation but a quick check. A valid ENS name\n * must contain at least one dot and should not be a valid Ethereum address.\n *\n * @param {string} nameOrAddress - The string to check.\n * @returns {boolean} True if the string is likely an ENS name.\n *\n * @example\n * isEnsName('vitalik.eth') // true\n * isEnsName('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045') // false\n * isEnsName('notanaddress') // false (doesn't contain a dot)\n */\nexport const isEnsName = (nameOrAddress: string): boolean => {\n return nameOrAddress.includes('.') && !isAddress(nameOrAddress);\n};\n","/**\n * @file This file contains a selector utility for generating a block explorer URL for a given EVM transaction.\n */\n\nimport { 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 or Safe UI for a given transaction.\n * It handles different URL structures for standard EVM transactions and Safe multi-sig transactions.\n *\n * @template TR - The generic type for the tracker identifier.\n * @template T - The transaction type.\n *\n * @param {TransactionPool<TR, T>} transactionsPool - The entire pool of transactions from the store.\n * @param {Chain[]} chains - An array of supported chain objects, typically from `viem/chains`.\n * @param {Hex} txKey - The unique key (`txKey`) of the transaction for which to generate the link.\n * @param {Hex} [replacedTxHash] - Optional. If this is a speed-up/cancel transaction, this is the hash of the new transaction.\n *\n * @returns {string} The full URL to the transaction on the corresponding block explorer or Safe app,\n * or an empty string if the transaction or required chain configuration is 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 // Handle Safe transactions, which link to the Safe web app instead of a block explorer.\n if (tx.tracker === TransactionTracker.Safe) {\n const safeBaseUrl = gnosisSafeLinksHelper[tx.chainId as number];\n if (!safeBaseUrl) return '';\n\n return `${safeBaseUrl}${tx.from}/transactions/tx?id=multisig_${tx.from}_${tx.txKey}`;\n }\n\n // Handle standard EVM transactions.\n const chain = chains.find((c) => c.id === tx.chainId);\n const explorerUrl = chain?.blockExplorers?.default.url;\n\n if (!explorerUrl) {\n // Return empty string if the chain or its explorer URL is not configured.\n return '';\n }\n\n // Determine the correct hash to display. Prioritize the replaced hash for speed-up/cancel transactions.\n const hash = replacedTxHash || (tx.adapter === TransactionAdapter.EVM ? tx.hash : tx.txKey);\n\n if (!hash) return '';\n\n return `${explorerUrl}/tx/${hash}`;\n};\n","/**\n * @file This file contains a utility function for speeding up a pending EVM transaction.\n */\n\nimport { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n// A common strategy is to increase gas by at least 10% to ensure replacement.\n// We use 15% for a higher chance of success.\nconst GAS_INCREASE_PERCENTAGE = 1.15;\n\n/**\n * Speeds up a pending EVM transaction by resubmitting it with the same nonce but higher gas fees.\n * This function is designed to work with wagmi's configuration and actions.\n *\n * @template TR - The type of the tracker identifier.\n * @template T - The transaction type, which must be a valid EVM transaction.\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. It must contain all necessary EVM fields.\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:\n * - The transaction is not an EVM transaction.\n * - The transaction is missing required fields (`nonce`, `from`, `to`, `value`, `maxFeePerGas`, etc.).\n * - The wagmi config is not provided.\n * - No connected account is found.\n * - The `sendTransaction` call fails for any reason.\n *\n * @example\n * ```ts\n * const handleSpeedUp = async (stuckTransaction) => {\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 * // You should now update your state to track this new transaction hash.\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 // 1. Validate the transaction type\n if (tx.adapter !== TransactionAdapter.EVM) {\n throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${tx.adapter}'.`);\n }\n\n // 2. Ensure all necessary transaction details are present.\n const { nonce, from, to, value, input, maxFeePerGas, maxPriorityFeePerGas, chainId } = tx;\n\n if (nonce === undefined || !from || !to || !value || !maxFeePerGas || !maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for speed-up.');\n }\n\n try {\n // 3. Verify wagmi configuration and connected account\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // 4. Calculate new gas fees.\n // We increase both fees to ensure the new transaction replaces the old one.\n // Using floating point for calculation and converting back to BigInt at the end.\n const newPriorityFee = BigInt(Math.ceil(Number(maxPriorityFeePerGas) * GAS_INCREASE_PERCENTAGE));\n const newMaxFee = BigInt(Math.ceil(Number(maxFeePerGas) * GAS_INCREASE_PERCENTAGE));\n\n // 5. Resubmit the transaction with the same details but higher gas fees.\n return await sendTransaction(config, {\n to: to as Hex,\n value: BigInt(value),\n data: (input as Hex) || '0x',\n chainId: chainId as number,\n nonce: 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 for easier debugging.\n throw new Error(`Failed to speed up transaction: ${errorMessage}`);\n }\n}\n","/**\n * @file This file contains the factory function for creating the EVM (Ethereum Virtual Machine) transaction adapter.\n * This adapter encapsulates all the logic required to interact with EVM-based chains using wagmi.\n */\n\nimport { Transaction, TransactionAdapter, TxAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount } from '@wagmi/core';\nimport { Chain, zeroAddress } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { cancelTxAction } from '../utils/cancelTxAction';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkChainForTx } from '../utils/checkChainForTx';\nimport { checkTransactionsTracker } from '../utils/checkTransactionsTracker';\nimport { getAvatar, getName } from '../utils/ensUtils';\nimport { selectEvmTxExplorerLink } from '../utils/selectEvmTxExplorerLink';\nimport { speedUpTxAction } from '../utils/speedUpTxAction';\n\n/**\n * Creates an EVM-specific transaction adapter.\n *\n * This function acts as a constructor for the EVM adapter, bundling all the necessary\n * chain-specific utilities (like checking chain, ENS resolution, speeding up transactions, etc.)\n * into a single object that conforms to the `TxAdapter` interface.\n *\n * @template T - The application-specific transaction type.\n * @param {Config} config - The wagmi configuration object.\n * @param {Chain[]} appChains - An array of viem `Chain` objects supported by the application.\n *\n * @returns {TxAdapter<TransactionTracker, T, ActionTxKey>} The configured EVM transaction adapter.\n *\n * @throws {Error} Throws an error if the wagmi `config` is not provided.\n */\nexport function evmAdapter<T extends Transaction<TransactionTracker>>(\n config: Config,\n appChains: Chain[],\n): TxAdapter<TransactionTracker, T, ActionTxKey> {\n if (!config) {\n throw new Error('EVM adapter requires a wagmi config object.');\n }\n\n return {\n key: TransactionAdapter.EVM,\n\n // --- Core Methods ---\n getWalletInfo: () => {\n const activeWallet = getAccount(config);\n return {\n walletAddress: activeWallet.address ?? zeroAddress,\n walletType: activeWallet.connector?.name?.toLowerCase() ?? 'unknown',\n };\n },\n checkChainForTx: (chainId: string | number) => checkChainForTx(chainId as number, config),\n checkTransactionsTracker: (actionTxKey, walletType) => checkTransactionsTracker(actionTxKey, walletType),\n checkAndInitializeTrackerInStore: ({ tx, ...rest }) =>\n checkAndInitializeTrackerInStore({ tracker: tx.tracker, tx, chains: appChains, ...rest }),\n\n // --- UI & Explorer Methods ---\n getExplorerUrl: () => {\n const { chain } = getAccount(config);\n return chain?.blockExplorers?.default.url;\n },\n getExplorerTxUrl: (transactionsPool, txKey, replacedTxHash) =>\n selectEvmTxExplorerLink(transactionsPool, appChains, txKey as `0x${string}`, replacedTxHash as `0x${string}`),\n getName: (address: string) => getName(address as `0x${string}`),\n getAvatar: (name: string) => getAvatar(name),\n\n // --- Optional Actions ---\n cancelTxAction: (tx) => cancelTxAction({ config, tx }),\n speedUpTxAction: (tx) => speedUpTxAction({ config, tx }),\n retryTxAction: async ({ onClose, txKey, handleTransaction, tx }) => {\n onClose(txKey);\n\n if (!handleTransaction) {\n console.error('Retry failed: handleTransaction function is not provided.');\n return;\n }\n\n await handleTransaction({\n actionFunction: () => tx.actionFunction({ config, ...tx.payload }),\n params: tx,\n defaultTracker: TransactionTracker.Ethereum,\n });\n },\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\nconst GELATO_API_URL = 'https://relay.gelato.digital/relays/v2/supported-chains';\n\n/**\n * Checks if the Gelato Relay service supports a given chain ID.\n *\n * This function fetches the list of supported chain IDs from the Gelato API and\n * caches the result in memory for 5 minutes to reduce network requests.\n *\n * @param {number} chainId - The chain identifier to check.\n * @returns {Promise<boolean>} A promise that resolves to `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, non-expired 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 the list from the Gelato API.\n try {\n const response = await fetch(GELATO_API_URL);\n\n if (!response.ok) {\n throw new Error(`Gelato API responded with status: ${response.status}`);\n }\n\n const data = (await response.json()) as { chains: string[] };\n // The endpoint returns an array of strings, which we convert to numbers.\n const supportedChainIds = data.chains.map(Number);\n\n // 3. Update the cache with the new data and timestamp.\n cachedRelayChainIds = supportedChainIds;\n cacheTimestamp = now;\n\n return supportedChainIds.includes(chainId);\n } catch (error) {\n console.error('Failed to fetch Gelato supported chains:', error);\n\n // In case of an error, clear the cache to allow for a retry on the next call.\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n\n return false;\n }\n}\n","/**\n * @file This file contains a utility for safely retrieving the active wallet account and the viem wallet client from wagmi.\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 * This function acts as a safeguard, ensuring that a wallet is connected before\n * attempting any on-chain actions.\n *\n * @param {Config} config - The wagmi configuration object.\n *\n * @returns {{ activeWallet: GetAccountReturnType; walletClient: NonNullable<GetClientReturnType> }}\n * An object containing the connected account details and the viem Wallet Client.\n * The return types are guaranteed to be non-nullable.\n *\n * @throws {Error} Throws an error if the wallet is not connected, the address is missing,\n * or the viem client is unavailable.\n */\nexport function getActiveWalletAndClient(config: Config): {\n activeWallet: GetAccountReturnType;\n walletClient: NonNullable<GetClientReturnType>;\n} {\n const activeWallet = getWagmiAccount(config);\n const walletClient = getClient(config);\n\n // This check is a crucial guard clause to prevent downstream errors.\n if (!activeWallet.address) {\n throw new Error('getActiveWalletAndClient failed: No connected wallet address found.');\n }\n\n if (!walletClient) {\n throw new Error('getActiveWalletAndClient failed: Wallet client is unavailable.');\n }\n\n return { activeWallet, walletClient };\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {TransactionAdapter,TransactionStatus,initializePollingTracker,selectTxByKey}from'@tuwaio/pulsar-core';import {getAccount,sendTransaction,switchChain,getClient}from'@wagmi/core';import {createPublicClient,http,zeroHash,isHex,isAddress,zeroAddress}from'viem';import {getTransaction,waitForTransactionReceipt,getBlock}from'viem/actions';import h from'dayjs';import {zksync,polygonZkEvm,optimism,gnosis,celo,bsc,boba,base,avalanche,aurora,arbitrum,polygon,sepolia,goerli,mainnet}from'viem/chains';import {getEnsName,getEnsAvatar,normalize,getEnsAddress}from'viem/ens';var T=(o=>(o.Ethereum="ethereum",o.Safe="safe",o.Gelato="gelato",o))(T||{});var P=1.15;async function v({config:e,tx:r}){if(r.adapter!==TransactionAdapter.EVM)throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${r.adapter}'.`);let{nonce:t,maxFeePerGas:o,maxPriorityFeePerGas:i,chainId:a}=r;if(t===void 0||!o||!i)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).");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 s=BigInt(Math.ceil(Number(i)*P)),c=BigInt(Math.ceil(Number(o)*P));return await sendTransaction(e,{to:n.address,value:0n,chainId:a,nonce:t,maxFeePerGas:c,maxPriorityFeePerGas:s})}catch(n){let s=n instanceof Error?n.message:String(n);throw new Error(`Failed to cancel transaction: ${s}`)}}function g(e,r){let t=r.find(o=>o.id===e);if(t)return createPublicClient({chain:t,transport:http()});console.warn(`createViemClient: No chain configuration found for chainId ${e}. A client could not be created.`);}var xe=10,ge=3e3;async function ke(e){let{tx:r,chains:t,onInitialize:o,onTxDetailsFetched:i,onSuccess:a,onFailure:n,onReplaced:s,retryCount:c=xe,retryTimeout:u=ge,waitForTransactionReceiptParams:p}=e;if(o?.(),r.txKey===zeroHash)return n(new Error("Transaction hash cannot be the zero hash."));let l=g(r.chainId,t);if(!l)return n(new Error(`Could not create a viem client for chainId: ${r.chainId}`));let f=null;for(let d=0;d<c;d++)try{f=await getTransaction(l,{hash:r.txKey}),i(f);break}catch(x){if(d===c-1)return console.error(`EVM tracker failed to fetch tx ${r.txKey} after ${c} retries:`,x),n(x);await new Promise(E=>setTimeout(E,u));}if(!f)return n(new Error("Transaction details could not be fetched."));try{let d=!1,x=await waitForTransactionReceipt(l,{hash:f.hash,onReplaced:E=>{d=!0,s(E);},...p});if(d)return;await a(f,x,l);}catch(d){console.error(`Error waiting for receipt for tx ${r.txKey}:`,d),n(d);}}async function S(e){let{tx:r,chains:t,transactionsPool:o,updateTxParams:i,onSucceedCallbacks:a}=e;return ke({tx:r,chains:t,onInitialize:()=>{i(r.txKey,{hash:r.txKey});},onTxDetailsFetched:n=>{i(r.txKey,{to:n.to??void 0,input:n.input,value:n.value?.toString(),nonce:n.nonce,maxFeePerGas:n.maxFeePerGas?.toString(),maxPriorityFeePerGas:n.maxPriorityFeePerGas?.toString()});},onSuccess:async(n,s,c)=>{let u=await getBlock(c,{blockNumber:s.blockNumber}),p=Number(u.timestamp),l=s.status==="success";i(r.txKey,{status:l?TransactionStatus.Success:TransactionStatus.Failed,isError:!l,pending:false,finishedTimestamp:p});let f=o[r.txKey];l&&a&&f&&a(f);},onReplaced:n=>{i(r.txKey,{status:TransactionStatus.Replaced,replacedTxHash:n.transaction.hash,pending:false});},onFailure:n=>{i(r.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,errorMessage:n instanceof Error?n.message:"Transaction failed or could not be tracked."});}})}function R(e){return typeof e=="object"&&e!==null&&"taskId"in e}var be=(s=>(s.CheckPending="CheckPending",s.ExecPending="ExecPending",s.WaitingForConfirmation="WaitingForConfirmation",s.ExecSuccess="ExecSuccess",s.ExecReverted="ExecReverted",s.Cancelled="Cancelled",s.NotFound="NotFound",s))(be||{}),we="https://api.gelato.digital/tasks/status/",F=new Set(["ExecReverted","Cancelled","NotFound"]);function Ee(e){return e!=="ExecSuccess"&&!F.has(e)}var Se=async({tx:e,stopPolling:r,onSuccess:t,onFailure:o,onIntervalTick:i})=>{let a=await fetch(`${we}${e.txKey}`);if(!a.ok){if(a.status===404){o();return}throw new Error(`Gelato API responded with status: ${a.status}`)}let n=await a.json(),{taskState:s,creationDate:c}=n.task;if(i?.(n),c&&h().diff(h(c),"day")>=1&&Ee(s)){r({withoutRemoving:true});return}s==="ExecSuccess"?t(n):F.has(s)&&o(n);};function I({tx:e,transactionsPool:r,updateTxParams:t,onSucceedCallbacks:o,removeTxFromPool:i}){return initializePollingTracker({tx:e,fetcher:Se,removeTxFromPool:i,onSuccess:a=>{t(e.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:a.task.transactionHash,finishedTimestamp:a.task.executionDate?h(a.task.executionDate).unix():void 0});let n=r[e.txKey];o&&n&&o(n);},onIntervalTick:a=>{t(e.txKey,{hash:a.task.transactionHash});},onFailure:a=>{t(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:a?.task.transactionHash,errorMessage:a?.task.lastCheckMessage??"Transaction failed or was not found.",finishedTimestamp:a?.task.executionDate?h(a.task.executionDate).unix():void 0});}})}var bt={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},O={[mainnet.id]:"https://app.safe.global/eth:",[goerli.id]:"https://app.safe.global/gor:",[sepolia.id]:"https://app.safe.global/sep:",[polygon.id]:"https://app.safe.global/matic:",[arbitrum.id]:"https://app.safe.global/arb1:",[aurora.id]:"https://app.safe.global/aurora:",[avalanche.id]:"https://app.safe.global/avax:",[base.id]:"https://app.safe.global/base:",[boba.id]:"https://app.safe.global/boba:",[bsc.id]:"https://app.safe.global/bnb:",[celo.id]:"https://app.safe.global/celo:",[gnosis.id]:"https://app.safe.global/gno:",[optimism.id]:"https://app.safe.global/oeth:",[polygonZkEvm.id]:"https://app.safe.global/zkevm:",[zksync.id]:"https://app.safe.global/zksync:"},q={[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",[polygon.id]:"https://safe-transaction-polygon.safe.global/api/v1",[arbitrum.id]:"https://safe-transaction-arbitrum.safe.global/api/v1",[aurora.id]:"https://safe-transaction-aurora.safe.global/api/v1",[avalanche.id]:"https://safe-transaction-avalanche.safe.global/api/v1",[base.id]:"https://safe-transaction-base.safe.global/api/v1",[boba.id]:"https://safe-transaction-boba.safe.global/api/v1",[bsc.id]:"https://safe-transaction-bsc.safe.global/api/v1",[celo.id]:"https://safe-transaction-celo.safe.global/api/v1",[gnosis.id]:"https://safe-transaction-gnosis-chain.safe.global/api/v1",[optimism.id]:"https://safe-transaction-optimism.safe.global/api/v1",[polygonZkEvm.id]:"https://safe-transaction-zkevm.safe.global/api/v1",[zksync.id]:"https://safe-transaction-zksync.safe.global/api/v1"};var ve=async({tx:e,stopPolling:r,onSuccess:t,onFailure:o,onReplaced:i,onIntervalTick:a})=>{let n=q[e.chainId];if(!n)throw new Error(`Safe Transaction Service URL not found for chainId: ${e.chainId}`);let s=await fetch(`${n}/multisig-transactions/${e.txKey}/`);if(!s.ok)throw s.status===404&&o(),new Error(`Safe API responded with status: ${s.status}`);let c=await s.json();if(a?.(c),c.isExecuted){c.isSuccessful?t(c):o(c);return}let u=await fetch(`${n}/safes/${e.from}/multisig-transactions/?nonce=${c.nonce}`);if(!u.ok)throw new Error(`Safe API (nonce check) responded with status: ${u.status}`);let l=(await u.json()).results.find(f=>f.isExecuted);if(l){i?.(l);return}h().diff(h(c.submissionDate),"day")>=1&&r({withoutRemoving:true});};function J({tx:e,transactionsPool:r,updateTxParams:t,onSucceedCallbacks:o,removeTxFromPool:i}){return initializePollingTracker({tx:e,fetcher:ve,removeTxFromPool:i,onSuccess:a=>{t(e.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:a.transactionHash??void 0,finishedTimestamp:a.executionDate?h(a.executionDate).unix():void 0});let n=r[e.txKey];o&&n&&o(n);},onIntervalTick:a=>{t(e.txKey,{hash:a.transactionHash??void 0});},onFailure:a=>{t(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:a?.transactionHash??void 0,errorMessage:a?"Safe transaction failed or was rejected.":"Transaction not found.",finishedTimestamp:a?.executionDate?h(a.executionDate).unix():void 0});},onReplaced:a=>{t(e.txKey,{status:TransactionStatus.Replaced,pending:false,hash:e.adapter===TransactionAdapter.EVM?e.hash:zeroHash,replacedTxHash:a.safeTxHash??zeroHash,finishedTimestamp:a.executionDate?h(a.executionDate).unix():void 0});}})}async function Z({tracker:e,tx:r,chains:t,...o}){switch(e){case "ethereum":return S({tx:r,chains:t,...o});case "gelato":return I({tx:r,...o});case "safe":return J({tx:r,...o});default:return console.warn(`Unknown tracker type: '${e}'. Falling back to default EVM tracker.`),S({tx:r,chains:t,...o})}}async function Q(e,r){let{connector:t,chainId:o}=getAccount(r);if(t&&o!==e)try{await switchChain(r,{chainId:e});}catch(i){throw i.cause?.name==="UserRejectedRequestError"?new Error("User rejected the request to switch network."):(console.error("Failed to switch network:",i),new Error("An error occurred while switching the network."))}}function X(e,r){if(R(e))return {tracker:"gelato",txKey:e.taskId};if(!isHex(e))throw new Error(`Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(e)}`);return r?.toLowerCase()==="safe"?{tracker:"safe",txKey:e}:{tracker:"ethereum",txKey:e}}var m=g(mainnet.id,[mainnet]),re=async e=>{if(!m)return null;try{return await getEnsName(m,{address:e})}catch(r){return console.error(`ENS name lookup failed for address ${e}:`,r),null}},ae=async e=>{if(!m)return null;try{return await getEnsAvatar(m,{name:normalize(e)})}catch(r){return console.error(`ENS avatar lookup failed for name ${e}:`,r),null}},Qt=async e=>{if(!m)return null;try{let r=await getEnsAddress(m,{name:normalize(e)});return r?r.toLowerCase():null}catch(r){return console.error(`ENS address lookup failed for name ${e}:`,r),null}},Xt=e=>e.includes(".")&&!isAddress(e);var ne=(e,r,t,o)=>{let i=selectTxByKey(e,t);if(!i)return "";if(i.tracker==="safe"){let c=O[i.chainId];return c?`${c}${i.from}/transactions/tx?id=multisig_${i.from}_${i.txKey}`:""}let n=r.find(c=>c.id===i.chainId)?.blockExplorers?.default.url;if(!n)return "";let s=o||(i.adapter===TransactionAdapter.EVM?i.hash:i.txKey);return s?`${n}/tx/${s}`:""};var oe=1.15;async function ie({config:e,tx:r}){if(r.adapter!==TransactionAdapter.EVM)throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${r.adapter}'.`);let{nonce:t,from:o,to:i,value:a,input:n,maxFeePerGas:s,maxPriorityFeePerGas:c,chainId:u}=r;if(t===void 0||!o||!i||!a||!s||!c)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 l=BigInt(Math.ceil(Number(c)*oe)),f=BigInt(Math.ceil(Number(s)*oe));return await sendTransaction(e,{to:i,value:BigInt(a),data:n||"0x",chainId:u,nonce:t,maxFeePerGas:f,maxPriorityFeePerGas:l})}catch(p){let l=p instanceof Error?p.message:String(p);throw new Error(`Failed to speed up transaction: ${l}`)}}function Cr(e,r){if(!e)throw new Error("EVM adapter requires a wagmi config object.");return {key:TransactionAdapter.EVM,getWalletInfo:()=>{let t=getAccount(e);return {walletAddress:t.address??zeroAddress,walletType:t.connector?.name?.toLowerCase()??"unknown"}},checkChainForTx:t=>Q(t,e),checkTransactionsTracker:(t,o)=>X(t,o),checkAndInitializeTrackerInStore:({tx:t,...o})=>Z({tracker:t.tracker,tx:t,chains:r,...o}),getExplorerUrl:()=>{let{chain:t}=getAccount(e);return t?.blockExplorers?.default.url},getExplorerTxUrl:(t,o,i)=>ne(t,r,o,i),getName:t=>re(t),getAvatar:t=>ae(t),cancelTxAction:t=>v({config:e,tx:t}),speedUpTxAction:t=>ie({config:e,tx:t}),retryTxAction:async({onClose:t,txKey:o,handleTransaction:i,tx:a})=>{if(t(o),!i){console.error("Retry failed: handleTransaction function is not provided.");return}await i({actionFunction:()=>a.actionFunction({config:e,...a.payload}),params:a,defaultTracker:"ethereum"});}}}var b=null,w=null,Le=300*1e3,Ve="https://relay.gelato.digital/relays/v2/supported-chains";async function Fr(e){let r=Date.now();if(b&&w&&r-w<Le)return b.includes(e);try{let t=await fetch(Ve);if(!t.ok)throw new Error(`Gelato API responded with status: ${t.status}`);let i=(await t.json()).chains.map(Number);return b=i,w=r,i.includes(e)}catch(t){return console.error("Failed to fetch Gelato supported chains:",t),b=null,w=null,false}}function Mr(e){let r=getAccount(e),t=getClient(e);if(!r.address)throw new Error("getActiveWalletAndClient failed: No connected wallet address found.");if(!t)throw new Error("getActiveWalletAndClient failed: Wallet client is unavailable.");return {activeWallet:r,walletClient:t}}
|
|
2
|
-
export{
|
|
1
|
+
import {TransactionAdapter,TransactionStatus,initializePollingTracker,selectTxByKey}from'@tuwaio/pulsar-core';import {getAccount,sendTransaction,switchChain,getClient}from'@wagmi/core';import {createPublicClient,http,zeroHash,isHex,isAddress,zeroAddress}from'viem';import {getTransaction,waitForTransactionReceipt,getBlock}from'viem/actions';import h from'dayjs';import {zksync,polygonZkEvm,optimism,gnosis,celo,bsc,boba,base,avalanche,aurora,arbitrum,polygon,sepolia,goerli,mainnet}from'viem/chains';import {getEnsName,getEnsAvatar,normalize,getEnsAddress}from'viem/ens';var T=(o=>(o.Ethereum="ethereum",o.Safe="safe",o.Gelato="gelato",o))(T||{});var A=1.15;async function R({config:e,tx:t}){if(t.adapter!==TransactionAdapter.EVM)throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${t.adapter}'.`);let{nonce:r,maxFeePerGas:o,maxPriorityFeePerGas:i,chainId:a}=t;if(r===void 0||!o||!i)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).");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 s=BigInt(Math.ceil(Number(i)*A)),c=BigInt(Math.ceil(Number(o)*A));return await sendTransaction(e,{to:n.address,value:0n,chainId:a,nonce:r,maxFeePerGas:c,maxPriorityFeePerGas:s})}catch(n){let s=n instanceof Error?n.message:String(n);throw new Error(`Failed to cancel transaction: ${s}`)}}function g(e,t){let r=t.find(o=>o.id===e);if(r)return createPublicClient({chain:r,transport:http()});console.warn(`createViemClient: No chain configuration found for chainId ${e}. A client could not be created.`);}var xe=10,ge=3e3;async function ke(e){let{tx:t,chains:r,onInitialize:o,onTxDetailsFetched:i,onSuccess:a,onFailure:n,onReplaced:s,retryCount:c=xe,retryTimeout:f=ge,waitForTransactionReceiptParams:p}=e;if(o?.(),t.txKey===zeroHash)return n(new Error("Transaction hash cannot be the zero hash."));let l=g(t.chainId,r);if(!l)return n(new Error(`Could not create a viem client for chainId: ${t.chainId}`));let u=null;for(let d=0;d<c;d++)try{u=await getTransaction(l,{hash:t.txKey}),i(u);break}catch(x){if(d===c-1)return console.error(`EVM tracker failed to fetch tx ${t.txKey} after ${c} retries:`,x),n(x);await new Promise(E=>setTimeout(E,f));}if(!u)return n(new Error("Transaction details could not be fetched."));try{let d=!1,x=await waitForTransactionReceipt(l,{hash:u.hash,onReplaced:E=>{d=!0,s(E);},...p});if(d)return;await a(u,x,l);}catch(d){console.error(`Error waiting for receipt for tx ${t.txKey}:`,d),n(d);}}async function S(e){let{tx:t,chains:r,transactionsPool:o,updateTxParams:i,onSucceedCallbacks:a}=e;return ke({tx:t,chains:r,onInitialize:()=>{i(t.txKey,{hash:t.txKey});},onTxDetailsFetched:n=>{i(t.txKey,{to:n.to??void 0,input:n.input,value:n.value?.toString(),nonce:n.nonce,maxFeePerGas:n.maxFeePerGas?.toString(),maxPriorityFeePerGas:n.maxPriorityFeePerGas?.toString()});},onSuccess:async(n,s,c)=>{let f=await getBlock(c,{blockNumber:s.blockNumber}),p=Number(f.timestamp),l=s.status==="success";i(t.txKey,{status:l?TransactionStatus.Success:TransactionStatus.Failed,isError:!l,pending:false,finishedTimestamp:p});let u=o[t.txKey];l&&a&&u&&a(u);},onReplaced:n=>{i(t.txKey,{status:TransactionStatus.Replaced,replacedTxHash:n.transaction.hash,pending:false});},onFailure:n=>{i(t.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,errorMessage:n instanceof Error?n.message:"Transaction failed or could not be tracked."});}})}function C(e){return typeof e=="object"&&e!==null&&"taskId"in e}var we=(s=>(s.CheckPending="CheckPending",s.ExecPending="ExecPending",s.WaitingForConfirmation="WaitingForConfirmation",s.ExecSuccess="ExecSuccess",s.ExecReverted="ExecReverted",s.Cancelled="Cancelled",s.NotFound="NotFound",s))(we||{}),be="https://api.gelato.digital/tasks/status/",F=new Set(["ExecReverted","Cancelled","NotFound"]);function Ee(e){return e!=="ExecSuccess"&&!F.has(e)}var Se=async({tx:e,stopPolling:t,onSuccess:r,onFailure:o,onIntervalTick:i})=>{let a=await fetch(`${be}${e.txKey}`);if(!a.ok){if(a.status===404){o(),t({withoutRemoving:true});return}throw new Error(`Gelato API responded with status: ${a.status}`)}let n=await a.json(),{taskState:s,creationDate:c}=n.task;if(i?.(n),c&&h().diff(h(c),"day")>=1&&Ee(s)){t({withoutRemoving:true});return}s==="ExecSuccess"?(r(n),t({withoutRemoving:true})):F.has(s)&&(o(n),t({withoutRemoving:true}));};function I({tx:e,transactionsPool:t,updateTxParams:r,onSucceedCallbacks:o,removeTxFromPool:i}){return initializePollingTracker({tx:e,fetcher:Se,removeTxFromPool:i,onSuccess:a=>{r(e.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:a.task.transactionHash,finishedTimestamp:a.task.executionDate?h(a.task.executionDate).unix():void 0});let n=t[e.txKey];o&&n&&o(n);},onIntervalTick:a=>{r(e.txKey,{hash:a.task.transactionHash});},onFailure:a=>{r(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:a?.task.transactionHash,errorMessage:a?.task.lastCheckMessage??"Transaction failed or was not found.",finishedTimestamp:a?.task.executionDate?h(a.task.executionDate).unix():void 0});}})}var wt={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},O={[mainnet.id]:"https://app.safe.global/eth:",[goerli.id]:"https://app.safe.global/gor:",[sepolia.id]:"https://app.safe.global/sep:",[polygon.id]:"https://app.safe.global/matic:",[arbitrum.id]:"https://app.safe.global/arb1:",[aurora.id]:"https://app.safe.global/aurora:",[avalanche.id]:"https://app.safe.global/avax:",[base.id]:"https://app.safe.global/base:",[boba.id]:"https://app.safe.global/boba:",[bsc.id]:"https://app.safe.global/bnb:",[celo.id]:"https://app.safe.global/celo:",[gnosis.id]:"https://app.safe.global/gno:",[optimism.id]:"https://app.safe.global/oeth:",[polygonZkEvm.id]:"https://app.safe.global/zkevm:",[zksync.id]:"https://app.safe.global/zksync:"},q={[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",[polygon.id]:"https://safe-transaction-polygon.safe.global/api/v1",[arbitrum.id]:"https://safe-transaction-arbitrum.safe.global/api/v1",[aurora.id]:"https://safe-transaction-aurora.safe.global/api/v1",[avalanche.id]:"https://safe-transaction-avalanche.safe.global/api/v1",[base.id]:"https://safe-transaction-base.safe.global/api/v1",[boba.id]:"https://safe-transaction-boba.safe.global/api/v1",[bsc.id]:"https://safe-transaction-bsc.safe.global/api/v1",[celo.id]:"https://safe-transaction-celo.safe.global/api/v1",[gnosis.id]:"https://safe-transaction-gnosis-chain.safe.global/api/v1",[optimism.id]:"https://safe-transaction-optimism.safe.global/api/v1",[polygonZkEvm.id]:"https://safe-transaction-zkevm.safe.global/api/v1",[zksync.id]:"https://safe-transaction-zksync.safe.global/api/v1"};var Re=async({tx:e,stopPolling:t,onSuccess:r,onFailure:o,onReplaced:i,onIntervalTick:a})=>{let n=q[e.chainId];if(!n)throw new Error(`Safe Transaction Service URL not found for chainId: ${e.chainId}`);let s=await fetch(`${n}/multisig-transactions/${e.txKey}/`);if(!s.ok)throw s.status===404&&(o(),t({withoutRemoving:true})),new Error(`Safe API responded with status: ${s.status}`);let c=await s.json();if(a?.(c),c.isExecuted){c.isSuccessful?r(c):o(c),t({withoutRemoving:true});return}let f=await fetch(`${n}/safes/${e.from}/multisig-transactions/?nonce=${c.nonce}`);if(!f.ok)throw new Error(`Safe API (nonce check) responded with status: ${f.status}`);let l=(await f.json()).results.find(u=>u.isExecuted);if(l){i?.(l),t({withoutRemoving:true});return}h().diff(h(c.submissionDate),"day")>=1&&t({withoutRemoving:true});};function J({tx:e,transactionsPool:t,updateTxParams:r,onSucceedCallbacks:o,removeTxFromPool:i}){return initializePollingTracker({tx:e,fetcher:Re,removeTxFromPool:i,onSuccess:a=>{r(e.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:a.transactionHash??void 0,finishedTimestamp:a.executionDate?h(a.executionDate).unix():void 0});let n=t[e.txKey];o&&n&&o(n);},onIntervalTick:a=>{r(e.txKey,{hash:a.transactionHash??void 0});},onFailure:a=>{r(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:a?.transactionHash??void 0,errorMessage:a?"Safe transaction failed or was rejected.":"Transaction not found.",finishedTimestamp:a?.executionDate?h(a.executionDate).unix():void 0});},onReplaced:a=>{r(e.txKey,{status:TransactionStatus.Replaced,pending:false,hash:e.adapter===TransactionAdapter.EVM?e.hash:zeroHash,replacedTxHash:a.safeTxHash??zeroHash,finishedTimestamp:a.executionDate?h(a.executionDate).unix():void 0});}})}async function Z({tracker:e,tx:t,chains:r,...o}){switch(e){case "ethereum":return S({tx:t,chains:r,...o});case "gelato":return I({tx:t,...o});case "safe":return J({tx:t,...o});default:return console.warn(`Unknown tracker type: '${e}'. Falling back to default EVM tracker.`),S({tx:t,chains:r,...o})}}async function Q(e,t){let{connector:r,chainId:o}=getAccount(t);if(r&&o!==e)try{await switchChain(t,{chainId:e});}catch(i){throw i.cause?.name==="UserRejectedRequestError"?new Error("User rejected the request to switch network."):(console.error("Failed to switch network:",i),new Error("An error occurred while switching the network."))}}function X(e,t){if(C(e))return {tracker:"gelato",txKey:e.taskId};if(!isHex(e))throw new Error(`Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(e)}`);return t?.toLowerCase()==="safe"?{tracker:"safe",txKey:e}:{tracker:"ethereum",txKey:e}}var m=g(mainnet.id,[mainnet]),re=async e=>{if(!m)return null;try{return await getEnsName(m,{address:e})}catch(t){return console.error(`ENS name lookup failed for address ${e}:`,t),null}},ae=async e=>{if(!m)return null;try{return await getEnsAvatar(m,{name:normalize(e)})}catch(t){return console.error(`ENS avatar lookup failed for name ${e}:`,t),null}},Qt=async e=>{if(!m)return null;try{let t=await getEnsAddress(m,{name:normalize(e)});return t?t.toLowerCase():null}catch(t){return console.error(`ENS address lookup failed for name ${e}:`,t),null}},Xt=e=>e.includes(".")&&!isAddress(e);var ne=(e,t,r,o)=>{let i=selectTxByKey(e,r);if(!i)return "";if(i.tracker==="safe"){let c=O[i.chainId];return c?`${c}${i.from}/transactions/tx?id=multisig_${i.from}_${i.txKey}`:""}let n=t.find(c=>c.id===i.chainId)?.blockExplorers?.default.url;if(!n)return "";let s=o||(i.adapter===TransactionAdapter.EVM?i.hash:i.txKey);return s?`${n}/tx/${s}`:""};var oe=1.15;async function ie({config:e,tx:t}){if(t.adapter!==TransactionAdapter.EVM)throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${t.adapter}'.`);let{nonce:r,from:o,to:i,value:a,input:n,maxFeePerGas:s,maxPriorityFeePerGas:c,chainId:f}=t;if(r===void 0||!o||!i||!a||!s||!c)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 l=BigInt(Math.ceil(Number(c)*oe)),u=BigInt(Math.ceil(Number(s)*oe));return await sendTransaction(e,{to:i,value:BigInt(a),data:n||"0x",chainId:f,nonce:r,maxFeePerGas:u,maxPriorityFeePerGas:l})}catch(p){let l=p instanceof Error?p.message:String(p);throw new Error(`Failed to speed up transaction: ${l}`)}}function Pr(e,t){if(!e)throw new Error("EVM adapter requires a wagmi config object.");return {key:TransactionAdapter.EVM,getWalletInfo:()=>{let r=getAccount(e);return {walletAddress:r.address??zeroAddress,walletType:r.connector?.name?.toLowerCase()??"unknown"}},checkChainForTx:r=>Q(r,e),checkTransactionsTracker:(r,o)=>X(r,o),checkAndInitializeTrackerInStore:({tx:r,...o})=>Z({tracker:r.tracker,tx:r,chains:t,...o}),getExplorerUrl:()=>{let{chain:r}=getAccount(e);return r?.blockExplorers?.default.url},getExplorerTxUrl:(r,o,i)=>ne(r,t,o,i),getName:r=>re(r),getAvatar:r=>ae(r),cancelTxAction:r=>R({config:e,tx:r}),speedUpTxAction:r=>ie({config:e,tx:r}),retryTxAction:async({onClose:r,txKey:o,handleTransaction:i,tx:a})=>{if(r(o),!i){console.error("Retry failed: handleTransaction function is not provided.");return}await i({actionFunction:()=>a.actionFunction({config:e,...a.payload}),params:a,defaultTracker:"ethereum"});}}}var w=null,b=null,Le=300*1e3,Ve="https://relay.gelato.digital/relays/v2/supported-chains";async function Fr(e){let t=Date.now();if(w&&b&&t-b<Le)return w.includes(e);try{let r=await fetch(Ve);if(!r.ok)throw new Error(`Gelato API responded with status: ${r.status}`);let i=(await r.json()).chains.map(Number);return w=i,b=t,i.includes(e)}catch(r){return console.error("Failed to fetch Gelato supported chains:",r),w=null,b=null,false}}function Mr(e){let t=getAccount(e),r=getClient(e);if(!t.address)throw new Error("getActiveWalletAndClient failed: No connected wallet address found.");if(!r)throw new Error("getActiveWalletAndClient failed: Wallet client is unavailable.");return {activeWallet:t,walletClient:r}}
|
|
2
|
+
export{we as GelatoTaskState,q as SafeTransactionServiceUrls,T as TransactionTracker,R as cancelTxAction,Z as checkAndInitializeTrackerInStore,Q as checkChainForTx,Fr as checkIsGelatoAvailable,X as checkTransactionsTracker,g as createViemClient,Pr as evmAdapter,ke as evmTracker,S as evmTrackerForStore,Se as gelatoFetcher,I as gelatoTrackerForStore,Mr as getActiveWalletAndClient,Qt as getAddress,ae as getAvatar,re as getName,O as gnosisSafeLinksHelper,Xt as isEnsName,C as isGelatoTxKey,Re as safeFetcher,wt as safeSdkOptions,J as safeTrackerForStore,ne as selectEvmTxExplorerLink,ie as speedUpTxAction};//# sourceMappingURL=index.mjs.map
|
|
3
3
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/utils/cancelTxAction.ts","../src/utils/createViemClient.ts","../src/trackers/evmTracker.ts","../src/trackers/gelatoTracker.ts","../src/utils/safeConstants.ts","../src/trackers/safeTracker.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkChainForTx.ts","../src/utils/checkTransactionsTracker.ts","../src/utils/ensUtils.ts","../src/utils/selectEvmTxExplorerLink.ts","../src/utils/speedUpTxAction.ts","../src/adapters/evmAdapter.ts","../src/utils/checkIsGelatoAvailable.ts","../src/utils/getActiveWalletAndClient.ts"],"names":["TransactionTracker","GAS_INCREASE_PERCENTAGE","cancelTxAction","config","tx","TransactionAdapter","nonce","maxFeePerGas","maxPriorityFeePerGas","chainId","account","getAccount","newPriorityFee","newMaxFee","sendTransaction","e","errorMessage","createViemClient","chains","chain","c","createPublicClient","http","DEFAULT_RETRY_COUNT","DEFAULT_RETRY_TIMEOUT_MS","evmTracker","params","onInitialize","onTxDetailsFetched","onSuccess","onFailure","onReplaced","retryCount","retryTimeout","waitForTransactionReceiptParams","zeroHash","client","txDetails","i","getTransaction","error","resolve","wasReplaced","receipt","waitForTransactionReceipt","replacement","evmTrackerForStore","transactionsPool","updateTxParams","onSucceedCallbacks","block","getBlock","timestamp","isSuccess","TransactionStatus","updatedTx","isGelatoTxKey","txKey","GelatoTaskState","GELATO_API_BASE_URL","GELATO_TERMINAL_FAILURE_STATES","isGelatoTxPending","gelatoStatus","gelatoFetcher","stopPolling","onIntervalTick","response","data","taskState","creationDate","dayjs","gelatoTrackerForStore","removeTxFromPool","initializePollingTracker","safeSdkOptions","gnosisSafeLinksHelper","mainnet","goerli","sepolia","polygon","arbitrum","aurora","avalanche","base","boba","bsc","celo","gnosis","optimism","polygonZkEvm","zksync","SafeTransactionServiceUrls","safeFetcher","baseUrl","primaryTxResponse","safeStatus","nonceTxsResponse","executedTx","t","safeTrackerForStore","checkAndInitializeTrackerInStore","tracker","rest","checkChainForTx","connector","activeChainId","switchChain","checkTransactionsTracker","actionTxKey","walletType","isHex","ensClient","getName","address","getEnsName","getAvatar","name","getEnsAvatar","normalize","getAddress","getEnsAddress","isEnsName","nameOrAddress","isAddress","selectEvmTxExplorerLink","replacedTxHash","selectTxByKey","safeBaseUrl","explorerUrl","hash","speedUpTxAction","from","to","value","input","evmAdapter","appChains","activeWallet","zeroAddress","onClose","handleTransaction","cachedRelayChainIds","cacheTimestamp","CACHE_DURATION_MS","GELATO_API_URL","checkIsGelatoAvailable","now","supportedChainIds","getActiveWalletAndClient","getWagmiAccount","walletClient","getClient"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @file This file defines types and enums specific to the EVM (Ethereum Virtual Machine) adapter.\n * It includes identifiers for different tracking strategies and the shape of transaction keys\n * used within the EVM ecosystem.\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 * Each tracker corresponds to a specific method of monitoring a transaction's lifecycle.\n */\nexport enum TransactionTracker {\n /** For standard on-chain EVM transactions tracked by their hash. */\n Ethereum = 'ethereum',\n /** For multi-signature transactions managed and executed via a Safe contract. */\n Safe = 'safe',\n /** For meta-transactions relayed and executed by the Gelato Network. */\n Gelato = 'gelato',\n}\n\n/**\n * A union type representing the unique identifier returned by an `actionFunction`\n * after a transaction is submitted to the network or a relay service.\n *\n * This key is crucial for the EVM adapter to determine which tracker should\n * monitor the transaction.\n *\n * It can be one of the following:\n * - A standard `0x...` transaction hash (`Hex`).\n * - A structured object from a relay service like Gelato (`GelatoTxKey`).\n */\nexport type ActionTxKey = Hex | GelatoTxKey;\n","/**\n * @file This file contains a utility function for canceling a pending EVM transaction.\n */\n\nimport { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n// A common strategy is to increase gas by at least 10% to ensure replacement.\n// We use 15% for a higher chance of success.\nconst GAS_INCREASE_PERCENTAGE = 1.15;\n\n/**\n * Cancels a pending EVM transaction by sending a new, zero-value transaction to oneself\n * with the same nonce but higher gas fees. This effectively replaces the original transaction.\n *\n * @template T - The transaction type, which must be a valid EVM transaction.\n *\n * @param {object} params - The parameters required to cancel the transaction.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The original transaction object to be canceled. It must contain the nonce and gas fee fields.\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:\n * - The transaction is not an EVM transaction.\n * - The transaction is missing required fields (`nonce`, `maxFeePerGas`, etc.).\n * - The wagmi config is not provided.\n * - No connected account is found.\n * - The `sendTransaction` call fails.\n *\n * @example\n * ```ts\n * const handleCancel = async (stuckTransaction) => {\n * try {\n * const cancelTxHash = await cancelTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Cancellation transaction sent with hash:', cancelTxHash);\n * // You should now update your state to track this new transaction.\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 // 1. Validate the transaction type\n if (tx.adapter !== TransactionAdapter.EVM) {\n throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${tx.adapter}'.`);\n }\n\n // 2. Ensure all necessary transaction details are present.\n const { nonce, maxFeePerGas, maxPriorityFeePerGas, chainId } = tx;\n\n if (nonce === undefined || !maxFeePerGas || !maxPriorityFeePerGas) {\n throw new Error(\n 'Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).',\n );\n }\n\n try {\n // 3. Verify wagmi configuration and connected account\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // 4. Calculate new gas fees.\n const newPriorityFee = BigInt(Math.ceil(Number(maxPriorityFeePerGas) * GAS_INCREASE_PERCENTAGE));\n const newMaxFee = BigInt(Math.ceil(Number(maxFeePerGas) * GAS_INCREASE_PERCENTAGE));\n\n // 5. Send a zero-value transaction to your own address with the same nonce and higher gas.\n return await sendTransaction(config, {\n to: account.address,\n value: 0n,\n chainId: chainId as number,\n nonce: 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 for easier debugging.\n throw new Error(`Failed to cancel transaction: ${errorMessage}`);\n }\n}\n","/**\n * @file This file contains a utility function for creating a viem Public Client.\n */\n\nimport { createPublicClient, http } from 'viem';\nimport { Chain } from 'viem/chains';\n\n/**\n * Creates a viem Public Client for a specific chain.\n *\n * This client is used for read-only interactions with the blockchain, such as fetching\n * transaction receipts or reading contract state, without needing a wallet connection.\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 *\n * @returns {import('viem').PublicClient | undefined} A viem PublicClient instance if a matching chain is found, otherwise undefined.\n * It will also log a warning to the console if the chain is not configured.\n */\nexport function createViemClient(chainId: number, chains: Chain[]): import('viem').PublicClient | undefined {\n const chain = chains.find((c) => c.id === chainId);\n\n if (chain) {\n return createPublicClient({\n chain: chain,\n transport: http(),\n });\n }\n\n // Log a warning for easier debugging if a chain configuration is missing.\n console.warn(`createViemClient: No chain configuration found for chainId ${chainId}. A client could not be created.`);\n\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 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\nconst DEFAULT_RETRY_COUNT = 10;\nconst DEFAULT_RETRY_TIMEOUT_MS = 3000;\n\n/**\n * Defines the parameters for the low-level EVM transaction tracker.\n */\nexport type EVMTrackerParams = {\n tx: Pick<Transaction<TransactionTracker>, 'chainId' | 'txKey'>;\n chains: Chain[];\n onTxDetailsFetched: (txDetails: GetTransactionReturnType) => void;\n onSuccess: (txDetails: GetTransactionReturnType, receipt: TransactionReceipt, client: Client) => Promise<void>;\n onReplaced: (replacement: ReplacementReturnType) => void;\n onFailure: (error?: unknown) => void;\n onInitialize?: () => void;\n retryCount?: number;\n retryTimeout?: number;\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 to determine the final status.\n *\n * @param {EVMTrackerParams} params - The configuration object for the tracker.\n */\nexport async function evmTracker(params: EVMTrackerParams): Promise<void> {\n const {\n tx,\n chains,\n onInitialize,\n onTxDetailsFetched,\n onSuccess,\n onFailure,\n onReplaced,\n retryCount = DEFAULT_RETRY_COUNT,\n retryTimeout = DEFAULT_RETRY_TIMEOUT_MS,\n waitForTransactionReceiptParams,\n } = params;\n\n onInitialize?.();\n\n if (tx.txKey === zeroHash) {\n return onFailure(new Error('Transaction hash cannot be the zero hash.'));\n }\n\n const client = createViemClient(tx.chainId as number, chains);\n if (!client) {\n return onFailure(new Error(`Could not create a viem client for chainId: ${tx.chainId}`));\n }\n\n let txDetails: GetTransactionReturnType | null = null;\n\n // 1. Retry loop to fetch the transaction details.\n // This handles cases where the transaction is not immediately available on the RPC node.\n for (let i = 0; i < retryCount; i++) {\n try {\n txDetails = await getTransaction(client, { hash: tx.txKey as Hex });\n onTxDetailsFetched(txDetails);\n break; // Exit loop on success\n } catch (error) {\n if (i === retryCount - 1) {\n console.error(`EVM tracker failed to fetch tx ${tx.txKey} after ${retryCount} retries:`, error);\n return onFailure(error);\n }\n await new Promise((resolve) => setTimeout(resolve, retryTimeout));\n }\n }\n\n if (!txDetails) {\n // This should theoretically not be reached if the loop completes, but it's a good safeguard.\n return onFailure(new Error('Transaction details could not be fetched.'));\n }\n\n // 2. Wait for the transaction to be mined and get the receipt.\n try {\n let wasReplaced = false;\n const receipt = await waitForTransactionReceipt(client, {\n hash: txDetails.hash,\n onReplaced: (replacement) => {\n wasReplaced = true;\n onReplaced(replacement);\n },\n ...waitForTransactionReceiptParams,\n });\n\n // If onReplaced was called, the promise resolves but we should not proceed to onSuccess.\n if (wasReplaced) {\n return;\n }\n\n // 3. Transaction is mined, call the onSuccess callback.\n await onSuccess(txDetails, receipt, client);\n } catch (error) {\n console.error(`Error waiting for receipt for tx ${tx.txKey}:`, error);\n onFailure(error);\n }\n}\n\n/**\n * A higher-level wrapper for `evmTracker` that integrates directly with the Pulsar store.\n * It provides the necessary callbacks to update a transaction's state throughout its lifecycle.\n *\n * @template T - The application-specific transaction type.\n */\nexport async function evmTrackerForStore<T extends Transaction<TransactionTracker>>(\n params: Pick<EVMTrackerParams, 'chains'> &\n Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks'\n > & { tx: T },\n) {\n const { tx, chains, transactionsPool, updateTxParams, onSucceedCallbacks } = params;\n\n return evmTracker({\n tx,\n chains,\n onInitialize: () => {\n // Set the initial hash, which is the same as the txKey for this tracker.\n updateTxParams(tx.txKey, { hash: tx.txKey as Hex });\n },\n onTxDetailsFetched: (txDetails) => {\n // Once we fetch details from the node, update the transaction with more info.\n updateTxParams(tx.txKey, {\n to: txDetails.to ?? undefined,\n input: txDetails.input,\n value: txDetails.value?.toString(),\n nonce: txDetails.nonce,\n maxFeePerGas: txDetails.maxFeePerGas?.toString(),\n maxPriorityFeePerGas: txDetails.maxPriorityFeePerGas?.toString(),\n });\n },\n onSuccess: async (txDetails, receipt, client) => {\n const block = await getBlock(client, { blockNumber: receipt.blockNumber });\n const timestamp = Number(block.timestamp);\n const isSuccess = receipt.status === 'success';\n\n updateTxParams(tx.txKey, {\n status: isSuccess ? TransactionStatus.Success : TransactionStatus.Failed,\n isError: !isSuccess,\n pending: false,\n finishedTimestamp: timestamp,\n });\n\n // After the final state update, retrieve the latest version of the transaction\n // and trigger the global success callback if applicable.\n const updatedTx = transactionsPool[tx.txKey];\n if (isSuccess && onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onReplaced: (replacement) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Replaced,\n replacedTxHash: replacement.transaction.hash,\n pending: false,\n });\n },\n onFailure: (error) => {\n updateTxParams(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 ITxTrackingStore,\n PollingTrackerConfig,\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// 1. TYPES AND TYPE GUARDS\n// =================================================================================================\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 typeof txKey === 'object' && txKey !== null && 'taskId' in txKey;\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 NotFound = 'NotFound',\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\nconst GELATO_API_BASE_URL = 'https://api.gelato.digital/tasks/status/';\n\n// =================================================================================================\n// 2. HELPER FUNCTIONS\n// =================================================================================================\n\nconst GELATO_TERMINAL_FAILURE_STATES = new Set([\n GelatoTaskState.ExecReverted,\n GelatoTaskState.Cancelled,\n GelatoTaskState.NotFound,\n]);\n\nfunction isGelatoTxPending(gelatoStatus: GelatoTaskState): boolean {\n return gelatoStatus !== GelatoTaskState.ExecSuccess && !GELATO_TERMINAL_FAILURE_STATES.has(gelatoStatus);\n}\n\n// =================================================================================================\n// 3. FETCHER IMPLEMENTATION\n// =================================================================================================\n\n/**\n * A reusable fetcher function for `initializePollingTracker` that queries the Gelato API for a task's status.\n * It handles the logic for interpreting Gelato's task states and calls the appropriate polling callbacks.\n */\nexport const gelatoFetcher: PollingTrackerConfig<\n GelatoTaskStatusResponse,\n Transaction<TransactionTracker>,\n TransactionTracker\n>['fetcher'] = async ({ tx, stopPolling, onSuccess, onFailure, onIntervalTick }) => {\n const response = await fetch(`${GELATO_API_BASE_URL}${tx.txKey}`);\n\n if (!response.ok) {\n if (response.status === 404) {\n onFailure(); // Treat 404 as a terminal failure.\n return;\n }\n // For other errors, let the polling tracker's retry mechanism handle it.\n throw new Error(`Gelato API responded with status: ${response.status}`);\n }\n\n const data = (await response.json()) as GelatoTaskStatusResponse;\n const { taskState, creationDate } = data.task;\n\n onIntervalTick?.(data);\n\n // Safeguard: Stop polling for tasks that have been pending for over a day.\n if (creationDate && dayjs().diff(dayjs(creationDate), 'day') >= 1 && isGelatoTxPending(taskState)) {\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // Check for terminal states to stop the polling.\n if (taskState === GelatoTaskState.ExecSuccess) {\n onSuccess(data);\n } else if (GELATO_TERMINAL_FAILURE_STATES.has(taskState)) {\n onFailure(data);\n }\n};\n\n// =================================================================================================\n// 4. STORE-CONNECTED TRACKER\n// =================================================================================================\n\n/**\n * A higher-level wrapper that integrates the Gelato polling logic with the Pulsar store.\n * It uses the generic `gelatoFetcher` and provides store-specific callbacks.\n *\n * @template T - The application-specific transaction type.\n */\nexport 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 initializePollingTracker<GelatoTaskStatusResponse, T, TransactionTracker>({\n tx,\n fetcher: gelatoFetcher, // Use the exported, reusable fetcher\n removeTxFromPool,\n onSuccess: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: 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: (response) => {\n updateTxParams(tx.txKey, {\n hash: response.task.transactionHash,\n });\n },\n onFailure: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response?.task.transactionHash,\n errorMessage: response?.task.lastCheckMessage ?? 'Transaction failed or was not found.',\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 for various chains.\n */\n\nimport {\n arbitrum,\n aurora,\n avalanche,\n base,\n boba,\n bsc,\n celo,\n gnosis,\n goerli,\n mainnet,\n optimism,\n polygon,\n polygonZkEvm,\n sepolia,\n zksync,\n} 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 [polygon.id]: 'https://app.safe.global/matic:',\n [arbitrum.id]: 'https://app.safe.global/arb1:',\n [aurora.id]: 'https://app.safe.global/aurora:',\n [avalanche.id]: 'https://app.safe.global/avax:',\n [base.id]: 'https://app.safe.global/base:',\n [boba.id]: 'https://app.safe.global/boba:',\n [bsc.id]: 'https://app.safe.global/bnb:',\n [celo.id]: 'https://app.safe.global/celo:',\n [gnosis.id]: 'https://app.safe.global/gno:',\n [optimism.id]: 'https://app.safe.global/oeth:',\n [polygonZkEvm.id]: 'https://app.safe.global/zkevm:',\n [zksync.id]: 'https://app.safe.global/zksync:',\n};\n\n/**\n * A comprehensive 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 from the correct service.\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 [polygon.id]: 'https://safe-transaction-polygon.safe.global/api/v1',\n [arbitrum.id]: 'https://safe-transaction-arbitrum.safe.global/api/v1',\n [aurora.id]: 'https://safe-transaction-aurora.safe.global/api/v1',\n [avalanche.id]: 'https://safe-transaction-avalanche.safe.global/api/v1',\n [base.id]: 'https://safe-transaction-base.safe.global/api/v1',\n [boba.id]: 'https://safe-transaction-boba.safe.global/api/v1',\n [bsc.id]: 'https://safe-transaction-bsc.safe.global/api/v1',\n [celo.id]: 'https://safe-transaction-celo.safe.global/api/v1',\n [gnosis.id]: 'https://safe-transaction-gnosis-chain.safe.global/api/v1',\n [optimism.id]: 'https://safe-transaction-optimism.safe.global/api/v1',\n [polygonZkEvm.id]: 'https://safe-transaction-zkevm.safe.global/api/v1',\n [zksync.id]: 'https://safe-transaction-zksync.safe.global/api/v1',\n};\n","/**\n * @file This file implements the transaction tracking logic for Safe (formerly Gnosis 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 ITxTrackingStore,\n PollingTrackerConfig,\n Transaction,\n TransactionAdapter,\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// 1. TYPES\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: Hex | null;\n safeTxHash: Hex;\n isExecuted: boolean;\n isSuccessful: boolean | null;\n executionDate: string | null;\n submissionDate: string;\n modified: string;\n nonce: number;\n};\n\n/**\n * The response shape when querying for multiple transactions (e.g., by nonce).\n */\ntype SafeTxSameNonceResponse = {\n count: number;\n results: SafeTxStatusResponse[];\n};\n\n// =================================================================================================\n// 2. FETCHER IMPLEMENTATION\n// =================================================================================================\n\n/**\n * A reusable fetcher for `initializePollingTracker` that queries the Safe Transaction Service API.\n * It handles the complex logic of detecting executed, failed, and replaced multisig transactions.\n */\nexport const safeFetcher: PollingTrackerConfig<\n SafeTxStatusResponse,\n Transaction<TransactionTracker>,\n TransactionTracker\n>['fetcher'] = async ({ tx, stopPolling, onSuccess, onFailure, onReplaced, onIntervalTick }) => {\n const baseUrl = SafeTransactionServiceUrls[tx.chainId as number];\n if (!baseUrl) {\n throw new Error(`Safe Transaction Service URL not found for chainId: ${tx.chainId}`);\n }\n\n // 1. Fetch the status of the primary transaction.\n const primaryTxResponse = await fetch(`${baseUrl}/multisig-transactions/${tx.txKey}/`);\n if (!primaryTxResponse.ok) {\n // Treat 404 as a terminal failure (transaction is lost).\n if (primaryTxResponse.status === 404) {\n onFailure();\n }\n throw new Error(`Safe API responded with status: ${primaryTxResponse.status}`);\n }\n const safeStatus = (await primaryTxResponse.json()) as SafeTxStatusResponse;\n onIntervalTick?.(safeStatus);\n\n // 2. Check if the primary transaction itself has been executed.\n if (safeStatus.isExecuted) {\n if (safeStatus.isSuccessful) {\n onSuccess(safeStatus);\n } else {\n onFailure(safeStatus);\n }\n return;\n }\n\n // 3. If still pending, check for replacements.\n // This is necessary because another transaction with the same nonce might have been executed.\n const nonceTxsResponse = await fetch(`${baseUrl}/safes/${tx.from}/multisig-transactions/?nonce=${safeStatus.nonce}`);\n if (!nonceTxsResponse.ok) {\n throw new Error(`Safe API (nonce check) responded with status: ${nonceTxsResponse.status}`);\n }\n const sameNonceTxs = (await nonceTxsResponse.json()) as SafeTxSameNonceResponse;\n const executedTx = sameNonceTxs.results.find((t) => t.isExecuted);\n\n if (executedTx) {\n // If an executed transaction exists and it's not ours, our transaction was replaced.\n onReplaced?.(executedTx);\n return;\n }\n\n // 4. Safeguard: Stop polling for very old pending transactions.\n if (dayjs().diff(dayjs(safeStatus.submissionDate), 'day') >= 1) {\n stopPolling({ withoutRemoving: true });\n }\n};\n\n// =================================================================================================\n// 3. STORE-CONNECTED TRACKER\n// =================================================================================================\n\n/**\n * A higher-level wrapper that integrates the Safe polling logic with the Pulsar store.\n * It uses the generic `safeFetcher` and provides store-specific callbacks.\n *\n * @template T - The application-specific transaction type.\n */\nexport 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 initializePollingTracker<SafeTxStatusResponse, T, TransactionTracker>({\n tx,\n fetcher: safeFetcher,\n removeTxFromPool,\n onSuccess: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: false,\n hash: response.transactionHash ?? undefined,\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: (response) => {\n // Only update fields that might change while pending.\n updateTxParams(tx.txKey, {\n hash: response.transactionHash ?? undefined,\n });\n },\n onFailure: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response?.transactionHash ?? undefined,\n errorMessage: response ? 'Safe transaction failed or was rejected.' : 'Transaction not found.',\n finishedTimestamp: response?.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n onReplaced: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Replaced,\n pending: false,\n hash: tx.adapter === TransactionAdapter.EVM ? tx.hash : zeroHash,\n // The `replacedTxHash` is the `safeTxHash` of the transaction that was executed instead.\n replacedTxHash: response.safeTxHash ?? zeroHash,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n });\n}\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 * The parameters required to initialize a tracker.\n * @template T - The application-specific transaction type.\n */\ntype InitializeTrackerParams<T extends Transaction<TransactionTracker>> = Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n chains: Chain[];\n tx: T;\n tracker: TransactionTracker;\n};\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., standard EVM, Gelato, or Safe).\n *\n * @template T - The application-specific transaction type, extending the base `Transaction`.\n * @param {InitializeTrackerParams<T>} params - The parameters for initializing the tracker.\n * @returns {Promise<void>} A promise that resolves once the tracking process has been successfully initiated.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<TransactionTracker>>({\n tracker,\n tx,\n chains,\n ...rest\n}: InitializeTrackerParams<T>): Promise<void> {\n switch (tracker) {\n case TransactionTracker.Ethereum:\n return evmTrackerForStore({ tx, chains, ...rest });\n\n case TransactionTracker.Gelato:\n // The Gelato tracker does not need the `chains` param as it uses its own API endpoints.\n return gelatoTrackerForStore({ tx, ...rest });\n\n case TransactionTracker.Safe:\n // The Safe tracker also uses its own API endpoints.\n return safeTrackerForStore({ tx, ...rest });\n\n // The default case handles any unknown or unspecified tracker types.\n // It logs a warning and treats them as standard EVM transactions.\n default:\n console.warn(`Unknown tracker type: '${tracker}'. Falling back to default EVM tracker.`);\n return evmTrackerForStore({ tx, chains, ...rest });\n }\n}\n","/**\n * @file This file contains a utility to ensure the user's wallet is connected to the correct chain before proceeding with a transaction.\n */\n\nimport { Config, getAccount, switchChain } 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.\n *\n * This function is a crucial prerequisite for any action that requires a specific network.\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 * It rejects if the user cancels the switch or if another error occurs.\n *\n * @throws {Error} Throws a specific error if the user rejects the chain switch or if the switch fails for other reasons.\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 is on a different chain than required.\n if (connector && activeChainId !== chainId) {\n try {\n // Pause execution and wait for the user to confirm the chain switch in their wallet.\n await switchChain(config, { chainId });\n } catch (error) {\n // Provide a more specific error message based on the type of error.\n // This helps in distinguishing user rejection from other issues.\n if ((error as any).cause?.name === 'UserRejectedRequestError') {\n throw new Error('User rejected the request to switch network.');\n }\n console.error('Failed to switch network:', error);\n throw new Error('An error occurred while switching the network.');\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. It inspects\n * the key returned by the `actionFunction` and the wallet type to decide the tracking strategy.\n * The logic follows a specific priority:\n * 1. Checks for a Gelato Task ID structure.\n * 2. Checks if the wallet type indicates a Safe transaction.\n * 3. Defaults to the standard on-chain EVM hash 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', 'injected').\n *\n * @returns {{ tracker: TransactionTracker; txKey: string }} An object containing the determined tracker type and the final string-based transaction key.\n *\n * @throws {Error} Throws an error if the `actionTxKey` is not a valid Hex string after failing the Gelato check.\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 (e.g., a transaction hash or SafeTxHash).\n // This check adds robustness in case of type mismatches.\n if (!isHex(actionTxKey)) {\n throw new Error(\n `Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(\n actionTxKey,\n )}`,\n );\n }\n\n // 2. Second priority: Check if the transaction came from a Safe wallet.\n // The check is case-insensitive for robustness.\n if (walletType?.toLowerCase() === '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","/**\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 * all specifically targeting the Ethereum Mainnet where ENS is deployed.\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// A single, shared viem client for all ENS lookups.\n// ENS lookups are always performed against Ethereum Mainnet, regardless of the app's connected chain.\nconst ensClient = createViemClient(mainnet.id, [mainnet]);\n\n/**\n * Fetches the primary ENS name for a given Ethereum address from the Ethereum Mainnet.\n *\n * @param {Hex} address - The Ethereum address to look up.\n * @returns {Promise<string | null>} The ENS name if found, otherwise null.\n */\nexport const getName = async (address: Hex): Promise<string | null> => {\n if (!ensClient) return null;\n try {\n // getEnsName returns the name or null if not found.\n return await getEnsName(ensClient, { address });\n } catch (error) {\n console.error(`ENS name lookup failed for address ${address}:`, error);\n return null;\n }\n};\n\n/**\n * Fetches the avatar URL for a given ENS name from the Ethereum Mainnet.\n *\n * @param {string} name - The ENS name (e.g., 'vitalik.eth').\n * @returns {Promise<string | null>} The URL of the avatar image if found, otherwise null.\n */\nexport const getAvatar = async (name: string): Promise<string | null> => {\n if (!ensClient) return null;\n try {\n // getEnsAvatar returns the URL or null if not found.\n return await getEnsAvatar(ensClient, { name: normalize(name) });\n } catch (error) {\n console.error(`ENS avatar lookup failed for name ${name}:`, error);\n return null;\n }\n};\n\n/**\n * Fetches the Ethereum address associated with a given ENS name from the Ethereum Mainnet.\n *\n * @param {string} name - The ENS name to resolve (e.g., 'vitalik.eth').\n * @returns {Promise<Address | null>} The associated Ethereum address (lowercase) or null if not found.\n */\nexport const getAddress = async (name: string): Promise<Address | null> => {\n if (!ensClient) return null;\n try {\n const address = await getEnsAddress(ensClient, { name: normalize(name) });\n // viem returns the address or null. We ensure it's lowercase if it exists.\n return address ? (address.toLowerCase() as Address) : null;\n } catch (error) {\n console.error(`ENS address lookup failed for name ${name}:`, error);\n return null;\n }\n};\n\n/**\n * A heuristic to check if a string is likely an ENS name.\n *\n * This is not a foolproof validation but a quick check. A valid ENS name\n * must contain at least one dot and should not be a valid Ethereum address.\n *\n * @param {string} nameOrAddress - The string to check.\n * @returns {boolean} True if the string is likely an ENS name.\n *\n * @example\n * isEnsName('vitalik.eth') // true\n * isEnsName('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045') // false\n * isEnsName('notanaddress') // false (doesn't contain a dot)\n */\nexport const isEnsName = (nameOrAddress: string): boolean => {\n return nameOrAddress.includes('.') && !isAddress(nameOrAddress);\n};\n","/**\n * @file This file contains a selector utility for generating a block explorer URL for a given EVM transaction.\n */\n\nimport { 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 or Safe UI for a given transaction.\n * It handles different URL structures for standard EVM transactions and Safe multi-sig transactions.\n *\n * @template TR - The generic type for the tracker identifier.\n * @template T - The transaction type.\n *\n * @param {TransactionPool<TR, T>} transactionsPool - The entire pool of transactions from the store.\n * @param {Chain[]} chains - An array of supported chain objects, typically from `viem/chains`.\n * @param {Hex} txKey - The unique key (`txKey`) of the transaction for which to generate the link.\n * @param {Hex} [replacedTxHash] - Optional. If this is a speed-up/cancel transaction, this is the hash of the new transaction.\n *\n * @returns {string} The full URL to the transaction on the corresponding block explorer or Safe app,\n * or an empty string if the transaction or required chain configuration is 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 // Handle Safe transactions, which link to the Safe web app instead of a block explorer.\n if (tx.tracker === TransactionTracker.Safe) {\n const safeBaseUrl = gnosisSafeLinksHelper[tx.chainId as number];\n if (!safeBaseUrl) return '';\n\n return `${safeBaseUrl}${tx.from}/transactions/tx?id=multisig_${tx.from}_${tx.txKey}`;\n }\n\n // Handle standard EVM transactions.\n const chain = chains.find((c) => c.id === tx.chainId);\n const explorerUrl = chain?.blockExplorers?.default.url;\n\n if (!explorerUrl) {\n // Return empty string if the chain or its explorer URL is not configured.\n return '';\n }\n\n // Determine the correct hash to display. Prioritize the replaced hash for speed-up/cancel transactions.\n const hash = replacedTxHash || (tx.adapter === TransactionAdapter.EVM ? tx.hash : tx.txKey);\n\n if (!hash) return '';\n\n return `${explorerUrl}/tx/${hash}`;\n};\n","/**\n * @file This file contains a utility function for speeding up a pending EVM transaction.\n */\n\nimport { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n// A common strategy is to increase gas by at least 10% to ensure replacement.\n// We use 15% for a higher chance of success.\nconst GAS_INCREASE_PERCENTAGE = 1.15;\n\n/**\n * Speeds up a pending EVM transaction by resubmitting it with the same nonce but higher gas fees.\n * This function is designed to work with wagmi's configuration and actions.\n *\n * @template TR - The type of the tracker identifier.\n * @template T - The transaction type, which must be a valid EVM transaction.\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. It must contain all necessary EVM fields.\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:\n * - The transaction is not an EVM transaction.\n * - The transaction is missing required fields (`nonce`, `from`, `to`, `value`, `maxFeePerGas`, etc.).\n * - The wagmi config is not provided.\n * - No connected account is found.\n * - The `sendTransaction` call fails for any reason.\n *\n * @example\n * ```ts\n * const handleSpeedUp = async (stuckTransaction) => {\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 * // You should now update your state to track this new transaction hash.\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 // 1. Validate the transaction type\n if (tx.adapter !== TransactionAdapter.EVM) {\n throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${tx.adapter}'.`);\n }\n\n // 2. Ensure all necessary transaction details are present.\n const { nonce, from, to, value, input, maxFeePerGas, maxPriorityFeePerGas, chainId } = tx;\n\n if (nonce === undefined || !from || !to || !value || !maxFeePerGas || !maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for speed-up.');\n }\n\n try {\n // 3. Verify wagmi configuration and connected account\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // 4. Calculate new gas fees.\n // We increase both fees to ensure the new transaction replaces the old one.\n // Using floating point for calculation and converting back to BigInt at the end.\n const newPriorityFee = BigInt(Math.ceil(Number(maxPriorityFeePerGas) * GAS_INCREASE_PERCENTAGE));\n const newMaxFee = BigInt(Math.ceil(Number(maxFeePerGas) * GAS_INCREASE_PERCENTAGE));\n\n // 5. Resubmit the transaction with the same details but higher gas fees.\n return await sendTransaction(config, {\n to: to as Hex,\n value: BigInt(value),\n data: (input as Hex) || '0x',\n chainId: chainId as number,\n nonce: 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 for easier debugging.\n throw new Error(`Failed to speed up transaction: ${errorMessage}`);\n }\n}\n","/**\n * @file This file contains the factory function for creating the EVM (Ethereum Virtual Machine) transaction adapter.\n * This adapter encapsulates all the logic required to interact with EVM-based chains using wagmi.\n */\n\nimport { Transaction, TransactionAdapter, TxAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount } from '@wagmi/core';\nimport { Chain, zeroAddress } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { cancelTxAction } from '../utils/cancelTxAction';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkChainForTx } from '../utils/checkChainForTx';\nimport { checkTransactionsTracker } from '../utils/checkTransactionsTracker';\nimport { getAvatar, getName } from '../utils/ensUtils';\nimport { selectEvmTxExplorerLink } from '../utils/selectEvmTxExplorerLink';\nimport { speedUpTxAction } from '../utils/speedUpTxAction';\n\n/**\n * Creates an EVM-specific transaction adapter.\n *\n * This function acts as a constructor for the EVM adapter, bundling all the necessary\n * chain-specific utilities (like checking chain, ENS resolution, speeding up transactions, etc.)\n * into a single object that conforms to the `TxAdapter` interface.\n *\n * @template T - The application-specific transaction type.\n * @param {Config} config - The wagmi configuration object.\n * @param {Chain[]} appChains - An array of viem `Chain` objects supported by the application.\n *\n * @returns {TxAdapter<TransactionTracker, T, ActionTxKey>} The configured EVM transaction adapter.\n *\n * @throws {Error} Throws an error if the wagmi `config` is not provided.\n */\nexport function evmAdapter<T extends Transaction<TransactionTracker>>(\n config: Config,\n appChains: Chain[],\n): TxAdapter<TransactionTracker, T, ActionTxKey> {\n if (!config) {\n throw new Error('EVM adapter requires a wagmi config object.');\n }\n\n return {\n key: TransactionAdapter.EVM,\n\n // --- Core Methods ---\n getWalletInfo: () => {\n const activeWallet = getAccount(config);\n return {\n walletAddress: activeWallet.address ?? zeroAddress,\n walletType: activeWallet.connector?.name?.toLowerCase() ?? 'unknown',\n };\n },\n checkChainForTx: (chainId: string | number) => checkChainForTx(chainId as number, config),\n checkTransactionsTracker: (actionTxKey, walletType) => checkTransactionsTracker(actionTxKey, walletType),\n checkAndInitializeTrackerInStore: ({ tx, ...rest }) =>\n checkAndInitializeTrackerInStore({ tracker: tx.tracker, tx, chains: appChains, ...rest }),\n\n // --- UI & Explorer Methods ---\n getExplorerUrl: () => {\n const { chain } = getAccount(config);\n return chain?.blockExplorers?.default.url;\n },\n getExplorerTxUrl: (transactionsPool, txKey, replacedTxHash) =>\n selectEvmTxExplorerLink(transactionsPool, appChains, txKey as `0x${string}`, replacedTxHash as `0x${string}`),\n getName: (address: string) => getName(address as `0x${string}`),\n getAvatar: (name: string) => getAvatar(name),\n\n // --- Optional Actions ---\n cancelTxAction: (tx) => cancelTxAction({ config, tx }),\n speedUpTxAction: (tx) => speedUpTxAction({ config, tx }),\n retryTxAction: async ({ onClose, txKey, handleTransaction, tx }) => {\n onClose(txKey);\n\n if (!handleTransaction) {\n console.error('Retry failed: handleTransaction function is not provided.');\n return;\n }\n\n await handleTransaction({\n actionFunction: () => tx.actionFunction({ config, ...tx.payload }),\n params: tx,\n defaultTracker: TransactionTracker.Ethereum,\n });\n },\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\nconst GELATO_API_URL = 'https://relay.gelato.digital/relays/v2/supported-chains';\n\n/**\n * Checks if the Gelato Relay service supports a given chain ID.\n *\n * This function fetches the list of supported chain IDs from the Gelato API and\n * caches the result in memory for 5 minutes to reduce network requests.\n *\n * @param {number} chainId - The chain identifier to check.\n * @returns {Promise<boolean>} A promise that resolves to `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, non-expired 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 the list from the Gelato API.\n try {\n const response = await fetch(GELATO_API_URL);\n\n if (!response.ok) {\n throw new Error(`Gelato API responded with status: ${response.status}`);\n }\n\n const data = (await response.json()) as { chains: string[] };\n // The endpoint returns an array of strings, which we convert to numbers.\n const supportedChainIds = data.chains.map(Number);\n\n // 3. Update the cache with the new data and timestamp.\n cachedRelayChainIds = supportedChainIds;\n cacheTimestamp = now;\n\n return supportedChainIds.includes(chainId);\n } catch (error) {\n console.error('Failed to fetch Gelato supported chains:', error);\n\n // In case of an error, clear the cache to allow for a retry on the next call.\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n\n return false;\n }\n}\n","/**\n * @file This file contains a utility for safely retrieving the active wallet account and the viem wallet client from wagmi.\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 * This function acts as a safeguard, ensuring that a wallet is connected before\n * attempting any on-chain actions.\n *\n * @param {Config} config - The wagmi configuration object.\n *\n * @returns {{ activeWallet: GetAccountReturnType; walletClient: NonNullable<GetClientReturnType> }}\n * An object containing the connected account details and the viem Wallet Client.\n * The return types are guaranteed to be non-nullable.\n *\n * @throws {Error} Throws an error if the wallet is not connected, the address is missing,\n * or the viem client is unavailable.\n */\nexport function getActiveWalletAndClient(config: Config): {\n activeWallet: GetAccountReturnType;\n walletClient: NonNullable<GetClientReturnType>;\n} {\n const activeWallet = getWagmiAccount(config);\n const walletClient = getClient(config);\n\n // This check is a crucial guard clause to prevent downstream errors.\n if (!activeWallet.address) {\n throw new Error('getActiveWalletAndClient failed: No connected wallet address found.');\n }\n\n if (!walletClient) {\n throw new Error('getActiveWalletAndClient failed: Wallet client is unavailable.');\n }\n\n return { activeWallet, walletClient };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/utils/cancelTxAction.ts","../src/utils/createViemClient.ts","../src/trackers/evmTracker.ts","../src/trackers/gelatoTracker.ts","../src/utils/safeConstants.ts","../src/trackers/safeTracker.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkChainForTx.ts","../src/utils/checkTransactionsTracker.ts","../src/utils/ensUtils.ts","../src/utils/selectEvmTxExplorerLink.ts","../src/utils/speedUpTxAction.ts","../src/adapters/evmAdapter.ts","../src/utils/checkIsGelatoAvailable.ts","../src/utils/getActiveWalletAndClient.ts"],"names":["TransactionTracker","GAS_INCREASE_PERCENTAGE","cancelTxAction","config","tx","TransactionAdapter","nonce","maxFeePerGas","maxPriorityFeePerGas","chainId","account","getAccount","newPriorityFee","newMaxFee","sendTransaction","e","errorMessage","createViemClient","chains","chain","c","createPublicClient","http","DEFAULT_RETRY_COUNT","DEFAULT_RETRY_TIMEOUT_MS","evmTracker","params","onInitialize","onTxDetailsFetched","onSuccess","onFailure","onReplaced","retryCount","retryTimeout","waitForTransactionReceiptParams","zeroHash","client","txDetails","i","getTransaction","error","resolve","wasReplaced","receipt","waitForTransactionReceipt","replacement","evmTrackerForStore","transactionsPool","updateTxParams","onSucceedCallbacks","block","getBlock","timestamp","isSuccess","TransactionStatus","updatedTx","isGelatoTxKey","txKey","GelatoTaskState","GELATO_API_BASE_URL","GELATO_TERMINAL_FAILURE_STATES","isGelatoTxPending","gelatoStatus","gelatoFetcher","stopPolling","onIntervalTick","response","data","taskState","creationDate","dayjs","gelatoTrackerForStore","removeTxFromPool","initializePollingTracker","safeSdkOptions","gnosisSafeLinksHelper","mainnet","goerli","sepolia","polygon","arbitrum","aurora","avalanche","base","boba","bsc","celo","gnosis","optimism","polygonZkEvm","zksync","SafeTransactionServiceUrls","safeFetcher","baseUrl","primaryTxResponse","safeStatus","nonceTxsResponse","executedTx","t","safeTrackerForStore","checkAndInitializeTrackerInStore","tracker","rest","checkChainForTx","connector","activeChainId","switchChain","checkTransactionsTracker","actionTxKey","walletType","isHex","ensClient","getName","address","getEnsName","getAvatar","name","getEnsAvatar","normalize","getAddress","getEnsAddress","isEnsName","nameOrAddress","isAddress","selectEvmTxExplorerLink","replacedTxHash","selectTxByKey","safeBaseUrl","explorerUrl","hash","speedUpTxAction","from","to","value","input","evmAdapter","appChains","activeWallet","zeroAddress","onClose","handleTransaction","cachedRelayChainIds","cacheTimestamp","CACHE_DURATION_MS","GELATO_API_URL","checkIsGelatoAvailable","now","supportedChainIds","getActiveWalletAndClient","getWagmiAccount","walletClient","getClient"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @file This file defines types and enums specific to the EVM (Ethereum Virtual Machine) adapter.\n * It includes identifiers for different tracking strategies and the shape of transaction keys\n * used within the EVM ecosystem.\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 * Each tracker corresponds to a specific method of monitoring a transaction's lifecycle.\n */\nexport enum TransactionTracker {\n /** For standard on-chain EVM transactions tracked by their hash. */\n Ethereum = 'ethereum',\n /** For multi-signature transactions managed and executed via a Safe contract. */\n Safe = 'safe',\n /** For meta-transactions relayed and executed by the Gelato Network. */\n Gelato = 'gelato',\n}\n\n/**\n * A union type representing the unique identifier returned by an `actionFunction`\n * after a transaction is submitted to the network or a relay service.\n *\n * This key is crucial for the EVM adapter to determine which tracker should\n * monitor the transaction.\n *\n * It can be one of the following:\n * - A standard `0x...` transaction hash (`Hex`).\n * - A structured object from a relay service like Gelato (`GelatoTxKey`).\n */\nexport type ActionTxKey = Hex | GelatoTxKey;\n","/**\n * @file This file contains a utility function for canceling a pending EVM transaction.\n */\n\nimport { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n// A common strategy is to increase gas by at least 10% to ensure replacement.\n// We use 15% for a higher chance of success.\nconst GAS_INCREASE_PERCENTAGE = 1.15;\n\n/**\n * Cancels a pending EVM transaction by sending a new, zero-value transaction to oneself\n * with the same nonce but higher gas fees. This effectively replaces the original transaction.\n *\n * @template T - The transaction type, which must be a valid EVM transaction.\n *\n * @param {object} params - The parameters required to cancel the transaction.\n * @param {Config} params.config - The wagmi configuration object.\n * @param {T} params.tx - The original transaction object to be canceled. It must contain the nonce and gas fee fields.\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:\n * - The transaction is not an EVM transaction.\n * - The transaction is missing required fields (`nonce`, `maxFeePerGas`, etc.).\n * - The wagmi config is not provided.\n * - No connected account is found.\n * - The `sendTransaction` call fails.\n *\n * @example\n * ```ts\n * const handleCancel = async (stuckTransaction) => {\n * try {\n * const cancelTxHash = await cancelTxAction({\n * config: wagmiConfig,\n * tx: stuckTransaction,\n * });\n * console.log('Cancellation transaction sent with hash:', cancelTxHash);\n * // You should now update your state to track this new transaction.\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 // 1. Validate the transaction type\n if (tx.adapter !== TransactionAdapter.EVM) {\n throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${tx.adapter}'.`);\n }\n\n // 2. Ensure all necessary transaction details are present.\n const { nonce, maxFeePerGas, maxPriorityFeePerGas, chainId } = tx;\n\n if (nonce === undefined || !maxFeePerGas || !maxPriorityFeePerGas) {\n throw new Error(\n 'Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).',\n );\n }\n\n try {\n // 3. Verify wagmi configuration and connected account\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // 4. Calculate new gas fees.\n const newPriorityFee = BigInt(Math.ceil(Number(maxPriorityFeePerGas) * GAS_INCREASE_PERCENTAGE));\n const newMaxFee = BigInt(Math.ceil(Number(maxFeePerGas) * GAS_INCREASE_PERCENTAGE));\n\n // 5. Send a zero-value transaction to your own address with the same nonce and higher gas.\n return await sendTransaction(config, {\n to: account.address,\n value: 0n,\n chainId: chainId as number,\n nonce: 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 for easier debugging.\n throw new Error(`Failed to cancel transaction: ${errorMessage}`);\n }\n}\n","/**\n * @file This file contains a utility function for creating a viem Public Client.\n */\n\nimport { createPublicClient, http } from 'viem';\nimport { Chain } from 'viem/chains';\n\n/**\n * Creates a viem Public Client for a specific chain.\n *\n * This client is used for read-only interactions with the blockchain, such as fetching\n * transaction receipts or reading contract state, without needing a wallet connection.\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 *\n * @returns {import('viem').PublicClient | undefined} A viem PublicClient instance if a matching chain is found, otherwise undefined.\n * It will also log a warning to the console if the chain is not configured.\n */\nexport function createViemClient(chainId: number, chains: Chain[]): import('viem').PublicClient | undefined {\n const chain = chains.find((c) => c.id === chainId);\n\n if (chain) {\n return createPublicClient({\n chain: chain,\n transport: http(),\n });\n }\n\n // Log a warning for easier debugging if a chain configuration is missing.\n console.warn(`createViemClient: No chain configuration found for chainId ${chainId}. A client could not be created.`);\n\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 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\nconst DEFAULT_RETRY_COUNT = 10;\nconst DEFAULT_RETRY_TIMEOUT_MS = 3000;\n\n/**\n * Defines the parameters for the low-level EVM transaction tracker.\n */\nexport type EVMTrackerParams = {\n tx: Pick<Transaction<TransactionTracker>, 'chainId' | 'txKey'>;\n chains: Chain[];\n onTxDetailsFetched: (txDetails: GetTransactionReturnType) => void;\n onSuccess: (txDetails: GetTransactionReturnType, receipt: TransactionReceipt, client: Client) => Promise<void>;\n onReplaced: (replacement: ReplacementReturnType) => void;\n onFailure: (error?: unknown) => void;\n onInitialize?: () => void;\n retryCount?: number;\n retryTimeout?: number;\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 to determine the final status.\n *\n * @param {EVMTrackerParams} params - The configuration object for the tracker.\n */\nexport async function evmTracker(params: EVMTrackerParams): Promise<void> {\n const {\n tx,\n chains,\n onInitialize,\n onTxDetailsFetched,\n onSuccess,\n onFailure,\n onReplaced,\n retryCount = DEFAULT_RETRY_COUNT,\n retryTimeout = DEFAULT_RETRY_TIMEOUT_MS,\n waitForTransactionReceiptParams,\n } = params;\n\n onInitialize?.();\n\n if (tx.txKey === zeroHash) {\n return onFailure(new Error('Transaction hash cannot be the zero hash.'));\n }\n\n const client = createViemClient(tx.chainId as number, chains);\n if (!client) {\n return onFailure(new Error(`Could not create a viem client for chainId: ${tx.chainId}`));\n }\n\n let txDetails: GetTransactionReturnType | null = null;\n\n // 1. Retry loop to fetch the transaction details.\n // This handles cases where the transaction is not immediately available on the RPC node.\n for (let i = 0; i < retryCount; i++) {\n try {\n txDetails = await getTransaction(client, { hash: tx.txKey as Hex });\n onTxDetailsFetched(txDetails);\n break; // Exit loop on success\n } catch (error) {\n if (i === retryCount - 1) {\n console.error(`EVM tracker failed to fetch tx ${tx.txKey} after ${retryCount} retries:`, error);\n return onFailure(error);\n }\n await new Promise((resolve) => setTimeout(resolve, retryTimeout));\n }\n }\n\n if (!txDetails) {\n // This should theoretically not be reached if the loop completes, but it's a good safeguard.\n return onFailure(new Error('Transaction details could not be fetched.'));\n }\n\n // 2. Wait for the transaction to be mined and get the receipt.\n try {\n let wasReplaced = false;\n const receipt = await waitForTransactionReceipt(client, {\n hash: txDetails.hash,\n onReplaced: (replacement) => {\n wasReplaced = true;\n onReplaced(replacement);\n },\n ...waitForTransactionReceiptParams,\n });\n\n // If onReplaced was called, the promise resolves but we should not proceed to onSuccess.\n if (wasReplaced) {\n return;\n }\n\n // 3. Transaction is mined, call the onSuccess callback.\n await onSuccess(txDetails, receipt, client);\n } catch (error) {\n console.error(`Error waiting for receipt for tx ${tx.txKey}:`, error);\n onFailure(error);\n }\n}\n\n/**\n * A higher-level wrapper for `evmTracker` that integrates directly with the Pulsar store.\n * It provides the necessary callbacks to update a transaction's state throughout its lifecycle.\n *\n * @template T - The application-specific transaction type.\n */\nexport async function evmTrackerForStore<T extends Transaction<TransactionTracker>>(\n params: Pick<EVMTrackerParams, 'chains'> &\n Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks'\n > & { tx: T },\n) {\n const { tx, chains, transactionsPool, updateTxParams, onSucceedCallbacks } = params;\n\n return evmTracker({\n tx,\n chains,\n onInitialize: () => {\n // Set the initial hash, which is the same as the txKey for this tracker.\n updateTxParams(tx.txKey, { hash: tx.txKey as Hex });\n },\n onTxDetailsFetched: (txDetails) => {\n // Once we fetch details from the node, update the transaction with more info.\n updateTxParams(tx.txKey, {\n to: txDetails.to ?? undefined,\n input: txDetails.input,\n value: txDetails.value?.toString(),\n nonce: txDetails.nonce,\n maxFeePerGas: txDetails.maxFeePerGas?.toString(),\n maxPriorityFeePerGas: txDetails.maxPriorityFeePerGas?.toString(),\n });\n },\n onSuccess: async (txDetails, receipt, client) => {\n const block = await getBlock(client, { blockNumber: receipt.blockNumber });\n const timestamp = Number(block.timestamp);\n const isSuccess = receipt.status === 'success';\n\n updateTxParams(tx.txKey, {\n status: isSuccess ? TransactionStatus.Success : TransactionStatus.Failed,\n isError: !isSuccess,\n pending: false,\n finishedTimestamp: timestamp,\n });\n\n // After the final state update, retrieve the latest version of the transaction\n // and trigger the global success callback if applicable.\n const updatedTx = transactionsPool[tx.txKey];\n if (isSuccess && onSucceedCallbacks && updatedTx) {\n onSucceedCallbacks(updatedTx);\n }\n },\n onReplaced: (replacement) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Replaced,\n replacedTxHash: replacement.transaction.hash,\n pending: false,\n });\n },\n onFailure: (error) => {\n updateTxParams(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 ITxTrackingStore,\n PollingTrackerConfig,\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// 1. TYPES AND TYPE GUARDS\n// =================================================================================================\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 typeof txKey === 'object' && txKey !== null && 'taskId' in txKey;\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 NotFound = 'NotFound',\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\nconst GELATO_API_BASE_URL = 'https://api.gelato.digital/tasks/status/';\n\n// =================================================================================================\n// 2. HELPER FUNCTIONS\n// =================================================================================================\n\nconst GELATO_TERMINAL_FAILURE_STATES = new Set([\n GelatoTaskState.ExecReverted,\n GelatoTaskState.Cancelled,\n GelatoTaskState.NotFound,\n]);\n\nfunction isGelatoTxPending(gelatoStatus: GelatoTaskState): boolean {\n return gelatoStatus !== GelatoTaskState.ExecSuccess && !GELATO_TERMINAL_FAILURE_STATES.has(gelatoStatus);\n}\n\n// =================================================================================================\n// 3. FETCHER IMPLEMENTATION\n// =================================================================================================\n\n/**\n * A reusable fetcher function for `initializePollingTracker` that queries the Gelato API for a task's status.\n * It handles the logic for interpreting Gelato's task states and calls the appropriate polling callbacks.\n */\nexport const gelatoFetcher: PollingTrackerConfig<\n GelatoTaskStatusResponse,\n Transaction<TransactionTracker>,\n TransactionTracker\n>['fetcher'] = async ({ tx, stopPolling, onSuccess, onFailure, onIntervalTick }) => {\n const response = await fetch(`${GELATO_API_BASE_URL}${tx.txKey}`);\n\n if (!response.ok) {\n if (response.status === 404) {\n onFailure(); // Treat 404 as a terminal failure.\n stopPolling({ withoutRemoving: true });\n return;\n }\n // For other errors, let the polling tracker's retry mechanism handle it.\n throw new Error(`Gelato API responded with status: ${response.status}`);\n }\n\n const data = (await response.json()) as GelatoTaskStatusResponse;\n const { taskState, creationDate } = data.task;\n\n onIntervalTick?.(data);\n\n // Safeguard: Stop polling for tasks that have been pending for over a day.\n if (creationDate && dayjs().diff(dayjs(creationDate), 'day') >= 1 && isGelatoTxPending(taskState)) {\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // Check for terminal states to stop the polling.\n if (taskState === GelatoTaskState.ExecSuccess) {\n onSuccess(data);\n stopPolling({ withoutRemoving: true });\n } else if (GELATO_TERMINAL_FAILURE_STATES.has(taskState)) {\n onFailure(data);\n stopPolling({ withoutRemoving: true });\n }\n};\n\n// =================================================================================================\n// 4. STORE-CONNECTED TRACKER\n// =================================================================================================\n\n/**\n * A higher-level wrapper that integrates the Gelato polling logic with the Pulsar store.\n * It uses the generic `gelatoFetcher` and provides store-specific callbacks.\n *\n * @template T - The application-specific transaction type.\n */\nexport 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 initializePollingTracker<GelatoTaskStatusResponse, T, TransactionTracker>({\n tx,\n fetcher: gelatoFetcher, // Use the exported, reusable fetcher\n removeTxFromPool,\n onSuccess: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: 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: (response) => {\n updateTxParams(tx.txKey, {\n hash: response.task.transactionHash,\n });\n },\n onFailure: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response?.task.transactionHash,\n errorMessage: response?.task.lastCheckMessage ?? 'Transaction failed or was not found.',\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 for various chains.\n */\n\nimport {\n arbitrum,\n aurora,\n avalanche,\n base,\n boba,\n bsc,\n celo,\n gnosis,\n goerli,\n mainnet,\n optimism,\n polygon,\n polygonZkEvm,\n sepolia,\n zksync,\n} 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 [polygon.id]: 'https://app.safe.global/matic:',\n [arbitrum.id]: 'https://app.safe.global/arb1:',\n [aurora.id]: 'https://app.safe.global/aurora:',\n [avalanche.id]: 'https://app.safe.global/avax:',\n [base.id]: 'https://app.safe.global/base:',\n [boba.id]: 'https://app.safe.global/boba:',\n [bsc.id]: 'https://app.safe.global/bnb:',\n [celo.id]: 'https://app.safe.global/celo:',\n [gnosis.id]: 'https://app.safe.global/gno:',\n [optimism.id]: 'https://app.safe.global/oeth:',\n [polygonZkEvm.id]: 'https://app.safe.global/zkevm:',\n [zksync.id]: 'https://app.safe.global/zksync:',\n};\n\n/**\n * A comprehensive 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 from the correct service.\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 [polygon.id]: 'https://safe-transaction-polygon.safe.global/api/v1',\n [arbitrum.id]: 'https://safe-transaction-arbitrum.safe.global/api/v1',\n [aurora.id]: 'https://safe-transaction-aurora.safe.global/api/v1',\n [avalanche.id]: 'https://safe-transaction-avalanche.safe.global/api/v1',\n [base.id]: 'https://safe-transaction-base.safe.global/api/v1',\n [boba.id]: 'https://safe-transaction-boba.safe.global/api/v1',\n [bsc.id]: 'https://safe-transaction-bsc.safe.global/api/v1',\n [celo.id]: 'https://safe-transaction-celo.safe.global/api/v1',\n [gnosis.id]: 'https://safe-transaction-gnosis-chain.safe.global/api/v1',\n [optimism.id]: 'https://safe-transaction-optimism.safe.global/api/v1',\n [polygonZkEvm.id]: 'https://safe-transaction-zkevm.safe.global/api/v1',\n [zksync.id]: 'https://safe-transaction-zksync.safe.global/api/v1',\n};\n","/**\n * @file This file implements the transaction tracking logic for Safe (formerly Gnosis 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 ITxTrackingStore,\n PollingTrackerConfig,\n Transaction,\n TransactionAdapter,\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// 1. TYPES\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: Hex | null;\n safeTxHash: Hex;\n isExecuted: boolean;\n isSuccessful: boolean | null;\n executionDate: string | null;\n submissionDate: string;\n modified: string;\n nonce: number;\n};\n\n/**\n * The response shape when querying for multiple transactions (e.g., by nonce).\n */\ntype SafeTxSameNonceResponse = {\n count: number;\n results: SafeTxStatusResponse[];\n};\n\n// =================================================================================================\n// 2. FETCHER IMPLEMENTATION\n// =================================================================================================\n\n/**\n * A reusable fetcher for `initializePollingTracker` that queries the Safe Transaction Service API.\n * It handles the complex logic of detecting executed, failed, and replaced multisig transactions.\n */\nexport const safeFetcher: PollingTrackerConfig<\n SafeTxStatusResponse,\n Transaction<TransactionTracker>,\n TransactionTracker\n>['fetcher'] = async ({ tx, stopPolling, onSuccess, onFailure, onReplaced, onIntervalTick }) => {\n const baseUrl = SafeTransactionServiceUrls[tx.chainId as number];\n if (!baseUrl) {\n throw new Error(`Safe Transaction Service URL not found for chainId: ${tx.chainId}`);\n }\n\n // 1. Fetch the status of the primary transaction.\n const primaryTxResponse = await fetch(`${baseUrl}/multisig-transactions/${tx.txKey}/`);\n if (!primaryTxResponse.ok) {\n // Treat 404 as a terminal failure (transaction is lost).\n if (primaryTxResponse.status === 404) {\n onFailure();\n stopPolling({ withoutRemoving: true });\n }\n throw new Error(`Safe API responded with status: ${primaryTxResponse.status}`);\n }\n const safeStatus = (await primaryTxResponse.json()) as SafeTxStatusResponse;\n onIntervalTick?.(safeStatus);\n\n // 2. Check if the primary transaction itself has been executed.\n if (safeStatus.isExecuted) {\n if (safeStatus.isSuccessful) {\n onSuccess(safeStatus);\n } else {\n onFailure(safeStatus);\n }\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // 3. If still pending, check for replacements.\n // This is necessary because another transaction with the same nonce might have been executed.\n const nonceTxsResponse = await fetch(`${baseUrl}/safes/${tx.from}/multisig-transactions/?nonce=${safeStatus.nonce}`);\n if (!nonceTxsResponse.ok) {\n throw new Error(`Safe API (nonce check) responded with status: ${nonceTxsResponse.status}`);\n }\n const sameNonceTxs = (await nonceTxsResponse.json()) as SafeTxSameNonceResponse;\n const executedTx = sameNonceTxs.results.find((t) => t.isExecuted);\n\n if (executedTx) {\n // If an executed transaction exists and it's not ours, our transaction was replaced.\n onReplaced?.(executedTx);\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // 4. Safeguard: Stop polling for very old pending transactions.\n if (dayjs().diff(dayjs(safeStatus.submissionDate), 'day') >= 1) {\n stopPolling({ withoutRemoving: true });\n }\n};\n\n// =================================================================================================\n// 3. STORE-CONNECTED TRACKER\n// =================================================================================================\n\n/**\n * A higher-level wrapper that integrates the Safe polling logic with the Pulsar store.\n * It uses the generic `safeFetcher` and provides store-specific callbacks.\n *\n * @template T - The application-specific transaction type.\n */\nexport 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 initializePollingTracker<SafeTxStatusResponse, T, TransactionTracker>({\n tx,\n fetcher: safeFetcher,\n removeTxFromPool,\n onSuccess: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: false,\n hash: response.transactionHash ?? undefined,\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: (response) => {\n // Only update fields that might change while pending.\n updateTxParams(tx.txKey, {\n hash: response.transactionHash ?? undefined,\n });\n },\n onFailure: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n hash: response?.transactionHash ?? undefined,\n errorMessage: response ? 'Safe transaction failed or was rejected.' : 'Transaction not found.',\n finishedTimestamp: response?.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n onReplaced: (response) => {\n updateTxParams(tx.txKey, {\n status: TransactionStatus.Replaced,\n pending: false,\n hash: tx.adapter === TransactionAdapter.EVM ? tx.hash : zeroHash,\n // The `replacedTxHash` is the `safeTxHash` of the transaction that was executed instead.\n replacedTxHash: response.safeTxHash ?? zeroHash,\n finishedTimestamp: response.executionDate ? dayjs(response.executionDate).unix() : undefined,\n });\n },\n });\n}\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 * The parameters required to initialize a tracker.\n * @template T - The application-specific transaction type.\n */\ntype InitializeTrackerParams<T extends Transaction<TransactionTracker>> = Pick<\n ITxTrackingStore<TransactionTracker, T, ActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n chains: Chain[];\n tx: T;\n tracker: TransactionTracker;\n};\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., standard EVM, Gelato, or Safe).\n *\n * @template T - The application-specific transaction type, extending the base `Transaction`.\n * @param {InitializeTrackerParams<T>} params - The parameters for initializing the tracker.\n * @returns {Promise<void>} A promise that resolves once the tracking process has been successfully initiated.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<TransactionTracker>>({\n tracker,\n tx,\n chains,\n ...rest\n}: InitializeTrackerParams<T>): Promise<void> {\n switch (tracker) {\n case TransactionTracker.Ethereum:\n return evmTrackerForStore({ tx, chains, ...rest });\n\n case TransactionTracker.Gelato:\n // The Gelato tracker does not need the `chains` param as it uses its own API endpoints.\n return gelatoTrackerForStore({ tx, ...rest });\n\n case TransactionTracker.Safe:\n // The Safe tracker also uses its own API endpoints.\n return safeTrackerForStore({ tx, ...rest });\n\n // The default case handles any unknown or unspecified tracker types.\n // It logs a warning and treats them as standard EVM transactions.\n default:\n console.warn(`Unknown tracker type: '${tracker}'. Falling back to default EVM tracker.`);\n return evmTrackerForStore({ tx, chains, ...rest });\n }\n}\n","/**\n * @file This file contains a utility to ensure the user's wallet is connected to the correct chain before proceeding with a transaction.\n */\n\nimport { Config, getAccount, switchChain } 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.\n *\n * This function is a crucial prerequisite for any action that requires a specific network.\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 * It rejects if the user cancels the switch or if another error occurs.\n *\n * @throws {Error} Throws a specific error if the user rejects the chain switch or if the switch fails for other reasons.\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 is on a different chain than required.\n if (connector && activeChainId !== chainId) {\n try {\n // Pause execution and wait for the user to confirm the chain switch in their wallet.\n await switchChain(config, { chainId });\n } catch (error) {\n // Provide a more specific error message based on the type of error.\n // This helps in distinguishing user rejection from other issues.\n if ((error as any).cause?.name === 'UserRejectedRequestError') {\n throw new Error('User rejected the request to switch network.');\n }\n console.error('Failed to switch network:', error);\n throw new Error('An error occurred while switching the network.');\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. It inspects\n * the key returned by the `actionFunction` and the wallet type to decide the tracking strategy.\n * The logic follows a specific priority:\n * 1. Checks for a Gelato Task ID structure.\n * 2. Checks if the wallet type indicates a Safe transaction.\n * 3. Defaults to the standard on-chain EVM hash 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', 'injected').\n *\n * @returns {{ tracker: TransactionTracker; txKey: string }} An object containing the determined tracker type and the final string-based transaction key.\n *\n * @throws {Error} Throws an error if the `actionTxKey` is not a valid Hex string after failing the Gelato check.\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 (e.g., a transaction hash or SafeTxHash).\n // This check adds robustness in case of type mismatches.\n if (!isHex(actionTxKey)) {\n throw new Error(\n `Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(\n actionTxKey,\n )}`,\n );\n }\n\n // 2. Second priority: Check if the transaction came from a Safe wallet.\n // The check is case-insensitive for robustness.\n if (walletType?.toLowerCase() === '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","/**\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 * all specifically targeting the Ethereum Mainnet where ENS is deployed.\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// A single, shared viem client for all ENS lookups.\n// ENS lookups are always performed against Ethereum Mainnet, regardless of the app's connected chain.\nconst ensClient = createViemClient(mainnet.id, [mainnet]);\n\n/**\n * Fetches the primary ENS name for a given Ethereum address from the Ethereum Mainnet.\n *\n * @param {Hex} address - The Ethereum address to look up.\n * @returns {Promise<string | null>} The ENS name if found, otherwise null.\n */\nexport const getName = async (address: Hex): Promise<string | null> => {\n if (!ensClient) return null;\n try {\n // getEnsName returns the name or null if not found.\n return await getEnsName(ensClient, { address });\n } catch (error) {\n console.error(`ENS name lookup failed for address ${address}:`, error);\n return null;\n }\n};\n\n/**\n * Fetches the avatar URL for a given ENS name from the Ethereum Mainnet.\n *\n * @param {string} name - The ENS name (e.g., 'vitalik.eth').\n * @returns {Promise<string | null>} The URL of the avatar image if found, otherwise null.\n */\nexport const getAvatar = async (name: string): Promise<string | null> => {\n if (!ensClient) return null;\n try {\n // getEnsAvatar returns the URL or null if not found.\n return await getEnsAvatar(ensClient, { name: normalize(name) });\n } catch (error) {\n console.error(`ENS avatar lookup failed for name ${name}:`, error);\n return null;\n }\n};\n\n/**\n * Fetches the Ethereum address associated with a given ENS name from the Ethereum Mainnet.\n *\n * @param {string} name - The ENS name to resolve (e.g., 'vitalik.eth').\n * @returns {Promise<Address | null>} The associated Ethereum address (lowercase) or null if not found.\n */\nexport const getAddress = async (name: string): Promise<Address | null> => {\n if (!ensClient) return null;\n try {\n const address = await getEnsAddress(ensClient, { name: normalize(name) });\n // viem returns the address or null. We ensure it's lowercase if it exists.\n return address ? (address.toLowerCase() as Address) : null;\n } catch (error) {\n console.error(`ENS address lookup failed for name ${name}:`, error);\n return null;\n }\n};\n\n/**\n * A heuristic to check if a string is likely an ENS name.\n *\n * This is not a foolproof validation but a quick check. A valid ENS name\n * must contain at least one dot and should not be a valid Ethereum address.\n *\n * @param {string} nameOrAddress - The string to check.\n * @returns {boolean} True if the string is likely an ENS name.\n *\n * @example\n * isEnsName('vitalik.eth') // true\n * isEnsName('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045') // false\n * isEnsName('notanaddress') // false (doesn't contain a dot)\n */\nexport const isEnsName = (nameOrAddress: string): boolean => {\n return nameOrAddress.includes('.') && !isAddress(nameOrAddress);\n};\n","/**\n * @file This file contains a selector utility for generating a block explorer URL for a given EVM transaction.\n */\n\nimport { 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 or Safe UI for a given transaction.\n * It handles different URL structures for standard EVM transactions and Safe multi-sig transactions.\n *\n * @template TR - The generic type for the tracker identifier.\n * @template T - The transaction type.\n *\n * @param {TransactionPool<TR, T>} transactionsPool - The entire pool of transactions from the store.\n * @param {Chain[]} chains - An array of supported chain objects, typically from `viem/chains`.\n * @param {Hex} txKey - The unique key (`txKey`) of the transaction for which to generate the link.\n * @param {Hex} [replacedTxHash] - Optional. If this is a speed-up/cancel transaction, this is the hash of the new transaction.\n *\n * @returns {string} The full URL to the transaction on the corresponding block explorer or Safe app,\n * or an empty string if the transaction or required chain configuration is 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 // Handle Safe transactions, which link to the Safe web app instead of a block explorer.\n if (tx.tracker === TransactionTracker.Safe) {\n const safeBaseUrl = gnosisSafeLinksHelper[tx.chainId as number];\n if (!safeBaseUrl) return '';\n\n return `${safeBaseUrl}${tx.from}/transactions/tx?id=multisig_${tx.from}_${tx.txKey}`;\n }\n\n // Handle standard EVM transactions.\n const chain = chains.find((c) => c.id === tx.chainId);\n const explorerUrl = chain?.blockExplorers?.default.url;\n\n if (!explorerUrl) {\n // Return empty string if the chain or its explorer URL is not configured.\n return '';\n }\n\n // Determine the correct hash to display. Prioritize the replaced hash for speed-up/cancel transactions.\n const hash = replacedTxHash || (tx.adapter === TransactionAdapter.EVM ? tx.hash : tx.txKey);\n\n if (!hash) return '';\n\n return `${explorerUrl}/tx/${hash}`;\n};\n","/**\n * @file This file contains a utility function for speeding up a pending EVM transaction.\n */\n\nimport { Transaction, TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount, sendTransaction } from '@wagmi/core';\nimport { Hex } from 'viem';\n\n// A common strategy is to increase gas by at least 10% to ensure replacement.\n// We use 15% for a higher chance of success.\nconst GAS_INCREASE_PERCENTAGE = 1.15;\n\n/**\n * Speeds up a pending EVM transaction by resubmitting it with the same nonce but higher gas fees.\n * This function is designed to work with wagmi's configuration and actions.\n *\n * @template TR - The type of the tracker identifier.\n * @template T - The transaction type, which must be a valid EVM transaction.\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. It must contain all necessary EVM fields.\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:\n * - The transaction is not an EVM transaction.\n * - The transaction is missing required fields (`nonce`, `from`, `to`, `value`, `maxFeePerGas`, etc.).\n * - The wagmi config is not provided.\n * - No connected account is found.\n * - The `sendTransaction` call fails for any reason.\n *\n * @example\n * ```ts\n * const handleSpeedUp = async (stuckTransaction) => {\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 * // You should now update your state to track this new transaction hash.\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 // 1. Validate the transaction type\n if (tx.adapter !== TransactionAdapter.EVM) {\n throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${tx.adapter}'.`);\n }\n\n // 2. Ensure all necessary transaction details are present.\n const { nonce, from, to, value, input, maxFeePerGas, maxPriorityFeePerGas, chainId } = tx;\n\n if (nonce === undefined || !from || !to || !value || !maxFeePerGas || !maxPriorityFeePerGas) {\n throw new Error('Transaction is missing required fields for speed-up.');\n }\n\n try {\n // 3. Verify wagmi configuration and connected account\n if (!config) {\n throw new Error('Wagmi config is not provided.');\n }\n const account = getAccount(config);\n if (!account.address) {\n throw new Error('No connected account found.');\n }\n\n // 4. Calculate new gas fees.\n // We increase both fees to ensure the new transaction replaces the old one.\n // Using floating point for calculation and converting back to BigInt at the end.\n const newPriorityFee = BigInt(Math.ceil(Number(maxPriorityFeePerGas) * GAS_INCREASE_PERCENTAGE));\n const newMaxFee = BigInt(Math.ceil(Number(maxFeePerGas) * GAS_INCREASE_PERCENTAGE));\n\n // 5. Resubmit the transaction with the same details but higher gas fees.\n return await sendTransaction(config, {\n to: to as Hex,\n value: BigInt(value),\n data: (input as Hex) || '0x',\n chainId: chainId as number,\n nonce: 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 for easier debugging.\n throw new Error(`Failed to speed up transaction: ${errorMessage}`);\n }\n}\n","/**\n * @file This file contains the factory function for creating the EVM (Ethereum Virtual Machine) transaction adapter.\n * This adapter encapsulates all the logic required to interact with EVM-based chains using wagmi.\n */\n\nimport { Transaction, TransactionAdapter, TxAdapter } from '@tuwaio/pulsar-core';\nimport { Config, getAccount } from '@wagmi/core';\nimport { Chain, zeroAddress } from 'viem';\n\nimport { ActionTxKey, TransactionTracker } from '../types';\nimport { cancelTxAction } from '../utils/cancelTxAction';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkChainForTx } from '../utils/checkChainForTx';\nimport { checkTransactionsTracker } from '../utils/checkTransactionsTracker';\nimport { getAvatar, getName } from '../utils/ensUtils';\nimport { selectEvmTxExplorerLink } from '../utils/selectEvmTxExplorerLink';\nimport { speedUpTxAction } from '../utils/speedUpTxAction';\n\n/**\n * Creates an EVM-specific transaction adapter.\n *\n * This function acts as a constructor for the EVM adapter, bundling all the necessary\n * chain-specific utilities (like checking chain, ENS resolution, speeding up transactions, etc.)\n * into a single object that conforms to the `TxAdapter` interface.\n *\n * @template T - The application-specific transaction type.\n * @param {Config} config - The wagmi configuration object.\n * @param {Chain[]} appChains - An array of viem `Chain` objects supported by the application.\n *\n * @returns {TxAdapter<TransactionTracker, T, ActionTxKey>} The configured EVM transaction adapter.\n *\n * @throws {Error} Throws an error if the wagmi `config` is not provided.\n */\nexport function evmAdapter<T extends Transaction<TransactionTracker>>(\n config: Config,\n appChains: Chain[],\n): TxAdapter<TransactionTracker, T, ActionTxKey> {\n if (!config) {\n throw new Error('EVM adapter requires a wagmi config object.');\n }\n\n return {\n key: TransactionAdapter.EVM,\n\n // --- Core Methods ---\n getWalletInfo: () => {\n const activeWallet = getAccount(config);\n return {\n walletAddress: activeWallet.address ?? zeroAddress,\n walletType: activeWallet.connector?.name?.toLowerCase() ?? 'unknown',\n };\n },\n checkChainForTx: (chainId: string | number) => checkChainForTx(chainId as number, config),\n checkTransactionsTracker: (actionTxKey, walletType) => checkTransactionsTracker(actionTxKey, walletType),\n checkAndInitializeTrackerInStore: ({ tx, ...rest }) =>\n checkAndInitializeTrackerInStore({ tracker: tx.tracker, tx, chains: appChains, ...rest }),\n\n // --- UI & Explorer Methods ---\n getExplorerUrl: () => {\n const { chain } = getAccount(config);\n return chain?.blockExplorers?.default.url;\n },\n getExplorerTxUrl: (transactionsPool, txKey, replacedTxHash) =>\n selectEvmTxExplorerLink(transactionsPool, appChains, txKey as `0x${string}`, replacedTxHash as `0x${string}`),\n getName: (address: string) => getName(address as `0x${string}`),\n getAvatar: (name: string) => getAvatar(name),\n\n // --- Optional Actions ---\n cancelTxAction: (tx) => cancelTxAction({ config, tx }),\n speedUpTxAction: (tx) => speedUpTxAction({ config, tx }),\n retryTxAction: async ({ onClose, txKey, handleTransaction, tx }) => {\n onClose(txKey);\n\n if (!handleTransaction) {\n console.error('Retry failed: handleTransaction function is not provided.');\n return;\n }\n\n await handleTransaction({\n actionFunction: () => tx.actionFunction({ config, ...tx.payload }),\n params: tx,\n defaultTracker: TransactionTracker.Ethereum,\n });\n },\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\nconst GELATO_API_URL = 'https://relay.gelato.digital/relays/v2/supported-chains';\n\n/**\n * Checks if the Gelato Relay service supports a given chain ID.\n *\n * This function fetches the list of supported chain IDs from the Gelato API and\n * caches the result in memory for 5 minutes to reduce network requests.\n *\n * @param {number} chainId - The chain identifier to check.\n * @returns {Promise<boolean>} A promise that resolves to `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, non-expired 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 the list from the Gelato API.\n try {\n const response = await fetch(GELATO_API_URL);\n\n if (!response.ok) {\n throw new Error(`Gelato API responded with status: ${response.status}`);\n }\n\n const data = (await response.json()) as { chains: string[] };\n // The endpoint returns an array of strings, which we convert to numbers.\n const supportedChainIds = data.chains.map(Number);\n\n // 3. Update the cache with the new data and timestamp.\n cachedRelayChainIds = supportedChainIds;\n cacheTimestamp = now;\n\n return supportedChainIds.includes(chainId);\n } catch (error) {\n console.error('Failed to fetch Gelato supported chains:', error);\n\n // In case of an error, clear the cache to allow for a retry on the next call.\n cachedRelayChainIds = null;\n cacheTimestamp = null;\n\n return false;\n }\n}\n","/**\n * @file This file contains a utility for safely retrieving the active wallet account and the viem wallet client from wagmi.\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 * This function acts as a safeguard, ensuring that a wallet is connected before\n * attempting any on-chain actions.\n *\n * @param {Config} config - The wagmi configuration object.\n *\n * @returns {{ activeWallet: GetAccountReturnType; walletClient: NonNullable<GetClientReturnType> }}\n * An object containing the connected account details and the viem Wallet Client.\n * The return types are guaranteed to be non-nullable.\n *\n * @throws {Error} Throws an error if the wallet is not connected, the address is missing,\n * or the viem client is unavailable.\n */\nexport function getActiveWalletAndClient(config: Config): {\n activeWallet: GetAccountReturnType;\n walletClient: NonNullable<GetClientReturnType>;\n} {\n const activeWallet = getWagmiAccount(config);\n const walletClient = getClient(config);\n\n // This check is a crucial guard clause to prevent downstream errors.\n if (!activeWallet.address) {\n throw new Error('getActiveWalletAndClient failed: No connected wallet address found.');\n }\n\n if (!walletClient) {\n throw new Error('getActiveWalletAndClient failed: Wallet client is unavailable.');\n }\n\n return { activeWallet, walletClient };\n}\n"]}
|