@tuwaio/pulsar-evm 0.5.7 → 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +29 -6
- package/dist/index.d.ts +29 -6
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -27,37 +27,60 @@ declare function pulsarEvmAdapter<T extends Transaction>(config: Config, appChai
|
|
|
27
27
|
/**
|
|
28
28
|
* @file This file contains the tracker implementation for standard EVM transactions.
|
|
29
29
|
* It uses viem's public actions (`getTransaction`, `waitForTransactionReceipt`) to monitor
|
|
30
|
-
* a transaction's lifecycle from submission to finality.
|
|
30
|
+
* a transaction's lifecycle from submission to finality with robust timeout handling.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Checks whether an error during receipt polling is transient (RPC network glitch, timeout, or unindexed tx).
|
|
35
|
+
* Recursively inspects nested error causes to handle wrapped Viem transport errors.
|
|
36
|
+
*
|
|
37
|
+
* @param error - The caught error object.
|
|
38
|
+
* @returns `true` if the error is considered transient and retryable; otherwise `false`.
|
|
39
|
+
*/
|
|
40
|
+
declare function isRetryableReceiptError(error: unknown): boolean;
|
|
33
41
|
/**
|
|
34
42
|
* Defines the parameters for the low-level EVM transaction tracker.
|
|
35
43
|
*/
|
|
36
44
|
type EVMTrackerParams = {
|
|
45
|
+
/** The transaction identity parameters (chainId, txKey, requiredConfirmations). */
|
|
37
46
|
tx: Pick<Transaction, 'chainId' | 'txKey' | 'requiredConfirmations'>;
|
|
47
|
+
/** The `@wagmi/core` configuration instance used to resolve network clients. */
|
|
38
48
|
config: Config;
|
|
49
|
+
/** Callback fired once transaction details (nonce, input, values) are successfully fetched. */
|
|
39
50
|
onTxDetailsFetched: (txDetails: GetTransactionReturnType) => void;
|
|
51
|
+
/** Callback fired when the transaction is mined successfully (or reverted on-chain). */
|
|
40
52
|
onSuccess: (txDetails: GetTransactionReturnType, receipt: TransactionReceipt, client: Client) => Promise<void>;
|
|
53
|
+
/** Callback fired when the transaction has been replaced (repriced or cancelled). */
|
|
41
54
|
onReplaced: (replacement: ReplacementReturnType) => void;
|
|
55
|
+
/** Callback fired when tracking fails fatally or exceeds all retry attempts. */
|
|
42
56
|
onFailure: (error?: unknown) => void;
|
|
57
|
+
/** Optional callback fired when tracker initialization starts. */
|
|
43
58
|
onInitialize?: () => void;
|
|
59
|
+
/** Number of retries for the initial `getTransaction` fetch step. Defaults to 10. */
|
|
44
60
|
retryCount?: number;
|
|
61
|
+
/** Timeout in milliseconds between `getTransaction` retry attempts. Defaults to 3000ms. */
|
|
45
62
|
retryTimeout?: number;
|
|
63
|
+
/** Optional callback fired whenever required block confirmation count updates. */
|
|
46
64
|
onConfirmationsUpdate?: (confirmations: number) => void;
|
|
65
|
+
/** Optional custom parameters passed directly to viem's `waitForTransactionReceipt`. */
|
|
47
66
|
waitForTransactionReceiptParams?: WaitForTransactionReceiptParameters;
|
|
48
67
|
};
|
|
49
68
|
/**
|
|
50
69
|
* A low-level tracker for monitoring a standard EVM transaction by its hash.
|
|
51
|
-
*
|
|
70
|
+
* Retries fetching transaction details and gracefully polls for transaction receipt,
|
|
71
|
+
* recovering automatically from RPC network glitches and timeout errors.
|
|
52
72
|
*
|
|
53
|
-
* @param
|
|
73
|
+
* @param params - The configuration parameters and lifecycle callbacks for the EVM tracker.
|
|
74
|
+
* @returns A promise that resolves when tracking completes or fails fatally.
|
|
54
75
|
*/
|
|
55
76
|
declare function evmTracker(params: EVMTrackerParams): Promise<void>;
|
|
56
77
|
/**
|
|
57
78
|
* A higher-level wrapper for `evmTracker` that integrates directly with the Pulsar store.
|
|
58
|
-
*
|
|
79
|
+
* Updates transaction lifecycle states (pending, success, failed, replaced) in the Zustand store.
|
|
59
80
|
*
|
|
60
|
-
* @template T - The application-specific transaction
|
|
81
|
+
* @template T - The application-specific transaction state structure extending `Transaction`.
|
|
82
|
+
* @param params - Configuration connecting `@wagmi/core`, store mutation methods, target transaction, and callbacks.
|
|
83
|
+
* @returns A promise that resolves when transaction tracking finishes and store state is committed.
|
|
61
84
|
*/
|
|
62
85
|
declare function evmTrackerForStore<T extends Transaction>(params: Pick<EVMTrackerParams, 'config'> & Pick<ITxTrackingStore<T>, 'updateTxParams' | 'transactionsPool'> & {
|
|
63
86
|
tx: T;
|
|
@@ -458,4 +481,4 @@ declare function speedUpTxAction<T extends Transaction>({ config, tx }: {
|
|
|
458
481
|
tx: T;
|
|
459
482
|
}): Promise<Hex>;
|
|
460
483
|
|
|
461
|
-
export { type EVMTrackerParams, type GelatoCapabilities, type GelatoCapabilitiesByChain, type GelatoClientConfig, GelatoStatusCode, type GelatoTaskStatus, type GelatoToken, SafeTransactionServiceUrls, type SafeTxStatusResponse, cancelTxAction, checkAndInitializeTrackerInStore, checkIsGelatoAvailable, checkTransactionsTracker, createGelatoClient, evmTracker, evmTrackerForStore, gelatoFetcher, gelatoTrackerForStore, gnosisSafeLinksHelper, pulsarEvmAdapter, safeFetcher, safeSdkOptions, safeTrackerForStore, selectEvmTxExplorerLink, speedUpTxAction };
|
|
484
|
+
export { type EVMTrackerParams, type GelatoCapabilities, type GelatoCapabilitiesByChain, type GelatoClientConfig, GelatoStatusCode, type GelatoTaskStatus, type GelatoToken, SafeTransactionServiceUrls, type SafeTxStatusResponse, cancelTxAction, checkAndInitializeTrackerInStore, checkIsGelatoAvailable, checkTransactionsTracker, createGelatoClient, evmTracker, evmTrackerForStore, gelatoFetcher, gelatoTrackerForStore, gnosisSafeLinksHelper, isRetryableReceiptError, pulsarEvmAdapter, safeFetcher, safeSdkOptions, safeTrackerForStore, selectEvmTxExplorerLink, speedUpTxAction };
|
package/dist/index.d.ts
CHANGED
|
@@ -27,37 +27,60 @@ declare function pulsarEvmAdapter<T extends Transaction>(config: Config, appChai
|
|
|
27
27
|
/**
|
|
28
28
|
* @file This file contains the tracker implementation for standard EVM transactions.
|
|
29
29
|
* It uses viem's public actions (`getTransaction`, `waitForTransactionReceipt`) to monitor
|
|
30
|
-
* a transaction's lifecycle from submission to finality.
|
|
30
|
+
* a transaction's lifecycle from submission to finality with robust timeout handling.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Checks whether an error during receipt polling is transient (RPC network glitch, timeout, or unindexed tx).
|
|
35
|
+
* Recursively inspects nested error causes to handle wrapped Viem transport errors.
|
|
36
|
+
*
|
|
37
|
+
* @param error - The caught error object.
|
|
38
|
+
* @returns `true` if the error is considered transient and retryable; otherwise `false`.
|
|
39
|
+
*/
|
|
40
|
+
declare function isRetryableReceiptError(error: unknown): boolean;
|
|
33
41
|
/**
|
|
34
42
|
* Defines the parameters for the low-level EVM transaction tracker.
|
|
35
43
|
*/
|
|
36
44
|
type EVMTrackerParams = {
|
|
45
|
+
/** The transaction identity parameters (chainId, txKey, requiredConfirmations). */
|
|
37
46
|
tx: Pick<Transaction, 'chainId' | 'txKey' | 'requiredConfirmations'>;
|
|
47
|
+
/** The `@wagmi/core` configuration instance used to resolve network clients. */
|
|
38
48
|
config: Config;
|
|
49
|
+
/** Callback fired once transaction details (nonce, input, values) are successfully fetched. */
|
|
39
50
|
onTxDetailsFetched: (txDetails: GetTransactionReturnType) => void;
|
|
51
|
+
/** Callback fired when the transaction is mined successfully (or reverted on-chain). */
|
|
40
52
|
onSuccess: (txDetails: GetTransactionReturnType, receipt: TransactionReceipt, client: Client) => Promise<void>;
|
|
53
|
+
/** Callback fired when the transaction has been replaced (repriced or cancelled). */
|
|
41
54
|
onReplaced: (replacement: ReplacementReturnType) => void;
|
|
55
|
+
/** Callback fired when tracking fails fatally or exceeds all retry attempts. */
|
|
42
56
|
onFailure: (error?: unknown) => void;
|
|
57
|
+
/** Optional callback fired when tracker initialization starts. */
|
|
43
58
|
onInitialize?: () => void;
|
|
59
|
+
/** Number of retries for the initial `getTransaction` fetch step. Defaults to 10. */
|
|
44
60
|
retryCount?: number;
|
|
61
|
+
/** Timeout in milliseconds between `getTransaction` retry attempts. Defaults to 3000ms. */
|
|
45
62
|
retryTimeout?: number;
|
|
63
|
+
/** Optional callback fired whenever required block confirmation count updates. */
|
|
46
64
|
onConfirmationsUpdate?: (confirmations: number) => void;
|
|
65
|
+
/** Optional custom parameters passed directly to viem's `waitForTransactionReceipt`. */
|
|
47
66
|
waitForTransactionReceiptParams?: WaitForTransactionReceiptParameters;
|
|
48
67
|
};
|
|
49
68
|
/**
|
|
50
69
|
* A low-level tracker for monitoring a standard EVM transaction by its hash.
|
|
51
|
-
*
|
|
70
|
+
* Retries fetching transaction details and gracefully polls for transaction receipt,
|
|
71
|
+
* recovering automatically from RPC network glitches and timeout errors.
|
|
52
72
|
*
|
|
53
|
-
* @param
|
|
73
|
+
* @param params - The configuration parameters and lifecycle callbacks for the EVM tracker.
|
|
74
|
+
* @returns A promise that resolves when tracking completes or fails fatally.
|
|
54
75
|
*/
|
|
55
76
|
declare function evmTracker(params: EVMTrackerParams): Promise<void>;
|
|
56
77
|
/**
|
|
57
78
|
* A higher-level wrapper for `evmTracker` that integrates directly with the Pulsar store.
|
|
58
|
-
*
|
|
79
|
+
* Updates transaction lifecycle states (pending, success, failed, replaced) in the Zustand store.
|
|
59
80
|
*
|
|
60
|
-
* @template T - The application-specific transaction
|
|
81
|
+
* @template T - The application-specific transaction state structure extending `Transaction`.
|
|
82
|
+
* @param params - Configuration connecting `@wagmi/core`, store mutation methods, target transaction, and callbacks.
|
|
83
|
+
* @returns A promise that resolves when transaction tracking finishes and store state is committed.
|
|
61
84
|
*/
|
|
62
85
|
declare function evmTrackerForStore<T extends Transaction>(params: Pick<EVMTrackerParams, 'config'> & Pick<ITxTrackingStore<T>, 'updateTxParams' | 'transactionsPool'> & {
|
|
63
86
|
tx: T;
|
|
@@ -458,4 +481,4 @@ declare function speedUpTxAction<T extends Transaction>({ config, tx }: {
|
|
|
458
481
|
tx: T;
|
|
459
482
|
}): Promise<Hex>;
|
|
460
483
|
|
|
461
|
-
export { type EVMTrackerParams, type GelatoCapabilities, type GelatoCapabilitiesByChain, type GelatoClientConfig, GelatoStatusCode, type GelatoTaskStatus, type GelatoToken, SafeTransactionServiceUrls, type SafeTxStatusResponse, cancelTxAction, checkAndInitializeTrackerInStore, checkIsGelatoAvailable, checkTransactionsTracker, createGelatoClient, evmTracker, evmTrackerForStore, gelatoFetcher, gelatoTrackerForStore, gnosisSafeLinksHelper, pulsarEvmAdapter, safeFetcher, safeSdkOptions, safeTrackerForStore, selectEvmTxExplorerLink, speedUpTxAction };
|
|
484
|
+
export { type EVMTrackerParams, type GelatoCapabilities, type GelatoCapabilitiesByChain, type GelatoClientConfig, GelatoStatusCode, type GelatoTaskStatus, type GelatoToken, SafeTransactionServiceUrls, type SafeTxStatusResponse, cancelTxAction, checkAndInitializeTrackerInStore, checkIsGelatoAvailable, checkTransactionsTracker, createGelatoClient, evmTracker, evmTrackerForStore, gelatoFetcher, gelatoTrackerForStore, gnosisSafeLinksHelper, isRetryableReceiptError, pulsarEvmAdapter, safeFetcher, safeSdkOptions, safeTrackerForStore, selectEvmTxExplorerLink, speedUpTxAction };
|
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'),b=require('dayjs'),chains=require('viem/chains');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var b__default=/*#__PURE__*/_interopDefault(b);var F=1.15;async function A({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:n,maxPriorityFeePerGas:i,chainId:o}=e;if(a===void 0||!n||!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 s=core.getAccount(t);if(!s.address)throw new Error("No connected account found.");let c=BigInt(Math.ceil(Number(i)*F)),r=BigInt(Math.ceil(Number(n)*F));return await core.sendTransaction(t,{to:s.address,value:0n,chainId:o,nonce:a,maxFeePerGas:r,maxPriorityFeePerGas:c})}catch(s){let c=s instanceof Error?s.message:String(s);throw new Error(`Failed to cancel transaction: ${c}`,{cause:s})}}var be=10,ke=3e3,v=3,ye=1e4,Ce=5e3;async function Se(t){let{tx:e,config:a,onInitialize:n,onTxDetailsFetched:i,onSuccess:o,onFailure:s,onReplaced:c,retryCount:r=be,retryTimeout:l=ke,onConfirmationsUpdate:p,waitForTransactionReceiptParams:f}=t,{requiredConfirmations:d}=e;if(n?.(),e.txKey===viem.zeroHash)return s(new Error("Transaction hash cannot be the zero hash."));let u=core.getClient(a,{chainId:e.chainId});if(!u)return s(new Error(`Could not create a viem client for chainId: ${e.chainId}`));let m=null;for(let T=0;T<r;T++)try{m=await actions.getTransaction(u,{hash:e.txKey}),i(m);break}catch(h){if(T===r-1)return console.error(`[evmTracker] Fatal error fetching transaction ${e.txKey} on chain ${e.chainId}:`,h),s(h);console.warn(`[evmTracker] Error fetching transaction ${e.txKey} on chain ${e.chainId} (attempt ${T+1}/${r}):`,h),await new Promise(g=>setTimeout(g,l));}if(!m)return s(new Error("Transaction details could not be fetched."));let E=false;for(let T=0;T<=v;T++)try{let h=await actions.waitForTransactionReceipt(u,{hash:m.hash,onReplaced:g=>{E=!0,c(g);},...f});if(!E){let g=d??1;if(g>1)for(;;){try{let x=await actions.getTransactionConfirmations(u,{transactionReceipt:h}),I=Number(x);if(p?.(I),I>=g)break}catch(x){console.warn(`[evmTracker] Error fetching confirmations for ${e.txKey} on chain ${e.chainId}:`,x);}await new Promise(x=>setTimeout(x,Ce));}await o(m,h,u);}return}catch(h){if(h instanceof Error&&h.name==="TransactionReceiptNotFoundError"&&!E&&T<v){console.warn(`[evmTracker] Receipt not found for ${e.txKey}, retry ${T+1}/${v}...`),await new Promise(x=>setTimeout(x,ye*(T+1)));continue}s(h);return}}async function y(t){let{tx:e,config:a,updateTxParams:n,transactionsPool:i,onSuccess:o,onError:s,onReplaced:c}=t;return Se({tx:e,config:a,onInitialize:()=>{n(e.txKey,{hash:e.txKey});},onTxDetailsFetched:r=>{n(e.txKey,{to:r.to??void 0,input:r.input,value:r.value?.toString(),nonce:r.nonce,maxFeePerGas:r.maxFeePerGas?.toString(),maxPriorityFeePerGas:r.maxPriorityFeePerGas?.toString()});},onConfirmationsUpdate:r=>{n(e.txKey,{confirmations:r});},onSuccess:async(r,l,p)=>{let f=await actions.getBlock(p,{blockNumber:l.blockNumber}),d=Number(f.timestamp),u=l.status==="success";n(e.txKey,{status:u?pulsarCore.TransactionStatus.Success:pulsarCore.TransactionStatus.Failed,isError:!u,pending:false,finishedTimestamp:d});let m=i[e.txKey];u&&o&&m&&o(m),!u&&s&&m&&s(new Error("Transaction reverted"),m);},onReplaced:r=>{n(e.txKey,{status:pulsarCore.TransactionStatus.Replaced,replacedTxHash:r.transaction.hash,pending:false});let l=i[e.txKey];c&&l&&c(l,e);},onFailure:r=>{n(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,error:orbitCore.normalizeError(r)});let l=i[e.txKey];s&&l&&s(r,l);}})}var $=new Map,C=t=>{let{apiKey:e,baseUrl:a,timeout:n}=t,i=a||"https://api.gelato.cloud",o=`${e}:${i}`,s=$.get(o);if(s)return s;let c={timeout:n??15e3,...t.httpTransportConfig,fetchOptions:{headers:{Authorization:`Bearer ${e}`,...t.httpTransportConfig?.fetchOptions?.headers},...t.httpTransportConfig?.fetchOptions}},r=viem.http(`${i}/rpc`,c)({});return $.set(o,r),r};var Re=(o=>(o[o.Pending=100]="Pending",o[o.Submitted=110]="Submitted",o[o.Success=200]="Success",o[o.Rejected=400]="Rejected",o[o.Reverted=500]="Reverted",o))(Re||{}),Ge=new Set([200,400,500]);function Pe(t){return !Ge.has(t)}function Ie(t){return async({tx:e,stopPolling:a,onSuccess:n,onFailure:i,onIntervalTick:o})=>{let s=await t.request({method:"relayer_getStatus",params:{id:e.txKey,logs:false}});o?.(s);let{status:c,createdAt:r}=s;if(r&&b__default.default().diff(b__default.default.unix(r),"hour")>=1&&Pe(c)){a();return}c===200?(n(s),a({withoutRemoving:true})):(c===400||c===500)&&(i(s),a({withoutRemoving:true}));}}function K({tx:t,gelatoApiKey:e,updateTxParams:a,removeTxFromPool:n,transactionsPool:i,onSuccess:o,onError:s}){let c=C({apiKey:e}),r=Ie(c);return pulsarCore.initializePollingTracker({tx:t,fetcher:r,removeTxFromPool:n,onSuccess:l=>{let p=l.status===200?l.receipt.transactionHash:void 0;a(t.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:p,finishedTimestamp:b__default.default().unix()});let f=i[t.txKey];o&&f&&o(f);},onIntervalTick:l=>{l.status===110&&a(t.txKey,{hash:l.hash});},onFailure:l=>{let p="Transaction failed or was not found.",f;l&&(l.status===400?p=l.message||"Transaction was rejected by Gelato Relay.":l.status===500&&(p=l.message||"Transaction reverted on-chain.",f=l.receipt.transactionHash));let d=new Error(p);a(t.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:f,error:orbitCore.normalizeError(d),finishedTimestamp:b__default.default().unix()});let u=i[t.txKey];s&&u&&s(d,u);}})}var Rt={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},X={[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:"},Z={[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 He=async({tx:t,stopPolling:e,onSuccess:a,onFailure:n,onReplaced:i,onIntervalTick:o})=>{let s=Z[t.chainId];if(!s)throw new Error(`Safe Transaction Service URL not found for chainId: ${t.chainId}`);let c=await fetch(`${s}/multisig-transactions/${t.txKey}/`);if(!c.ok)throw c.status===404&&(n(),e()),new Error(`Safe API responded with status: ${c.status}`);let r=await c.json();if(o?.(r),r.isExecuted){r.isSuccessful?a(r):n(r),e({withoutRemoving:true});return}let l=await fetch(`${s}/safes/${t.from}/multisig-transactions/?nonce=${r.nonce}`);if(!l.ok)throw new Error(`Safe API (nonce check) responded with status: ${l.status}`);let f=(await l.json()).results.find(d=>d.isExecuted);if(f){i?.(f),e({withoutRemoving:true});return}b__default.default().diff(b__default.default(r.submissionDate),"day")>=1&&e();};function ee({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s}){return pulsarCore.initializePollingTracker({tx:t,fetcher:He,removeTxFromPool:a,onSuccess:c=>{e(t.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:c.transactionHash??void 0,finishedTimestamp:c.executionDate?b__default.default(c.executionDate).unix():void 0});let r=n[t.txKey];i&&r&&i(r);},onIntervalTick:c=>{e(t.txKey,{hash:c.transactionHash??void 0});},onFailure:c=>{let r=c?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:c?.transactionHash??void 0,error:orbitCore.normalizeError(r),finishedTimestamp:c?.executionDate?b__default.default(c.executionDate).unix():void 0});let l=n[t.txKey];o&&l&&o(r,l);},onReplaced:c=>{e(t.txKey,{status:pulsarCore.TransactionStatus.Replaced,pending:false,hash:t.adapter===orbitCore.OrbitAdapter.EVM?t.hash:viem.zeroHash,replacedTxHash:c.safeTxHash??viem.zeroHash,finishedTimestamp:c.executionDate?b__default.default(c.executionDate).unix():void 0});let r=n[t.txKey];s&&r&&s(r,t);}})}async function te({tracker:t,tx:e,config:a,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s,gelatoApiKey:c,...r}){switch(t){case pulsarCore.TransactionTracker.Ethereum:return y({tx:e,config:a,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s,...r});case pulsarCore.TransactionTracker.Gelato:return c?K({tx:e,transactionsPool:n,onSuccess:i,onError:o,gelatoApiKey:c,...r}):(console.warn(`Gelato tracker requested for tx '${e.txKey}', but no 'gelatoApiKey' was provided. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s,...r}));case pulsarCore.TransactionTracker.Safe:return ee({tx:e,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s,...r});default:return console.warn(`Unknown tracker type: '${t}'. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s,...r})}}function ae({actionTxKey:t,connectorType:e,tracker:a,gelatoApiKey:n}){if(a&&a===pulsarCore.TransactionTracker.Gelato&&n)return {tracker:pulsarCore.TransactionTracker.Gelato,txKey:t};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 i=e.split(":");return (i.length>1?i[i.length-1]==="safe"||i[i.length-1]==="safewallet":e?.toLowerCase()==="safe")?{tracker:pulsarCore.TransactionTracker.Safe,txKey:t}:{tracker:pulsarCore.TransactionTracker.Ethereum,txKey:t}}var ne=({chains:t,tx:e})=>{if(e.tracker===pulsarCore.TransactionTracker.Safe){let o=X[e.chainId];return o?`${o}${e.from}/transactions/tx?id=multisig_${e.from}_${e.txKey}`:""}let n=t.find(o=>o.id===e.chainId)?.blockExplorers?.default.url;if(!n)return "";let i=(e.adapter===orbitCore.OrbitAdapter.EVM?e.replacedTxHash:e.txKey)||(e.adapter===orbitCore.OrbitAdapter.EVM?e.hash:e.txKey);return i?`${n}/tx/${i}`:""};var oe=1.15;async function ie({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:n,to:i,value:o,input:s,maxFeePerGas:c,maxPriorityFeePerGas:r,chainId:l}=e;if(a===void 0||!n||!i||!o||!c||!r)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 f=BigInt(Math.ceil(Number(r)*oe)),d=BigInt(Math.ceil(Number(c)*oe));return await core.sendTransaction(t,{to:i,value:BigInt(o),data:s||"0x",chainId:l,nonce:a,maxFeePerGas:d,maxPriorityFeePerGas:f})}catch(p){let f=p instanceof Error?p.message:String(p);throw new Error(`Failed to speed up transaction: ${f}`,{cause:p})}}function ya(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),n=orbitCore.lastConnectedConnectorHelpers.getLastConnectedConnector();return {walletAddress:a.address??n?.address??viem.zeroAddress,connectorType:orbitCore.getConnectorTypeFromName(orbitCore.OrbitAdapter.EVM,a.connector?.name?.toLowerCase()??"unknown")}},checkChainForTx:a=>orbitEvm.checkAndSwitchChain(a,t),checkTransactionsTracker:a=>ae(a),checkAndInitializeTrackerInStore:({tx:a,...n})=>te({tracker:a.tracker,tx:a,config:t,...n}),getExplorerUrl:a=>{let{chain:n}=core.getConnection(t),i=n?.blockExplorers?.default.url;return a?`${i}/${a}`:i},getExplorerTxUrl:a=>ne({chains:e,tx:a}),cancelTxAction:a=>A({config:t,tx:a}),speedUpTxAction:a=>ie({config:t,tx:a}),retryTxAction:async({onClose:a,txKey:n,executeTxAction:i,tx:o})=>{if(a(n),!i){console.error("Retry failed: executeTxAction function is not provided.");return}await i({actionFunction:()=>o.actionFunction({config:t,...o.payload}),params:o,defaultTracker:pulsarCore.TransactionTracker.Ethereum});}}}var P=new Map;async function De(t){let e=await t.request({method:"relayer_getCapabilities",params:[]}),a={};for(let[n,i]of Object.entries(e))a[Number(n)]=i;return a}async function je(t){let e=P.get(t);if(e)return e;let a=C({apiKey:t}),n=await De(a);return P.set(t,n),n}async function wa(t,e){try{let a=await je(e);return t in a}catch(a){return console.error("Failed to fetch Gelato relay capabilities:",a),P.delete(e),false}}
|
|
2
|
-
exports.GelatoStatusCode
|
|
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'),b=require('dayjs'),chains=require('viem/chains');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var b__default=/*#__PURE__*/_interopDefault(b);var P=1.15;async function A({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:r,maxPriorityFeePerGas:i,chainId:o}=e;if(a===void 0||!r||!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 s=core.getAccount(t);if(!s.address)throw new Error("No connected account found.");let c=BigInt(Math.ceil(Number(i)*P)),n=BigInt(Math.ceil(Number(r)*P));return await core.sendTransaction(t,{to:s.address,value:0n,chainId:o,nonce:a,maxFeePerGas:n,maxPriorityFeePerGas:c})}catch(s){let c=s instanceof Error?s.message:String(s);throw new Error(`Failed to cancel transaction: ${c}`,{cause:s})}}var $=10,H=3e3,R=5,Re=5e3,ve=5e3,Ge=6e4;function K(t){return t?(a=>{if(!(a instanceof Error))return false;if(a instanceof viem.WaitForTransactionReceiptTimeoutError||a instanceof viem.TransactionReceiptNotFoundError||a.name==="WaitForTransactionReceiptTimeoutError"||a.name==="TransactionReceiptNotFoundError"||a instanceof viem.HttpRequestError||a instanceof viem.WebSocketRequestError||a.name==="HttpRequestError"||a.name==="WebSocketRequestError"||a.name==="TimeoutError")return true;let r=a.message.toLowerCase();return r.includes("fetch failed")||r.includes("network error")||r.includes("timeout")||r.includes("timed out")||r.includes("econnreset")||r.includes("rate limit")||r.includes("502")||r.includes("503")||r.includes("504")})(t)?true:t instanceof Error&&"cause"in t&&t.cause?K(t.cause):false:false}async function Ie(t){let{tx:e,config:a,onInitialize:r,onTxDetailsFetched:i,onSuccess:o,onFailure:s,onReplaced:c,retryCount:n=$,retryTimeout:l=H,onConfirmationsUpdate:p,waitForTransactionReceiptParams:f}=t,{requiredConfirmations:m}=e;if(r?.(),e.txKey===viem.zeroHash)return s(new Error("Transaction hash cannot be the zero hash."));let u=core.getClient(a,{chainId:e.chainId});if(!u)return s(new Error(`Could not create a viem client for chainId: ${e.chainId}`));let T=null;for(let h=0;h<n;h++)try{T=await actions.getTransaction(u,{hash:e.txKey}),i(T);break}catch(d){if(h===n-1)return console.error(`[evmTracker] Fatal error fetching transaction ${e.txKey} on chain ${e.chainId}:`,d),s(d);console.warn(`[evmTracker] Error fetching transaction ${e.txKey} on chain ${e.chainId} (attempt ${h+1}/${n}):`,d),await new Promise(g=>setTimeout(g,l));}if(!T)return s(new Error("Transaction details could not be fetched."));let w=false;for(let h=0;h<=R;h++)try{let d=await actions.waitForTransactionReceipt(u,{hash:T.hash,onReplaced:g=>{w=!0,c(g);},retryCount:$,retryDelay:H,timeout:Ge,...f});if(!w){let g=m??1;if(g>1)for(;;){try{let x=await actions.getTransactionConfirmations(u,{transactionReceipt:d}),F=Number(x);if(p?.(F),F>=g)break}catch(x){console.warn(`[evmTracker] Error fetching confirmations for ${e.txKey} on chain ${e.chainId}:`,x);}await new Promise(x=>setTimeout(x,ve));}await o(T,d,u);}return}catch(d){if(K(d)&&!w&&h<R){console.warn(`[evmTracker] Transient error for ${e.txKey} on chain ${e.chainId} (attempt ${h+1}/${R}). Error: ${d instanceof Error?d.name:"Unknown"}. Retrying...`),await new Promise(x=>setTimeout(x,Re*(h+1)));continue}s(d);return}}async function y(t){let{tx:e,config:a,updateTxParams:r,transactionsPool:i,onSuccess:o,onError:s,onReplaced:c}=t;return Ie({tx:e,config:a,onInitialize:()=>{r(e.txKey,{hash:e.txKey});},onTxDetailsFetched:n=>{r(e.txKey,{to:n.to??void 0,input:n.input,value:n.value?.toString(),nonce:n.nonce,maxFeePerGas:n.maxFeePerGas?.toString(),maxPriorityFeePerGas:n.maxPriorityFeePerGas?.toString()});},onConfirmationsUpdate:n=>{r(e.txKey,{confirmations:n});},onSuccess:async(n,l,p)=>{let f=await actions.getBlock(p,{blockNumber:l.blockNumber}),m=Number(f.timestamp),u=l.status==="success";r(e.txKey,{status:u?pulsarCore.TransactionStatus.Success:pulsarCore.TransactionStatus.Failed,isError:!u,pending:false,finishedTimestamp:m});let T=i[e.txKey];u&&o&&T&&o(T),!u&&s&&T&&s(new Error("Transaction reverted"),T);},onReplaced:n=>{r(e.txKey,{status:pulsarCore.TransactionStatus.Replaced,replacedTxHash:n.transaction.hash,pending:false});let l=i[e.txKey];c&&l&&c(l,e);},onFailure:n=>{r(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,error:orbitCore.normalizeError(n)});let l=i[e.txKey];s&&l&&s(n,l);}})}var M=new Map,E=t=>{let{apiKey:e,baseUrl:a,timeout:r}=t,i=a||"https://api.gelato.cloud",o=`${e}:${i}`,s=M.get(o);if(s)return s;let c={timeout:r??15e3,...t.httpTransportConfig,fetchOptions:{headers:{Authorization:`Bearer ${e}`,...t.httpTransportConfig?.fetchOptions?.headers},...t.httpTransportConfig?.fetchOptions}},n=viem.http(`${i}/rpc`,c)({});return M.set(o,n),n};var $e=(o=>(o[o.Pending=100]="Pending",o[o.Submitted=110]="Submitted",o[o.Success=200]="Success",o[o.Rejected=400]="Rejected",o[o.Reverted=500]="Reverted",o))($e||{}),He=new Set([200,400,500]);function Ke(t){return !He.has(t)}function Me(t){return async({tx:e,stopPolling:a,onSuccess:r,onFailure:i,onIntervalTick:o})=>{let s=await t.request({method:"relayer_getStatus",params:{id:e.txKey,logs:false}});o?.(s);let{status:c,createdAt:n}=s;if(n&&b__default.default().diff(b__default.default.unix(n),"hour")>=1&&Ke(c)){a();return}c===200?(r(s),a({withoutRemoving:true})):(c===400||c===500)&&(i(s),a({withoutRemoving:true}));}}function _({tx:t,gelatoApiKey:e,updateTxParams:a,removeTxFromPool:r,transactionsPool:i,onSuccess:o,onError:s}){let c=E({apiKey:e}),n=Me(c);return pulsarCore.initializePollingTracker({tx:t,fetcher:n,removeTxFromPool:r,onSuccess:l=>{let p=l.status===200?l.receipt.transactionHash:void 0;a(t.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:p,finishedTimestamp:b__default.default().unix()});let f=i[t.txKey];o&&f&&o(f);},onIntervalTick:l=>{l.status===110&&a(t.txKey,{hash:l.hash});},onFailure:l=>{let p="Transaction failed or was not found.",f;l&&(l.status===400?p=l.message||"Transaction was rejected by Gelato Relay.":l.status===500&&(p=l.message||"Transaction reverted on-chain.",f=l.receipt.transactionHash));let m=new Error(p);a(t.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,hash:f,error:orbitCore.normalizeError(m),finishedTimestamp:b__default.default().unix()});let u=i[t.txKey];s&&u&&s(m,u);}})}var $t={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},ee={[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:"},te={[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 Ue=async({tx:t,stopPolling:e,onSuccess:a,onFailure:r,onReplaced:i,onIntervalTick:o})=>{let s=te[t.chainId];if(!s)throw new Error(`Safe Transaction Service URL not found for chainId: ${t.chainId}`);let c=await fetch(`${s}/multisig-transactions/${t.txKey}/`);if(!c.ok)throw c.status===404&&(r(),e()),new Error(`Safe API responded with status: ${c.status}`);let n=await c.json();if(o?.(n),n.isExecuted){n.isSuccessful?a(n):r(n),e({withoutRemoving:true});return}let l=await fetch(`${s}/safes/${t.from}/multisig-transactions/?nonce=${n.nonce}`);if(!l.ok)throw new Error(`Safe API (nonce check) responded with status: ${l.status}`);let f=(await l.json()).results.find(m=>m.isExecuted);if(f){i?.(f),e({withoutRemoving:true});return}b__default.default().diff(b__default.default(n.submissionDate),"day")>=1&&e();};function re({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s}){return pulsarCore.initializePollingTracker({tx:t,fetcher:Ue,removeTxFromPool:a,onSuccess:c=>{e(t.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,hash:c.transactionHash??void 0,finishedTimestamp:c.executionDate?b__default.default(c.executionDate).unix():void 0});let n=r[t.txKey];i&&n&&i(n);},onIntervalTick:c=>{e(t.txKey,{hash:c.transactionHash??void 0});},onFailure:c=>{let n=c?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:c?.transactionHash??void 0,error:orbitCore.normalizeError(n),finishedTimestamp:c?.executionDate?b__default.default(c.executionDate).unix():void 0});let l=r[t.txKey];o&&l&&o(n,l);},onReplaced:c=>{e(t.txKey,{status:pulsarCore.TransactionStatus.Replaced,pending:false,hash:t.adapter===orbitCore.OrbitAdapter.EVM?t.hash:viem.zeroHash,replacedTxHash:c.safeTxHash??viem.zeroHash,finishedTimestamp:c.executionDate?b__default.default(c.executionDate).unix():void 0});let n=r[t.txKey];s&&n&&s(n,t);}})}async function ne({tracker:t,tx:e,config:a,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s,gelatoApiKey:c,...n}){switch(t){case pulsarCore.TransactionTracker.Ethereum:return y({tx:e,config:a,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s,...n});case pulsarCore.TransactionTracker.Gelato:return c?_({tx:e,transactionsPool:r,onSuccess:i,onError:o,gelatoApiKey:c,...n}):(console.warn(`Gelato tracker requested for tx '${e.txKey}', but no 'gelatoApiKey' was provided. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s,...n}));case pulsarCore.TransactionTracker.Safe:return re({tx:e,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s,...n});default:return console.warn(`Unknown tracker type: '${t}'. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s,...n})}}function oe({actionTxKey:t,connectorType:e,tracker:a,gelatoApiKey:r}){if(a&&a===pulsarCore.TransactionTracker.Gelato&&r)return {tracker:pulsarCore.TransactionTracker.Gelato,txKey:t};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 i=e.split(":");return (i.length>1?i[i.length-1]==="safe"||i[i.length-1]==="safewallet":e?.toLowerCase()==="safe")?{tracker:pulsarCore.TransactionTracker.Safe,txKey:t}:{tracker:pulsarCore.TransactionTracker.Ethereum,txKey:t}}var se=({chains:t,tx:e})=>{if(e.tracker===pulsarCore.TransactionTracker.Safe){let o=ee[e.chainId];return o?`${o}${e.from}/transactions/tx?id=multisig_${e.from}_${e.txKey}`:""}let r=t.find(o=>o.id===e.chainId)?.blockExplorers?.default.url;if(!r)return "";let i=(e.adapter===orbitCore.OrbitAdapter.EVM?e.replacedTxHash:e.txKey)||(e.adapter===orbitCore.OrbitAdapter.EVM?e.hash:e.txKey);return i?`${r}/tx/${i}`:""};var ce=1.15;async function le({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:r,to:i,value:o,input:s,maxFeePerGas:c,maxPriorityFeePerGas:n,chainId:l}=e;if(a===void 0||!r||!i||!o||!c||!n)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 f=BigInt(Math.ceil(Number(n)*ce)),m=BigInt(Math.ceil(Number(c)*ce));return await core.sendTransaction(t,{to:i,value:BigInt(o),data:s||"0x",chainId:l,nonce:a,maxFeePerGas:m,maxPriorityFeePerGas:f})}catch(p){let f=p instanceof Error?p.message:String(p);throw new Error(`Failed to speed up transaction: ${f}`,{cause:p})}}function va(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),r=orbitCore.lastConnectedConnectorHelpers.getLastConnectedConnector();return {walletAddress:a.address??r?.address??viem.zeroAddress,connectorType:orbitCore.getConnectorTypeFromName(orbitCore.OrbitAdapter.EVM,a.connector?.name?.toLowerCase()??"unknown")}},checkChainForTx:a=>orbitEvm.checkAndSwitchChain(a,t),checkTransactionsTracker:a=>oe(a),checkAndInitializeTrackerInStore:({tx:a,...r})=>ne({tracker:a.tracker,tx:a,config:t,...r}),getExplorerUrl:a=>{let{chain:r}=core.getConnection(t),i=r?.blockExplorers?.default.url;return a?`${i}/${a}`:i},getExplorerTxUrl:a=>se({chains:e,tx:a}),cancelTxAction:a=>A({config:t,tx:a}),speedUpTxAction:a=>le({config:t,tx:a}),retryTxAction:async({onClose:a,txKey:r,executeTxAction:i,tx:o})=>{if(a(r),!i){console.error("Retry failed: executeTxAction function is not provided.");return}await i({actionFunction:()=>o.actionFunction({config:t,...o.payload}),params:o,defaultTracker:pulsarCore.TransactionTracker.Ethereum});}}}var I=new Map;async function Xe(t){let e=await t.request({method:"relayer_getCapabilities",params:[]}),a={};for(let[r,i]of Object.entries(e))a[Number(r)]=i;return a}async function Ze(t){let e=I.get(t);if(e)return e;let a=E({apiKey:t}),r=await Xe(a);return I.set(t,r),r}async function Fa(t,e){try{let a=await Ze(e);return t in a}catch(a){return console.error("Failed to fetch Gelato relay capabilities:",a),I.delete(e),false}}
|
|
2
|
+
exports.GelatoStatusCode=$e;exports.SafeTransactionServiceUrls=te;exports.cancelTxAction=A;exports.checkAndInitializeTrackerInStore=ne;exports.checkIsGelatoAvailable=Fa;exports.checkTransactionsTracker=oe;exports.createGelatoClient=E;exports.evmTracker=Ie;exports.evmTrackerForStore=y;exports.gelatoFetcher=Me;exports.gelatoTrackerForStore=_;exports.gnosisSafeLinksHelper=ee;exports.isRetryableReceiptError=K;exports.pulsarEvmAdapter=va;exports.safeFetcher=Ue;exports.safeSdkOptions=$t;exports.safeTrackerForStore=re;exports.selectEvmTxExplorerLink=se;exports.speedUpTxAction=le;
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
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,http,isHex,zeroAddress}from'viem';import {getTransaction,waitForTransactionReceipt,getTransactionConfirmations,getBlock}from'viem/actions';import b from'dayjs';import {zksync,polygonZkEvm,optimism,gnosis,celo,bsc,boba,base,avalanche,aurora,arbitrum,polygon,sepolia,goerli,mainnet}from'viem/chains';var F=1.15;async function A({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:n,maxPriorityFeePerGas:i,chainId:o}=e;if(a===void 0||!n||!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 s=getAccount(t);if(!s.address)throw new Error("No connected account found.");let c=BigInt(Math.ceil(Number(i)*F)),r=BigInt(Math.ceil(Number(n)*F));return await sendTransaction(t,{to:s.address,value:0n,chainId:o,nonce:a,maxFeePerGas:r,maxPriorityFeePerGas:c})}catch(s){let c=s instanceof Error?s.message:String(s);throw new Error(`Failed to cancel transaction: ${c}`,{cause:s})}}var be=10,ke=3e3,v=3,ye=1e4,Ce=5e3;async function Se(t){let{tx:e,config:a,onInitialize:n,onTxDetailsFetched:i,onSuccess:o,onFailure:s,onReplaced:c,retryCount:r=be,retryTimeout:l=ke,onConfirmationsUpdate:p,waitForTransactionReceiptParams:f}=t,{requiredConfirmations:d}=e;if(n?.(),e.txKey===zeroHash)return s(new Error("Transaction hash cannot be the zero hash."));let u=getClient(a,{chainId:e.chainId});if(!u)return s(new Error(`Could not create a viem client for chainId: ${e.chainId}`));let m=null;for(let T=0;T<r;T++)try{m=await getTransaction(u,{hash:e.txKey}),i(m);break}catch(h){if(T===r-1)return console.error(`[evmTracker] Fatal error fetching transaction ${e.txKey} on chain ${e.chainId}:`,h),s(h);console.warn(`[evmTracker] Error fetching transaction ${e.txKey} on chain ${e.chainId} (attempt ${T+1}/${r}):`,h),await new Promise(g=>setTimeout(g,l));}if(!m)return s(new Error("Transaction details could not be fetched."));let E=false;for(let T=0;T<=v;T++)try{let h=await waitForTransactionReceipt(u,{hash:m.hash,onReplaced:g=>{E=!0,c(g);},...f});if(!E){let g=d??1;if(g>1)for(;;){try{let x=await getTransactionConfirmations(u,{transactionReceipt:h}),I=Number(x);if(p?.(I),I>=g)break}catch(x){console.warn(`[evmTracker] Error fetching confirmations for ${e.txKey} on chain ${e.chainId}:`,x);}await new Promise(x=>setTimeout(x,Ce));}await o(m,h,u);}return}catch(h){if(h instanceof Error&&h.name==="TransactionReceiptNotFoundError"&&!E&&T<v){console.warn(`[evmTracker] Receipt not found for ${e.txKey}, retry ${T+1}/${v}...`),await new Promise(x=>setTimeout(x,ye*(T+1)));continue}s(h);return}}async function y(t){let{tx:e,config:a,updateTxParams:n,transactionsPool:i,onSuccess:o,onError:s,onReplaced:c}=t;return Se({tx:e,config:a,onInitialize:()=>{n(e.txKey,{hash:e.txKey});},onTxDetailsFetched:r=>{n(e.txKey,{to:r.to??void 0,input:r.input,value:r.value?.toString(),nonce:r.nonce,maxFeePerGas:r.maxFeePerGas?.toString(),maxPriorityFeePerGas:r.maxPriorityFeePerGas?.toString()});},onConfirmationsUpdate:r=>{n(e.txKey,{confirmations:r});},onSuccess:async(r,l,p)=>{let f=await getBlock(p,{blockNumber:l.blockNumber}),d=Number(f.timestamp),u=l.status==="success";n(e.txKey,{status:u?TransactionStatus.Success:TransactionStatus.Failed,isError:!u,pending:false,finishedTimestamp:d});let m=i[e.txKey];u&&o&&m&&o(m),!u&&s&&m&&s(new Error("Transaction reverted"),m);},onReplaced:r=>{n(e.txKey,{status:TransactionStatus.Replaced,replacedTxHash:r.transaction.hash,pending:false});let l=i[e.txKey];c&&l&&c(l,e);},onFailure:r=>{n(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,error:normalizeError(r)});let l=i[e.txKey];s&&l&&s(r,l);}})}var $=new Map,C=t=>{let{apiKey:e,baseUrl:a,timeout:n}=t,i=a||"https://api.gelato.cloud",o=`${e}:${i}`,s=$.get(o);if(s)return s;let c={timeout:n??15e3,...t.httpTransportConfig,fetchOptions:{headers:{Authorization:`Bearer ${e}`,...t.httpTransportConfig?.fetchOptions?.headers},...t.httpTransportConfig?.fetchOptions}},r=http(`${i}/rpc`,c)({});return $.set(o,r),r};var Re=(o=>(o[o.Pending=100]="Pending",o[o.Submitted=110]="Submitted",o[o.Success=200]="Success",o[o.Rejected=400]="Rejected",o[o.Reverted=500]="Reverted",o))(Re||{}),Ge=new Set([200,400,500]);function Pe(t){return !Ge.has(t)}function Ie(t){return async({tx:e,stopPolling:a,onSuccess:n,onFailure:i,onIntervalTick:o})=>{let s=await t.request({method:"relayer_getStatus",params:{id:e.txKey,logs:false}});o?.(s);let{status:c,createdAt:r}=s;if(r&&b().diff(b.unix(r),"hour")>=1&&Pe(c)){a();return}c===200?(n(s),a({withoutRemoving:true})):(c===400||c===500)&&(i(s),a({withoutRemoving:true}));}}function K({tx:t,gelatoApiKey:e,updateTxParams:a,removeTxFromPool:n,transactionsPool:i,onSuccess:o,onError:s}){let c=C({apiKey:e}),r=Ie(c);return initializePollingTracker({tx:t,fetcher:r,removeTxFromPool:n,onSuccess:l=>{let p=l.status===200?l.receipt.transactionHash:void 0;a(t.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:p,finishedTimestamp:b().unix()});let f=i[t.txKey];o&&f&&o(f);},onIntervalTick:l=>{l.status===110&&a(t.txKey,{hash:l.hash});},onFailure:l=>{let p="Transaction failed or was not found.",f;l&&(l.status===400?p=l.message||"Transaction was rejected by Gelato Relay.":l.status===500&&(p=l.message||"Transaction reverted on-chain.",f=l.receipt.transactionHash));let d=new Error(p);a(t.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:f,error:normalizeError(d),finishedTimestamp:b().unix()});let u=i[t.txKey];s&&u&&s(d,u);}})}var Rt={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},X={[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:"},Z={[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 He=async({tx:t,stopPolling:e,onSuccess:a,onFailure:n,onReplaced:i,onIntervalTick:o})=>{let s=Z[t.chainId];if(!s)throw new Error(`Safe Transaction Service URL not found for chainId: ${t.chainId}`);let c=await fetch(`${s}/multisig-transactions/${t.txKey}/`);if(!c.ok)throw c.status===404&&(n(),e()),new Error(`Safe API responded with status: ${c.status}`);let r=await c.json();if(o?.(r),r.isExecuted){r.isSuccessful?a(r):n(r),e({withoutRemoving:true});return}let l=await fetch(`${s}/safes/${t.from}/multisig-transactions/?nonce=${r.nonce}`);if(!l.ok)throw new Error(`Safe API (nonce check) responded with status: ${l.status}`);let f=(await l.json()).results.find(d=>d.isExecuted);if(f){i?.(f),e({withoutRemoving:true});return}b().diff(b(r.submissionDate),"day")>=1&&e();};function ee({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s}){return initializePollingTracker({tx:t,fetcher:He,removeTxFromPool:a,onSuccess:c=>{e(t.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:c.transactionHash??void 0,finishedTimestamp:c.executionDate?b(c.executionDate).unix():void 0});let r=n[t.txKey];i&&r&&i(r);},onIntervalTick:c=>{e(t.txKey,{hash:c.transactionHash??void 0});},onFailure:c=>{let r=c?new Error("Safe transaction failed or was rejected."):new Error("Transaction not found.");e(t.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:c?.transactionHash??void 0,error:normalizeError(r),finishedTimestamp:c?.executionDate?b(c.executionDate).unix():void 0});let l=n[t.txKey];o&&l&&o(r,l);},onReplaced:c=>{e(t.txKey,{status:TransactionStatus.Replaced,pending:false,hash:t.adapter===OrbitAdapter.EVM?t.hash:zeroHash,replacedTxHash:c.safeTxHash??zeroHash,finishedTimestamp:c.executionDate?b(c.executionDate).unix():void 0});let r=n[t.txKey];s&&r&&s(r,t);}})}async function te({tracker:t,tx:e,config:a,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s,gelatoApiKey:c,...r}){switch(t){case TransactionTracker.Ethereum:return y({tx:e,config:a,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s,...r});case TransactionTracker.Gelato:return c?K({tx:e,transactionsPool:n,onSuccess:i,onError:o,gelatoApiKey:c,...r}):(console.warn(`Gelato tracker requested for tx '${e.txKey}', but no 'gelatoApiKey' was provided. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s,...r}));case TransactionTracker.Safe:return ee({tx:e,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s,...r});default:return console.warn(`Unknown tracker type: '${t}'. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:n,onSuccess:i,onError:o,onReplaced:s,...r})}}function ae({actionTxKey:t,connectorType:e,tracker:a,gelatoApiKey:n}){if(a&&a===TransactionTracker.Gelato&&n)return {tracker:TransactionTracker.Gelato,txKey:t};if(!isHex(t))throw new Error(`Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(t)}`);let i=e.split(":");return (i.length>1?i[i.length-1]==="safe"||i[i.length-1]==="safewallet":e?.toLowerCase()==="safe")?{tracker:TransactionTracker.Safe,txKey:t}:{tracker:TransactionTracker.Ethereum,txKey:t}}var ne=({chains:t,tx:e})=>{if(e.tracker===TransactionTracker.Safe){let o=X[e.chainId];return o?`${o}${e.from}/transactions/tx?id=multisig_${e.from}_${e.txKey}`:""}let n=t.find(o=>o.id===e.chainId)?.blockExplorers?.default.url;if(!n)return "";let i=(e.adapter===OrbitAdapter.EVM?e.replacedTxHash:e.txKey)||(e.adapter===OrbitAdapter.EVM?e.hash:e.txKey);return i?`${n}/tx/${i}`:""};var oe=1.15;async function ie({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:n,to:i,value:o,input:s,maxFeePerGas:c,maxPriorityFeePerGas:r,chainId:l}=e;if(a===void 0||!n||!i||!o||!c||!r)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 f=BigInt(Math.ceil(Number(r)*oe)),d=BigInt(Math.ceil(Number(c)*oe));return await sendTransaction(t,{to:i,value:BigInt(o),data:s||"0x",chainId:l,nonce:a,maxFeePerGas:d,maxPriorityFeePerGas:f})}catch(p){let f=p instanceof Error?p.message:String(p);throw new Error(`Failed to speed up transaction: ${f}`,{cause:p})}}function ya(t,e){if(!t)throw new Error("EVM adapter requires a wagmi config object.");return {key:OrbitAdapter.EVM,getConnectorInfo:()=>{let a=getConnection(t),n=lastConnectedConnectorHelpers.getLastConnectedConnector();return {walletAddress:a.address??n?.address??zeroAddress,connectorType:getConnectorTypeFromName(OrbitAdapter.EVM,a.connector?.name?.toLowerCase()??"unknown")}},checkChainForTx:a=>checkAndSwitchChain(a,t),checkTransactionsTracker:a=>ae(a),checkAndInitializeTrackerInStore:({tx:a,...n})=>te({tracker:a.tracker,tx:a,config:t,...n}),getExplorerUrl:a=>{let{chain:n}=getConnection(t),i=n?.blockExplorers?.default.url;return a?`${i}/${a}`:i},getExplorerTxUrl:a=>ne({chains:e,tx:a}),cancelTxAction:a=>A({config:t,tx:a}),speedUpTxAction:a=>ie({config:t,tx:a}),retryTxAction:async({onClose:a,txKey:n,executeTxAction:i,tx:o})=>{if(a(n),!i){console.error("Retry failed: executeTxAction function is not provided.");return}await i({actionFunction:()=>o.actionFunction({config:t,...o.payload}),params:o,defaultTracker:TransactionTracker.Ethereum});}}}var P=new Map;async function De(t){let e=await t.request({method:"relayer_getCapabilities",params:[]}),a={};for(let[n,i]of Object.entries(e))a[Number(n)]=i;return a}async function je(t){let e=P.get(t);if(e)return e;let a=C({apiKey:t}),n=await De(a);return P.set(t,n),n}async function wa(t,e){try{let a=await je(e);return t in a}catch(a){return console.error("Failed to fetch Gelato relay capabilities:",a),P.delete(e),false}}
|
|
2
|
-
export{
|
|
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 {WaitForTransactionReceiptTimeoutError,TransactionReceiptNotFoundError,HttpRequestError,WebSocketRequestError,zeroHash,http,isHex,zeroAddress}from'viem';import {getTransaction,waitForTransactionReceipt,getTransactionConfirmations,getBlock}from'viem/actions';import b from'dayjs';import {zksync,polygonZkEvm,optimism,gnosis,celo,bsc,boba,base,avalanche,aurora,arbitrum,polygon,sepolia,goerli,mainnet}from'viem/chains';var P=1.15;async function A({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:r,maxPriorityFeePerGas:i,chainId:o}=e;if(a===void 0||!r||!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 s=getAccount(t);if(!s.address)throw new Error("No connected account found.");let c=BigInt(Math.ceil(Number(i)*P)),n=BigInt(Math.ceil(Number(r)*P));return await sendTransaction(t,{to:s.address,value:0n,chainId:o,nonce:a,maxFeePerGas:n,maxPriorityFeePerGas:c})}catch(s){let c=s instanceof Error?s.message:String(s);throw new Error(`Failed to cancel transaction: ${c}`,{cause:s})}}var $=10,H=3e3,R=5,Re=5e3,ve=5e3,Ge=6e4;function K(t){return t?(a=>{if(!(a instanceof Error))return false;if(a instanceof WaitForTransactionReceiptTimeoutError||a instanceof TransactionReceiptNotFoundError||a.name==="WaitForTransactionReceiptTimeoutError"||a.name==="TransactionReceiptNotFoundError"||a instanceof HttpRequestError||a instanceof WebSocketRequestError||a.name==="HttpRequestError"||a.name==="WebSocketRequestError"||a.name==="TimeoutError")return true;let r=a.message.toLowerCase();return r.includes("fetch failed")||r.includes("network error")||r.includes("timeout")||r.includes("timed out")||r.includes("econnreset")||r.includes("rate limit")||r.includes("502")||r.includes("503")||r.includes("504")})(t)?true:t instanceof Error&&"cause"in t&&t.cause?K(t.cause):false:false}async function Ie(t){let{tx:e,config:a,onInitialize:r,onTxDetailsFetched:i,onSuccess:o,onFailure:s,onReplaced:c,retryCount:n=$,retryTimeout:l=H,onConfirmationsUpdate:p,waitForTransactionReceiptParams:f}=t,{requiredConfirmations:m}=e;if(r?.(),e.txKey===zeroHash)return s(new Error("Transaction hash cannot be the zero hash."));let u=getClient(a,{chainId:e.chainId});if(!u)return s(new Error(`Could not create a viem client for chainId: ${e.chainId}`));let T=null;for(let h=0;h<n;h++)try{T=await getTransaction(u,{hash:e.txKey}),i(T);break}catch(d){if(h===n-1)return console.error(`[evmTracker] Fatal error fetching transaction ${e.txKey} on chain ${e.chainId}:`,d),s(d);console.warn(`[evmTracker] Error fetching transaction ${e.txKey} on chain ${e.chainId} (attempt ${h+1}/${n}):`,d),await new Promise(g=>setTimeout(g,l));}if(!T)return s(new Error("Transaction details could not be fetched."));let w=false;for(let h=0;h<=R;h++)try{let d=await waitForTransactionReceipt(u,{hash:T.hash,onReplaced:g=>{w=!0,c(g);},retryCount:$,retryDelay:H,timeout:Ge,...f});if(!w){let g=m??1;if(g>1)for(;;){try{let x=await getTransactionConfirmations(u,{transactionReceipt:d}),F=Number(x);if(p?.(F),F>=g)break}catch(x){console.warn(`[evmTracker] Error fetching confirmations for ${e.txKey} on chain ${e.chainId}:`,x);}await new Promise(x=>setTimeout(x,ve));}await o(T,d,u);}return}catch(d){if(K(d)&&!w&&h<R){console.warn(`[evmTracker] Transient error for ${e.txKey} on chain ${e.chainId} (attempt ${h+1}/${R}). Error: ${d instanceof Error?d.name:"Unknown"}. Retrying...`),await new Promise(x=>setTimeout(x,Re*(h+1)));continue}s(d);return}}async function y(t){let{tx:e,config:a,updateTxParams:r,transactionsPool:i,onSuccess:o,onError:s,onReplaced:c}=t;return Ie({tx:e,config:a,onInitialize:()=>{r(e.txKey,{hash:e.txKey});},onTxDetailsFetched:n=>{r(e.txKey,{to:n.to??void 0,input:n.input,value:n.value?.toString(),nonce:n.nonce,maxFeePerGas:n.maxFeePerGas?.toString(),maxPriorityFeePerGas:n.maxPriorityFeePerGas?.toString()});},onConfirmationsUpdate:n=>{r(e.txKey,{confirmations:n});},onSuccess:async(n,l,p)=>{let f=await getBlock(p,{blockNumber:l.blockNumber}),m=Number(f.timestamp),u=l.status==="success";r(e.txKey,{status:u?TransactionStatus.Success:TransactionStatus.Failed,isError:!u,pending:false,finishedTimestamp:m});let T=i[e.txKey];u&&o&&T&&o(T),!u&&s&&T&&s(new Error("Transaction reverted"),T);},onReplaced:n=>{r(e.txKey,{status:TransactionStatus.Replaced,replacedTxHash:n.transaction.hash,pending:false});let l=i[e.txKey];c&&l&&c(l,e);},onFailure:n=>{r(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,error:normalizeError(n)});let l=i[e.txKey];s&&l&&s(n,l);}})}var M=new Map,E=t=>{let{apiKey:e,baseUrl:a,timeout:r}=t,i=a||"https://api.gelato.cloud",o=`${e}:${i}`,s=M.get(o);if(s)return s;let c={timeout:r??15e3,...t.httpTransportConfig,fetchOptions:{headers:{Authorization:`Bearer ${e}`,...t.httpTransportConfig?.fetchOptions?.headers},...t.httpTransportConfig?.fetchOptions}},n=http(`${i}/rpc`,c)({});return M.set(o,n),n};var $e=(o=>(o[o.Pending=100]="Pending",o[o.Submitted=110]="Submitted",o[o.Success=200]="Success",o[o.Rejected=400]="Rejected",o[o.Reverted=500]="Reverted",o))($e||{}),He=new Set([200,400,500]);function Ke(t){return !He.has(t)}function Me(t){return async({tx:e,stopPolling:a,onSuccess:r,onFailure:i,onIntervalTick:o})=>{let s=await t.request({method:"relayer_getStatus",params:{id:e.txKey,logs:false}});o?.(s);let{status:c,createdAt:n}=s;if(n&&b().diff(b.unix(n),"hour")>=1&&Ke(c)){a();return}c===200?(r(s),a({withoutRemoving:true})):(c===400||c===500)&&(i(s),a({withoutRemoving:true}));}}function _({tx:t,gelatoApiKey:e,updateTxParams:a,removeTxFromPool:r,transactionsPool:i,onSuccess:o,onError:s}){let c=E({apiKey:e}),n=Me(c);return initializePollingTracker({tx:t,fetcher:n,removeTxFromPool:r,onSuccess:l=>{let p=l.status===200?l.receipt.transactionHash:void 0;a(t.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:p,finishedTimestamp:b().unix()});let f=i[t.txKey];o&&f&&o(f);},onIntervalTick:l=>{l.status===110&&a(t.txKey,{hash:l.hash});},onFailure:l=>{let p="Transaction failed or was not found.",f;l&&(l.status===400?p=l.message||"Transaction was rejected by Gelato Relay.":l.status===500&&(p=l.message||"Transaction reverted on-chain.",f=l.receipt.transactionHash));let m=new Error(p);a(t.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:f,error:normalizeError(m),finishedTimestamp:b().unix()});let u=i[t.txKey];s&&u&&s(m,u);}})}var $t={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false},ee={[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:"},te={[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 Ue=async({tx:t,stopPolling:e,onSuccess:a,onFailure:r,onReplaced:i,onIntervalTick:o})=>{let s=te[t.chainId];if(!s)throw new Error(`Safe Transaction Service URL not found for chainId: ${t.chainId}`);let c=await fetch(`${s}/multisig-transactions/${t.txKey}/`);if(!c.ok)throw c.status===404&&(r(),e()),new Error(`Safe API responded with status: ${c.status}`);let n=await c.json();if(o?.(n),n.isExecuted){n.isSuccessful?a(n):r(n),e({withoutRemoving:true});return}let l=await fetch(`${s}/safes/${t.from}/multisig-transactions/?nonce=${n.nonce}`);if(!l.ok)throw new Error(`Safe API (nonce check) responded with status: ${l.status}`);let f=(await l.json()).results.find(m=>m.isExecuted);if(f){i?.(f),e({withoutRemoving:true});return}b().diff(b(n.submissionDate),"day")>=1&&e();};function re({tx:t,updateTxParams:e,removeTxFromPool:a,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s}){return initializePollingTracker({tx:t,fetcher:Ue,removeTxFromPool:a,onSuccess:c=>{e(t.txKey,{status:TransactionStatus.Success,pending:false,isError:false,hash:c.transactionHash??void 0,finishedTimestamp:c.executionDate?b(c.executionDate).unix():void 0});let n=r[t.txKey];i&&n&&i(n);},onIntervalTick:c=>{e(t.txKey,{hash:c.transactionHash??void 0});},onFailure:c=>{let n=c?new Error("Safe transaction failed or was rejected."):new Error("Transaction not found.");e(t.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,hash:c?.transactionHash??void 0,error:normalizeError(n),finishedTimestamp:c?.executionDate?b(c.executionDate).unix():void 0});let l=r[t.txKey];o&&l&&o(n,l);},onReplaced:c=>{e(t.txKey,{status:TransactionStatus.Replaced,pending:false,hash:t.adapter===OrbitAdapter.EVM?t.hash:zeroHash,replacedTxHash:c.safeTxHash??zeroHash,finishedTimestamp:c.executionDate?b(c.executionDate).unix():void 0});let n=r[t.txKey];s&&n&&s(n,t);}})}async function ne({tracker:t,tx:e,config:a,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s,gelatoApiKey:c,...n}){switch(t){case TransactionTracker.Ethereum:return y({tx:e,config:a,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s,...n});case TransactionTracker.Gelato:return c?_({tx:e,transactionsPool:r,onSuccess:i,onError:o,gelatoApiKey:c,...n}):(console.warn(`Gelato tracker requested for tx '${e.txKey}', but no 'gelatoApiKey' was provided. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s,...n}));case TransactionTracker.Safe:return re({tx:e,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s,...n});default:return console.warn(`Unknown tracker type: '${t}'. Falling back to default EVM tracker.`),y({tx:e,config:a,transactionsPool:r,onSuccess:i,onError:o,onReplaced:s,...n})}}function oe({actionTxKey:t,connectorType:e,tracker:a,gelatoApiKey:r}){if(a&&a===TransactionTracker.Gelato&&r)return {tracker:TransactionTracker.Gelato,txKey:t};if(!isHex(t))throw new Error(`Invalid transaction key format. Expected a Hex string or a GelatoTxKey object, but received: ${JSON.stringify(t)}`);let i=e.split(":");return (i.length>1?i[i.length-1]==="safe"||i[i.length-1]==="safewallet":e?.toLowerCase()==="safe")?{tracker:TransactionTracker.Safe,txKey:t}:{tracker:TransactionTracker.Ethereum,txKey:t}}var se=({chains:t,tx:e})=>{if(e.tracker===TransactionTracker.Safe){let o=ee[e.chainId];return o?`${o}${e.from}/transactions/tx?id=multisig_${e.from}_${e.txKey}`:""}let r=t.find(o=>o.id===e.chainId)?.blockExplorers?.default.url;if(!r)return "";let i=(e.adapter===OrbitAdapter.EVM?e.replacedTxHash:e.txKey)||(e.adapter===OrbitAdapter.EVM?e.hash:e.txKey);return i?`${r}/tx/${i}`:""};var ce=1.15;async function le({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:r,to:i,value:o,input:s,maxFeePerGas:c,maxPriorityFeePerGas:n,chainId:l}=e;if(a===void 0||!r||!i||!o||!c||!n)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 f=BigInt(Math.ceil(Number(n)*ce)),m=BigInt(Math.ceil(Number(c)*ce));return await sendTransaction(t,{to:i,value:BigInt(o),data:s||"0x",chainId:l,nonce:a,maxFeePerGas:m,maxPriorityFeePerGas:f})}catch(p){let f=p instanceof Error?p.message:String(p);throw new Error(`Failed to speed up transaction: ${f}`,{cause:p})}}function va(t,e){if(!t)throw new Error("EVM adapter requires a wagmi config object.");return {key:OrbitAdapter.EVM,getConnectorInfo:()=>{let a=getConnection(t),r=lastConnectedConnectorHelpers.getLastConnectedConnector();return {walletAddress:a.address??r?.address??zeroAddress,connectorType:getConnectorTypeFromName(OrbitAdapter.EVM,a.connector?.name?.toLowerCase()??"unknown")}},checkChainForTx:a=>checkAndSwitchChain(a,t),checkTransactionsTracker:a=>oe(a),checkAndInitializeTrackerInStore:({tx:a,...r})=>ne({tracker:a.tracker,tx:a,config:t,...r}),getExplorerUrl:a=>{let{chain:r}=getConnection(t),i=r?.blockExplorers?.default.url;return a?`${i}/${a}`:i},getExplorerTxUrl:a=>se({chains:e,tx:a}),cancelTxAction:a=>A({config:t,tx:a}),speedUpTxAction:a=>le({config:t,tx:a}),retryTxAction:async({onClose:a,txKey:r,executeTxAction:i,tx:o})=>{if(a(r),!i){console.error("Retry failed: executeTxAction function is not provided.");return}await i({actionFunction:()=>o.actionFunction({config:t,...o.payload}),params:o,defaultTracker:TransactionTracker.Ethereum});}}}var I=new Map;async function Xe(t){let e=await t.request({method:"relayer_getCapabilities",params:[]}),a={};for(let[r,i]of Object.entries(e))a[Number(r)]=i;return a}async function Ze(t){let e=I.get(t);if(e)return e;let a=E({apiKey:t}),r=await Xe(a);return I.set(t,r),r}async function Fa(t,e){try{let a=await Ze(e);return t in a}catch(a){return console.error("Failed to fetch Gelato relay capabilities:",a),I.delete(e),false}}
|
|
2
|
+
export{$e as GelatoStatusCode,te as SafeTransactionServiceUrls,A as cancelTxAction,ne as checkAndInitializeTrackerInStore,Fa as checkIsGelatoAvailable,oe as checkTransactionsTracker,E as createGelatoClient,Ie as evmTracker,y as evmTrackerForStore,Me as gelatoFetcher,_ as gelatoTrackerForStore,ee as gnosisSafeLinksHelper,K as isRetryableReceiptError,va as pulsarEvmAdapter,Ue as safeFetcher,$t as safeSdkOptions,re as safeTrackerForStore,se as selectEvmTxExplorerLink,le as speedUpTxAction};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuwaio/pulsar-evm",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Oleksandr Tkach",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -51,18 +51,18 @@
|
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@tuwaio/orbit-core": "^0.2.15",
|
|
54
|
-
"@tuwaio/orbit-evm": "^0.2.
|
|
54
|
+
"@tuwaio/orbit-evm": "^0.2.21",
|
|
55
55
|
"@wagmi/core": "^3.6.4",
|
|
56
56
|
"dayjs": "^1.11.21",
|
|
57
57
|
"immer": "^11.1.15",
|
|
58
|
-
"jsdom": "^
|
|
58
|
+
"jsdom": "^30.0.1",
|
|
59
59
|
"tsup": "^8.5.1",
|
|
60
60
|
"typescript": "^6.0.3",
|
|
61
|
-
"viem": "^2.55.
|
|
61
|
+
"viem": "^2.55.10",
|
|
62
62
|
"vitest": "^4.1.10",
|
|
63
63
|
"zustand": "^5.0.14",
|
|
64
64
|
"dotenv": "^17.4.2",
|
|
65
|
-
"@tuwaio/pulsar-core": "^0.6.
|
|
65
|
+
"@tuwaio/pulsar-core": "^0.6.10"
|
|
66
66
|
},
|
|
67
67
|
"scripts": {
|
|
68
68
|
"start": "tsup src/index.ts --watch",
|