@tuwaio/pulsar-evm 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,17 +12,17 @@ An advanced toolkit for the Pulsar Engine that adds comprehensive support for tr
12
12
 
13
13
  This package is a powerful, official adapter for `@tuwaio/pulsar-core`. It contains all the necessary logic to interact with EVM-compatible blockchains, acting as the primary logic provider for most dApps.
14
14
 
15
- While its main export is the `evmAdapter`, it also includes a suite of standalone trackers, actions, and utilities that can be used for advanced or custom implementations.
15
+ While its main export is the `pulsarEvmAdapter`, it also includes a suite of standalone trackers, actions, and utilities that can be used for advanced or custom implementations.
16
16
 
17
17
  ---
18
18
 
19
19
  ## ✨ Core Features
20
20
 
21
- - **🔌 Simple Integration:** A single `evmAdapter` factory function to easily plug full EVM support into `@tuwaio/pulsar-core`.
21
+ - **🔌 Simple Integration:** A single `pulsarEvmAdapter` factory function to easily plug full EVM support into `@tuwaio/pulsar-core`.
22
22
  - **🎯 Multi-Tracker Support:** Provides distinct, optimized trackers for:
23
- - **Standard EVM Transactions** (via transaction hash polling `viem`).
24
- - **Safe (formerly Gnosis Safe)** Multisig Transactions (via the Safe Transaction Service API).
25
- - **Gelato Relay** Meta-Transactions (via the Gelato API).
23
+ - **Standard EVM Transactions** (via `evmTracker` and `viem`).
24
+ - **Safe (formerly Gnosis Safe)** Multisig Transactions (via `safeFetcher` and the Safe Transaction Service API).
25
+ - **Gelato Relay** Meta-Transactions (via `gelatoFetcher` and the Gelato API).
26
26
  - **🤖 Automatic Routing:** The adapter automatically detects the correct tracker to use (Safe, Gelato, or standard EVM) based on the transaction context and wallet type.
27
27
  - **⚡ Built-in Actions:** Includes ready-to-use functions for common user needs like `speedUpTxAction` and `cancelTxAction`.
28
28
 
@@ -33,28 +33,22 @@ While its main export is the `evmAdapter`, it also includes a suite of standalon
33
33
  This package is designed to be used as part of the Pulsar stack and requires `@wagmi/core` and `viem`. Install all necessary packages together:
34
34
 
35
35
  ```bash
36
- # Using pnpm
36
+ # Using pnpm (recommended), but you can use npm, yarn or bun as well
37
37
  pnpm add @tuwaio/pulsar-evm @tuwaio/pulsar-core @tuwaio/orbit-core @tuwaio/orbit-evm @wagmi/core viem zustand immer dayjs
38
-
39
- # Using npm
40
- npm install @tuwaio/pulsar-evm @tuwaio/pulsar-core @tuwaio/orbit-core @tuwaio/orbit-evm @wagmi/core viem zustand immer dayjs
41
-
42
- # Using yarn
43
- yarn add @tuwaio/pulsar-evm @tuwaio/pulsar-core @tuwaio/orbit-core @tuwaio/orbit-evm @wagmi/core viem zustand immer dayjs
44
38
  ```
45
39
 
46
40
  ---
47
41
 
48
42
  ## 🚀 Usage
49
43
 
50
- ### 1. Primary Usage: The `evmAdapter`
44
+ ### 1. Primary Usage: The `pulsarEvmAdapter`
51
45
 
52
- For most applications, you'll only need to import the `evmAdapter` and pass it to your `createPulsarStore` configuration.
46
+ For most applications, you'll only need to import the `pulsarEvmAdapter` and pass it to your `createPulsarStore` configuration.
53
47
 
54
48
  ```ts
55
49
  // src/hooks/txTrackingHooks.ts
56
50
  import { createBoundedUseStore, createPulsarStore, Transaction } from '@tuwaio/pulsar-core';
57
- import { evmAdapter } from '@tuwaio/pulsar-evm';
51
+ import { pulsarEvmAdapter } from '@tuwaio/pulsar-evm';
58
52
 
59
53
  import { appChains, config } from '@/configs/wagmiConfig';
60
54
 
@@ -76,12 +70,42 @@ export type TransactionUnion = ExampleTx;
76
70
  export const usePulsarStore = createBoundedUseStore(
77
71
  createPulsarStore<TransactionUnion>({
78
72
  name: storageName,
79
- adapter: evmAdapter(config, appChains),
73
+ adapter: pulsarEvmAdapter(config, appChains),
80
74
  }),
81
75
  );
82
76
  ```
83
77
 
84
- ### 2. Using Standalone Actions
78
+ ### 2. Using Standalone Trackers
79
+
80
+ You can use `evmTracker` for standard transactions or `initializePollingTracker` with `gelatoFetcher`/`safeFetcher` for polling-based tracking.
81
+
82
+ #### Standard EVM Tracker
83
+
84
+ ```tsx
85
+ import { evmTracker } from '@tuwaio/pulsar-evm';
86
+ import { config } from './wagmi'; // Your wagmi config
87
+
88
+ async function trackMyTransaction(txHash: string, chainId: number) {
89
+ await evmTracker({
90
+ config,
91
+ tx: { txKey: txHash, chainId },
92
+ onTxDetailsFetched: (txDetails) => {
93
+ console.log('Transaction details:', txDetails);
94
+ },
95
+ onSuccess: async (txDetails, receipt, client) => {
96
+ console.log('Transaction mined!', receipt);
97
+ },
98
+ onReplaced: (replacement) => {
99
+ console.log('Transaction replaced:', replacement);
100
+ },
101
+ onFailure: (error) => {
102
+ console.error('Tracking failed:', error);
103
+ },
104
+ });
105
+ }
106
+ ```
107
+
108
+ ### 3. Using Standalone Actions
85
109
 
86
110
  This package also exports utility actions that you can wire up to your UI for features like speeding up or canceling transactions.
87
111
 
@@ -120,20 +144,31 @@ function SpeedUpButton({ txKey }) {
120
144
  }
121
145
  ```
122
146
 
123
- ### 3. Using Standalone Utilities
147
+ ### 4. Using Standalone Utilities
148
+
149
+ You can use exported utilities, like selectors or routing functions, to get derived data for your UI.
150
+
151
+ **Example: Determining the correct tracker**
124
152
 
125
- You can use exported utilities, like selectors, to get derived data for your UI.
153
+ ```tsx
154
+ import { checkTransactionsTracker } from '@tuwaio/pulsar-evm';
155
+ import { TransactionTracker } from '@tuwaio/pulsar-core';
156
+
157
+ // Automatically routes to 'gelato', 'safe', or 'ethereum'
158
+ const { tracker, txKey } = checkTransactionsTracker('0xabc...', 'injected');
159
+ // tracker -> TransactionTracker.Ethereum
160
+ ```
126
161
 
127
162
  **Example: Getting a block explorer link for a transaction**
128
163
 
129
164
  ```tsx
130
165
  // src/components/ExplorerLink.tsx
131
166
  import { selectEvmTxExplorerLink } from '@tuwaio/pulsar-evm';
132
- import { chains } from '../configs/wagmi'; // Your wagmi config
167
+ import { appChains } from '../configs/wagmi'; // Your wagmi chains
133
168
 
134
169
  function ExplorerLink({ tx }) {
135
170
  // The selector needs your app's chains, and the transaction.
136
- const explorerLink = selectEvmTxExplorerLink({ chains, tx });
171
+ const explorerLink = selectEvmTxExplorerLink({ chains: appChains, tx });
137
172
 
138
173
  if (!explorerLink) return null;
139
174
 
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var orbitCore=require('@tuwaio/orbit-core'),orbitEvm=require('@tuwaio/orbit-evm'),pulsarCore=require('@tuwaio/pulsar-core'),core=require('@wagmi/core'),viem=require('viem'),actions=require('viem/actions'),T=require('dayjs'),chains=require('viem/chains');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var T__default=/*#__PURE__*/_interopDefault(T);var v=1.15;async function C({config:t,tx:e}){if(e.adapter!==orbitCore.OrbitAdapter.EVM)throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${e.adapter}'.`);let{nonce:a,maxFeePerGas:s,maxPriorityFeePerGas:i,chainId:c}=e;if(a===void 0||!s||!i)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).");try{if(!t)throw new Error("Wagmi config is not provided.");let n=core.getAccount(t);if(!n.address)throw new Error("No connected account found.");let r=BigInt(Math.ceil(Number(i)*v)),o=BigInt(Math.ceil(Number(s)*v));return await core.sendTransaction(t,{to:n.address,value:0n,chainId:c,nonce:a,maxFeePerGas:o,maxPriorityFeePerGas:r})}catch(n){let r=n instanceof Error?n.message:String(n);throw new Error(`Failed to cancel transaction: ${r}`)}}var de=10,ue=3e3;async function me(t){let{tx:e,config:a,onInitialize:s,onTxDetailsFetched:i,onSuccess:c,onFailure:n,onReplaced:r,retryCount:o=de,retryTimeout:l=ue,waitForTransactionReceiptParams:u}=t;if(s?.(),e.txKey===viem.zeroHash)return n(new Error("Transaction hash cannot be the zero hash."));let p=core.getClient(a,{chainId:e.chainId});if(!p)return n(new Error(`Could not create a viem client for chainId: ${e.chainId}`));let d=null;for(let f=0;f<o;f++)try{d=await actions.getTransaction(p,{hash:e.txKey}),i(d);break}catch(m){if(f===o-1)return console.error(`EVM tracker failed to fetch tx ${e.txKey} after ${o} retries:`,m),n(m);await new Promise(b=>setTimeout(b,l));}if(!d)return n(new Error("Transaction details could not be fetched."));try{let f=!1,m=await actions.waitForTransactionReceipt(p,{hash:d.hash,onReplaced:b=>{f=!0,r(b);},...u});if(f)return;await c(d,m,p);}catch(f){console.error(`Error waiting for receipt for tx ${e.txKey}:`,f),n(f);}}async function y(t){let{tx:e,config:a,updateTxParams:s,transactionsPool:i,onSuccess:c,onError:n,onReplaced:r}=t;return me({tx:e,config:a,onInitialize:()=>{s(e.txKey,{hash:e.txKey});},onTxDetailsFetched:o=>{s(e.txKey,{to:o.to??void 0,input:o.input,value:o.value?.toString(),nonce:o.nonce,maxFeePerGas:o.maxFeePerGas?.toString(),maxPriorityFeePerGas:o.maxPriorityFeePerGas?.toString()});},onSuccess:async(o,l,u)=>{let p=await actions.getBlock(u,{blockNumber:l.blockNumber}),d=Number(p.timestamp),f=l.status==="success";s(e.txKey,{status:f?pulsarCore.TransactionStatus.Success:pulsarCore.TransactionStatus.Failed,isError:!f,pending:false,finishedTimestamp:d});let m=i[e.txKey];f&&c&&m&&c(m),!f&&n&&m&&n(new Error("Transaction reverted"),m);},onReplaced:o=>{s(e.txKey,{status:pulsarCore.TransactionStatus.Replaced,replacedTxHash:o.transaction.hash,pending:false});let l=i[e.txKey];r&&l&&r(l,e);},onFailure:o=>{s(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,errorMessage:o instanceof Error?o.message:"Transaction failed or could not be tracked."});let l=i[e.txKey];n&&l&&n(o,l);}})}function F(t){return typeof t=="object"&&t!==null&&"taskId"in t}var he=(r=>(r.CheckPending="CheckPending",r.ExecPending="ExecPending",r.WaitingForConfirmation="WaitingForConfirmation",r.ExecSuccess="ExecSuccess",r.ExecReverted="ExecReverted",r.Cancelled="Cancelled",r.NotFound="NotFound",r))(he||{}),xe="https://api.gelato.digital/tasks/status/",I=new Set(["ExecReverted","Cancelled","NotFound"]);function ge(t){return t!=="ExecSuccess"&&!I.has(t)}var ke=async({tx:t,stopPolling:e,onSuccess:a,onFailure:s,onIntervalTick:i})=>{let c=await fetch(`${xe}${t.txKey}`);if(!c.ok){if(c.status===404){s(),e();return}throw new Error(`Gelato API responded with status: ${c.status}`)}let n=await c.json(),{taskState:r,creationDate:o}=n.task;if(i?.(n),o&&T__default.default().diff(T__default.default(o),"hour")>=1&&ge(r)){e();return}r==="ExecSuccess"?(a(n),e({withoutRemoving:true})):I.has(r)&&(s(n),e({withoutRemoving:true}));};function P({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:s,onSuccess:i,onError:c}){return pulsarCore.initializePollingTracker({tx:t,fetcher:ke,removeTxFromPool:a,onSuccess:n=>{e(t.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:n.task.transactionHash,finishedTimestamp:n.task.executionDate?T__default.default(n.task.executionDate).unix():void 0});let r=s[t.txKey];i&&r&&i(r);},onIntervalTick:n=>{e(t.txKey,{hash:n.task.transactionHash});},onFailure:n=>{let r=n?.task.lastCheckMessage??"Transaction failed or was not found.";e(t.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:n?.task.transactionHash,errorMessage:r,finishedTimestamp:n?.task.executionDate?T__default.default(n.task.executionDate).unix():void 0});let o=s[t.txKey];c&&o&&c(new Error(r),o);}})}var ft={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},B={[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:"},W={[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 Ee=async({tx:t,stopPolling:e,onSuccess:a,onFailure:s,onReplaced:i,onIntervalTick:c})=>{let n=W[t.chainId];if(!n)throw new Error(`Safe Transaction Service URL not found for chainId: ${t.chainId}`);let r=await fetch(`${n}/multisig-transactions/${t.txKey}/`);if(!r.ok)throw r.status===404&&(s(),e()),new Error(`Safe API responded with status: ${r.status}`);let o=await r.json();if(c?.(o),o.isExecuted){o.isSuccessful?a(o):s(o),e({withoutRemoving:true});return}let l=await fetch(`${n}/safes/${t.from}/multisig-transactions/?nonce=${o.nonce}`);if(!l.ok)throw new Error(`Safe API (nonce check) responded with status: ${l.status}`);let p=(await l.json()).results.find(d=>d.isExecuted);if(p){i?.(p),e({withoutRemoving:true});return}T__default.default().diff(T__default.default(o.submissionDate),"day")>=1&&e();};function Y({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:s,onSuccess:i,onError:c,onReplaced:n}){return pulsarCore.initializePollingTracker({tx:t,fetcher:Ee,removeTxFromPool:a,onSuccess:r=>{e(t.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:r.transactionHash??void 0,finishedTimestamp:r.executionDate?T__default.default(r.executionDate).unix():void 0});let o=s[t.txKey];i&&o&&i(o);},onIntervalTick:r=>{e(t.txKey,{hash:r.transactionHash??void 0});},onFailure:r=>{let o=r?"Safe transaction failed or was rejected.":"Transaction not found.";e(t.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:r?.transactionHash??void 0,errorMessage:o,finishedTimestamp:r?.executionDate?T__default.default(r.executionDate).unix():void 0});let l=s[t.txKey];c&&l&&c(new Error(o),l);},onReplaced:r=>{e(t.txKey,{status:pulsarCore.TransactionStatus.Replaced,pending:false,hash:t.adapter===orbitCore.OrbitAdapter.EVM?t.hash:viem.zeroHash,replacedTxHash:r.safeTxHash??viem.zeroHash,finishedTimestamp:r.executionDate?T__default.default(r.executionDate).unix():void 0});let o=s[t.txKey];n&&o&&n(o,t);}})}async function J({tracker:t,tx:e,config:a,transactionsPool:s,onSuccess:i,onError:c,onReplaced:n,...r}){switch(t){case pulsarCore.TransactionTracker.Ethereum:return y({tx:e,config:a,transactionsPool:s,onSuccess:i,onError:c,onReplaced:n,...r});case pulsarCore.TransactionTracker.Gelato:return P({tx:e,transactionsPool:s,onSuccess:i,onError:c,...r});case pulsarCore.TransactionTracker.Safe:return Y({tx:e,transactionsPool:s,onSuccess:i,onError:c,onReplaced:n,...r});default:return console.warn(`Unknown tracker type: '${t}'. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:s,onSuccess:i,onError:c,onReplaced:n,...r})}}function Z(t,e){if(F(t))return {tracker:pulsarCore.TransactionTracker.Gelato,txKey:t.taskId};if(!viem.isHex(t))throw new Error(`Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(t)}`);let a=e.split(":");return (a.length>1?a[a.length-1]==="safe"||a[a.length-1]==="safewallet":e?.toLowerCase()==="safe")?{tracker:pulsarCore.TransactionTracker.Safe,txKey:t}:{tracker:pulsarCore.TransactionTracker.Ethereum,txKey:t}}var X=({chains:t,tx:e})=>{if(e.tracker===pulsarCore.TransactionTracker.Safe){let c=B[e.chainId];return c?`${c}${e.from}/transactions/tx?id=multisig_${e.from}_${e.txKey}`:""}let s=t.find(c=>c.id===e.chainId)?.blockExplorers?.default.url;if(!s)return "";let i=(e.adapter===orbitCore.OrbitAdapter.EVM?e.replacedTxHash:e.txKey)||(e.adapter===orbitCore.OrbitAdapter.EVM?e.hash:e.txKey);return i?`${s}/tx/${i}`:""};var ee=1.15;async function te({config:t,tx:e}){if(e.adapter!==orbitCore.OrbitAdapter.EVM)throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${e.adapter}'.`);let{nonce:a,from:s,to:i,value:c,input:n,maxFeePerGas:r,maxPriorityFeePerGas:o,chainId:l}=e;if(a===void 0||!s||!i||!c||!r||!o)throw new Error("Transaction is missing required fields for speed-up.");try{if(!t)throw new Error("Wagmi config is not provided.");if(!core.getAccount(t).address)throw new Error("No connected account found.");let p=BigInt(Math.ceil(Number(o)*ee)),d=BigInt(Math.ceil(Number(r)*ee));return await core.sendTransaction(t,{to:i,value:BigInt(c),data:n||"0x",chainId:l,nonce:a,maxFeePerGas:d,maxPriorityFeePerGas:p})}catch(u){let p=u instanceof Error?u.message:String(u);throw new Error(`Failed to speed up transaction: ${p}`)}}function oa(t,e){if(!t)throw new Error("EVM adapter requires a wagmi config object.");return {key:orbitCore.OrbitAdapter.EVM,getConnectorInfo:()=>{let a=core.getConnection(t),s=orbitCore.lastConnectedConnectorHelpers.getLastConnectedConnector();return {walletAddress:a.address??s?.address??viem.zeroAddress,connectorType:orbitCore.getConnectorTypeFromName(orbitCore.OrbitAdapter.EVM,a.connector?.name?.toLowerCase()??"unknown")}},checkChainForTx:a=>orbitEvm.checkAndSwitchChain(a,t),checkTransactionsTracker:(a,s)=>Z(a,s),checkAndInitializeTrackerInStore:({tx:a,...s})=>J({tracker:a.tracker,tx:a,config:t,...s}),getExplorerUrl:a=>{let{chain:s}=core.getConnection(t),i=s?.blockExplorers?.default.url;return a?`${i}/${a}`:i},getExplorerTxUrl:a=>X({chains:e,tx:a}),cancelTxAction:a=>C({config:t,tx:a}),speedUpTxAction:a=>te({config:t,tx:a}),retryTxAction:async({onClose:a,txKey:s,executeTxAction:i,tx:c})=>{if(a(s),!i){console.error("Retry failed: executeTxAction function is not provided.");return}await i({actionFunction:()=>c.actionFunction({config:t,...c.payload}),params:c,defaultTracker:pulsarCore.TransactionTracker.Ethereum});}}}var g=null,k=null,Ke=300*1e3,He="https://relay.gelato.digital/relays/v2/supported-chains";async function ia(t){let e=Date.now();if(g&&k&&e-k<Ke)return g.includes(t);try{let a=await fetch(He);if(!a.ok)throw new Error(`Gelato API responded with status: ${a.status}`);let i=(await a.json()).chains.map(Number);return g=i,k=e,i.includes(t)}catch(a){return console.error("Failed to fetch Gelato supported chains:",a),g=null,k=null,false}}
2
- exports.GelatoTaskState=he;exports.SafeTransactionServiceUrls=W;exports.cancelTxAction=C;exports.checkAndInitializeTrackerInStore=J;exports.checkIsGelatoAvailable=ia;exports.checkTransactionsTracker=Z;exports.evmTracker=me;exports.evmTrackerForStore=y;exports.gelatoFetcher=ke;exports.gelatoTrackerForStore=P;exports.gnosisSafeLinksHelper=B;exports.isGelatoTxKey=F;exports.pulsarEvmAdapter=oa;exports.safeFetcher=Ee;exports.safeSdkOptions=ft;exports.safeTrackerForStore=Y;exports.selectEvmTxExplorerLink=X;exports.speedUpTxAction=te;
1
+ 'use strict';var orbitCore=require('@tuwaio/orbit-core'),orbitEvm=require('@tuwaio/orbit-evm'),pulsarCore=require('@tuwaio/pulsar-core'),core=require('@wagmi/core'),viem=require('viem'),actions=require('viem/actions'),T=require('dayjs'),chains=require('viem/chains');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var T__default=/*#__PURE__*/_interopDefault(T);var C=1.15;async function v({config:t,tx:e}){if(e.adapter!==orbitCore.OrbitAdapter.EVM)throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${e.adapter}'.`);let{nonce:a,maxFeePerGas:o,maxPriorityFeePerGas:s,chainId:c}=e;if(a===void 0||!o||!s)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).");try{if(!t)throw new Error("Wagmi config is not provided.");let n=core.getAccount(t);if(!n.address)throw new Error("No connected account found.");let r=BigInt(Math.ceil(Number(s)*C)),i=BigInt(Math.ceil(Number(o)*C));return await core.sendTransaction(t,{to:n.address,value:0n,chainId:c,nonce:a,maxFeePerGas:i,maxPriorityFeePerGas:r})}catch(n){let r=n instanceof Error?n.message:String(n);throw new Error(`Failed to cancel transaction: ${r}`)}}var ue=10,me=3e3;async function Te(t){let{tx:e,config:a,onInitialize:o,onTxDetailsFetched:s,onSuccess:c,onFailure:n,onReplaced:r,retryCount:i=ue,retryTimeout:l=me,waitForTransactionReceiptParams:u}=t;if(o?.(),e.txKey===viem.zeroHash)return n(new Error("Transaction hash cannot be the zero hash."));let p=core.getClient(a,{chainId:e.chainId});if(!p)return n(new Error(`Could not create a viem client for chainId: ${e.chainId}`));let d=null;for(let f=0;f<i;f++)try{d=await actions.getTransaction(p,{hash:e.txKey}),s(d);break}catch(m){if(f===i-1)return console.error(`EVM tracker failed to fetch tx ${e.txKey} after ${i} retries:`,m),n(m);await new Promise(b=>setTimeout(b,l));}if(!d)return n(new Error("Transaction details could not be fetched."));try{let f=!1,m=await actions.waitForTransactionReceipt(p,{hash:d.hash,onReplaced:b=>{f=!0,r(b);},...u});if(f)return;await c(d,m,p);}catch(f){console.error(`Error waiting for receipt for tx ${e.txKey}:`,f),n(f);}}async function y(t){let{tx:e,config:a,updateTxParams:o,transactionsPool:s,onSuccess:c,onError:n,onReplaced:r}=t;return Te({tx:e,config:a,onInitialize:()=>{o(e.txKey,{hash:e.txKey});},onTxDetailsFetched:i=>{o(e.txKey,{to:i.to??void 0,input:i.input,value:i.value?.toString(),nonce:i.nonce,maxFeePerGas:i.maxFeePerGas?.toString(),maxPriorityFeePerGas:i.maxPriorityFeePerGas?.toString()});},onSuccess:async(i,l,u)=>{let p=await actions.getBlock(u,{blockNumber:l.blockNumber}),d=Number(p.timestamp),f=l.status==="success";o(e.txKey,{status:f?pulsarCore.TransactionStatus.Success:pulsarCore.TransactionStatus.Failed,isError:!f,pending:false,finishedTimestamp:d});let m=s[e.txKey];f&&c&&m&&c(m),!f&&n&&m&&n(new Error("Transaction reverted"),m);},onReplaced:i=>{o(e.txKey,{status:pulsarCore.TransactionStatus.Replaced,replacedTxHash:i.transaction.hash,pending:false});let l=s[e.txKey];r&&l&&r(l,e);},onFailure:i=>{o(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,error:orbitCore.normalizeError(i)});let l=s[e.txKey];n&&l&&n(i,l);}})}function F(t){return typeof t=="object"&&t!==null&&"taskId"in t}var ge=(r=>(r.CheckPending="CheckPending",r.ExecPending="ExecPending",r.WaitingForConfirmation="WaitingForConfirmation",r.ExecSuccess="ExecSuccess",r.ExecReverted="ExecReverted",r.Cancelled="Cancelled",r.NotFound="NotFound",r))(ge||{}),ke="https://api.gelato.digital/tasks/status/",I=new Set(["ExecReverted","Cancelled","NotFound"]);function be(t){return t!=="ExecSuccess"&&!I.has(t)}var ye=async({tx:t,stopPolling:e,onSuccess:a,onFailure:o,onIntervalTick:s})=>{let c=await fetch(`${ke}${t.txKey}`);if(!c.ok){if(c.status===404){o(),e();return}throw new Error(`Gelato API responded with status: ${c.status}`)}let n=await c.json(),{taskState:r,creationDate:i}=n.task;if(s?.(n),i&&T__default.default().diff(T__default.default(i),"hour")>=1&&be(r)){e();return}r==="ExecSuccess"?(a(n),e({withoutRemoving:true})):I.has(r)&&(o(n),e({withoutRemoving:true}));};function P({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:o,onSuccess:s,onError:c}){return pulsarCore.initializePollingTracker({tx:t,fetcher:ye,removeTxFromPool:a,onSuccess:n=>{e(t.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:n.task.transactionHash,finishedTimestamp:n.task.executionDate?T__default.default(n.task.executionDate).unix():void 0});let r=o[t.txKey];s&&r&&s(r);},onIntervalTick:n=>{e(t.txKey,{hash:n.task.transactionHash});},onFailure:n=>{let r=n?.task.lastCheckMessage?new Error(n.task.lastCheckMessage):new Error("Transaction failed or was not found.");e(t.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:n?.task.transactionHash,error:orbitCore.normalizeError(r),finishedTimestamp:n?.task.executionDate?T__default.default(n.task.executionDate).unix():void 0});let i=o[t.txKey];c&&i&&c(r,i);}})}var Tt={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},B={[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:"},W={[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 Ce=async({tx:t,stopPolling:e,onSuccess:a,onFailure:o,onReplaced:s,onIntervalTick:c})=>{let n=W[t.chainId];if(!n)throw new Error(`Safe Transaction Service URL not found for chainId: ${t.chainId}`);let r=await fetch(`${n}/multisig-transactions/${t.txKey}/`);if(!r.ok)throw r.status===404&&(o(),e()),new Error(`Safe API responded with status: ${r.status}`);let i=await r.json();if(c?.(i),i.isExecuted){i.isSuccessful?a(i):o(i),e({withoutRemoving:true});return}let l=await fetch(`${n}/safes/${t.from}/multisig-transactions/?nonce=${i.nonce}`);if(!l.ok)throw new Error(`Safe API (nonce check) responded with status: ${l.status}`);let p=(await l.json()).results.find(d=>d.isExecuted);if(p){s?.(p),e({withoutRemoving:true});return}T__default.default().diff(T__default.default(i.submissionDate),"day")>=1&&e();};function Y({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:o,onSuccess:s,onError:c,onReplaced:n}){return pulsarCore.initializePollingTracker({tx:t,fetcher:Ce,removeTxFromPool:a,onSuccess:r=>{e(t.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:r.transactionHash??void 0,finishedTimestamp:r.executionDate?T__default.default(r.executionDate).unix():void 0});let i=o[t.txKey];s&&i&&s(i);},onIntervalTick:r=>{e(t.txKey,{hash:r.transactionHash??void 0});},onFailure:r=>{let i=r?new Error("Safe transaction failed or was rejected."):new Error("Transaction not found.");e(t.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:r?.transactionHash??void 0,error:orbitCore.normalizeError(i),finishedTimestamp:r?.executionDate?T__default.default(r.executionDate).unix():void 0});let l=o[t.txKey];c&&l&&c(i,l);},onReplaced:r=>{e(t.txKey,{status:pulsarCore.TransactionStatus.Replaced,pending:false,hash:t.adapter===orbitCore.OrbitAdapter.EVM?t.hash:viem.zeroHash,replacedTxHash:r.safeTxHash??viem.zeroHash,finishedTimestamp:r.executionDate?T__default.default(r.executionDate).unix():void 0});let i=o[t.txKey];n&&i&&n(i,t);}})}async function J({tracker:t,tx:e,config:a,transactionsPool:o,onSuccess:s,onError:c,onReplaced:n,...r}){switch(t){case pulsarCore.TransactionTracker.Ethereum:return y({tx:e,config:a,transactionsPool:o,onSuccess:s,onError:c,onReplaced:n,...r});case pulsarCore.TransactionTracker.Gelato:return P({tx:e,transactionsPool:o,onSuccess:s,onError:c,...r});case pulsarCore.TransactionTracker.Safe:return Y({tx:e,transactionsPool:o,onSuccess:s,onError:c,onReplaced:n,...r});default:return console.warn(`Unknown tracker type: '${t}'. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:o,onSuccess:s,onError:c,onReplaced:n,...r})}}function Z(t,e){if(F(t))return {tracker:pulsarCore.TransactionTracker.Gelato,txKey:t.taskId};if(!viem.isHex(t))throw new Error(`Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(t)}`);let a=e.split(":");return (a.length>1?a[a.length-1]==="safe"||a[a.length-1]==="safewallet":e?.toLowerCase()==="safe")?{tracker:pulsarCore.TransactionTracker.Safe,txKey:t}:{tracker:pulsarCore.TransactionTracker.Ethereum,txKey:t}}var X=({chains:t,tx:e})=>{if(e.tracker===pulsarCore.TransactionTracker.Safe){let c=B[e.chainId];return c?`${c}${e.from}/transactions/tx?id=multisig_${e.from}_${e.txKey}`:""}let o=t.find(c=>c.id===e.chainId)?.blockExplorers?.default.url;if(!o)return "";let s=(e.adapter===orbitCore.OrbitAdapter.EVM?e.replacedTxHash:e.txKey)||(e.adapter===orbitCore.OrbitAdapter.EVM?e.hash:e.txKey);return s?`${o}/tx/${s}`:""};var ee=1.15;async function te({config:t,tx:e}){if(e.adapter!==orbitCore.OrbitAdapter.EVM)throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${e.adapter}'.`);let{nonce:a,from:o,to:s,value:c,input:n,maxFeePerGas:r,maxPriorityFeePerGas:i,chainId:l}=e;if(a===void 0||!o||!s||!c||!r||!i)throw new Error("Transaction is missing required fields for speed-up.");try{if(!t)throw new Error("Wagmi config is not provided.");if(!core.getAccount(t).address)throw new Error("No connected account found.");let p=BigInt(Math.ceil(Number(i)*ee)),d=BigInt(Math.ceil(Number(r)*ee));return await core.sendTransaction(t,{to:s,value:BigInt(c),data:n||"0x",chainId:l,nonce:a,maxFeePerGas:d,maxPriorityFeePerGas:p})}catch(u){let p=u instanceof Error?u.message:String(u);throw new Error(`Failed to speed up transaction: ${p}`)}}function fa(t,e){if(!t)throw new Error("EVM adapter requires a wagmi config object.");return {key:orbitCore.OrbitAdapter.EVM,getConnectorInfo:()=>{let a=core.getConnection(t),o=orbitCore.lastConnectedConnectorHelpers.getLastConnectedConnector();return {walletAddress:a.address??o?.address??viem.zeroAddress,connectorType:orbitCore.getConnectorTypeFromName(orbitCore.OrbitAdapter.EVM,a.connector?.name?.toLowerCase()??"unknown")}},checkChainForTx:a=>orbitEvm.checkAndSwitchChain(a,t),checkTransactionsTracker:(a,o)=>Z(a,o),checkAndInitializeTrackerInStore:({tx:a,...o})=>J({tracker:a.tracker,tx:a,config:t,...o}),getExplorerUrl:a=>{let{chain:o}=core.getConnection(t),s=o?.blockExplorers?.default.url;return a?`${s}/${a}`:s},getExplorerTxUrl:a=>X({chains:e,tx:a}),cancelTxAction:a=>v({config:t,tx:a}),speedUpTxAction:a=>te({config:t,tx:a}),retryTxAction:async({onClose:a,txKey:o,executeTxAction:s,tx:c})=>{if(a(o),!s){console.error("Retry failed: executeTxAction function is not provided.");return}await s({actionFunction:()=>c.actionFunction({config:t,...c.payload}),params:c,defaultTracker:pulsarCore.TransactionTracker.Ethereum});}}}var g=null,k=null,Me=300*1e3,Ne="https://relay.gelato.digital/relays/v2/supported-chains";async function da(t){let e=Date.now();if(g&&k&&e-k<Me)return g.includes(t);try{let a=await fetch(Ne);if(!a.ok)throw new Error(`Gelato API responded with status: ${a.status}`);let s=(await a.json()).chains.map(Number);return g=s,k=e,s.includes(t)}catch(a){return console.error("Failed to fetch Gelato supported chains:",a),g=null,k=null,false}}
2
+ exports.GelatoTaskState=ge;exports.SafeTransactionServiceUrls=W;exports.cancelTxAction=v;exports.checkAndInitializeTrackerInStore=J;exports.checkIsGelatoAvailable=da;exports.checkTransactionsTracker=Z;exports.evmTracker=Te;exports.evmTrackerForStore=y;exports.gelatoFetcher=ye;exports.gelatoTrackerForStore=P;exports.gnosisSafeLinksHelper=B;exports.isGelatoTxKey=F;exports.pulsarEvmAdapter=fa;exports.safeFetcher=Ce;exports.safeSdkOptions=Tt;exports.safeTrackerForStore=Y;exports.selectEvmTxExplorerLink=X;exports.speedUpTxAction=te;
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import {OrbitAdapter,lastConnectedConnectorHelpers,getConnectorTypeFromName}from'@tuwaio/orbit-core';import {checkAndSwitchChain}from'@tuwaio/orbit-evm';import {TransactionStatus,initializePollingTracker,TransactionTracker}from'@tuwaio/pulsar-core';import {getAccount,sendTransaction,getClient,getConnection}from'@wagmi/core';import {zeroHash,isHex,zeroAddress}from'viem';import {getTransaction,waitForTransactionReceipt,getBlock}from'viem/actions';import T from'dayjs';import {zksync,polygonZkEvm,optimism,gnosis,celo,bsc,boba,base,avalanche,aurora,arbitrum,polygon,sepolia,goerli,mainnet}from'viem/chains';var v=1.15;async function C({config:t,tx:e}){if(e.adapter!==OrbitAdapter.EVM)throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${e.adapter}'.`);let{nonce:a,maxFeePerGas:s,maxPriorityFeePerGas:i,chainId:c}=e;if(a===void 0||!s||!i)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).");try{if(!t)throw new Error("Wagmi config is not provided.");let n=getAccount(t);if(!n.address)throw new Error("No connected account found.");let r=BigInt(Math.ceil(Number(i)*v)),o=BigInt(Math.ceil(Number(s)*v));return await sendTransaction(t,{to:n.address,value:0n,chainId:c,nonce:a,maxFeePerGas:o,maxPriorityFeePerGas:r})}catch(n){let r=n instanceof Error?n.message:String(n);throw new Error(`Failed to cancel transaction: ${r}`)}}var de=10,ue=3e3;async function me(t){let{tx:e,config:a,onInitialize:s,onTxDetailsFetched:i,onSuccess:c,onFailure:n,onReplaced:r,retryCount:o=de,retryTimeout:l=ue,waitForTransactionReceiptParams:u}=t;if(s?.(),e.txKey===zeroHash)return n(new Error("Transaction hash cannot be the zero hash."));let p=getClient(a,{chainId:e.chainId});if(!p)return n(new Error(`Could not create a viem client for chainId: ${e.chainId}`));let d=null;for(let f=0;f<o;f++)try{d=await getTransaction(p,{hash:e.txKey}),i(d);break}catch(m){if(f===o-1)return console.error(`EVM tracker failed to fetch tx ${e.txKey} after ${o} retries:`,m),n(m);await new Promise(b=>setTimeout(b,l));}if(!d)return n(new Error("Transaction details could not be fetched."));try{let f=!1,m=await waitForTransactionReceipt(p,{hash:d.hash,onReplaced:b=>{f=!0,r(b);},...u});if(f)return;await c(d,m,p);}catch(f){console.error(`Error waiting for receipt for tx ${e.txKey}:`,f),n(f);}}async function y(t){let{tx:e,config:a,updateTxParams:s,transactionsPool:i,onSuccess:c,onError:n,onReplaced:r}=t;return me({tx:e,config:a,onInitialize:()=>{s(e.txKey,{hash:e.txKey});},onTxDetailsFetched:o=>{s(e.txKey,{to:o.to??void 0,input:o.input,value:o.value?.toString(),nonce:o.nonce,maxFeePerGas:o.maxFeePerGas?.toString(),maxPriorityFeePerGas:o.maxPriorityFeePerGas?.toString()});},onSuccess:async(o,l,u)=>{let p=await getBlock(u,{blockNumber:l.blockNumber}),d=Number(p.timestamp),f=l.status==="success";s(e.txKey,{status:f?TransactionStatus.Success:TransactionStatus.Failed,isError:!f,pending:false,finishedTimestamp:d});let m=i[e.txKey];f&&c&&m&&c(m),!f&&n&&m&&n(new Error("Transaction reverted"),m);},onReplaced:o=>{s(e.txKey,{status:TransactionStatus.Replaced,replacedTxHash:o.transaction.hash,pending:false});let l=i[e.txKey];r&&l&&r(l,e);},onFailure:o=>{s(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,errorMessage:o instanceof Error?o.message:"Transaction failed or could not be tracked."});let l=i[e.txKey];n&&l&&n(o,l);}})}function F(t){return typeof t=="object"&&t!==null&&"taskId"in t}var he=(r=>(r.CheckPending="CheckPending",r.ExecPending="ExecPending",r.WaitingForConfirmation="WaitingForConfirmation",r.ExecSuccess="ExecSuccess",r.ExecReverted="ExecReverted",r.Cancelled="Cancelled",r.NotFound="NotFound",r))(he||{}),xe="https://api.gelato.digital/tasks/status/",I=new Set(["ExecReverted","Cancelled","NotFound"]);function ge(t){return t!=="ExecSuccess"&&!I.has(t)}var ke=async({tx:t,stopPolling:e,onSuccess:a,onFailure:s,onIntervalTick:i})=>{let c=await fetch(`${xe}${t.txKey}`);if(!c.ok){if(c.status===404){s(),e();return}throw new Error(`Gelato API responded with status: ${c.status}`)}let n=await c.json(),{taskState:r,creationDate:o}=n.task;if(i?.(n),o&&T().diff(T(o),"hour")>=1&&ge(r)){e();return}r==="ExecSuccess"?(a(n),e({withoutRemoving:true})):I.has(r)&&(s(n),e({withoutRemoving:true}));};function P({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:s,onSuccess:i,onError:c}){return initializePollingTracker({tx:t,fetcher:ke,removeTxFromPool:a,onSuccess:n=>{e(t.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:n.task.transactionHash,finishedTimestamp:n.task.executionDate?T(n.task.executionDate).unix():void 0});let r=s[t.txKey];i&&r&&i(r);},onIntervalTick:n=>{e(t.txKey,{hash:n.task.transactionHash});},onFailure:n=>{let r=n?.task.lastCheckMessage??"Transaction failed or was not found.";e(t.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:n?.task.transactionHash,errorMessage:r,finishedTimestamp:n?.task.executionDate?T(n.task.executionDate).unix():void 0});let o=s[t.txKey];c&&o&&c(new Error(r),o);}})}var ft={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},B={[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:"},W={[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 Ee=async({tx:t,stopPolling:e,onSuccess:a,onFailure:s,onReplaced:i,onIntervalTick:c})=>{let n=W[t.chainId];if(!n)throw new Error(`Safe Transaction Service URL not found for chainId: ${t.chainId}`);let r=await fetch(`${n}/multisig-transactions/${t.txKey}/`);if(!r.ok)throw r.status===404&&(s(),e()),new Error(`Safe API responded with status: ${r.status}`);let o=await r.json();if(c?.(o),o.isExecuted){o.isSuccessful?a(o):s(o),e({withoutRemoving:true});return}let l=await fetch(`${n}/safes/${t.from}/multisig-transactions/?nonce=${o.nonce}`);if(!l.ok)throw new Error(`Safe API (nonce check) responded with status: ${l.status}`);let p=(await l.json()).results.find(d=>d.isExecuted);if(p){i?.(p),e({withoutRemoving:true});return}T().diff(T(o.submissionDate),"day")>=1&&e();};function Y({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:s,onSuccess:i,onError:c,onReplaced:n}){return initializePollingTracker({tx:t,fetcher:Ee,removeTxFromPool:a,onSuccess:r=>{e(t.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:r.transactionHash??void 0,finishedTimestamp:r.executionDate?T(r.executionDate).unix():void 0});let o=s[t.txKey];i&&o&&i(o);},onIntervalTick:r=>{e(t.txKey,{hash:r.transactionHash??void 0});},onFailure:r=>{let o=r?"Safe transaction failed or was rejected.":"Transaction not found.";e(t.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:r?.transactionHash??void 0,errorMessage:o,finishedTimestamp:r?.executionDate?T(r.executionDate).unix():void 0});let l=s[t.txKey];c&&l&&c(new Error(o),l);},onReplaced:r=>{e(t.txKey,{status:TransactionStatus.Replaced,pending:false,hash:t.adapter===OrbitAdapter.EVM?t.hash:zeroHash,replacedTxHash:r.safeTxHash??zeroHash,finishedTimestamp:r.executionDate?T(r.executionDate).unix():void 0});let o=s[t.txKey];n&&o&&n(o,t);}})}async function J({tracker:t,tx:e,config:a,transactionsPool:s,onSuccess:i,onError:c,onReplaced:n,...r}){switch(t){case TransactionTracker.Ethereum:return y({tx:e,config:a,transactionsPool:s,onSuccess:i,onError:c,onReplaced:n,...r});case TransactionTracker.Gelato:return P({tx:e,transactionsPool:s,onSuccess:i,onError:c,...r});case TransactionTracker.Safe:return Y({tx:e,transactionsPool:s,onSuccess:i,onError:c,onReplaced:n,...r});default:return console.warn(`Unknown tracker type: '${t}'. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:s,onSuccess:i,onError:c,onReplaced:n,...r})}}function Z(t,e){if(F(t))return {tracker:TransactionTracker.Gelato,txKey:t.taskId};if(!isHex(t))throw new Error(`Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(t)}`);let a=e.split(":");return (a.length>1?a[a.length-1]==="safe"||a[a.length-1]==="safewallet":e?.toLowerCase()==="safe")?{tracker:TransactionTracker.Safe,txKey:t}:{tracker:TransactionTracker.Ethereum,txKey:t}}var X=({chains:t,tx:e})=>{if(e.tracker===TransactionTracker.Safe){let c=B[e.chainId];return c?`${c}${e.from}/transactions/tx?id=multisig_${e.from}_${e.txKey}`:""}let s=t.find(c=>c.id===e.chainId)?.blockExplorers?.default.url;if(!s)return "";let i=(e.adapter===OrbitAdapter.EVM?e.replacedTxHash:e.txKey)||(e.adapter===OrbitAdapter.EVM?e.hash:e.txKey);return i?`${s}/tx/${i}`:""};var ee=1.15;async function te({config:t,tx:e}){if(e.adapter!==OrbitAdapter.EVM)throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${e.adapter}'.`);let{nonce:a,from:s,to:i,value:c,input:n,maxFeePerGas:r,maxPriorityFeePerGas:o,chainId:l}=e;if(a===void 0||!s||!i||!c||!r||!o)throw new Error("Transaction is missing required fields for speed-up.");try{if(!t)throw new Error("Wagmi config is not provided.");if(!getAccount(t).address)throw new Error("No connected account found.");let p=BigInt(Math.ceil(Number(o)*ee)),d=BigInt(Math.ceil(Number(r)*ee));return await sendTransaction(t,{to:i,value:BigInt(c),data:n||"0x",chainId:l,nonce:a,maxFeePerGas:d,maxPriorityFeePerGas:p})}catch(u){let p=u instanceof Error?u.message:String(u);throw new Error(`Failed to speed up transaction: ${p}`)}}function oa(t,e){if(!t)throw new Error("EVM adapter requires a wagmi config object.");return {key:OrbitAdapter.EVM,getConnectorInfo:()=>{let a=getConnection(t),s=lastConnectedConnectorHelpers.getLastConnectedConnector();return {walletAddress:a.address??s?.address??zeroAddress,connectorType:getConnectorTypeFromName(OrbitAdapter.EVM,a.connector?.name?.toLowerCase()??"unknown")}},checkChainForTx:a=>checkAndSwitchChain(a,t),checkTransactionsTracker:(a,s)=>Z(a,s),checkAndInitializeTrackerInStore:({tx:a,...s})=>J({tracker:a.tracker,tx:a,config:t,...s}),getExplorerUrl:a=>{let{chain:s}=getConnection(t),i=s?.blockExplorers?.default.url;return a?`${i}/${a}`:i},getExplorerTxUrl:a=>X({chains:e,tx:a}),cancelTxAction:a=>C({config:t,tx:a}),speedUpTxAction:a=>te({config:t,tx:a}),retryTxAction:async({onClose:a,txKey:s,executeTxAction:i,tx:c})=>{if(a(s),!i){console.error("Retry failed: executeTxAction function is not provided.");return}await i({actionFunction:()=>c.actionFunction({config:t,...c.payload}),params:c,defaultTracker:TransactionTracker.Ethereum});}}}var g=null,k=null,Ke=300*1e3,He="https://relay.gelato.digital/relays/v2/supported-chains";async function ia(t){let e=Date.now();if(g&&k&&e-k<Ke)return g.includes(t);try{let a=await fetch(He);if(!a.ok)throw new Error(`Gelato API responded with status: ${a.status}`);let i=(await a.json()).chains.map(Number);return g=i,k=e,i.includes(t)}catch(a){return console.error("Failed to fetch Gelato supported chains:",a),g=null,k=null,false}}
2
- export{he as GelatoTaskState,W as SafeTransactionServiceUrls,C as cancelTxAction,J as checkAndInitializeTrackerInStore,ia as checkIsGelatoAvailable,Z as checkTransactionsTracker,me as evmTracker,y as evmTrackerForStore,ke as gelatoFetcher,P as gelatoTrackerForStore,B as gnosisSafeLinksHelper,F as isGelatoTxKey,oa as pulsarEvmAdapter,Ee as safeFetcher,ft as safeSdkOptions,Y as safeTrackerForStore,X as selectEvmTxExplorerLink,te as speedUpTxAction};
1
+ import {OrbitAdapter,normalizeError,lastConnectedConnectorHelpers,getConnectorTypeFromName}from'@tuwaio/orbit-core';import {checkAndSwitchChain}from'@tuwaio/orbit-evm';import {TransactionStatus,initializePollingTracker,TransactionTracker}from'@tuwaio/pulsar-core';import {getAccount,sendTransaction,getClient,getConnection}from'@wagmi/core';import {zeroHash,isHex,zeroAddress}from'viem';import {getTransaction,waitForTransactionReceipt,getBlock}from'viem/actions';import T from'dayjs';import {zksync,polygonZkEvm,optimism,gnosis,celo,bsc,boba,base,avalanche,aurora,arbitrum,polygon,sepolia,goerli,mainnet}from'viem/chains';var C=1.15;async function v({config:t,tx:e}){if(e.adapter!==OrbitAdapter.EVM)throw new Error(`Cancellation is only available for EVM transactions. Received adapter type: '${e.adapter}'.`);let{nonce:a,maxFeePerGas:o,maxPriorityFeePerGas:s,chainId:c}=e;if(a===void 0||!o||!s)throw new Error("Transaction is missing required fields for cancellation (nonce, maxFeePerGas, maxPriorityFeePerGas).");try{if(!t)throw new Error("Wagmi config is not provided.");let n=getAccount(t);if(!n.address)throw new Error("No connected account found.");let r=BigInt(Math.ceil(Number(s)*C)),i=BigInt(Math.ceil(Number(o)*C));return await sendTransaction(t,{to:n.address,value:0n,chainId:c,nonce:a,maxFeePerGas:i,maxPriorityFeePerGas:r})}catch(n){let r=n instanceof Error?n.message:String(n);throw new Error(`Failed to cancel transaction: ${r}`)}}var ue=10,me=3e3;async function Te(t){let{tx:e,config:a,onInitialize:o,onTxDetailsFetched:s,onSuccess:c,onFailure:n,onReplaced:r,retryCount:i=ue,retryTimeout:l=me,waitForTransactionReceiptParams:u}=t;if(o?.(),e.txKey===zeroHash)return n(new Error("Transaction hash cannot be the zero hash."));let p=getClient(a,{chainId:e.chainId});if(!p)return n(new Error(`Could not create a viem client for chainId: ${e.chainId}`));let d=null;for(let f=0;f<i;f++)try{d=await getTransaction(p,{hash:e.txKey}),s(d);break}catch(m){if(f===i-1)return console.error(`EVM tracker failed to fetch tx ${e.txKey} after ${i} retries:`,m),n(m);await new Promise(b=>setTimeout(b,l));}if(!d)return n(new Error("Transaction details could not be fetched."));try{let f=!1,m=await waitForTransactionReceipt(p,{hash:d.hash,onReplaced:b=>{f=!0,r(b);},...u});if(f)return;await c(d,m,p);}catch(f){console.error(`Error waiting for receipt for tx ${e.txKey}:`,f),n(f);}}async function y(t){let{tx:e,config:a,updateTxParams:o,transactionsPool:s,onSuccess:c,onError:n,onReplaced:r}=t;return Te({tx:e,config:a,onInitialize:()=>{o(e.txKey,{hash:e.txKey});},onTxDetailsFetched:i=>{o(e.txKey,{to:i.to??void 0,input:i.input,value:i.value?.toString(),nonce:i.nonce,maxFeePerGas:i.maxFeePerGas?.toString(),maxPriorityFeePerGas:i.maxPriorityFeePerGas?.toString()});},onSuccess:async(i,l,u)=>{let p=await getBlock(u,{blockNumber:l.blockNumber}),d=Number(p.timestamp),f=l.status==="success";o(e.txKey,{status:f?TransactionStatus.Success:TransactionStatus.Failed,isError:!f,pending:false,finishedTimestamp:d});let m=s[e.txKey];f&&c&&m&&c(m),!f&&n&&m&&n(new Error("Transaction reverted"),m);},onReplaced:i=>{o(e.txKey,{status:TransactionStatus.Replaced,replacedTxHash:i.transaction.hash,pending:false});let l=s[e.txKey];r&&l&&r(l,e);},onFailure:i=>{o(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,error:normalizeError(i)});let l=s[e.txKey];n&&l&&n(i,l);}})}function F(t){return typeof t=="object"&&t!==null&&"taskId"in t}var ge=(r=>(r.CheckPending="CheckPending",r.ExecPending="ExecPending",r.WaitingForConfirmation="WaitingForConfirmation",r.ExecSuccess="ExecSuccess",r.ExecReverted="ExecReverted",r.Cancelled="Cancelled",r.NotFound="NotFound",r))(ge||{}),ke="https://api.gelato.digital/tasks/status/",I=new Set(["ExecReverted","Cancelled","NotFound"]);function be(t){return t!=="ExecSuccess"&&!I.has(t)}var ye=async({tx:t,stopPolling:e,onSuccess:a,onFailure:o,onIntervalTick:s})=>{let c=await fetch(`${ke}${t.txKey}`);if(!c.ok){if(c.status===404){o(),e();return}throw new Error(`Gelato API responded with status: ${c.status}`)}let n=await c.json(),{taskState:r,creationDate:i}=n.task;if(s?.(n),i&&T().diff(T(i),"hour")>=1&&be(r)){e();return}r==="ExecSuccess"?(a(n),e({withoutRemoving:true})):I.has(r)&&(o(n),e({withoutRemoving:true}));};function P({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:o,onSuccess:s,onError:c}){return initializePollingTracker({tx:t,fetcher:ye,removeTxFromPool:a,onSuccess:n=>{e(t.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:n.task.transactionHash,finishedTimestamp:n.task.executionDate?T(n.task.executionDate).unix():void 0});let r=o[t.txKey];s&&r&&s(r);},onIntervalTick:n=>{e(t.txKey,{hash:n.task.transactionHash});},onFailure:n=>{let r=n?.task.lastCheckMessage?new Error(n.task.lastCheckMessage):new Error("Transaction failed or was not found.");e(t.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:n?.task.transactionHash,error:normalizeError(r),finishedTimestamp:n?.task.executionDate?T(n.task.executionDate).unix():void 0});let i=o[t.txKey];c&&i&&c(r,i);}})}var Tt={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},B={[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:"},W={[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 Ce=async({tx:t,stopPolling:e,onSuccess:a,onFailure:o,onReplaced:s,onIntervalTick:c})=>{let n=W[t.chainId];if(!n)throw new Error(`Safe Transaction Service URL not found for chainId: ${t.chainId}`);let r=await fetch(`${n}/multisig-transactions/${t.txKey}/`);if(!r.ok)throw r.status===404&&(o(),e()),new Error(`Safe API responded with status: ${r.status}`);let i=await r.json();if(c?.(i),i.isExecuted){i.isSuccessful?a(i):o(i),e({withoutRemoving:true});return}let l=await fetch(`${n}/safes/${t.from}/multisig-transactions/?nonce=${i.nonce}`);if(!l.ok)throw new Error(`Safe API (nonce check) responded with status: ${l.status}`);let p=(await l.json()).results.find(d=>d.isExecuted);if(p){s?.(p),e({withoutRemoving:true});return}T().diff(T(i.submissionDate),"day")>=1&&e();};function Y({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:o,onSuccess:s,onError:c,onReplaced:n}){return initializePollingTracker({tx:t,fetcher:Ce,removeTxFromPool:a,onSuccess:r=>{e(t.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:r.transactionHash??void 0,finishedTimestamp:r.executionDate?T(r.executionDate).unix():void 0});let i=o[t.txKey];s&&i&&s(i);},onIntervalTick:r=>{e(t.txKey,{hash:r.transactionHash??void 0});},onFailure:r=>{let i=r?new Error("Safe transaction failed or was rejected."):new Error("Transaction not found.");e(t.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:r?.transactionHash??void 0,error:normalizeError(i),finishedTimestamp:r?.executionDate?T(r.executionDate).unix():void 0});let l=o[t.txKey];c&&l&&c(i,l);},onReplaced:r=>{e(t.txKey,{status:TransactionStatus.Replaced,pending:false,hash:t.adapter===OrbitAdapter.EVM?t.hash:zeroHash,replacedTxHash:r.safeTxHash??zeroHash,finishedTimestamp:r.executionDate?T(r.executionDate).unix():void 0});let i=o[t.txKey];n&&i&&n(i,t);}})}async function J({tracker:t,tx:e,config:a,transactionsPool:o,onSuccess:s,onError:c,onReplaced:n,...r}){switch(t){case TransactionTracker.Ethereum:return y({tx:e,config:a,transactionsPool:o,onSuccess:s,onError:c,onReplaced:n,...r});case TransactionTracker.Gelato:return P({tx:e,transactionsPool:o,onSuccess:s,onError:c,...r});case TransactionTracker.Safe:return Y({tx:e,transactionsPool:o,onSuccess:s,onError:c,onReplaced:n,...r});default:return console.warn(`Unknown tracker type: '${t}'. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:o,onSuccess:s,onError:c,onReplaced:n,...r})}}function Z(t,e){if(F(t))return {tracker:TransactionTracker.Gelato,txKey:t.taskId};if(!isHex(t))throw new Error(`Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(t)}`);let a=e.split(":");return (a.length>1?a[a.length-1]==="safe"||a[a.length-1]==="safewallet":e?.toLowerCase()==="safe")?{tracker:TransactionTracker.Safe,txKey:t}:{tracker:TransactionTracker.Ethereum,txKey:t}}var X=({chains:t,tx:e})=>{if(e.tracker===TransactionTracker.Safe){let c=B[e.chainId];return c?`${c}${e.from}/transactions/tx?id=multisig_${e.from}_${e.txKey}`:""}let o=t.find(c=>c.id===e.chainId)?.blockExplorers?.default.url;if(!o)return "";let s=(e.adapter===OrbitAdapter.EVM?e.replacedTxHash:e.txKey)||(e.adapter===OrbitAdapter.EVM?e.hash:e.txKey);return s?`${o}/tx/${s}`:""};var ee=1.15;async function te({config:t,tx:e}){if(e.adapter!==OrbitAdapter.EVM)throw new Error(`Speed up is only available for EVM transactions. Received adapter type: '${e.adapter}'.`);let{nonce:a,from:o,to:s,value:c,input:n,maxFeePerGas:r,maxPriorityFeePerGas:i,chainId:l}=e;if(a===void 0||!o||!s||!c||!r||!i)throw new Error("Transaction is missing required fields for speed-up.");try{if(!t)throw new Error("Wagmi config is not provided.");if(!getAccount(t).address)throw new Error("No connected account found.");let p=BigInt(Math.ceil(Number(i)*ee)),d=BigInt(Math.ceil(Number(r)*ee));return await sendTransaction(t,{to:s,value:BigInt(c),data:n||"0x",chainId:l,nonce:a,maxFeePerGas:d,maxPriorityFeePerGas:p})}catch(u){let p=u instanceof Error?u.message:String(u);throw new Error(`Failed to speed up transaction: ${p}`)}}function fa(t,e){if(!t)throw new Error("EVM adapter requires a wagmi config object.");return {key:OrbitAdapter.EVM,getConnectorInfo:()=>{let a=getConnection(t),o=lastConnectedConnectorHelpers.getLastConnectedConnector();return {walletAddress:a.address??o?.address??zeroAddress,connectorType:getConnectorTypeFromName(OrbitAdapter.EVM,a.connector?.name?.toLowerCase()??"unknown")}},checkChainForTx:a=>checkAndSwitchChain(a,t),checkTransactionsTracker:(a,o)=>Z(a,o),checkAndInitializeTrackerInStore:({tx:a,...o})=>J({tracker:a.tracker,tx:a,config:t,...o}),getExplorerUrl:a=>{let{chain:o}=getConnection(t),s=o?.blockExplorers?.default.url;return a?`${s}/${a}`:s},getExplorerTxUrl:a=>X({chains:e,tx:a}),cancelTxAction:a=>v({config:t,tx:a}),speedUpTxAction:a=>te({config:t,tx:a}),retryTxAction:async({onClose:a,txKey:o,executeTxAction:s,tx:c})=>{if(a(o),!s){console.error("Retry failed: executeTxAction function is not provided.");return}await s({actionFunction:()=>c.actionFunction({config:t,...c.payload}),params:c,defaultTracker:TransactionTracker.Ethereum});}}}var g=null,k=null,Me=300*1e3,Ne="https://relay.gelato.digital/relays/v2/supported-chains";async function da(t){let e=Date.now();if(g&&k&&e-k<Me)return g.includes(t);try{let a=await fetch(Ne);if(!a.ok)throw new Error(`Gelato API responded with status: ${a.status}`);let s=(await a.json()).chains.map(Number);return g=s,k=e,s.includes(t)}catch(a){return console.error("Failed to fetch Gelato supported chains:",a),g=null,k=null,false}}
2
+ export{ge as GelatoTaskState,W as SafeTransactionServiceUrls,v as cancelTxAction,J as checkAndInitializeTrackerInStore,da as checkIsGelatoAvailable,Z as checkTransactionsTracker,Te as evmTracker,y as evmTrackerForStore,ye as gelatoFetcher,P as gelatoTrackerForStore,B as gnosisSafeLinksHelper,F as isGelatoTxKey,fa as pulsarEvmAdapter,Ce as safeFetcher,Tt as safeSdkOptions,Y as safeTrackerForStore,X as selectEvmTxExplorerLink,te as speedUpTxAction};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuwaio/pulsar-evm",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",
@@ -39,9 +39,9 @@
39
39
  }
40
40
  ],
41
41
  "peerDependencies": {
42
- "@tuwaio/pulsar-core": ">=0.3",
43
- "@tuwaio/orbit-core": ">=0.2",
44
- "@tuwaio/orbit-evm": ">=0.2",
42
+ "@tuwaio/pulsar-core": ">=0.5",
43
+ "@tuwaio/orbit-core": ">=0.2.7",
44
+ "@tuwaio/orbit-evm": ">=0.2.9",
45
45
  "@wagmi/core": "3.x.x",
46
46
  "dayjs": "1.x.x",
47
47
  "immer": "11.x.x",
@@ -49,18 +49,18 @@
49
49
  "zustand": "5.x.x"
50
50
  },
51
51
  "devDependencies": {
52
- "@tuwaio/orbit-core": "^0.2.4",
53
- "@tuwaio/orbit-evm": "^0.2.7",
54
- "@wagmi/core": "^3.3.1",
52
+ "@tuwaio/orbit-core": "^0.2.7",
53
+ "@tuwaio/orbit-evm": "^0.2.9",
54
+ "@wagmi/core": "^3.3.2",
55
55
  "dayjs": "^1.11.19",
56
56
  "immer": "^11.1.3",
57
- "jsdom": "^27.4.0",
57
+ "jsdom": "^28.0.0",
58
58
  "tsup": "^8.5.1",
59
59
  "typescript": "^5.9.3",
60
- "viem": "^2.44.4",
60
+ "viem": "^2.45.1",
61
61
  "vitest": "^4.0.18",
62
- "zustand": "^5.0.10",
63
- "@tuwaio/pulsar-core": "^0.4.0"
62
+ "zustand": "^5.0.11",
63
+ "@tuwaio/pulsar-core": "^0.5.0"
64
64
  },
65
65
  "scripts": {
66
66
  "start": "tsup src/index.ts --watch",