@tuwaio/pulsar-solana 0.1.7 → 0.1.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 CHANGED
@@ -81,56 +81,58 @@ declare class SolanaChainMismatchError extends Error {
81
81
  }
82
82
 
83
83
  /**
84
- * @file Implements the transaction tracking logic for standard Solana transactions.
85
- * It uses a polling mechanism to query the `getSignatureStatuses` RPC method
86
- * and updates the transaction's state in the Pulsar store.
84
+ * @file Implements the transaction tracking logic for Solana transactions.
85
+ * It integrates with the Pulsar store and uses a polling mechanism to query the
86
+ * `getSignatureStatuses` RPC method for updates on transaction status.
87
87
  */
88
88
 
89
89
  /**
90
- * The structure of the status object returned by the Solana RPC `getSignatureStatuses` method.
91
- * It represents the real-time status of a Solana transaction.
92
- * Note: `slot and confirmations` is received as a `bigint` but converted to `number` before being processed.
93
- * @internal
90
+ * @typedef SolanaSignatureStatusResponse
91
+ * Represents the status of a Solana transaction and includes additional metadata.
92
+ *
93
+ * @property {number} slot - The slot in which the transaction was processed.
94
+ * @property {number | null} confirmations - The number of confirmations received.
95
+ * @property {TransactionError | null} err - The error, if any, associated with the transaction.
96
+ * @property {'processed' | 'confirmed' | 'finalized' | null} confirmationStatus - The status of the transaction's confirmation.
97
+ * @property {number} [fee] - The transaction fee in lamports.
98
+ * @property {string} [recentBlockhash] - The blockhash used for the transaction.
99
+ * @property {unknown[]} [instructions] - The instructions included in the transaction.
94
100
  */
95
101
  type SolanaSignatureStatusResponse = {
96
102
  slot: number;
97
103
  confirmations: number | null;
98
104
  err: TransactionError | null;
99
105
  confirmationStatus: 'processed' | 'confirmed' | 'finalized' | null;
106
+ fee?: number;
107
+ recentBlockhash?: string;
108
+ instructions?: unknown[];
100
109
  };
101
110
  /**
102
- * The function parameters for the `solanaFetcher` function.
103
- * These are automatically derived from the generic `PollingTrackerConfig` fetcher function.
104
- * @internal
111
+ * @typedef SolanaFetcherParams
112
+ * Parameters used for the Solana fetcher function.
105
113
  */
106
114
  type SolanaFetcherParams = Parameters<PollingTrackerConfig<SolanaSignatureStatusResponse, Transaction<SolanaTransactionTracker>, SolanaTransactionTracker>['fetcher']>[0];
107
115
  /**
108
- * The core polling fetcher function for Solana transactions.
109
- *
110
- * This function queries the Solana RPC for updates on a transaction's status.
111
- * It processes the response and triggers appropriate callbacks (`onSuccess`, `onFailure`, etc.)
112
- * based on the transaction's state.
116
+ * Fetches and tracks Solana transactions using the `getSignatureStatuses` RPC method.
117
+ * Transaction details (`getTransaction`) are only fetched once, if not already present in the transaction object.
113
118
  *
114
- * @param {SolanaFetcherParams} params - The parameters for the fetcher, including the transaction object
115
- * and various callbacks for handling updates.
116
- * @returns {Promise<void>} A promise that resolves once the fetcher function completes.
119
+ * @param {SolanaFetcherParams} params - The fetcher parameters, automatically provided by the tracker.
120
+ * @throws Will throw an error if the transaction adapter is not set to Solana.
121
+ * @returns {Promise<void>} Resolves when the fetcher completes execution for the current polling cycle.
117
122
  */
118
123
  declare function solanaFetcher({ tx, stopPolling, onSuccess, onFailure, onIntervalTick, }: SolanaFetcherParams): Promise<void>;
119
124
  /**
120
- * A higher-level polling tracker that integrates the Solana transaction tracking logic
121
- * with the Pulsar store's transaction management.
125
+ * A higher-level tracker that integrates the Solana polling logic with the Pulsar store.
122
126
  *
123
- * This function initializes and manages the lifecycle of polling for a Solana transaction's status.
124
- * It dynamically updates the transaction state in the store based on polling results.
127
+ * @template T - The application-specific Solana transaction type.
125
128
  *
126
- * @template T - The application-specific type for the transaction, extending `Transaction`.
127
- * @param {object} params - The parameters for the store-connected tracker.
128
- * @param {T} params.tx - The Solana transaction object to be tracked.
129
- * @param {Record<string, T>} params.transactionsPool - The current pool of transactions in the store.
130
- * @param {Function} params.updateTxParams - A function to update specific fields of a transaction in the store.
131
- * @param {Function} [params.onSucceedCallbacks] - Optional callbacks to trigger on a successful tracking outcome.
132
- * @param {Function} [params.removeTxFromPool] - A function to remove the tracked transaction from the pool.
133
- * @returns {Promise<void>} A promise that resolves once the tracking process is initialized.
129
+ * @param {object} params - Parameters to connect the Solana tracker with the store.
130
+ * @param {T} params.tx - The Solana transaction being tracked.
131
+ * @param {Record<string, T>} params.transactionsPool - A pool of tracked transactions in the store.
132
+ * @param {Function} params.updateTxParams - A callback to update specific fields of a transaction in the store.
133
+ * @param {Function} [params.onSucceedCallbacks] - Optional callbacks executed upon successful transaction completion.
134
+ * @param {Function} [params.removeTxFromPool] - A function to remove a completed or canceled transaction from the store.
135
+ * @returns {Promise<void>} Resolves when the tracker is successfully initialized.
134
136
  */
135
137
  declare function solanaTrackerForStore<T extends Transaction<SolanaTransactionTracker>>({ tx, ...rest }: Pick<ITxTrackingStore<SolanaTransactionTracker, T, SolanaActionTxKey>, 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'> & {
136
138
  tx: T;
package/dist/index.d.ts CHANGED
@@ -81,56 +81,58 @@ declare class SolanaChainMismatchError extends Error {
81
81
  }
82
82
 
83
83
  /**
84
- * @file Implements the transaction tracking logic for standard Solana transactions.
85
- * It uses a polling mechanism to query the `getSignatureStatuses` RPC method
86
- * and updates the transaction's state in the Pulsar store.
84
+ * @file Implements the transaction tracking logic for Solana transactions.
85
+ * It integrates with the Pulsar store and uses a polling mechanism to query the
86
+ * `getSignatureStatuses` RPC method for updates on transaction status.
87
87
  */
88
88
 
89
89
  /**
90
- * The structure of the status object returned by the Solana RPC `getSignatureStatuses` method.
91
- * It represents the real-time status of a Solana transaction.
92
- * Note: `slot and confirmations` is received as a `bigint` but converted to `number` before being processed.
93
- * @internal
90
+ * @typedef SolanaSignatureStatusResponse
91
+ * Represents the status of a Solana transaction and includes additional metadata.
92
+ *
93
+ * @property {number} slot - The slot in which the transaction was processed.
94
+ * @property {number | null} confirmations - The number of confirmations received.
95
+ * @property {TransactionError | null} err - The error, if any, associated with the transaction.
96
+ * @property {'processed' | 'confirmed' | 'finalized' | null} confirmationStatus - The status of the transaction's confirmation.
97
+ * @property {number} [fee] - The transaction fee in lamports.
98
+ * @property {string} [recentBlockhash] - The blockhash used for the transaction.
99
+ * @property {unknown[]} [instructions] - The instructions included in the transaction.
94
100
  */
95
101
  type SolanaSignatureStatusResponse = {
96
102
  slot: number;
97
103
  confirmations: number | null;
98
104
  err: TransactionError | null;
99
105
  confirmationStatus: 'processed' | 'confirmed' | 'finalized' | null;
106
+ fee?: number;
107
+ recentBlockhash?: string;
108
+ instructions?: unknown[];
100
109
  };
101
110
  /**
102
- * The function parameters for the `solanaFetcher` function.
103
- * These are automatically derived from the generic `PollingTrackerConfig` fetcher function.
104
- * @internal
111
+ * @typedef SolanaFetcherParams
112
+ * Parameters used for the Solana fetcher function.
105
113
  */
106
114
  type SolanaFetcherParams = Parameters<PollingTrackerConfig<SolanaSignatureStatusResponse, Transaction<SolanaTransactionTracker>, SolanaTransactionTracker>['fetcher']>[0];
107
115
  /**
108
- * The core polling fetcher function for Solana transactions.
109
- *
110
- * This function queries the Solana RPC for updates on a transaction's status.
111
- * It processes the response and triggers appropriate callbacks (`onSuccess`, `onFailure`, etc.)
112
- * based on the transaction's state.
116
+ * Fetches and tracks Solana transactions using the `getSignatureStatuses` RPC method.
117
+ * Transaction details (`getTransaction`) are only fetched once, if not already present in the transaction object.
113
118
  *
114
- * @param {SolanaFetcherParams} params - The parameters for the fetcher, including the transaction object
115
- * and various callbacks for handling updates.
116
- * @returns {Promise<void>} A promise that resolves once the fetcher function completes.
119
+ * @param {SolanaFetcherParams} params - The fetcher parameters, automatically provided by the tracker.
120
+ * @throws Will throw an error if the transaction adapter is not set to Solana.
121
+ * @returns {Promise<void>} Resolves when the fetcher completes execution for the current polling cycle.
117
122
  */
118
123
  declare function solanaFetcher({ tx, stopPolling, onSuccess, onFailure, onIntervalTick, }: SolanaFetcherParams): Promise<void>;
119
124
  /**
120
- * A higher-level polling tracker that integrates the Solana transaction tracking logic
121
- * with the Pulsar store's transaction management.
125
+ * A higher-level tracker that integrates the Solana polling logic with the Pulsar store.
122
126
  *
123
- * This function initializes and manages the lifecycle of polling for a Solana transaction's status.
124
- * It dynamically updates the transaction state in the store based on polling results.
127
+ * @template T - The application-specific Solana transaction type.
125
128
  *
126
- * @template T - The application-specific type for the transaction, extending `Transaction`.
127
- * @param {object} params - The parameters for the store-connected tracker.
128
- * @param {T} params.tx - The Solana transaction object to be tracked.
129
- * @param {Record<string, T>} params.transactionsPool - The current pool of transactions in the store.
130
- * @param {Function} params.updateTxParams - A function to update specific fields of a transaction in the store.
131
- * @param {Function} [params.onSucceedCallbacks] - Optional callbacks to trigger on a successful tracking outcome.
132
- * @param {Function} [params.removeTxFromPool] - A function to remove the tracked transaction from the pool.
133
- * @returns {Promise<void>} A promise that resolves once the tracking process is initialized.
129
+ * @param {object} params - Parameters to connect the Solana tracker with the store.
130
+ * @param {T} params.tx - The Solana transaction being tracked.
131
+ * @param {Record<string, T>} params.transactionsPool - A pool of tracked transactions in the store.
132
+ * @param {Function} params.updateTxParams - A callback to update specific fields of a transaction in the store.
133
+ * @param {Function} [params.onSucceedCallbacks] - Optional callbacks executed upon successful transaction completion.
134
+ * @param {Function} [params.removeTxFromPool] - A function to remove a completed or canceled transaction from the store.
135
+ * @returns {Promise<void>} Resolves when the tracker is successfully initialized.
134
136
  */
135
137
  declare function solanaTrackerForStore<T extends Transaction<SolanaTransactionTracker>>({ tx, ...rest }: Pick<ITxTrackingStore<SolanaTransactionTracker, T, SolanaActionTxKey>, 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'> & {
136
138
  tx: T;
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- 'use strict';var pulsarCore=require('@tuwaio/pulsar-core'),gill=require('gill'),p=require('dayjs'),splNameService=require('@bonfida/spl-name-service'),web3_js=require('@solana/web3.js');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var p__default=/*#__PURE__*/_interopDefault(p);var l=class extends Error{name="SolanaChainMismatchError";requiredChain;currentChain;constructor(t,r){let o=`Wrong chain. The transaction requires ${t}, but you are connected to ${r}.`;super(o),this.requiredChain=t,this.currentChain=r;}};var f=(t=>(t.Solana="solana",t))(f||{});function E(n){try{return new URL(n),!0}catch{return false}}var b={mainnet:"https://api.mainnet-beta.solana.com",devnet:"https://api.devnet.solana.com",testnet:"https://api.testnet.solana.com"},d=new Map,m=n=>{if(d.has(n))return d.get(n);let t=E(n)?n:b[n];if(!t)throw new Error(`Unable to resolve RPC URL for input: "${n}". Ensure it's a valid URL or known moniker.`);let r=gill.createSolanaRpc(t);return d.set(n,r),r};async function M({tx:n,stopPolling:t,onSuccess:r,onFailure:o,onIntervalTick:s}){if(n.adapter!==pulsarCore.TransactionAdapter.SOLANA)throw new Error('Tx adapter is not Solana. Please set adapter to "solana" in the transaction object.');let c=(await m(n.rpcUrl??n.chainId).getSignatureStatuses([n.txKey]).send())?.value[0];if(!c)return;let i={...c,slot:Number(c.slot),confirmations:Number(c.confirmations??0)};if(s?.(i),i.err){o(i),t({withoutRemoving:true});return}if(i.confirmationStatus==="finalized"){r(i),t({withoutRemoving:true});return}p__default.default().diff(p__default.default.unix(n.localTimestamp),"minute")>=30&&(t({withoutRemoving:true}),o(i));}async function k({tx:n,...t}){return pulsarCore.initializePollingTracker({tx:n,fetcher:M,removeTxFromPool:t.removeTxFromPool,pollingInterval:2500,maxRetries:10,onSuccess:r=>{t.updateTxParams(n.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,finishedTimestamp:p__default.default().unix(),confirmations:r.confirmations??1,slot:r.slot});let o=t.transactionsPool[n.txKey];t.onSucceedCallbacks&&o&&t.onSucceedCallbacks(o);},onIntervalTick:r=>{t.updateTxParams(n.txKey,{confirmations:r.confirmations??0,slot:r.slot});},onFailure:r=>{let o=r?.err?`Transaction failed: ${JSON.stringify(r.err)}`:"Transaction tracking timed out or the transaction was not found.";t.updateTxParams(n.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,errorMessage:o,finishedTimestamp:p__default.default().unix()});}})}async function x({tx:n,tracker:t,...r}){switch(t){case "solana":await k({tx:n,...r});break;default:console.error(`Unknown tracker type for Solana adapter: ${t}`),r.updateTxParams(n.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,errorMessage:`Unsupported tracker type: "${t}"`});break}}var w=(n,t)=>{if(t!==n)throw new l(n,t)};var C=(n,t)=>{let r=gill.getExplorerLink({cluster:t}),o=r.endsWith("/")?r.slice(0,-1):r,s=t?`?cluster=${t}`:"";return `${o}/tx/${n}${s}`};var S=new Map,u=new Map,y=n=>(S.has(n)||S.set(n,new web3_js.Connection(n)),S.get(n)),A=async(n,t)=>{if(u.has(t))return u.get(t);try{let r=y(n),o=new web3_js.PublicKey(t),s=await splNameService.getDomainKeysWithReverses(r,o);if(s.length===0)return u.set(t,null),null;let e=`${await splNameService.performReverseLookup(r,s[0])}.sol`;return u.set(t,e),e}catch{return u.set(t,null),null}},R=async(n,t)=>{try{let r=y(n),o=await splNameService.getRecord(r,t,splNameService.Record.Pic);return !o||!o.data?null:o.data.toString("utf-8")}catch{return null}};function Kt(n){let{wallet:t,rpcUrls:r}=n,o=a=>{let e="mainnet";return a?a.includes(":")?a.split(":")[1]:a:t?.walletActiveChain??e},s=a=>{let e=a??t?.walletActiveChain;if(e)return r[e]};return {key:pulsarCore.TransactionAdapter.SOLANA,getWalletInfo:()=>({walletAddress:t?.walletAddress??"0x0",walletType:t?.walletType??"disconnected"}),checkChainForTx:async a=>{if(!t)throw new Error("Wallet not provided. Cannot perform chain check.");try{w(a,t.walletActiveChain);}catch(e){throw e instanceof l?e:new Error(`Chain check failed: ${e instanceof Error?e.message:String(e)}`)}},checkTransactionsTracker:a=>({tracker:"solana",txKey:a}),checkAndInitializeTrackerInStore:({tx:a,...e})=>x({tracker:a.tracker,tx:a,...e}),getExplorerUrl:()=>{let a=t?.walletActiveChain??"mainnet-beta";return gill.getExplorerLink({cluster:a})},getExplorerTxUrl:(a,e)=>{let c=a[e],i=o(c?.chainId);return C(e,i)},getName:async a=>{let e=s(t?.walletActiveChain);return e?A(e,a):(console.warn("Cannot get name: RPC URL for the current chain is not configured."),null)},getAvatar:async a=>{let e=s(t?.walletActiveChain);return e?R(e,a):(console.warn("Cannot get avatar: RPC URL for the current chain is not configured."),null)},retryTxAction:async({onClose:a,txKey:e,handleTransaction:c,tx:i})=>{if(a(e),!t||!t.walletAddress||t.walletAddress==="0x0")throw new Error("Retry failed: A wallet must be connected.");if(!c)throw new Error("Retry failed: handleTransaction function is not provided.");let T=o(i.desiredChainID),g=i.rpcUrl??s(T);if(!g)throw new Error("Retry failed: Could not determine RPC endpoint for the transaction chain.");let P=m(g);await c({actionFunction:()=>i.actionFunction({wallet:n.wallet,rpc:P,...i.payload}),params:i,defaultTracker:"solana"});}}}async function $t({client:n,signer:t,instruction:r}){let{value:o}=await n.rpc.getLatestBlockhash().send(),s=gill.createTransaction({feePayer:t,version:0,latestBlockhash:o,instructions:Array.isArray(r)?r:[r]}),a=await gill.signAndSendTransactionMessageWithSigners(s);return gill.getBase58Decoder().decode(a)}
2
- exports.SolanaChainMismatchError=l;exports.SolanaTransactionTracker=f;exports.checkAndInitializeTrackerInStore=x;exports.checkSolanaChain=w;exports.createSolanaRPC=m;exports.getSolanaAvatar=R;exports.getSolanaName=A;exports.selectSolanaTxExplorerLink=C;exports.signAndSendSolanaTx=$t;exports.solanaAdapter=Kt;exports.solanaFetcher=M;exports.solanaTrackerForStore=k;//# sourceMappingURL=index.js.map
1
+ 'use strict';var pulsarCore=require('@tuwaio/pulsar-core'),gill=require('gill'),S=require('dayjs'),splNameService=require('@bonfida/spl-name-service'),web3_js=require('@solana/web3.js');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var S__default=/*#__PURE__*/_interopDefault(S);var m=class extends Error{name="SolanaChainMismatchError";requiredChain;currentChain;constructor(t,r){let o=`Wrong chain. The transaction requires ${t}, but you are connected to ${r}.`;super(o),this.requiredChain=t,this.currentChain=r;}};var T=(t=>(t.Solana="solana",t))(T||{});function F(n){try{return new URL(n),!0}catch{return false}}var K={mainnet:"https://api.mainnet-beta.solana.com",devnet:"https://api.devnet.solana.com",testnet:"https://api.testnet.solana.com"},h=new Map,d=n=>{if(h.has(n))return h.get(n);let t=F(n)?n:K[n];if(!t)throw new Error(`Unable to resolve RPC URL for input: "${n}". Ensure it's a valid URL or known moniker.`);let r=gill.createSolanaRpc(t);return h.set(n,r),r};async function L({tx:n,stopPolling:t,onSuccess:r,onFailure:o,onIntervalTick:i}){if(n.adapter!==pulsarCore.TransactionAdapter.SOLANA)throw new Error('Tx adapter is not Solana. Please set the adapter to "solana" in the transaction object.');try{let a=d(n.rpcUrl??n.chainId),c=(await a.getSignatureStatuses([n.txKey]).send())?.value?.[0];if(!c)return;let{fee:s,recentBlockhash:p,instructions:u}=n;if(!s||!p||!u){let b=await a.getTransaction(n.txKey,{encoding:"json"}).send(),{meta:x,transaction:g}=b||{};if(!x||!g)return;s=Number(x.fee??0),p=g.message.recentBlockhash?.toString(),u=g.message.instructions;}let l={...c,slot:Number(c.slot),confirmations:Number(c.confirmations??0),fee:s,recentBlockhash:p,instructions:u};if(i?.(l),l.err){o(l),t({withoutRemoving:!0});return}if(l.confirmationStatus==="finalized"){r(l),t({withoutRemoving:!0});return}S__default.default().diff(S__default.default.unix(n.localTimestamp),"day")>=1&&(o(l),t());}catch(a){console.error("Error in solanaFetcher:",a),o({err:a}),t();}}async function y({tx:n,...t}){return pulsarCore.initializePollingTracker({tx:n,fetcher:L,removeTxFromPool:t.removeTxFromPool,pollingInterval:2500,maxRetries:10,onSuccess:r=>{t.updateTxParams(n.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,finishedTimestamp:S__default.default().unix(),fee:r.fee,instructions:r.instructions,recentBlockhash:r.recentBlockhash,confirmations:r.confirmations??1,slot:r.slot});let o=t.transactionsPool[n.txKey];t.onSucceedCallbacks&&o&&t.onSucceedCallbacks(o);},onIntervalTick:r=>{t.updateTxParams(n.txKey,{confirmations:r.confirmations??0,slot:r.slot,fee:r.fee,instructions:r.instructions,recentBlockhash:r.recentBlockhash});},onFailure:r=>{let o=r?.err?`Transaction failed: ${JSON.stringify(r.err)}`:"Transaction tracking timed out or the transaction was not found.";t.updateTxParams(n.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,errorMessage:o,finishedTimestamp:S__default.default().unix()});}})}async function C({tx:n,tracker:t,...r}){switch(t){case "solana":await y({tx:n,...r});break;default:console.error(`Unknown tracker type for Solana adapter: ${t}`),r.updateTxParams(n.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,errorMessage:`Unsupported tracker type: "${t}"`});break}}var A=(n,t)=>{if(t!==n)throw new m(n,t)};var R=(n,t)=>{let r=gill.getExplorerLink({cluster:t}),o=r.endsWith("/")?r.slice(0,-1):r,i=t?`?cluster=${t}`:"";return `${o}/tx/${n}${i}`};var k=new Map,f=new Map,P=n=>(k.has(n)||k.set(n,new web3_js.Connection(n)),k.get(n)),v=async(n,t)=>{if(f.has(t))return f.get(t);try{let r=P(n),o=new web3_js.PublicKey(t),i=await splNameService.getDomainKeysWithReverses(r,o);if(i.length===0)return f.set(t,null),null;let e=`${await splNameService.performReverseLookup(r,i[0])}.sol`;return f.set(t,e),e}catch{return f.set(t,null),null}},E=async(n,t)=>{try{let r=P(n),o=await splNameService.getRecord(r,t,splNameService.Record.Pic);return !o||!o.data?null:o.data.toString("utf-8")}catch{return null}};function Nt(n){let{wallet:t,rpcUrls:r}=n,o=a=>{let e="mainnet";return a?a.includes(":")?a.split(":")[1]:a:t?.walletActiveChain??e},i=a=>{let e=a??t?.walletActiveChain;if(e)return r[e]};return {key:pulsarCore.TransactionAdapter.SOLANA,getWalletInfo:()=>({walletAddress:t?.walletAddress??"0x0",walletType:t?.walletType??"disconnected"}),checkChainForTx:async a=>{if(!t)throw new Error("Wallet not provided. Cannot perform chain check.");try{A(a,t.walletActiveChain);}catch(e){throw e instanceof m?e:new Error(`Chain check failed: ${e instanceof Error?e.message:String(e)}`)}},checkTransactionsTracker:a=>({tracker:"solana",txKey:a}),checkAndInitializeTrackerInStore:({tx:a,...e})=>C({tracker:a.tracker,tx:a,...e}),getExplorerUrl:()=>{let a=t?.walletActiveChain??"mainnet-beta";return gill.getExplorerLink({cluster:a})},getExplorerTxUrl:(a,e)=>{let c=a[e],s=o(c?.chainId);return R(e,s)},getName:async a=>{let e=i(t?.walletActiveChain);return e?v(e,a):(console.warn("Cannot get name: RPC URL for the current chain is not configured."),null)},getAvatar:async a=>{let e=i(t?.walletActiveChain);return e?E(e,a):(console.warn("Cannot get avatar: RPC URL for the current chain is not configured."),null)},retryTxAction:async({onClose:a,txKey:e,handleTransaction:c,tx:s})=>{if(a(e),!t||!t.walletAddress||t.walletAddress==="0x0")throw new Error("Retry failed: A wallet must be connected.");if(!c)throw new Error("Retry failed: handleTransaction function is not provided.");let p=o(s.desiredChainID),u=s.rpcUrl??i(p);if(!u)throw new Error("Retry failed: Could not determine RPC endpoint for the transaction chain.");let l=d(u);await c({actionFunction:()=>s.actionFunction({wallet:n.wallet,rpc:l,...s.payload}),params:s,defaultTracker:"solana"});}}}async function zt({client:n,signer:t,instruction:r}){let{value:o}=await n.rpc.getLatestBlockhash().send(),i=gill.createTransaction({feePayer:t,version:0,latestBlockhash:o,instructions:Array.isArray(r)?r:[r]}),a=await gill.signAndSendTransactionMessageWithSigners(i);return gill.getBase58Decoder().decode(a)}
2
+ exports.SolanaChainMismatchError=m;exports.SolanaTransactionTracker=T;exports.checkAndInitializeTrackerInStore=C;exports.checkSolanaChain=A;exports.createSolanaRPC=d;exports.getSolanaAvatar=E;exports.getSolanaName=v;exports.selectSolanaTxExplorerLink=R;exports.signAndSendSolanaTx=zt;exports.solanaAdapter=Nt;exports.solanaFetcher=L;exports.solanaTrackerForStore=y;//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/utils/createSolanaRPC.ts","../src/trackers/solanaTracker.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkSolanaChain.ts","../src/utils/selectSolanaTxExplorerLink.ts","../src/utils/snsUtils.ts","../src/adapters/solanaAdapter.ts","../src/utils/signAndSendSolanaTx.ts"],"names":["SolanaChainMismatchError","requiredChain","currentChain","message","SolanaTransactionTracker","isValidUrl","str","defaultRpcUrlsByMoniker","rpcCache","createSolanaRPC","rpcUrlOrMoniker","rpcUrl","newRpc","createSolanaRpc","solanaFetcher","tx","stopPolling","onSuccess","onFailure","onIntervalTick","TransactionAdapter","status","typedStatus","dayjs","solanaTrackerForStore","rest","initializePollingTracker","response","TransactionStatus","updatedTx","errorMessage","checkAndInitializeTrackerInStore","tracker","checkSolanaChain","selectSolanaTxExplorerLink","txKey","cluster","baseUrl","getExplorerLink","sanitizedBaseUrl","clusterParam","connectionCache","domainNameCache","getConnection","Connection","getSolanaName","address","connection","pubKey","PublicKey","domainKeys","getDomainKeysWithReverses","fullDomain","performReverseLookup","getSolanaAvatar","name","record","getRecord","Record","solanaAdapter","config","wallet","rpcUrls","getCluster","chain","defaultCluster","getRpcUrlForCluster","targetCluster","txChain","actionTxKey","txPool","onClose","handleTransaction","clusterForRetry","rpcUrlForRetry","rpcForRetry","signAndSendSolanaTx","client","signer","instruction","latestBlockhash","transaction","createTransaction","signature","signAndSendTransactionMessageWithSigners","getBase58Decoder"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @file This file defines custom error classes for the @tuwaio/pulsar-solana package.\n */\n\n/**\n * Thrown when the connected Solana chain does not match the required chain for a transaction.\n *\n * This allows consuming applications to `catch` this specific error and\n * implement custom logic, such as prompting the user to switch networks.\n */\nexport class SolanaChainMismatchError extends Error {\n /** The name of the error, for easy identification. */\n name = 'SolanaChainMismatchError';\n /** The chain that the transaction requires (e.g., 'solana:mainnet'). */\n requiredChain: string;\n /** The chain the wallet is currently connected to. */\n currentChain: string;\n\n constructor(requiredChain: string, currentChain: string) {\n const message = `Wrong chain. The transaction requires ${requiredChain}, but you are connected to ${currentChain}.`;\n super(message);\n this.requiredChain = requiredChain;\n this.currentChain = currentChain;\n }\n}\n","/**\n * @file Defines the core types and enums specific to the @tuwaio/pulsar-solana package.\n */\n\nimport type { SolanaClusterMoniker } from 'gill';\n\n/**\n * Represents the essential wallet information required by the Solana adapter.\n * This interface provides a simple, library-agnostic abstraction for wallet connections,\n * enabling integration with any wallet library that meets these basic requirements.\n *\n * @property {string} walletAddress - The public address of the connected wallet on Solana.\n * @property {string} walletType - The type or name of the wallet (e.g., 'Phantom', 'Solflare').\n * @property {SolanaClusterMoniker} walletActiveChain - The current chain or cluster the wallet is connected to.\n */\nexport interface SolanaAdapterWallet {\n walletAddress: string;\n walletType: string;\n walletActiveChain: SolanaClusterMoniker;\n}\n\n/**\n * Represents the simplified configuration object for the Solana adapter.\n *\n * This configuration enables both wallet-based (connected) and read-only (disconnected) modes,\n * supporting operations like transaction tracking, name/identity resolution, and more.\n *\n * @property {SolanaAdapterWallet} [wallet] - An optional object describing the connected wallet's state.\n * @property {Partial<Record<SolanaClusterMoniker, string>>} rpcUrls - A mapping of cluster names to their respective RPC endpoints.\n */\nexport interface SolanaAdapterConfig {\n wallet?: SolanaAdapterWallet;\n rpcUrls: Partial<Record<SolanaClusterMoniker, string>>;\n}\n\n/**\n * Enum defining the available transaction tracker types in the Solana adapter.\n */\nexport enum SolanaTransactionTracker {\n /** The tracker for monitoring standard Solana transaction signatures. */\n Solana = 'solana',\n}\n\n/**\n * Represents the unique identifier for a transaction action initiated on Solana.\n *\n * - For standard Solana transactions, this is the transaction signature encoded as a base58 string.\n */\nexport type SolanaActionTxKey = string;\n","// --- RPC Client Caching ---\n\nimport { createSolanaRpc, Rpc, SolanaClusterMoniker, SolanaRpcApi } from 'gill';\n\n/**\n * Validates whether a string is a properly formatted URL.\n * @param str - The string to validate.\n * @returns True if the string is a valid URL, otherwise false.\n */\nfunction isValidUrl(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * The default RPC URLs for each Solana cluster.\n * Not all clusters need to be defined; undefined ones will fall back to other logic.\n * @internal\n */\nconst defaultRpcUrlsByMoniker: Partial<Record<SolanaClusterMoniker, string>> = {\n mainnet: 'https://api.mainnet-beta.solana.com',\n devnet: 'https://api.devnet.solana.com',\n testnet: 'https://api.testnet.solana.com',\n};\n\n/**\n * An in-memory cache for RPC clients to avoid redundant instance creation.\n * @internal\n */\nconst rpcCache = new Map<string, Rpc<SolanaRpcApi>>();\n\n/**\n * Retrieves a cached RPC client for a given URL or cluster moniker.\n * If no cached client exists, it creates a new instance.\n *\n * @param rpcUrlOrMoniker - Either a full RPC URL or a cluster moniker like 'mainnet'.\n * @returns The RPC client instance.\n * @internal\n */\nexport const createSolanaRPC = (rpcUrlOrMoniker: string): Rpc<SolanaRpcApi> => {\n // Check the cache first for an existing RPC instance.\n if (rpcCache.has(rpcUrlOrMoniker)) {\n return rpcCache.get(rpcUrlOrMoniker)!;\n }\n\n // Determine the RPC URL: validate if it's a full URL or fall back to default list.\n const rpcUrl = isValidUrl(rpcUrlOrMoniker)\n ? rpcUrlOrMoniker\n : defaultRpcUrlsByMoniker[rpcUrlOrMoniker as SolanaClusterMoniker];\n\n // If no valid RPC URL could be resolved, default to the mainnet URL.\n if (!rpcUrl) {\n throw new Error(\n `Unable to resolve RPC URL for input: \"${rpcUrlOrMoniker}\". Ensure it's a valid URL or known moniker.`,\n );\n }\n\n // Create a new RPC client instance.\n const newRpc = createSolanaRpc(rpcUrl);\n\n // Cache the new instance and return it.\n rpcCache.set(rpcUrlOrMoniker, newRpc);\n return newRpc;\n};\n","/**\n * @file Implements the transaction tracking logic for standard Solana transactions.\n * It uses a polling mechanism to query the `getSignatureStatuses` RPC method\n * and updates the transaction's state in the Pulsar store.\n */\n\nimport {\n initializePollingTracker,\n ITxTrackingStore,\n PollingTrackerConfig,\n Transaction,\n TransactionAdapter,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Signature, TransactionError } from 'gill';\n\nimport { SolanaActionTxKey, SolanaTransactionTracker } from '../types';\nimport { createSolanaRPC } from '../utils/createSolanaRPC';\n\n// --- Types ---\n\n/**\n * The structure of the status object returned by the Solana RPC `getSignatureStatuses` method.\n * It represents the real-time status of a Solana transaction.\n * Note: `slot and confirmations` is received as a `bigint` but converted to `number` before being processed.\n * @internal\n */\ntype SolanaSignatureStatusResponse = {\n slot: number;\n confirmations: number | null;\n err: TransactionError | null;\n confirmationStatus: 'processed' | 'confirmed' | 'finalized' | null;\n};\n\n/**\n * The function parameters for the `solanaFetcher` function.\n * These are automatically derived from the generic `PollingTrackerConfig` fetcher function.\n * @internal\n */\ntype SolanaFetcherParams = Parameters<\n PollingTrackerConfig<\n SolanaSignatureStatusResponse,\n Transaction<SolanaTransactionTracker>,\n SolanaTransactionTracker\n >['fetcher']\n>[0];\n\n// --- Fetcher Implementation ---\n\n/**\n * The core polling fetcher function for Solana transactions.\n *\n * This function queries the Solana RPC for updates on a transaction's status.\n * It processes the response and triggers appropriate callbacks (`onSuccess`, `onFailure`, etc.)\n * based on the transaction's state.\n *\n * @param {SolanaFetcherParams} params - The parameters for the fetcher, including the transaction object\n * and various callbacks for handling updates.\n * @returns {Promise<void>} A promise that resolves once the fetcher function completes.\n */\nexport async function solanaFetcher({\n tx,\n stopPolling,\n onSuccess,\n onFailure,\n onIntervalTick,\n}: SolanaFetcherParams): Promise<void> {\n if (tx.adapter !== TransactionAdapter.SOLANA) {\n throw new Error('Tx adapter is not Solana. Please set adapter to \"solana\" in the transaction object.');\n }\n\n // Fetch the transaction status from the Solana RPC.\n const rpc = createSolanaRPC(tx.rpcUrl ?? (tx.chainId as string));\n const statuses = await rpc.getSignatureStatuses([tx.txKey as Signature]).send();\n const status = statuses?.value[0];\n\n if (!status) {\n // Skip processing if the transaction is not yet found by the RPC node.\n return;\n }\n\n // Convert `slot` and `confirmations` to a number and process the response.\n const typedStatus: SolanaSignatureStatusResponse = {\n ...status,\n slot: Number(status.slot),\n confirmations: Number(status.confirmations ?? 0),\n };\n\n // Trigger onIntervalTick for intermediate updates.\n onIntervalTick?.(typedStatus);\n\n if (typedStatus.err) {\n // Handle a terminal error state if an error exists in the response.\n onFailure(typedStatus);\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n if (typedStatus.confirmationStatus === 'finalized') {\n // Handle a terminal success state when the transaction is finalized.\n onSuccess(typedStatus);\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // Safeguard: Stop polling for transactions pending longer than 30 minutes.\n const elapsedMinutes = dayjs().diff(dayjs.unix(tx.localTimestamp), 'minute');\n if (elapsedMinutes >= 30) {\n stopPolling({ withoutRemoving: true });\n onFailure(typedStatus);\n }\n}\n\n// --- Store-Connected Tracker ---\n\n/**\n * A higher-level polling tracker that integrates the Solana transaction tracking logic\n * with the Pulsar store's transaction management.\n *\n * This function initializes and manages the lifecycle of polling for a Solana transaction's status.\n * It dynamically updates the transaction state in the store based on polling results.\n *\n * @template T - The application-specific type for the transaction, extending `Transaction`.\n * @param {object} params - The parameters for the store-connected tracker.\n * @param {T} params.tx - The Solana transaction object to be tracked.\n * @param {Record<string, T>} params.transactionsPool - The current pool of transactions in the store.\n * @param {Function} params.updateTxParams - A function to update specific fields of a transaction in the store.\n * @param {Function} [params.onSucceedCallbacks] - Optional callbacks to trigger on a successful tracking outcome.\n * @param {Function} [params.removeTxFromPool] - A function to remove the tracked transaction from the pool.\n * @returns {Promise<void>} A promise that resolves once the tracking process is initialized.\n */\nexport async function solanaTrackerForStore<T extends Transaction<SolanaTransactionTracker>>({\n tx,\n ...rest\n}: Pick<\n ITxTrackingStore<SolanaTransactionTracker, T, SolanaActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}): Promise<void> {\n return initializePollingTracker<SolanaSignatureStatusResponse, T, SolanaTransactionTracker>({\n tx,\n fetcher: solanaFetcher,\n removeTxFromPool: rest.removeTxFromPool,\n pollingInterval: 2500, // Poll every 2.5 seconds.\n maxRetries: 10, // Limit retries to 10 attempts.\n\n onSuccess: (response) => {\n // Update the store on a successful transaction outcome.\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: false,\n finishedTimestamp: dayjs().unix(),\n confirmations: response.confirmations ?? 1,\n slot: response.slot,\n });\n\n // Trigger global success callbacks if provided.\n const updatedTx = rest.transactionsPool[tx.txKey];\n if (rest.onSucceedCallbacks && updatedTx) {\n rest.onSucceedCallbacks(updatedTx);\n }\n },\n\n onIntervalTick: (response) => {\n // Update fields at each polling interval (e.g., confirmations and slot).\n rest.updateTxParams(tx.txKey, {\n confirmations: response.confirmations ?? 0,\n slot: response.slot,\n });\n },\n\n onFailure: (response) => {\n // Handle a failure state for the transaction.\n const errorMessage = response?.err\n ? `Transaction failed: ${JSON.stringify(response.err)}`\n : 'Transaction tracking timed out or the transaction was not found.';\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage,\n finishedTimestamp: dayjs().unix(),\n });\n },\n });\n}\n","/**\n * @file This file contains the primary router for initializing transaction trackers.\n */\n\nimport { ITxTrackingStore, Transaction, TransactionStatus } from '@tuwaio/pulsar-core';\n\nimport { solanaTrackerForStore } from '../trackers/solanaTracker';\nimport { SolanaActionTxKey, SolanaTransactionTracker } from '../types';\n\n/**\n * Initializes the correct background tracker for a given Solana transaction.\n * This function acts as a router, selecting the appropriate tracker based on the `tx.tracker` property.\n *\n * @template T - The transaction type, constrained to Solana transactions.\n * @param {object} params - The parameters for initializing the tracker.\n * @param {T} params.tx - The transaction object to be tracked.\n * @param {SolanaTransactionTracker} params.tracker - The specific tracker to use.\n * @param {object} params.rest - The rest of the store's methods and state needed by the tracker.\n * @returns {Promise<void>} A promise that resolves when the tracker has been initialized.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<SolanaTransactionTracker>>({\n tx,\n tracker,\n ...rest\n}: {\n tx: T;\n tracker: SolanaTransactionTracker;\n} & Pick<\n ITxTrackingStore<SolanaTransactionTracker, T, SolanaActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n>): Promise<void> {\n switch (tracker) {\n case SolanaTransactionTracker.Solana:\n await solanaTrackerForStore({\n tx,\n ...rest,\n });\n break;\n default:\n console.error(`Unknown tracker type for Solana adapter: ${tracker}`);\n // If an unsupported tracker is specified, mark the transaction as failed.\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage: `Unsupported tracker type: \"${tracker}\"`,\n });\n break;\n }\n}\n","/**\n * @file This file contains a utility to verify the connected Solana chain.\n */\n\nimport { SolanaChainMismatchError } from '../errors';\n\n/**\n * Checks if the wallet's current chain matches the required chain for a transaction.\n *\n * This function compares the `chain` property from the Wallet Standard account object\n * with the required chain identifier (e.g., 'solana:mainnet').\n *\n * @param {string} requiredChain - The chain identifier that the transaction requires.\n * @param {string} currentChain - The chain identifier the wallet is currently connected to.\n * @throws {SolanaChainMismatchError} If the connected chain does not match the required chain.\n */\nexport const checkSolanaChain = (requiredChain: string, currentChain: string): void => {\n if (currentChain !== requiredChain) {\n throw new SolanaChainMismatchError(requiredChain, currentChain);\n }\n};\n","/**\n * @file This file contains a utility function for generating Solana transaction explorer links.\n */\n\nimport { getExplorerLink, SolanaClusterMoniker } from 'gill';\n\n/**\n * Generates a full URL to a transaction on a Solana explorer like Solscan.\n *\n * @param {string} baseUrl - The base URL of the explorer (e.g., \"https://solscan.io\").\n * @param {string} txKey - The transaction signature (hash).\n * @param {SolanaCluster} [cluster] - The optional cluster name ('devnet', 'testnet') to add as a query parameter.\n * @returns {string} The full URL to the transaction on the explorer.\n */\nexport const selectSolanaTxExplorerLink = (txKey: string, cluster?: SolanaClusterMoniker): string => {\n // Ensure there are no trailing slashes on the base URL for clean URL construction.\n const baseUrl = getExplorerLink({ cluster });\n const sanitizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n\n // Build the cluster query parameter if provided.\n const clusterParam = cluster ? `?cluster=${cluster}` : '';\n\n return `${sanitizedBaseUrl}/tx/${txKey}${clusterParam}`;\n};\n","/**\n * @file This file contains utility functions for interacting with the Solana Name Service (SNS) provided by Bonfida.\n */\n\nimport { getDomainKeysWithReverses, getRecord, performReverseLookup, Record } from '@bonfida/spl-name-service';\nimport { Connection, PublicKey } from '@solana/web3.js';\n\n/**\n * A cache to store Connection instances for different RPC URLs.\n * This prevents creating a new Connection object for every function call.\n * @type {Map<string, Connection>}\n */\nconst connectionCache = new Map<string, Connection>();\n\n/**\n * A cache to store resolved domain names against wallet addresses.\n * This prevents repeated reverse lookups for the same address.\n * @type {Map<string, string | null>}\n */\nconst domainNameCache = new Map<string, string | null>();\n\n/**\n * Retrieves a cached Connection object or creates a new one if it doesn't exist.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @returns {Connection} An instance of the Connection class.\n */\nconst getConnection = (rpcUrl: string): Connection => {\n if (!connectionCache.has(rpcUrl)) {\n connectionCache.set(rpcUrl, new Connection(rpcUrl));\n }\n return connectionCache.get(rpcUrl)!;\n};\n\n/**\n * Performs a reverse lookup to find the .sol domain name for a given wallet address.\n * Results are cached to avoid redundant network requests.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @param {string} address - The public key of the wallet as a string.\n * @returns {Promise<string | null>} The .sol domain name (e.g., \"bonfida.sol\") or null if not found.\n */\nexport const getSolanaName = async (rpcUrl: string, address: string): Promise<string | null> => {\n // Return the cached domain name if it exists for the given address.\n if (domainNameCache.has(address)) {\n return domainNameCache.get(address)!;\n }\n\n try {\n const connection = getConnection(rpcUrl);\n const pubKey = new PublicKey(address);\n\n const domainKeys = await getDomainKeysWithReverses(connection, pubKey);\n\n if (domainKeys.length === 0) {\n // Cache the null result to prevent future lookups for this address.\n domainNameCache.set(address, null);\n return null;\n }\n\n // @ts-expect-error - domainKeys is an array of PublicKey objects.\n const domainName = await performReverseLookup(connection, domainKeys[0]);\n const fullDomain = `${domainName}.sol`;\n\n // Cache the successful result.\n domainNameCache.set(address, fullDomain);\n return fullDomain;\n } catch {\n // Cache the null result in case of an error.\n domainNameCache.set(address, null);\n return null;\n }\n};\n\n/**\n * Retrieves the avatar URL from the 'pic' record of a .sol domain name.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @param {string} name - The .sol domain name (e.g., \"bonfida.sol\").\n * @returns {Promise<string | null>} The URL of the avatar or null if not found or set.\n */\nexport const getSolanaAvatar = async (rpcUrl: string, name: string): Promise<string | null> => {\n try {\n const connection = getConnection(rpcUrl);\n const record = await getRecord(connection, name, Record.Pic);\n\n if (!record || !record.data) {\n return null;\n }\n\n return record.data.toString('utf-8');\n } catch {\n // Fails silently if the record doesn't exist.\n return null;\n }\n};\n","/**\n * @file This file contains the factory function for creating the Solana adapter for Pulsar.\n */\nimport type { Transaction, TxAdapter } from '@tuwaio/pulsar-core';\nimport { TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { getExplorerLink, SolanaClusterMoniker } from 'gill';\n\nimport { SolanaChainMismatchError } from '../errors';\nimport { SolanaActionTxKey, SolanaAdapterConfig, SolanaTransactionTracker } from '../types';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkSolanaChain } from '../utils/checkSolanaChain';\nimport { createSolanaRPC } from '../utils/createSolanaRPC';\nimport { selectSolanaTxExplorerLink } from '../utils/selectSolanaTxExplorerLink';\nimport { getSolanaAvatar, getSolanaName } from '../utils/snsUtils';\n\n/**\n * Creates a Solana adapter for the Pulsar transaction tracking engine.\n * This factory function produces a wallet-library-agnostic adapter that can be\n * configured for multiple Solana clusters (e.g., mainnet-beta, devnet) and\n * can operate even without a connected wallet for read-only tasks.\n *\n * @param config The configuration object for the adapter.\n * @returns An object implementing the `TxAdapter` interface for Solana.\n */\nexport function solanaAdapter<T extends Transaction<SolanaTransactionTracker>>(\n config: SolanaAdapterConfig,\n): TxAdapter<SolanaTransactionTracker, T, SolanaActionTxKey> {\n const { wallet, rpcUrls } = config;\n\n /**\n * Safely extracts the cluster moniker from a chain identifier.\n * Handles both full chain IDs ('solana:mainnet-beta') and simple monikers ('mainnet-beta').\n * @param chain The chain identifier or moniker.\n * @returns The extracted cluster moniker.\n */\n const getCluster = (chain?: string): SolanaClusterMoniker => {\n const defaultCluster: SolanaClusterMoniker = 'mainnet';\n if (!chain) {\n return wallet?.walletActiveChain ?? defaultCluster;\n }\n return (chain.includes(':') ? chain.split(':')[1] : chain) as SolanaClusterMoniker;\n };\n\n /**\n * Retrieves the configured RPC URL for a given cluster moniker.\n * @param cluster The target cluster. Defaults to the wallet's active chain.\n * @returns The RPC URL or undefined if not found.\n */\n const getRpcUrlForCluster = (cluster?: SolanaClusterMoniker): string | undefined => {\n const targetCluster = cluster ?? wallet?.walletActiveChain;\n if (!targetCluster) return undefined;\n return rpcUrls[targetCluster];\n };\n\n return {\n key: TransactionAdapter.SOLANA,\n\n getWalletInfo: () => ({\n walletAddress: wallet?.walletAddress ?? '0x0',\n walletType: wallet?.walletType ?? 'disconnected',\n }),\n\n checkChainForTx: async (txChain) => {\n if (!wallet) {\n throw new Error('Wallet not provided. Cannot perform chain check.');\n }\n try {\n checkSolanaChain(txChain as string, wallet.walletActiveChain);\n } catch (e) {\n if (e instanceof SolanaChainMismatchError) throw e;\n throw new Error(`Chain check failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n },\n\n checkTransactionsTracker: (actionTxKey) => ({\n tracker: SolanaTransactionTracker.Solana,\n txKey: actionTxKey,\n }),\n\n checkAndInitializeTrackerInStore: ({ tx, ...rest }) => {\n return checkAndInitializeTrackerInStore({\n tracker: tx.tracker,\n tx,\n ...rest,\n });\n },\n\n getExplorerUrl: () => {\n const cluster = wallet?.walletActiveChain ?? 'mainnet-beta';\n return getExplorerLink({ cluster });\n },\n\n getExplorerTxUrl: (txPool, txKey) => {\n const tx = txPool[txKey];\n const cluster = getCluster(tx?.chainId as string);\n return selectSolanaTxExplorerLink(txKey, cluster);\n },\n\n getName: async (address) => {\n const rpcUrl = getRpcUrlForCluster(wallet?.walletActiveChain);\n if (!rpcUrl) {\n console.warn('Cannot get name: RPC URL for the current chain is not configured.');\n return null;\n }\n return getSolanaName(rpcUrl, address);\n },\n\n getAvatar: async (name) => {\n const rpcUrl = getRpcUrlForCluster(wallet?.walletActiveChain);\n if (!rpcUrl) {\n console.warn('Cannot get avatar: RPC URL for the current chain is not configured.');\n return null;\n }\n return getSolanaAvatar(rpcUrl, name);\n },\n\n retryTxAction: async ({ onClose, txKey, handleTransaction, tx }) => {\n onClose(txKey);\n\n if (!wallet || !wallet.walletAddress || wallet.walletAddress === '0x0') {\n throw new Error('Retry failed: A wallet must be connected.');\n }\n if (!handleTransaction) {\n throw new Error('Retry failed: handleTransaction function is not provided.');\n }\n\n const clusterForRetry = getCluster(tx.desiredChainID as string);\n const rpcUrlForRetry = tx.rpcUrl ?? getRpcUrlForCluster(clusterForRetry);\n if (!rpcUrlForRetry) {\n throw new Error('Retry failed: Could not determine RPC endpoint for the transaction chain.');\n }\n\n const rpcForRetry = createSolanaRPC(rpcUrlForRetry);\n\n await handleTransaction({\n actionFunction: () =>\n tx.actionFunction({\n wallet: config.wallet,\n rpc: rpcForRetry,\n ...tx.payload,\n }),\n params: tx,\n defaultTracker: SolanaTransactionTracker.Solana,\n });\n },\n };\n}\n","/**\n * @file This file contains a utility function for signing and sending Solana transactions.\n * It simplifies the process of creating, signing, and broadcasting a transaction to the network.\n */\n\nimport type { Instruction, SolanaClient, TransactionSendingSigner } from 'gill';\nimport { createTransaction, getBase58Decoder, signAndSendTransactionMessageWithSigners } from 'gill';\n\n/**\n * Creates, signs, and sends a Solana transaction with one or more instructions.\n *\n * This async function orchestrates the common flow for broadcasting a transaction:\n * 1. Fetches the latest blockhash from the RPC.\n * 2. Creates a versioned transaction (`v0`).\n * 3. Signs the transaction with the provided signer.\n * 4. Sends the transaction to the network.\n * 5. Decodes and returns the resulting transaction signature.\n *\n * @param {object} params - The parameters for signing and sending the transaction.\n * @param {SolanaClient} params.client - The Solana client instance for RPC communication.\n * @param {TransactionSendingSigner} params.signer - The signer (e.g., a wallet) responsible for signing the transaction.\n * @param {Instruction | Instruction[]} params.instruction - A single instruction or an array of instructions to include in the transaction.\n * @returns A promise that resolves to the transaction signature.\n * @throws Will throw an error if any of the async operations (fetching blockhash, signing, sending) fail.\n *\n * @example\n * const signature = await signAndSendSolanaTx({\n * client: mySolanaClient,\n * signer: wallet,\n * instruction: myTransferInstruction,\n * });\n * console.log('Transaction sent with signature:', signature);\n */\nexport async function signAndSendSolanaTx({\n client,\n signer,\n instruction,\n}: {\n client: SolanaClient;\n signer: TransactionSendingSigner;\n instruction: Instruction | Instruction[];\n}) {\n // 1. Fetch the latest blockhash to ensure transaction validity.\n const { value: latestBlockhash } = await client.rpc.getLatestBlockhash().send();\n\n // 2. Create a version 0 transaction, which is the current standard.\n const transaction = createTransaction({\n feePayer: signer,\n version: 0,\n latestBlockhash,\n instructions: Array.isArray(instruction) ? instruction : [instruction],\n });\n\n // 3. Sign the transaction message and send it to the network.\n const signature = await signAndSendTransactionMessageWithSigners(transaction);\n\n // 4. Decode the resulting signature into the final format.\n return getBase58Decoder().decode(signature);\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/utils/createSolanaRPC.ts","../src/trackers/solanaTracker.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkSolanaChain.ts","../src/utils/selectSolanaTxExplorerLink.ts","../src/utils/snsUtils.ts","../src/adapters/solanaAdapter.ts","../src/utils/signAndSendSolanaTx.ts"],"names":["SolanaChainMismatchError","requiredChain","currentChain","message","SolanaTransactionTracker","isValidUrl","str","defaultRpcUrlsByMoniker","rpcCache","createSolanaRPC","rpcUrlOrMoniker","rpcUrl","newRpc","createSolanaRpc","solanaFetcher","tx","stopPolling","onSuccess","onFailure","onIntervalTick","TransactionAdapter","rpc","status","fee","recentBlockhash","instructions","txDetails","meta","transaction","typedStatus","dayjs","error","solanaTrackerForStore","rest","initializePollingTracker","response","TransactionStatus","updatedTx","errorMessage","checkAndInitializeTrackerInStore","tracker","checkSolanaChain","selectSolanaTxExplorerLink","txKey","cluster","baseUrl","getExplorerLink","sanitizedBaseUrl","clusterParam","connectionCache","domainNameCache","getConnection","Connection","getSolanaName","address","connection","pubKey","PublicKey","domainKeys","getDomainKeysWithReverses","fullDomain","performReverseLookup","getSolanaAvatar","name","record","getRecord","Record","solanaAdapter","config","wallet","rpcUrls","getCluster","chain","defaultCluster","getRpcUrlForCluster","targetCluster","txChain","actionTxKey","txPool","onClose","handleTransaction","clusterForRetry","rpcUrlForRetry","rpcForRetry","signAndSendSolanaTx","client","signer","instruction","latestBlockhash","createTransaction","signature","signAndSendTransactionMessageWithSigners","getBase58Decoder"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @file This file defines custom error classes for the @tuwaio/pulsar-solana package.\n */\n\n/**\n * Thrown when the connected Solana chain does not match the required chain for a transaction.\n *\n * This allows consuming applications to `catch` this specific error and\n * implement custom logic, such as prompting the user to switch networks.\n */\nexport class SolanaChainMismatchError extends Error {\n /** The name of the error, for easy identification. */\n name = 'SolanaChainMismatchError';\n /** The chain that the transaction requires (e.g., 'solana:mainnet'). */\n requiredChain: string;\n /** The chain the wallet is currently connected to. */\n currentChain: string;\n\n constructor(requiredChain: string, currentChain: string) {\n const message = `Wrong chain. The transaction requires ${requiredChain}, but you are connected to ${currentChain}.`;\n super(message);\n this.requiredChain = requiredChain;\n this.currentChain = currentChain;\n }\n}\n","/**\n * @file Defines the core types and enums specific to the @tuwaio/pulsar-solana package.\n */\n\nimport type { SolanaClusterMoniker } from 'gill';\n\n/**\n * Represents the essential wallet information required by the Solana adapter.\n * This interface provides a simple, library-agnostic abstraction for wallet connections,\n * enabling integration with any wallet library that meets these basic requirements.\n *\n * @property {string} walletAddress - The public address of the connected wallet on Solana.\n * @property {string} walletType - The type or name of the wallet (e.g., 'Phantom', 'Solflare').\n * @property {SolanaClusterMoniker} walletActiveChain - The current chain or cluster the wallet is connected to.\n */\nexport interface SolanaAdapterWallet {\n walletAddress: string;\n walletType: string;\n walletActiveChain: SolanaClusterMoniker;\n}\n\n/**\n * Represents the simplified configuration object for the Solana adapter.\n *\n * This configuration enables both wallet-based (connected) and read-only (disconnected) modes,\n * supporting operations like transaction tracking, name/identity resolution, and more.\n *\n * @property {SolanaAdapterWallet} [wallet] - An optional object describing the connected wallet's state.\n * @property {Partial<Record<SolanaClusterMoniker, string>>} rpcUrls - A mapping of cluster names to their respective RPC endpoints.\n */\nexport interface SolanaAdapterConfig {\n wallet?: SolanaAdapterWallet;\n rpcUrls: Partial<Record<SolanaClusterMoniker, string>>;\n}\n\n/**\n * Enum defining the available transaction tracker types in the Solana adapter.\n */\nexport enum SolanaTransactionTracker {\n /** The tracker for monitoring standard Solana transaction signatures. */\n Solana = 'solana',\n}\n\n/**\n * Represents the unique identifier for a transaction action initiated on Solana.\n *\n * - For standard Solana transactions, this is the transaction signature encoded as a base58 string.\n */\nexport type SolanaActionTxKey = string;\n","// --- RPC Client Caching ---\n\nimport { createSolanaRpc, Rpc, SolanaClusterMoniker, SolanaRpcApi } from 'gill';\n\n/**\n * Validates whether a string is a properly formatted URL.\n * @param str - The string to validate.\n * @returns True if the string is a valid URL, otherwise false.\n */\nfunction isValidUrl(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * The default RPC URLs for each Solana cluster.\n * Not all clusters need to be defined; undefined ones will fall back to other logic.\n * @internal\n */\nconst defaultRpcUrlsByMoniker: Partial<Record<SolanaClusterMoniker, string>> = {\n mainnet: 'https://api.mainnet-beta.solana.com',\n devnet: 'https://api.devnet.solana.com',\n testnet: 'https://api.testnet.solana.com',\n};\n\n/**\n * An in-memory cache for RPC clients to avoid redundant instance creation.\n * @internal\n */\nconst rpcCache = new Map<string, Rpc<SolanaRpcApi>>();\n\n/**\n * Retrieves a cached RPC client for a given URL or cluster moniker.\n * If no cached client exists, it creates a new instance.\n *\n * @param rpcUrlOrMoniker - Either a full RPC URL or a cluster moniker like 'mainnet'.\n * @returns The RPC client instance.\n * @internal\n */\nexport const createSolanaRPC = (rpcUrlOrMoniker: string): Rpc<SolanaRpcApi> => {\n // Check the cache first for an existing RPC instance.\n if (rpcCache.has(rpcUrlOrMoniker)) {\n return rpcCache.get(rpcUrlOrMoniker)!;\n }\n\n // Determine the RPC URL: validate if it's a full URL or fall back to default list.\n const rpcUrl = isValidUrl(rpcUrlOrMoniker)\n ? rpcUrlOrMoniker\n : defaultRpcUrlsByMoniker[rpcUrlOrMoniker as SolanaClusterMoniker];\n\n // If no valid RPC URL could be resolved, default to the mainnet URL.\n if (!rpcUrl) {\n throw new Error(\n `Unable to resolve RPC URL for input: \"${rpcUrlOrMoniker}\". Ensure it's a valid URL or known moniker.`,\n );\n }\n\n // Create a new RPC client instance.\n const newRpc = createSolanaRpc(rpcUrl);\n\n // Cache the new instance and return it.\n rpcCache.set(rpcUrlOrMoniker, newRpc);\n return newRpc;\n};\n","/**\n * @file Implements the transaction tracking logic for Solana transactions.\n * It integrates with the Pulsar store and uses a polling mechanism to query the\n * `getSignatureStatuses` RPC method for updates on transaction status.\n */\n\nimport {\n initializePollingTracker,\n ITxTrackingStore,\n PollingTrackerConfig,\n Transaction,\n TransactionAdapter,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Signature, TransactionError } from 'gill';\n\nimport { SolanaActionTxKey, SolanaTransactionTracker } from '../types';\nimport { createSolanaRPC } from '../utils/createSolanaRPC';\n\n/**\n * @typedef SolanaSignatureStatusResponse\n * Represents the status of a Solana transaction and includes additional metadata.\n *\n * @property {number} slot - The slot in which the transaction was processed.\n * @property {number | null} confirmations - The number of confirmations received.\n * @property {TransactionError | null} err - The error, if any, associated with the transaction.\n * @property {'processed' | 'confirmed' | 'finalized' | null} confirmationStatus - The status of the transaction's confirmation.\n * @property {number} [fee] - The transaction fee in lamports.\n * @property {string} [recentBlockhash] - The blockhash used for the transaction.\n * @property {unknown[]} [instructions] - The instructions included in the transaction.\n */\ntype SolanaSignatureStatusResponse = {\n slot: number;\n confirmations: number | null;\n err: TransactionError | null;\n confirmationStatus: 'processed' | 'confirmed' | 'finalized' | null;\n fee?: number;\n recentBlockhash?: string;\n instructions?: unknown[];\n};\n\n/**\n * @typedef SolanaFetcherParams\n * Parameters used for the Solana fetcher function.\n */\ntype SolanaFetcherParams = Parameters<\n PollingTrackerConfig<\n SolanaSignatureStatusResponse,\n Transaction<SolanaTransactionTracker>,\n SolanaTransactionTracker\n >['fetcher']\n>[0];\n\n/**\n * Fetches and tracks Solana transactions using the `getSignatureStatuses` RPC method.\n * Transaction details (`getTransaction`) are only fetched once, if not already present in the transaction object.\n *\n * @param {SolanaFetcherParams} params - The fetcher parameters, automatically provided by the tracker.\n * @throws Will throw an error if the transaction adapter is not set to Solana.\n * @returns {Promise<void>} Resolves when the fetcher completes execution for the current polling cycle.\n */\nexport async function solanaFetcher({\n tx,\n stopPolling,\n onSuccess,\n onFailure,\n onIntervalTick,\n}: SolanaFetcherParams): Promise<void> {\n // Validate that the transaction uses the Solana adapter\n if (tx.adapter !== TransactionAdapter.SOLANA) {\n throw new Error('Tx adapter is not Solana. Please set the adapter to \"solana\" in the transaction object.');\n }\n\n try {\n // Initialize the Solana RPC client\n const rpc = createSolanaRPC(tx.rpcUrl ?? (tx.chainId as string));\n\n // Fetch transaction signature status\n const statuses = await rpc.getSignatureStatuses([tx.txKey as Signature]).send();\n const status = statuses?.value?.[0];\n\n // Skip further processing if no status is found\n if (!status) {\n return;\n }\n\n // Extract or fetch transaction details only when missing\n let { fee, recentBlockhash, instructions } = tx;\n\n if (!fee || !recentBlockhash || !instructions) {\n const txDetails = await rpc.getTransaction(tx.txKey as Signature, { encoding: 'json' }).send();\n const { meta, transaction } = txDetails || {};\n\n // If no transaction details are found, skip further processing\n if (!meta || !transaction) {\n return;\n }\n\n // Extract details from RPC response\n fee = Number(meta.fee ?? 0);\n recentBlockhash = transaction.message.recentBlockhash?.toString();\n instructions = transaction.message.instructions as unknown[];\n }\n\n // Construct the extended transaction status object\n const typedStatus: SolanaSignatureStatusResponse = {\n ...status,\n slot: Number(status.slot),\n confirmations: Number(status.confirmations ?? 0),\n fee,\n recentBlockhash,\n instructions,\n };\n\n // Trigger periodic updates for transaction tracking\n onIntervalTick?.(typedStatus);\n\n // Handle transaction error state\n if (typedStatus.err) {\n onFailure(typedStatus);\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // Handle finalized transaction state\n if (typedStatus.confirmationStatus === 'finalized') {\n onSuccess(typedStatus);\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // Stop polling if the transaction is unconfirmed for more than 1 day\n const elapsedDays = dayjs().diff(dayjs.unix(tx.localTimestamp), 'day');\n if (elapsedDays >= 1) {\n onFailure(typedStatus);\n stopPolling();\n }\n } catch (error) {\n console.error('Error in solanaFetcher:', error);\n onFailure({ err: error } as SolanaSignatureStatusResponse);\n stopPolling();\n }\n}\n\n/**\n * A higher-level tracker that integrates the Solana polling logic with the Pulsar store.\n *\n * @template T - The application-specific Solana transaction type.\n *\n * @param {object} params - Parameters to connect the Solana tracker with the store.\n * @param {T} params.tx - The Solana transaction being tracked.\n * @param {Record<string, T>} params.transactionsPool - A pool of tracked transactions in the store.\n * @param {Function} params.updateTxParams - A callback to update specific fields of a transaction in the store.\n * @param {Function} [params.onSucceedCallbacks] - Optional callbacks executed upon successful transaction completion.\n * @param {Function} [params.removeTxFromPool] - A function to remove a completed or canceled transaction from the store.\n * @returns {Promise<void>} Resolves when the tracker is successfully initialized.\n */\nexport async function solanaTrackerForStore<T extends Transaction<SolanaTransactionTracker>>({\n tx,\n ...rest\n}: Pick<\n ITxTrackingStore<SolanaTransactionTracker, T, SolanaActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}): Promise<void> {\n return initializePollingTracker<SolanaSignatureStatusResponse, T, SolanaTransactionTracker>({\n tx,\n fetcher: solanaFetcher,\n removeTxFromPool: rest.removeTxFromPool,\n pollingInterval: 2500, // Polling interval: 2.5 seconds\n maxRetries: 10, // Max retries: 10 times\n\n /**\n * Success handler - updates the Pulsar store with finalized transaction details.\n *\n * @param {SolanaSignatureStatusResponse} response - The finalized transaction details.\n */\n onSuccess: (response) => {\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: false,\n finishedTimestamp: dayjs().unix(),\n fee: response.fee,\n instructions: response.instructions,\n recentBlockhash: response.recentBlockhash,\n confirmations: response.confirmations ?? 1,\n slot: response.slot,\n });\n\n // Trigger global success callbacks, if applicable\n const updatedTx = rest.transactionsPool[tx.txKey];\n if (rest.onSucceedCallbacks && updatedTx) {\n rest.onSucceedCallbacks(updatedTx);\n }\n },\n\n /**\n * Interval handler - updates interim transaction details in the store.\n *\n * @param {SolanaSignatureStatusResponse} response - The latest transaction status update.\n */\n onIntervalTick: (response) => {\n rest.updateTxParams(tx.txKey, {\n confirmations: response.confirmations ?? 0,\n slot: response.slot,\n fee: response.fee,\n instructions: response.instructions,\n recentBlockhash: response.recentBlockhash,\n });\n },\n\n /**\n * Failure handler - updates the store when the transaction fails or times out.\n *\n * @param {SolanaSignatureStatusResponse} response - The failure response details.\n */\n onFailure: (response) => {\n const errorMessage = response?.err\n ? `Transaction failed: ${JSON.stringify(response.err)}`\n : 'Transaction tracking timed out or the transaction was not found.';\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage,\n finishedTimestamp: dayjs().unix(),\n });\n },\n });\n}\n","/**\n * @file This file contains the primary router for initializing transaction trackers.\n */\n\nimport { ITxTrackingStore, Transaction, TransactionStatus } from '@tuwaio/pulsar-core';\n\nimport { solanaTrackerForStore } from '../trackers/solanaTracker';\nimport { SolanaActionTxKey, SolanaTransactionTracker } from '../types';\n\n/**\n * Initializes the correct background tracker for a given Solana transaction.\n * This function acts as a router, selecting the appropriate tracker based on the `tx.tracker` property.\n *\n * @template T - The transaction type, constrained to Solana transactions.\n * @param {object} params - The parameters for initializing the tracker.\n * @param {T} params.tx - The transaction object to be tracked.\n * @param {SolanaTransactionTracker} params.tracker - The specific tracker to use.\n * @param {object} params.rest - The rest of the store's methods and state needed by the tracker.\n * @returns {Promise<void>} A promise that resolves when the tracker has been initialized.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<SolanaTransactionTracker>>({\n tx,\n tracker,\n ...rest\n}: {\n tx: T;\n tracker: SolanaTransactionTracker;\n} & Pick<\n ITxTrackingStore<SolanaTransactionTracker, T, SolanaActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n>): Promise<void> {\n switch (tracker) {\n case SolanaTransactionTracker.Solana:\n await solanaTrackerForStore({\n tx,\n ...rest,\n });\n break;\n default:\n console.error(`Unknown tracker type for Solana adapter: ${tracker}`);\n // If an unsupported tracker is specified, mark the transaction as failed.\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage: `Unsupported tracker type: \"${tracker}\"`,\n });\n break;\n }\n}\n","/**\n * @file This file contains a utility to verify the connected Solana chain.\n */\n\nimport { SolanaChainMismatchError } from '../errors';\n\n/**\n * Checks if the wallet's current chain matches the required chain for a transaction.\n *\n * This function compares the `chain` property from the Wallet Standard account object\n * with the required chain identifier (e.g., 'solana:mainnet').\n *\n * @param {string} requiredChain - The chain identifier that the transaction requires.\n * @param {string} currentChain - The chain identifier the wallet is currently connected to.\n * @throws {SolanaChainMismatchError} If the connected chain does not match the required chain.\n */\nexport const checkSolanaChain = (requiredChain: string, currentChain: string): void => {\n if (currentChain !== requiredChain) {\n throw new SolanaChainMismatchError(requiredChain, currentChain);\n }\n};\n","/**\n * @file This file contains a utility function for generating Solana transaction explorer links.\n */\n\nimport { getExplorerLink, SolanaClusterMoniker } from 'gill';\n\n/**\n * Generates a full URL to a transaction on a Solana explorer like Solscan.\n *\n * @param {string} baseUrl - The base URL of the explorer (e.g., \"https://solscan.io\").\n * @param {string} txKey - The transaction signature (hash).\n * @param {SolanaCluster} [cluster] - The optional cluster name ('devnet', 'testnet') to add as a query parameter.\n * @returns {string} The full URL to the transaction on the explorer.\n */\nexport const selectSolanaTxExplorerLink = (txKey: string, cluster?: SolanaClusterMoniker): string => {\n // Ensure there are no trailing slashes on the base URL for clean URL construction.\n const baseUrl = getExplorerLink({ cluster });\n const sanitizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n\n // Build the cluster query parameter if provided.\n const clusterParam = cluster ? `?cluster=${cluster}` : '';\n\n return `${sanitizedBaseUrl}/tx/${txKey}${clusterParam}`;\n};\n","/**\n * @file This file contains utility functions for interacting with the Solana Name Service (SNS) provided by Bonfida.\n */\n\nimport { getDomainKeysWithReverses, getRecord, performReverseLookup, Record } from '@bonfida/spl-name-service';\nimport { Connection, PublicKey } from '@solana/web3.js';\n\n/**\n * A cache to store Connection instances for different RPC URLs.\n * This prevents creating a new Connection object for every function call.\n * @type {Map<string, Connection>}\n */\nconst connectionCache = new Map<string, Connection>();\n\n/**\n * A cache to store resolved domain names against wallet addresses.\n * This prevents repeated reverse lookups for the same address.\n * @type {Map<string, string | null>}\n */\nconst domainNameCache = new Map<string, string | null>();\n\n/**\n * Retrieves a cached Connection object or creates a new one if it doesn't exist.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @returns {Connection} An instance of the Connection class.\n */\nconst getConnection = (rpcUrl: string): Connection => {\n if (!connectionCache.has(rpcUrl)) {\n connectionCache.set(rpcUrl, new Connection(rpcUrl));\n }\n return connectionCache.get(rpcUrl)!;\n};\n\n/**\n * Performs a reverse lookup to find the .sol domain name for a given wallet address.\n * Results are cached to avoid redundant network requests.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @param {string} address - The public key of the wallet as a string.\n * @returns {Promise<string | null>} The .sol domain name (e.g., \"bonfida.sol\") or null if not found.\n */\nexport const getSolanaName = async (rpcUrl: string, address: string): Promise<string | null> => {\n // Return the cached domain name if it exists for the given address.\n if (domainNameCache.has(address)) {\n return domainNameCache.get(address)!;\n }\n\n try {\n const connection = getConnection(rpcUrl);\n const pubKey = new PublicKey(address);\n\n const domainKeys = await getDomainKeysWithReverses(connection, pubKey);\n\n if (domainKeys.length === 0) {\n // Cache the null result to prevent future lookups for this address.\n domainNameCache.set(address, null);\n return null;\n }\n\n // @ts-expect-error - domainKeys is an array of PublicKey objects.\n const domainName = await performReverseLookup(connection, domainKeys[0]);\n const fullDomain = `${domainName}.sol`;\n\n // Cache the successful result.\n domainNameCache.set(address, fullDomain);\n return fullDomain;\n } catch {\n // Cache the null result in case of an error.\n domainNameCache.set(address, null);\n return null;\n }\n};\n\n/**\n * Retrieves the avatar URL from the 'pic' record of a .sol domain name.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @param {string} name - The .sol domain name (e.g., \"bonfida.sol\").\n * @returns {Promise<string | null>} The URL of the avatar or null if not found or set.\n */\nexport const getSolanaAvatar = async (rpcUrl: string, name: string): Promise<string | null> => {\n try {\n const connection = getConnection(rpcUrl);\n const record = await getRecord(connection, name, Record.Pic);\n\n if (!record || !record.data) {\n return null;\n }\n\n return record.data.toString('utf-8');\n } catch {\n // Fails silently if the record doesn't exist.\n return null;\n }\n};\n","/**\n * @file This file contains the factory function for creating the Solana adapter for Pulsar.\n */\nimport type { Transaction, TxAdapter } from '@tuwaio/pulsar-core';\nimport { TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { getExplorerLink, SolanaClusterMoniker } from 'gill';\n\nimport { SolanaChainMismatchError } from '../errors';\nimport { SolanaActionTxKey, SolanaAdapterConfig, SolanaTransactionTracker } from '../types';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkSolanaChain } from '../utils/checkSolanaChain';\nimport { createSolanaRPC } from '../utils/createSolanaRPC';\nimport { selectSolanaTxExplorerLink } from '../utils/selectSolanaTxExplorerLink';\nimport { getSolanaAvatar, getSolanaName } from '../utils/snsUtils';\n\n/**\n * Creates a Solana adapter for the Pulsar transaction tracking engine.\n * This factory function produces a wallet-library-agnostic adapter that can be\n * configured for multiple Solana clusters (e.g., mainnet-beta, devnet) and\n * can operate even without a connected wallet for read-only tasks.\n *\n * @param config The configuration object for the adapter.\n * @returns An object implementing the `TxAdapter` interface for Solana.\n */\nexport function solanaAdapter<T extends Transaction<SolanaTransactionTracker>>(\n config: SolanaAdapterConfig,\n): TxAdapter<SolanaTransactionTracker, T, SolanaActionTxKey> {\n const { wallet, rpcUrls } = config;\n\n /**\n * Safely extracts the cluster moniker from a chain identifier.\n * Handles both full chain IDs ('solana:mainnet-beta') and simple monikers ('mainnet-beta').\n * @param chain The chain identifier or moniker.\n * @returns The extracted cluster moniker.\n */\n const getCluster = (chain?: string): SolanaClusterMoniker => {\n const defaultCluster: SolanaClusterMoniker = 'mainnet';\n if (!chain) {\n return wallet?.walletActiveChain ?? defaultCluster;\n }\n return (chain.includes(':') ? chain.split(':')[1] : chain) as SolanaClusterMoniker;\n };\n\n /**\n * Retrieves the configured RPC URL for a given cluster moniker.\n * @param cluster The target cluster. Defaults to the wallet's active chain.\n * @returns The RPC URL or undefined if not found.\n */\n const getRpcUrlForCluster = (cluster?: SolanaClusterMoniker): string | undefined => {\n const targetCluster = cluster ?? wallet?.walletActiveChain;\n if (!targetCluster) return undefined;\n return rpcUrls[targetCluster];\n };\n\n return {\n key: TransactionAdapter.SOLANA,\n\n getWalletInfo: () => ({\n walletAddress: wallet?.walletAddress ?? '0x0',\n walletType: wallet?.walletType ?? 'disconnected',\n }),\n\n checkChainForTx: async (txChain) => {\n if (!wallet) {\n throw new Error('Wallet not provided. Cannot perform chain check.');\n }\n try {\n checkSolanaChain(txChain as string, wallet.walletActiveChain);\n } catch (e) {\n if (e instanceof SolanaChainMismatchError) throw e;\n throw new Error(`Chain check failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n },\n\n checkTransactionsTracker: (actionTxKey) => ({\n tracker: SolanaTransactionTracker.Solana,\n txKey: actionTxKey,\n }),\n\n checkAndInitializeTrackerInStore: ({ tx, ...rest }) => {\n return checkAndInitializeTrackerInStore({\n tracker: tx.tracker,\n tx,\n ...rest,\n });\n },\n\n getExplorerUrl: () => {\n const cluster = wallet?.walletActiveChain ?? 'mainnet-beta';\n return getExplorerLink({ cluster });\n },\n\n getExplorerTxUrl: (txPool, txKey) => {\n const tx = txPool[txKey];\n const cluster = getCluster(tx?.chainId as string);\n return selectSolanaTxExplorerLink(txKey, cluster);\n },\n\n getName: async (address) => {\n const rpcUrl = getRpcUrlForCluster(wallet?.walletActiveChain);\n if (!rpcUrl) {\n console.warn('Cannot get name: RPC URL for the current chain is not configured.');\n return null;\n }\n return getSolanaName(rpcUrl, address);\n },\n\n getAvatar: async (name) => {\n const rpcUrl = getRpcUrlForCluster(wallet?.walletActiveChain);\n if (!rpcUrl) {\n console.warn('Cannot get avatar: RPC URL for the current chain is not configured.');\n return null;\n }\n return getSolanaAvatar(rpcUrl, name);\n },\n\n retryTxAction: async ({ onClose, txKey, handleTransaction, tx }) => {\n onClose(txKey);\n\n if (!wallet || !wallet.walletAddress || wallet.walletAddress === '0x0') {\n throw new Error('Retry failed: A wallet must be connected.');\n }\n if (!handleTransaction) {\n throw new Error('Retry failed: handleTransaction function is not provided.');\n }\n\n const clusterForRetry = getCluster(tx.desiredChainID as string);\n const rpcUrlForRetry = tx.rpcUrl ?? getRpcUrlForCluster(clusterForRetry);\n if (!rpcUrlForRetry) {\n throw new Error('Retry failed: Could not determine RPC endpoint for the transaction chain.');\n }\n\n const rpcForRetry = createSolanaRPC(rpcUrlForRetry);\n\n await handleTransaction({\n actionFunction: () =>\n tx.actionFunction({\n wallet: config.wallet,\n rpc: rpcForRetry,\n ...tx.payload,\n }),\n params: tx,\n defaultTracker: SolanaTransactionTracker.Solana,\n });\n },\n };\n}\n","/**\n * @file This file contains a utility function for signing and sending Solana transactions.\n * It simplifies the process of creating, signing, and broadcasting a transaction to the network.\n */\n\nimport type { Instruction, SolanaClient, TransactionSendingSigner } from 'gill';\nimport { createTransaction, getBase58Decoder, signAndSendTransactionMessageWithSigners } from 'gill';\n\n/**\n * Creates, signs, and sends a Solana transaction with one or more instructions.\n *\n * This async function orchestrates the common flow for broadcasting a transaction:\n * 1. Fetches the latest blockhash from the RPC.\n * 2. Creates a versioned transaction (`v0`).\n * 3. Signs the transaction with the provided signer.\n * 4. Sends the transaction to the network.\n * 5. Decodes and returns the resulting transaction signature.\n *\n * @param {object} params - The parameters for signing and sending the transaction.\n * @param {SolanaClient} params.client - The Solana client instance for RPC communication.\n * @param {TransactionSendingSigner} params.signer - The signer (e.g., a wallet) responsible for signing the transaction.\n * @param {Instruction | Instruction[]} params.instruction - A single instruction or an array of instructions to include in the transaction.\n * @returns A promise that resolves to the transaction signature.\n * @throws Will throw an error if any of the async operations (fetching blockhash, signing, sending) fail.\n *\n * @example\n * const signature = await signAndSendSolanaTx({\n * client: mySolanaClient,\n * signer: wallet,\n * instruction: myTransferInstruction,\n * });\n * console.log('Transaction sent with signature:', signature);\n */\nexport async function signAndSendSolanaTx({\n client,\n signer,\n instruction,\n}: {\n client: SolanaClient;\n signer: TransactionSendingSigner;\n instruction: Instruction | Instruction[];\n}) {\n // 1. Fetch the latest blockhash to ensure transaction validity.\n const { value: latestBlockhash } = await client.rpc.getLatestBlockhash().send();\n\n // 2. Create a version 0 transaction, which is the current standard.\n const transaction = createTransaction({\n feePayer: signer,\n version: 0,\n latestBlockhash,\n instructions: Array.isArray(instruction) ? instruction : [instruction],\n });\n\n // 3. Sign the transaction message and send it to the network.\n const signature = await signAndSendTransactionMessageWithSigners(transaction);\n\n // 4. Decode the resulting signature into the final format.\n return getBase58Decoder().decode(signature);\n}\n"]}
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import {TransactionAdapter,initializePollingTracker,TransactionStatus}from'@tuwaio/pulsar-core';import {createSolanaRpc,getExplorerLink,createTransaction,signAndSendTransactionMessageWithSigners,getBase58Decoder}from'gill';import p from'dayjs';import {getDomainKeysWithReverses,performReverseLookup,getRecord,Record}from'@bonfida/spl-name-service';import {PublicKey,Connection}from'@solana/web3.js';var l=class extends Error{name="SolanaChainMismatchError";requiredChain;currentChain;constructor(t,r){let o=`Wrong chain. The transaction requires ${t}, but you are connected to ${r}.`;super(o),this.requiredChain=t,this.currentChain=r;}};var f=(t=>(t.Solana="solana",t))(f||{});function E(n){try{return new URL(n),!0}catch{return false}}var b={mainnet:"https://api.mainnet-beta.solana.com",devnet:"https://api.devnet.solana.com",testnet:"https://api.testnet.solana.com"},d=new Map,m=n=>{if(d.has(n))return d.get(n);let t=E(n)?n:b[n];if(!t)throw new Error(`Unable to resolve RPC URL for input: "${n}". Ensure it's a valid URL or known moniker.`);let r=createSolanaRpc(t);return d.set(n,r),r};async function M({tx:n,stopPolling:t,onSuccess:r,onFailure:o,onIntervalTick:s}){if(n.adapter!==TransactionAdapter.SOLANA)throw new Error('Tx adapter is not Solana. Please set adapter to "solana" in the transaction object.');let c=(await m(n.rpcUrl??n.chainId).getSignatureStatuses([n.txKey]).send())?.value[0];if(!c)return;let i={...c,slot:Number(c.slot),confirmations:Number(c.confirmations??0)};if(s?.(i),i.err){o(i),t({withoutRemoving:true});return}if(i.confirmationStatus==="finalized"){r(i),t({withoutRemoving:true});return}p().diff(p.unix(n.localTimestamp),"minute")>=30&&(t({withoutRemoving:true}),o(i));}async function k({tx:n,...t}){return initializePollingTracker({tx:n,fetcher:M,removeTxFromPool:t.removeTxFromPool,pollingInterval:2500,maxRetries:10,onSuccess:r=>{t.updateTxParams(n.txKey,{status:TransactionStatus.Success,pending:false,isError:false,finishedTimestamp:p().unix(),confirmations:r.confirmations??1,slot:r.slot});let o=t.transactionsPool[n.txKey];t.onSucceedCallbacks&&o&&t.onSucceedCallbacks(o);},onIntervalTick:r=>{t.updateTxParams(n.txKey,{confirmations:r.confirmations??0,slot:r.slot});},onFailure:r=>{let o=r?.err?`Transaction failed: ${JSON.stringify(r.err)}`:"Transaction tracking timed out or the transaction was not found.";t.updateTxParams(n.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,errorMessage:o,finishedTimestamp:p().unix()});}})}async function x({tx:n,tracker:t,...r}){switch(t){case "solana":await k({tx:n,...r});break;default:console.error(`Unknown tracker type for Solana adapter: ${t}`),r.updateTxParams(n.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,errorMessage:`Unsupported tracker type: "${t}"`});break}}var w=(n,t)=>{if(t!==n)throw new l(n,t)};var C=(n,t)=>{let r=getExplorerLink({cluster:t}),o=r.endsWith("/")?r.slice(0,-1):r,s=t?`?cluster=${t}`:"";return `${o}/tx/${n}${s}`};var S=new Map,u=new Map,y=n=>(S.has(n)||S.set(n,new Connection(n)),S.get(n)),A=async(n,t)=>{if(u.has(t))return u.get(t);try{let r=y(n),o=new PublicKey(t),s=await getDomainKeysWithReverses(r,o);if(s.length===0)return u.set(t,null),null;let e=`${await performReverseLookup(r,s[0])}.sol`;return u.set(t,e),e}catch{return u.set(t,null),null}},R=async(n,t)=>{try{let r=y(n),o=await getRecord(r,t,Record.Pic);return !o||!o.data?null:o.data.toString("utf-8")}catch{return null}};function Kt(n){let{wallet:t,rpcUrls:r}=n,o=a=>{let e="mainnet";return a?a.includes(":")?a.split(":")[1]:a:t?.walletActiveChain??e},s=a=>{let e=a??t?.walletActiveChain;if(e)return r[e]};return {key:TransactionAdapter.SOLANA,getWalletInfo:()=>({walletAddress:t?.walletAddress??"0x0",walletType:t?.walletType??"disconnected"}),checkChainForTx:async a=>{if(!t)throw new Error("Wallet not provided. Cannot perform chain check.");try{w(a,t.walletActiveChain);}catch(e){throw e instanceof l?e:new Error(`Chain check failed: ${e instanceof Error?e.message:String(e)}`)}},checkTransactionsTracker:a=>({tracker:"solana",txKey:a}),checkAndInitializeTrackerInStore:({tx:a,...e})=>x({tracker:a.tracker,tx:a,...e}),getExplorerUrl:()=>{let a=t?.walletActiveChain??"mainnet-beta";return getExplorerLink({cluster:a})},getExplorerTxUrl:(a,e)=>{let c=a[e],i=o(c?.chainId);return C(e,i)},getName:async a=>{let e=s(t?.walletActiveChain);return e?A(e,a):(console.warn("Cannot get name: RPC URL for the current chain is not configured."),null)},getAvatar:async a=>{let e=s(t?.walletActiveChain);return e?R(e,a):(console.warn("Cannot get avatar: RPC URL for the current chain is not configured."),null)},retryTxAction:async({onClose:a,txKey:e,handleTransaction:c,tx:i})=>{if(a(e),!t||!t.walletAddress||t.walletAddress==="0x0")throw new Error("Retry failed: A wallet must be connected.");if(!c)throw new Error("Retry failed: handleTransaction function is not provided.");let T=o(i.desiredChainID),g=i.rpcUrl??s(T);if(!g)throw new Error("Retry failed: Could not determine RPC endpoint for the transaction chain.");let P=m(g);await c({actionFunction:()=>i.actionFunction({wallet:n.wallet,rpc:P,...i.payload}),params:i,defaultTracker:"solana"});}}}async function $t({client:n,signer:t,instruction:r}){let{value:o}=await n.rpc.getLatestBlockhash().send(),s=createTransaction({feePayer:t,version:0,latestBlockhash:o,instructions:Array.isArray(r)?r:[r]}),a=await signAndSendTransactionMessageWithSigners(s);return getBase58Decoder().decode(a)}
2
- export{l as SolanaChainMismatchError,f as SolanaTransactionTracker,x as checkAndInitializeTrackerInStore,w as checkSolanaChain,m as createSolanaRPC,R as getSolanaAvatar,A as getSolanaName,C as selectSolanaTxExplorerLink,$t as signAndSendSolanaTx,Kt as solanaAdapter,M as solanaFetcher,k as solanaTrackerForStore};//# sourceMappingURL=index.mjs.map
1
+ import {TransactionAdapter,initializePollingTracker,TransactionStatus}from'@tuwaio/pulsar-core';import {createSolanaRpc,getExplorerLink,createTransaction,signAndSendTransactionMessageWithSigners,getBase58Decoder}from'gill';import S from'dayjs';import {getDomainKeysWithReverses,performReverseLookup,getRecord,Record}from'@bonfida/spl-name-service';import {PublicKey,Connection}from'@solana/web3.js';var m=class extends Error{name="SolanaChainMismatchError";requiredChain;currentChain;constructor(t,r){let o=`Wrong chain. The transaction requires ${t}, but you are connected to ${r}.`;super(o),this.requiredChain=t,this.currentChain=r;}};var T=(t=>(t.Solana="solana",t))(T||{});function F(n){try{return new URL(n),!0}catch{return false}}var K={mainnet:"https://api.mainnet-beta.solana.com",devnet:"https://api.devnet.solana.com",testnet:"https://api.testnet.solana.com"},h=new Map,d=n=>{if(h.has(n))return h.get(n);let t=F(n)?n:K[n];if(!t)throw new Error(`Unable to resolve RPC URL for input: "${n}". Ensure it's a valid URL or known moniker.`);let r=createSolanaRpc(t);return h.set(n,r),r};async function L({tx:n,stopPolling:t,onSuccess:r,onFailure:o,onIntervalTick:i}){if(n.adapter!==TransactionAdapter.SOLANA)throw new Error('Tx adapter is not Solana. Please set the adapter to "solana" in the transaction object.');try{let a=d(n.rpcUrl??n.chainId),c=(await a.getSignatureStatuses([n.txKey]).send())?.value?.[0];if(!c)return;let{fee:s,recentBlockhash:p,instructions:u}=n;if(!s||!p||!u){let b=await a.getTransaction(n.txKey,{encoding:"json"}).send(),{meta:x,transaction:g}=b||{};if(!x||!g)return;s=Number(x.fee??0),p=g.message.recentBlockhash?.toString(),u=g.message.instructions;}let l={...c,slot:Number(c.slot),confirmations:Number(c.confirmations??0),fee:s,recentBlockhash:p,instructions:u};if(i?.(l),l.err){o(l),t({withoutRemoving:!0});return}if(l.confirmationStatus==="finalized"){r(l),t({withoutRemoving:!0});return}S().diff(S.unix(n.localTimestamp),"day")>=1&&(o(l),t());}catch(a){console.error("Error in solanaFetcher:",a),o({err:a}),t();}}async function y({tx:n,...t}){return initializePollingTracker({tx:n,fetcher:L,removeTxFromPool:t.removeTxFromPool,pollingInterval:2500,maxRetries:10,onSuccess:r=>{t.updateTxParams(n.txKey,{status:TransactionStatus.Success,pending:false,isError:false,finishedTimestamp:S().unix(),fee:r.fee,instructions:r.instructions,recentBlockhash:r.recentBlockhash,confirmations:r.confirmations??1,slot:r.slot});let o=t.transactionsPool[n.txKey];t.onSucceedCallbacks&&o&&t.onSucceedCallbacks(o);},onIntervalTick:r=>{t.updateTxParams(n.txKey,{confirmations:r.confirmations??0,slot:r.slot,fee:r.fee,instructions:r.instructions,recentBlockhash:r.recentBlockhash});},onFailure:r=>{let o=r?.err?`Transaction failed: ${JSON.stringify(r.err)}`:"Transaction tracking timed out or the transaction was not found.";t.updateTxParams(n.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,errorMessage:o,finishedTimestamp:S().unix()});}})}async function C({tx:n,tracker:t,...r}){switch(t){case "solana":await y({tx:n,...r});break;default:console.error(`Unknown tracker type for Solana adapter: ${t}`),r.updateTxParams(n.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,errorMessage:`Unsupported tracker type: "${t}"`});break}}var A=(n,t)=>{if(t!==n)throw new m(n,t)};var R=(n,t)=>{let r=getExplorerLink({cluster:t}),o=r.endsWith("/")?r.slice(0,-1):r,i=t?`?cluster=${t}`:"";return `${o}/tx/${n}${i}`};var k=new Map,f=new Map,P=n=>(k.has(n)||k.set(n,new Connection(n)),k.get(n)),v=async(n,t)=>{if(f.has(t))return f.get(t);try{let r=P(n),o=new PublicKey(t),i=await getDomainKeysWithReverses(r,o);if(i.length===0)return f.set(t,null),null;let e=`${await performReverseLookup(r,i[0])}.sol`;return f.set(t,e),e}catch{return f.set(t,null),null}},E=async(n,t)=>{try{let r=P(n),o=await getRecord(r,t,Record.Pic);return !o||!o.data?null:o.data.toString("utf-8")}catch{return null}};function Nt(n){let{wallet:t,rpcUrls:r}=n,o=a=>{let e="mainnet";return a?a.includes(":")?a.split(":")[1]:a:t?.walletActiveChain??e},i=a=>{let e=a??t?.walletActiveChain;if(e)return r[e]};return {key:TransactionAdapter.SOLANA,getWalletInfo:()=>({walletAddress:t?.walletAddress??"0x0",walletType:t?.walletType??"disconnected"}),checkChainForTx:async a=>{if(!t)throw new Error("Wallet not provided. Cannot perform chain check.");try{A(a,t.walletActiveChain);}catch(e){throw e instanceof m?e:new Error(`Chain check failed: ${e instanceof Error?e.message:String(e)}`)}},checkTransactionsTracker:a=>({tracker:"solana",txKey:a}),checkAndInitializeTrackerInStore:({tx:a,...e})=>C({tracker:a.tracker,tx:a,...e}),getExplorerUrl:()=>{let a=t?.walletActiveChain??"mainnet-beta";return getExplorerLink({cluster:a})},getExplorerTxUrl:(a,e)=>{let c=a[e],s=o(c?.chainId);return R(e,s)},getName:async a=>{let e=i(t?.walletActiveChain);return e?v(e,a):(console.warn("Cannot get name: RPC URL for the current chain is not configured."),null)},getAvatar:async a=>{let e=i(t?.walletActiveChain);return e?E(e,a):(console.warn("Cannot get avatar: RPC URL for the current chain is not configured."),null)},retryTxAction:async({onClose:a,txKey:e,handleTransaction:c,tx:s})=>{if(a(e),!t||!t.walletAddress||t.walletAddress==="0x0")throw new Error("Retry failed: A wallet must be connected.");if(!c)throw new Error("Retry failed: handleTransaction function is not provided.");let p=o(s.desiredChainID),u=s.rpcUrl??i(p);if(!u)throw new Error("Retry failed: Could not determine RPC endpoint for the transaction chain.");let l=d(u);await c({actionFunction:()=>s.actionFunction({wallet:n.wallet,rpc:l,...s.payload}),params:s,defaultTracker:"solana"});}}}async function zt({client:n,signer:t,instruction:r}){let{value:o}=await n.rpc.getLatestBlockhash().send(),i=createTransaction({feePayer:t,version:0,latestBlockhash:o,instructions:Array.isArray(r)?r:[r]}),a=await signAndSendTransactionMessageWithSigners(i);return getBase58Decoder().decode(a)}
2
+ export{m as SolanaChainMismatchError,T as SolanaTransactionTracker,C as checkAndInitializeTrackerInStore,A as checkSolanaChain,d as createSolanaRPC,E as getSolanaAvatar,v as getSolanaName,R as selectSolanaTxExplorerLink,zt as signAndSendSolanaTx,Nt as solanaAdapter,L as solanaFetcher,y as solanaTrackerForStore};//# sourceMappingURL=index.mjs.map
3
3
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/utils/createSolanaRPC.ts","../src/trackers/solanaTracker.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkSolanaChain.ts","../src/utils/selectSolanaTxExplorerLink.ts","../src/utils/snsUtils.ts","../src/adapters/solanaAdapter.ts","../src/utils/signAndSendSolanaTx.ts"],"names":["SolanaChainMismatchError","requiredChain","currentChain","message","SolanaTransactionTracker","isValidUrl","str","defaultRpcUrlsByMoniker","rpcCache","createSolanaRPC","rpcUrlOrMoniker","rpcUrl","newRpc","createSolanaRpc","solanaFetcher","tx","stopPolling","onSuccess","onFailure","onIntervalTick","TransactionAdapter","status","typedStatus","dayjs","solanaTrackerForStore","rest","initializePollingTracker","response","TransactionStatus","updatedTx","errorMessage","checkAndInitializeTrackerInStore","tracker","checkSolanaChain","selectSolanaTxExplorerLink","txKey","cluster","baseUrl","getExplorerLink","sanitizedBaseUrl","clusterParam","connectionCache","domainNameCache","getConnection","Connection","getSolanaName","address","connection","pubKey","PublicKey","domainKeys","getDomainKeysWithReverses","fullDomain","performReverseLookup","getSolanaAvatar","name","record","getRecord","Record","solanaAdapter","config","wallet","rpcUrls","getCluster","chain","defaultCluster","getRpcUrlForCluster","targetCluster","txChain","actionTxKey","txPool","onClose","handleTransaction","clusterForRetry","rpcUrlForRetry","rpcForRetry","signAndSendSolanaTx","client","signer","instruction","latestBlockhash","transaction","createTransaction","signature","signAndSendTransactionMessageWithSigners","getBase58Decoder"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @file This file defines custom error classes for the @tuwaio/pulsar-solana package.\n */\n\n/**\n * Thrown when the connected Solana chain does not match the required chain for a transaction.\n *\n * This allows consuming applications to `catch` this specific error and\n * implement custom logic, such as prompting the user to switch networks.\n */\nexport class SolanaChainMismatchError extends Error {\n /** The name of the error, for easy identification. */\n name = 'SolanaChainMismatchError';\n /** The chain that the transaction requires (e.g., 'solana:mainnet'). */\n requiredChain: string;\n /** The chain the wallet is currently connected to. */\n currentChain: string;\n\n constructor(requiredChain: string, currentChain: string) {\n const message = `Wrong chain. The transaction requires ${requiredChain}, but you are connected to ${currentChain}.`;\n super(message);\n this.requiredChain = requiredChain;\n this.currentChain = currentChain;\n }\n}\n","/**\n * @file Defines the core types and enums specific to the @tuwaio/pulsar-solana package.\n */\n\nimport type { SolanaClusterMoniker } from 'gill';\n\n/**\n * Represents the essential wallet information required by the Solana adapter.\n * This interface provides a simple, library-agnostic abstraction for wallet connections,\n * enabling integration with any wallet library that meets these basic requirements.\n *\n * @property {string} walletAddress - The public address of the connected wallet on Solana.\n * @property {string} walletType - The type or name of the wallet (e.g., 'Phantom', 'Solflare').\n * @property {SolanaClusterMoniker} walletActiveChain - The current chain or cluster the wallet is connected to.\n */\nexport interface SolanaAdapterWallet {\n walletAddress: string;\n walletType: string;\n walletActiveChain: SolanaClusterMoniker;\n}\n\n/**\n * Represents the simplified configuration object for the Solana adapter.\n *\n * This configuration enables both wallet-based (connected) and read-only (disconnected) modes,\n * supporting operations like transaction tracking, name/identity resolution, and more.\n *\n * @property {SolanaAdapterWallet} [wallet] - An optional object describing the connected wallet's state.\n * @property {Partial<Record<SolanaClusterMoniker, string>>} rpcUrls - A mapping of cluster names to their respective RPC endpoints.\n */\nexport interface SolanaAdapterConfig {\n wallet?: SolanaAdapterWallet;\n rpcUrls: Partial<Record<SolanaClusterMoniker, string>>;\n}\n\n/**\n * Enum defining the available transaction tracker types in the Solana adapter.\n */\nexport enum SolanaTransactionTracker {\n /** The tracker for monitoring standard Solana transaction signatures. */\n Solana = 'solana',\n}\n\n/**\n * Represents the unique identifier for a transaction action initiated on Solana.\n *\n * - For standard Solana transactions, this is the transaction signature encoded as a base58 string.\n */\nexport type SolanaActionTxKey = string;\n","// --- RPC Client Caching ---\n\nimport { createSolanaRpc, Rpc, SolanaClusterMoniker, SolanaRpcApi } from 'gill';\n\n/**\n * Validates whether a string is a properly formatted URL.\n * @param str - The string to validate.\n * @returns True if the string is a valid URL, otherwise false.\n */\nfunction isValidUrl(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * The default RPC URLs for each Solana cluster.\n * Not all clusters need to be defined; undefined ones will fall back to other logic.\n * @internal\n */\nconst defaultRpcUrlsByMoniker: Partial<Record<SolanaClusterMoniker, string>> = {\n mainnet: 'https://api.mainnet-beta.solana.com',\n devnet: 'https://api.devnet.solana.com',\n testnet: 'https://api.testnet.solana.com',\n};\n\n/**\n * An in-memory cache for RPC clients to avoid redundant instance creation.\n * @internal\n */\nconst rpcCache = new Map<string, Rpc<SolanaRpcApi>>();\n\n/**\n * Retrieves a cached RPC client for a given URL or cluster moniker.\n * If no cached client exists, it creates a new instance.\n *\n * @param rpcUrlOrMoniker - Either a full RPC URL or a cluster moniker like 'mainnet'.\n * @returns The RPC client instance.\n * @internal\n */\nexport const createSolanaRPC = (rpcUrlOrMoniker: string): Rpc<SolanaRpcApi> => {\n // Check the cache first for an existing RPC instance.\n if (rpcCache.has(rpcUrlOrMoniker)) {\n return rpcCache.get(rpcUrlOrMoniker)!;\n }\n\n // Determine the RPC URL: validate if it's a full URL or fall back to default list.\n const rpcUrl = isValidUrl(rpcUrlOrMoniker)\n ? rpcUrlOrMoniker\n : defaultRpcUrlsByMoniker[rpcUrlOrMoniker as SolanaClusterMoniker];\n\n // If no valid RPC URL could be resolved, default to the mainnet URL.\n if (!rpcUrl) {\n throw new Error(\n `Unable to resolve RPC URL for input: \"${rpcUrlOrMoniker}\". Ensure it's a valid URL or known moniker.`,\n );\n }\n\n // Create a new RPC client instance.\n const newRpc = createSolanaRpc(rpcUrl);\n\n // Cache the new instance and return it.\n rpcCache.set(rpcUrlOrMoniker, newRpc);\n return newRpc;\n};\n","/**\n * @file Implements the transaction tracking logic for standard Solana transactions.\n * It uses a polling mechanism to query the `getSignatureStatuses` RPC method\n * and updates the transaction's state in the Pulsar store.\n */\n\nimport {\n initializePollingTracker,\n ITxTrackingStore,\n PollingTrackerConfig,\n Transaction,\n TransactionAdapter,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Signature, TransactionError } from 'gill';\n\nimport { SolanaActionTxKey, SolanaTransactionTracker } from '../types';\nimport { createSolanaRPC } from '../utils/createSolanaRPC';\n\n// --- Types ---\n\n/**\n * The structure of the status object returned by the Solana RPC `getSignatureStatuses` method.\n * It represents the real-time status of a Solana transaction.\n * Note: `slot and confirmations` is received as a `bigint` but converted to `number` before being processed.\n * @internal\n */\ntype SolanaSignatureStatusResponse = {\n slot: number;\n confirmations: number | null;\n err: TransactionError | null;\n confirmationStatus: 'processed' | 'confirmed' | 'finalized' | null;\n};\n\n/**\n * The function parameters for the `solanaFetcher` function.\n * These are automatically derived from the generic `PollingTrackerConfig` fetcher function.\n * @internal\n */\ntype SolanaFetcherParams = Parameters<\n PollingTrackerConfig<\n SolanaSignatureStatusResponse,\n Transaction<SolanaTransactionTracker>,\n SolanaTransactionTracker\n >['fetcher']\n>[0];\n\n// --- Fetcher Implementation ---\n\n/**\n * The core polling fetcher function for Solana transactions.\n *\n * This function queries the Solana RPC for updates on a transaction's status.\n * It processes the response and triggers appropriate callbacks (`onSuccess`, `onFailure`, etc.)\n * based on the transaction's state.\n *\n * @param {SolanaFetcherParams} params - The parameters for the fetcher, including the transaction object\n * and various callbacks for handling updates.\n * @returns {Promise<void>} A promise that resolves once the fetcher function completes.\n */\nexport async function solanaFetcher({\n tx,\n stopPolling,\n onSuccess,\n onFailure,\n onIntervalTick,\n}: SolanaFetcherParams): Promise<void> {\n if (tx.adapter !== TransactionAdapter.SOLANA) {\n throw new Error('Tx adapter is not Solana. Please set adapter to \"solana\" in the transaction object.');\n }\n\n // Fetch the transaction status from the Solana RPC.\n const rpc = createSolanaRPC(tx.rpcUrl ?? (tx.chainId as string));\n const statuses = await rpc.getSignatureStatuses([tx.txKey as Signature]).send();\n const status = statuses?.value[0];\n\n if (!status) {\n // Skip processing if the transaction is not yet found by the RPC node.\n return;\n }\n\n // Convert `slot` and `confirmations` to a number and process the response.\n const typedStatus: SolanaSignatureStatusResponse = {\n ...status,\n slot: Number(status.slot),\n confirmations: Number(status.confirmations ?? 0),\n };\n\n // Trigger onIntervalTick for intermediate updates.\n onIntervalTick?.(typedStatus);\n\n if (typedStatus.err) {\n // Handle a terminal error state if an error exists in the response.\n onFailure(typedStatus);\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n if (typedStatus.confirmationStatus === 'finalized') {\n // Handle a terminal success state when the transaction is finalized.\n onSuccess(typedStatus);\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // Safeguard: Stop polling for transactions pending longer than 30 minutes.\n const elapsedMinutes = dayjs().diff(dayjs.unix(tx.localTimestamp), 'minute');\n if (elapsedMinutes >= 30) {\n stopPolling({ withoutRemoving: true });\n onFailure(typedStatus);\n }\n}\n\n// --- Store-Connected Tracker ---\n\n/**\n * A higher-level polling tracker that integrates the Solana transaction tracking logic\n * with the Pulsar store's transaction management.\n *\n * This function initializes and manages the lifecycle of polling for a Solana transaction's status.\n * It dynamically updates the transaction state in the store based on polling results.\n *\n * @template T - The application-specific type for the transaction, extending `Transaction`.\n * @param {object} params - The parameters for the store-connected tracker.\n * @param {T} params.tx - The Solana transaction object to be tracked.\n * @param {Record<string, T>} params.transactionsPool - The current pool of transactions in the store.\n * @param {Function} params.updateTxParams - A function to update specific fields of a transaction in the store.\n * @param {Function} [params.onSucceedCallbacks] - Optional callbacks to trigger on a successful tracking outcome.\n * @param {Function} [params.removeTxFromPool] - A function to remove the tracked transaction from the pool.\n * @returns {Promise<void>} A promise that resolves once the tracking process is initialized.\n */\nexport async function solanaTrackerForStore<T extends Transaction<SolanaTransactionTracker>>({\n tx,\n ...rest\n}: Pick<\n ITxTrackingStore<SolanaTransactionTracker, T, SolanaActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}): Promise<void> {\n return initializePollingTracker<SolanaSignatureStatusResponse, T, SolanaTransactionTracker>({\n tx,\n fetcher: solanaFetcher,\n removeTxFromPool: rest.removeTxFromPool,\n pollingInterval: 2500, // Poll every 2.5 seconds.\n maxRetries: 10, // Limit retries to 10 attempts.\n\n onSuccess: (response) => {\n // Update the store on a successful transaction outcome.\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: false,\n finishedTimestamp: dayjs().unix(),\n confirmations: response.confirmations ?? 1,\n slot: response.slot,\n });\n\n // Trigger global success callbacks if provided.\n const updatedTx = rest.transactionsPool[tx.txKey];\n if (rest.onSucceedCallbacks && updatedTx) {\n rest.onSucceedCallbacks(updatedTx);\n }\n },\n\n onIntervalTick: (response) => {\n // Update fields at each polling interval (e.g., confirmations and slot).\n rest.updateTxParams(tx.txKey, {\n confirmations: response.confirmations ?? 0,\n slot: response.slot,\n });\n },\n\n onFailure: (response) => {\n // Handle a failure state for the transaction.\n const errorMessage = response?.err\n ? `Transaction failed: ${JSON.stringify(response.err)}`\n : 'Transaction tracking timed out or the transaction was not found.';\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage,\n finishedTimestamp: dayjs().unix(),\n });\n },\n });\n}\n","/**\n * @file This file contains the primary router for initializing transaction trackers.\n */\n\nimport { ITxTrackingStore, Transaction, TransactionStatus } from '@tuwaio/pulsar-core';\n\nimport { solanaTrackerForStore } from '../trackers/solanaTracker';\nimport { SolanaActionTxKey, SolanaTransactionTracker } from '../types';\n\n/**\n * Initializes the correct background tracker for a given Solana transaction.\n * This function acts as a router, selecting the appropriate tracker based on the `tx.tracker` property.\n *\n * @template T - The transaction type, constrained to Solana transactions.\n * @param {object} params - The parameters for initializing the tracker.\n * @param {T} params.tx - The transaction object to be tracked.\n * @param {SolanaTransactionTracker} params.tracker - The specific tracker to use.\n * @param {object} params.rest - The rest of the store's methods and state needed by the tracker.\n * @returns {Promise<void>} A promise that resolves when the tracker has been initialized.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<SolanaTransactionTracker>>({\n tx,\n tracker,\n ...rest\n}: {\n tx: T;\n tracker: SolanaTransactionTracker;\n} & Pick<\n ITxTrackingStore<SolanaTransactionTracker, T, SolanaActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n>): Promise<void> {\n switch (tracker) {\n case SolanaTransactionTracker.Solana:\n await solanaTrackerForStore({\n tx,\n ...rest,\n });\n break;\n default:\n console.error(`Unknown tracker type for Solana adapter: ${tracker}`);\n // If an unsupported tracker is specified, mark the transaction as failed.\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage: `Unsupported tracker type: \"${tracker}\"`,\n });\n break;\n }\n}\n","/**\n * @file This file contains a utility to verify the connected Solana chain.\n */\n\nimport { SolanaChainMismatchError } from '../errors';\n\n/**\n * Checks if the wallet's current chain matches the required chain for a transaction.\n *\n * This function compares the `chain` property from the Wallet Standard account object\n * with the required chain identifier (e.g., 'solana:mainnet').\n *\n * @param {string} requiredChain - The chain identifier that the transaction requires.\n * @param {string} currentChain - The chain identifier the wallet is currently connected to.\n * @throws {SolanaChainMismatchError} If the connected chain does not match the required chain.\n */\nexport const checkSolanaChain = (requiredChain: string, currentChain: string): void => {\n if (currentChain !== requiredChain) {\n throw new SolanaChainMismatchError(requiredChain, currentChain);\n }\n};\n","/**\n * @file This file contains a utility function for generating Solana transaction explorer links.\n */\n\nimport { getExplorerLink, SolanaClusterMoniker } from 'gill';\n\n/**\n * Generates a full URL to a transaction on a Solana explorer like Solscan.\n *\n * @param {string} baseUrl - The base URL of the explorer (e.g., \"https://solscan.io\").\n * @param {string} txKey - The transaction signature (hash).\n * @param {SolanaCluster} [cluster] - The optional cluster name ('devnet', 'testnet') to add as a query parameter.\n * @returns {string} The full URL to the transaction on the explorer.\n */\nexport const selectSolanaTxExplorerLink = (txKey: string, cluster?: SolanaClusterMoniker): string => {\n // Ensure there are no trailing slashes on the base URL for clean URL construction.\n const baseUrl = getExplorerLink({ cluster });\n const sanitizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n\n // Build the cluster query parameter if provided.\n const clusterParam = cluster ? `?cluster=${cluster}` : '';\n\n return `${sanitizedBaseUrl}/tx/${txKey}${clusterParam}`;\n};\n","/**\n * @file This file contains utility functions for interacting with the Solana Name Service (SNS) provided by Bonfida.\n */\n\nimport { getDomainKeysWithReverses, getRecord, performReverseLookup, Record } from '@bonfida/spl-name-service';\nimport { Connection, PublicKey } from '@solana/web3.js';\n\n/**\n * A cache to store Connection instances for different RPC URLs.\n * This prevents creating a new Connection object for every function call.\n * @type {Map<string, Connection>}\n */\nconst connectionCache = new Map<string, Connection>();\n\n/**\n * A cache to store resolved domain names against wallet addresses.\n * This prevents repeated reverse lookups for the same address.\n * @type {Map<string, string | null>}\n */\nconst domainNameCache = new Map<string, string | null>();\n\n/**\n * Retrieves a cached Connection object or creates a new one if it doesn't exist.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @returns {Connection} An instance of the Connection class.\n */\nconst getConnection = (rpcUrl: string): Connection => {\n if (!connectionCache.has(rpcUrl)) {\n connectionCache.set(rpcUrl, new Connection(rpcUrl));\n }\n return connectionCache.get(rpcUrl)!;\n};\n\n/**\n * Performs a reverse lookup to find the .sol domain name for a given wallet address.\n * Results are cached to avoid redundant network requests.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @param {string} address - The public key of the wallet as a string.\n * @returns {Promise<string | null>} The .sol domain name (e.g., \"bonfida.sol\") or null if not found.\n */\nexport const getSolanaName = async (rpcUrl: string, address: string): Promise<string | null> => {\n // Return the cached domain name if it exists for the given address.\n if (domainNameCache.has(address)) {\n return domainNameCache.get(address)!;\n }\n\n try {\n const connection = getConnection(rpcUrl);\n const pubKey = new PublicKey(address);\n\n const domainKeys = await getDomainKeysWithReverses(connection, pubKey);\n\n if (domainKeys.length === 0) {\n // Cache the null result to prevent future lookups for this address.\n domainNameCache.set(address, null);\n return null;\n }\n\n // @ts-expect-error - domainKeys is an array of PublicKey objects.\n const domainName = await performReverseLookup(connection, domainKeys[0]);\n const fullDomain = `${domainName}.sol`;\n\n // Cache the successful result.\n domainNameCache.set(address, fullDomain);\n return fullDomain;\n } catch {\n // Cache the null result in case of an error.\n domainNameCache.set(address, null);\n return null;\n }\n};\n\n/**\n * Retrieves the avatar URL from the 'pic' record of a .sol domain name.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @param {string} name - The .sol domain name (e.g., \"bonfida.sol\").\n * @returns {Promise<string | null>} The URL of the avatar or null if not found or set.\n */\nexport const getSolanaAvatar = async (rpcUrl: string, name: string): Promise<string | null> => {\n try {\n const connection = getConnection(rpcUrl);\n const record = await getRecord(connection, name, Record.Pic);\n\n if (!record || !record.data) {\n return null;\n }\n\n return record.data.toString('utf-8');\n } catch {\n // Fails silently if the record doesn't exist.\n return null;\n }\n};\n","/**\n * @file This file contains the factory function for creating the Solana adapter for Pulsar.\n */\nimport type { Transaction, TxAdapter } from '@tuwaio/pulsar-core';\nimport { TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { getExplorerLink, SolanaClusterMoniker } from 'gill';\n\nimport { SolanaChainMismatchError } from '../errors';\nimport { SolanaActionTxKey, SolanaAdapterConfig, SolanaTransactionTracker } from '../types';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkSolanaChain } from '../utils/checkSolanaChain';\nimport { createSolanaRPC } from '../utils/createSolanaRPC';\nimport { selectSolanaTxExplorerLink } from '../utils/selectSolanaTxExplorerLink';\nimport { getSolanaAvatar, getSolanaName } from '../utils/snsUtils';\n\n/**\n * Creates a Solana adapter for the Pulsar transaction tracking engine.\n * This factory function produces a wallet-library-agnostic adapter that can be\n * configured for multiple Solana clusters (e.g., mainnet-beta, devnet) and\n * can operate even without a connected wallet for read-only tasks.\n *\n * @param config The configuration object for the adapter.\n * @returns An object implementing the `TxAdapter` interface for Solana.\n */\nexport function solanaAdapter<T extends Transaction<SolanaTransactionTracker>>(\n config: SolanaAdapterConfig,\n): TxAdapter<SolanaTransactionTracker, T, SolanaActionTxKey> {\n const { wallet, rpcUrls } = config;\n\n /**\n * Safely extracts the cluster moniker from a chain identifier.\n * Handles both full chain IDs ('solana:mainnet-beta') and simple monikers ('mainnet-beta').\n * @param chain The chain identifier or moniker.\n * @returns The extracted cluster moniker.\n */\n const getCluster = (chain?: string): SolanaClusterMoniker => {\n const defaultCluster: SolanaClusterMoniker = 'mainnet';\n if (!chain) {\n return wallet?.walletActiveChain ?? defaultCluster;\n }\n return (chain.includes(':') ? chain.split(':')[1] : chain) as SolanaClusterMoniker;\n };\n\n /**\n * Retrieves the configured RPC URL for a given cluster moniker.\n * @param cluster The target cluster. Defaults to the wallet's active chain.\n * @returns The RPC URL or undefined if not found.\n */\n const getRpcUrlForCluster = (cluster?: SolanaClusterMoniker): string | undefined => {\n const targetCluster = cluster ?? wallet?.walletActiveChain;\n if (!targetCluster) return undefined;\n return rpcUrls[targetCluster];\n };\n\n return {\n key: TransactionAdapter.SOLANA,\n\n getWalletInfo: () => ({\n walletAddress: wallet?.walletAddress ?? '0x0',\n walletType: wallet?.walletType ?? 'disconnected',\n }),\n\n checkChainForTx: async (txChain) => {\n if (!wallet) {\n throw new Error('Wallet not provided. Cannot perform chain check.');\n }\n try {\n checkSolanaChain(txChain as string, wallet.walletActiveChain);\n } catch (e) {\n if (e instanceof SolanaChainMismatchError) throw e;\n throw new Error(`Chain check failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n },\n\n checkTransactionsTracker: (actionTxKey) => ({\n tracker: SolanaTransactionTracker.Solana,\n txKey: actionTxKey,\n }),\n\n checkAndInitializeTrackerInStore: ({ tx, ...rest }) => {\n return checkAndInitializeTrackerInStore({\n tracker: tx.tracker,\n tx,\n ...rest,\n });\n },\n\n getExplorerUrl: () => {\n const cluster = wallet?.walletActiveChain ?? 'mainnet-beta';\n return getExplorerLink({ cluster });\n },\n\n getExplorerTxUrl: (txPool, txKey) => {\n const tx = txPool[txKey];\n const cluster = getCluster(tx?.chainId as string);\n return selectSolanaTxExplorerLink(txKey, cluster);\n },\n\n getName: async (address) => {\n const rpcUrl = getRpcUrlForCluster(wallet?.walletActiveChain);\n if (!rpcUrl) {\n console.warn('Cannot get name: RPC URL for the current chain is not configured.');\n return null;\n }\n return getSolanaName(rpcUrl, address);\n },\n\n getAvatar: async (name) => {\n const rpcUrl = getRpcUrlForCluster(wallet?.walletActiveChain);\n if (!rpcUrl) {\n console.warn('Cannot get avatar: RPC URL for the current chain is not configured.');\n return null;\n }\n return getSolanaAvatar(rpcUrl, name);\n },\n\n retryTxAction: async ({ onClose, txKey, handleTransaction, tx }) => {\n onClose(txKey);\n\n if (!wallet || !wallet.walletAddress || wallet.walletAddress === '0x0') {\n throw new Error('Retry failed: A wallet must be connected.');\n }\n if (!handleTransaction) {\n throw new Error('Retry failed: handleTransaction function is not provided.');\n }\n\n const clusterForRetry = getCluster(tx.desiredChainID as string);\n const rpcUrlForRetry = tx.rpcUrl ?? getRpcUrlForCluster(clusterForRetry);\n if (!rpcUrlForRetry) {\n throw new Error('Retry failed: Could not determine RPC endpoint for the transaction chain.');\n }\n\n const rpcForRetry = createSolanaRPC(rpcUrlForRetry);\n\n await handleTransaction({\n actionFunction: () =>\n tx.actionFunction({\n wallet: config.wallet,\n rpc: rpcForRetry,\n ...tx.payload,\n }),\n params: tx,\n defaultTracker: SolanaTransactionTracker.Solana,\n });\n },\n };\n}\n","/**\n * @file This file contains a utility function for signing and sending Solana transactions.\n * It simplifies the process of creating, signing, and broadcasting a transaction to the network.\n */\n\nimport type { Instruction, SolanaClient, TransactionSendingSigner } from 'gill';\nimport { createTransaction, getBase58Decoder, signAndSendTransactionMessageWithSigners } from 'gill';\n\n/**\n * Creates, signs, and sends a Solana transaction with one or more instructions.\n *\n * This async function orchestrates the common flow for broadcasting a transaction:\n * 1. Fetches the latest blockhash from the RPC.\n * 2. Creates a versioned transaction (`v0`).\n * 3. Signs the transaction with the provided signer.\n * 4. Sends the transaction to the network.\n * 5. Decodes and returns the resulting transaction signature.\n *\n * @param {object} params - The parameters for signing and sending the transaction.\n * @param {SolanaClient} params.client - The Solana client instance for RPC communication.\n * @param {TransactionSendingSigner} params.signer - The signer (e.g., a wallet) responsible for signing the transaction.\n * @param {Instruction | Instruction[]} params.instruction - A single instruction or an array of instructions to include in the transaction.\n * @returns A promise that resolves to the transaction signature.\n * @throws Will throw an error if any of the async operations (fetching blockhash, signing, sending) fail.\n *\n * @example\n * const signature = await signAndSendSolanaTx({\n * client: mySolanaClient,\n * signer: wallet,\n * instruction: myTransferInstruction,\n * });\n * console.log('Transaction sent with signature:', signature);\n */\nexport async function signAndSendSolanaTx({\n client,\n signer,\n instruction,\n}: {\n client: SolanaClient;\n signer: TransactionSendingSigner;\n instruction: Instruction | Instruction[];\n}) {\n // 1. Fetch the latest blockhash to ensure transaction validity.\n const { value: latestBlockhash } = await client.rpc.getLatestBlockhash().send();\n\n // 2. Create a version 0 transaction, which is the current standard.\n const transaction = createTransaction({\n feePayer: signer,\n version: 0,\n latestBlockhash,\n instructions: Array.isArray(instruction) ? instruction : [instruction],\n });\n\n // 3. Sign the transaction message and send it to the network.\n const signature = await signAndSendTransactionMessageWithSigners(transaction);\n\n // 4. Decode the resulting signature into the final format.\n return getBase58Decoder().decode(signature);\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/utils/createSolanaRPC.ts","../src/trackers/solanaTracker.ts","../src/utils/checkAndInitializeTrackerInStore.ts","../src/utils/checkSolanaChain.ts","../src/utils/selectSolanaTxExplorerLink.ts","../src/utils/snsUtils.ts","../src/adapters/solanaAdapter.ts","../src/utils/signAndSendSolanaTx.ts"],"names":["SolanaChainMismatchError","requiredChain","currentChain","message","SolanaTransactionTracker","isValidUrl","str","defaultRpcUrlsByMoniker","rpcCache","createSolanaRPC","rpcUrlOrMoniker","rpcUrl","newRpc","createSolanaRpc","solanaFetcher","tx","stopPolling","onSuccess","onFailure","onIntervalTick","TransactionAdapter","rpc","status","fee","recentBlockhash","instructions","txDetails","meta","transaction","typedStatus","dayjs","error","solanaTrackerForStore","rest","initializePollingTracker","response","TransactionStatus","updatedTx","errorMessage","checkAndInitializeTrackerInStore","tracker","checkSolanaChain","selectSolanaTxExplorerLink","txKey","cluster","baseUrl","getExplorerLink","sanitizedBaseUrl","clusterParam","connectionCache","domainNameCache","getConnection","Connection","getSolanaName","address","connection","pubKey","PublicKey","domainKeys","getDomainKeysWithReverses","fullDomain","performReverseLookup","getSolanaAvatar","name","record","getRecord","Record","solanaAdapter","config","wallet","rpcUrls","getCluster","chain","defaultCluster","getRpcUrlForCluster","targetCluster","txChain","actionTxKey","txPool","onClose","handleTransaction","clusterForRetry","rpcUrlForRetry","rpcForRetry","signAndSendSolanaTx","client","signer","instruction","latestBlockhash","createTransaction","signature","signAndSendTransactionMessageWithSigners","getBase58Decoder"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @file This file defines custom error classes for the @tuwaio/pulsar-solana package.\n */\n\n/**\n * Thrown when the connected Solana chain does not match the required chain for a transaction.\n *\n * This allows consuming applications to `catch` this specific error and\n * implement custom logic, such as prompting the user to switch networks.\n */\nexport class SolanaChainMismatchError extends Error {\n /** The name of the error, for easy identification. */\n name = 'SolanaChainMismatchError';\n /** The chain that the transaction requires (e.g., 'solana:mainnet'). */\n requiredChain: string;\n /** The chain the wallet is currently connected to. */\n currentChain: string;\n\n constructor(requiredChain: string, currentChain: string) {\n const message = `Wrong chain. The transaction requires ${requiredChain}, but you are connected to ${currentChain}.`;\n super(message);\n this.requiredChain = requiredChain;\n this.currentChain = currentChain;\n }\n}\n","/**\n * @file Defines the core types and enums specific to the @tuwaio/pulsar-solana package.\n */\n\nimport type { SolanaClusterMoniker } from 'gill';\n\n/**\n * Represents the essential wallet information required by the Solana adapter.\n * This interface provides a simple, library-agnostic abstraction for wallet connections,\n * enabling integration with any wallet library that meets these basic requirements.\n *\n * @property {string} walletAddress - The public address of the connected wallet on Solana.\n * @property {string} walletType - The type or name of the wallet (e.g., 'Phantom', 'Solflare').\n * @property {SolanaClusterMoniker} walletActiveChain - The current chain or cluster the wallet is connected to.\n */\nexport interface SolanaAdapterWallet {\n walletAddress: string;\n walletType: string;\n walletActiveChain: SolanaClusterMoniker;\n}\n\n/**\n * Represents the simplified configuration object for the Solana adapter.\n *\n * This configuration enables both wallet-based (connected) and read-only (disconnected) modes,\n * supporting operations like transaction tracking, name/identity resolution, and more.\n *\n * @property {SolanaAdapterWallet} [wallet] - An optional object describing the connected wallet's state.\n * @property {Partial<Record<SolanaClusterMoniker, string>>} rpcUrls - A mapping of cluster names to their respective RPC endpoints.\n */\nexport interface SolanaAdapterConfig {\n wallet?: SolanaAdapterWallet;\n rpcUrls: Partial<Record<SolanaClusterMoniker, string>>;\n}\n\n/**\n * Enum defining the available transaction tracker types in the Solana adapter.\n */\nexport enum SolanaTransactionTracker {\n /** The tracker for monitoring standard Solana transaction signatures. */\n Solana = 'solana',\n}\n\n/**\n * Represents the unique identifier for a transaction action initiated on Solana.\n *\n * - For standard Solana transactions, this is the transaction signature encoded as a base58 string.\n */\nexport type SolanaActionTxKey = string;\n","// --- RPC Client Caching ---\n\nimport { createSolanaRpc, Rpc, SolanaClusterMoniker, SolanaRpcApi } from 'gill';\n\n/**\n * Validates whether a string is a properly formatted URL.\n * @param str - The string to validate.\n * @returns True if the string is a valid URL, otherwise false.\n */\nfunction isValidUrl(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * The default RPC URLs for each Solana cluster.\n * Not all clusters need to be defined; undefined ones will fall back to other logic.\n * @internal\n */\nconst defaultRpcUrlsByMoniker: Partial<Record<SolanaClusterMoniker, string>> = {\n mainnet: 'https://api.mainnet-beta.solana.com',\n devnet: 'https://api.devnet.solana.com',\n testnet: 'https://api.testnet.solana.com',\n};\n\n/**\n * An in-memory cache for RPC clients to avoid redundant instance creation.\n * @internal\n */\nconst rpcCache = new Map<string, Rpc<SolanaRpcApi>>();\n\n/**\n * Retrieves a cached RPC client for a given URL or cluster moniker.\n * If no cached client exists, it creates a new instance.\n *\n * @param rpcUrlOrMoniker - Either a full RPC URL or a cluster moniker like 'mainnet'.\n * @returns The RPC client instance.\n * @internal\n */\nexport const createSolanaRPC = (rpcUrlOrMoniker: string): Rpc<SolanaRpcApi> => {\n // Check the cache first for an existing RPC instance.\n if (rpcCache.has(rpcUrlOrMoniker)) {\n return rpcCache.get(rpcUrlOrMoniker)!;\n }\n\n // Determine the RPC URL: validate if it's a full URL or fall back to default list.\n const rpcUrl = isValidUrl(rpcUrlOrMoniker)\n ? rpcUrlOrMoniker\n : defaultRpcUrlsByMoniker[rpcUrlOrMoniker as SolanaClusterMoniker];\n\n // If no valid RPC URL could be resolved, default to the mainnet URL.\n if (!rpcUrl) {\n throw new Error(\n `Unable to resolve RPC URL for input: \"${rpcUrlOrMoniker}\". Ensure it's a valid URL or known moniker.`,\n );\n }\n\n // Create a new RPC client instance.\n const newRpc = createSolanaRpc(rpcUrl);\n\n // Cache the new instance and return it.\n rpcCache.set(rpcUrlOrMoniker, newRpc);\n return newRpc;\n};\n","/**\n * @file Implements the transaction tracking logic for Solana transactions.\n * It integrates with the Pulsar store and uses a polling mechanism to query the\n * `getSignatureStatuses` RPC method for updates on transaction status.\n */\n\nimport {\n initializePollingTracker,\n ITxTrackingStore,\n PollingTrackerConfig,\n Transaction,\n TransactionAdapter,\n TransactionStatus,\n} from '@tuwaio/pulsar-core';\nimport dayjs from 'dayjs';\nimport { Signature, TransactionError } from 'gill';\n\nimport { SolanaActionTxKey, SolanaTransactionTracker } from '../types';\nimport { createSolanaRPC } from '../utils/createSolanaRPC';\n\n/**\n * @typedef SolanaSignatureStatusResponse\n * Represents the status of a Solana transaction and includes additional metadata.\n *\n * @property {number} slot - The slot in which the transaction was processed.\n * @property {number | null} confirmations - The number of confirmations received.\n * @property {TransactionError | null} err - The error, if any, associated with the transaction.\n * @property {'processed' | 'confirmed' | 'finalized' | null} confirmationStatus - The status of the transaction's confirmation.\n * @property {number} [fee] - The transaction fee in lamports.\n * @property {string} [recentBlockhash] - The blockhash used for the transaction.\n * @property {unknown[]} [instructions] - The instructions included in the transaction.\n */\ntype SolanaSignatureStatusResponse = {\n slot: number;\n confirmations: number | null;\n err: TransactionError | null;\n confirmationStatus: 'processed' | 'confirmed' | 'finalized' | null;\n fee?: number;\n recentBlockhash?: string;\n instructions?: unknown[];\n};\n\n/**\n * @typedef SolanaFetcherParams\n * Parameters used for the Solana fetcher function.\n */\ntype SolanaFetcherParams = Parameters<\n PollingTrackerConfig<\n SolanaSignatureStatusResponse,\n Transaction<SolanaTransactionTracker>,\n SolanaTransactionTracker\n >['fetcher']\n>[0];\n\n/**\n * Fetches and tracks Solana transactions using the `getSignatureStatuses` RPC method.\n * Transaction details (`getTransaction`) are only fetched once, if not already present in the transaction object.\n *\n * @param {SolanaFetcherParams} params - The fetcher parameters, automatically provided by the tracker.\n * @throws Will throw an error if the transaction adapter is not set to Solana.\n * @returns {Promise<void>} Resolves when the fetcher completes execution for the current polling cycle.\n */\nexport async function solanaFetcher({\n tx,\n stopPolling,\n onSuccess,\n onFailure,\n onIntervalTick,\n}: SolanaFetcherParams): Promise<void> {\n // Validate that the transaction uses the Solana adapter\n if (tx.adapter !== TransactionAdapter.SOLANA) {\n throw new Error('Tx adapter is not Solana. Please set the adapter to \"solana\" in the transaction object.');\n }\n\n try {\n // Initialize the Solana RPC client\n const rpc = createSolanaRPC(tx.rpcUrl ?? (tx.chainId as string));\n\n // Fetch transaction signature status\n const statuses = await rpc.getSignatureStatuses([tx.txKey as Signature]).send();\n const status = statuses?.value?.[0];\n\n // Skip further processing if no status is found\n if (!status) {\n return;\n }\n\n // Extract or fetch transaction details only when missing\n let { fee, recentBlockhash, instructions } = tx;\n\n if (!fee || !recentBlockhash || !instructions) {\n const txDetails = await rpc.getTransaction(tx.txKey as Signature, { encoding: 'json' }).send();\n const { meta, transaction } = txDetails || {};\n\n // If no transaction details are found, skip further processing\n if (!meta || !transaction) {\n return;\n }\n\n // Extract details from RPC response\n fee = Number(meta.fee ?? 0);\n recentBlockhash = transaction.message.recentBlockhash?.toString();\n instructions = transaction.message.instructions as unknown[];\n }\n\n // Construct the extended transaction status object\n const typedStatus: SolanaSignatureStatusResponse = {\n ...status,\n slot: Number(status.slot),\n confirmations: Number(status.confirmations ?? 0),\n fee,\n recentBlockhash,\n instructions,\n };\n\n // Trigger periodic updates for transaction tracking\n onIntervalTick?.(typedStatus);\n\n // Handle transaction error state\n if (typedStatus.err) {\n onFailure(typedStatus);\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // Handle finalized transaction state\n if (typedStatus.confirmationStatus === 'finalized') {\n onSuccess(typedStatus);\n stopPolling({ withoutRemoving: true });\n return;\n }\n\n // Stop polling if the transaction is unconfirmed for more than 1 day\n const elapsedDays = dayjs().diff(dayjs.unix(tx.localTimestamp), 'day');\n if (elapsedDays >= 1) {\n onFailure(typedStatus);\n stopPolling();\n }\n } catch (error) {\n console.error('Error in solanaFetcher:', error);\n onFailure({ err: error } as SolanaSignatureStatusResponse);\n stopPolling();\n }\n}\n\n/**\n * A higher-level tracker that integrates the Solana polling logic with the Pulsar store.\n *\n * @template T - The application-specific Solana transaction type.\n *\n * @param {object} params - Parameters to connect the Solana tracker with the store.\n * @param {T} params.tx - The Solana transaction being tracked.\n * @param {Record<string, T>} params.transactionsPool - A pool of tracked transactions in the store.\n * @param {Function} params.updateTxParams - A callback to update specific fields of a transaction in the store.\n * @param {Function} [params.onSucceedCallbacks] - Optional callbacks executed upon successful transaction completion.\n * @param {Function} [params.removeTxFromPool] - A function to remove a completed or canceled transaction from the store.\n * @returns {Promise<void>} Resolves when the tracker is successfully initialized.\n */\nexport async function solanaTrackerForStore<T extends Transaction<SolanaTransactionTracker>>({\n tx,\n ...rest\n}: Pick<\n ITxTrackingStore<SolanaTransactionTracker, T, SolanaActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n> & {\n tx: T;\n}): Promise<void> {\n return initializePollingTracker<SolanaSignatureStatusResponse, T, SolanaTransactionTracker>({\n tx,\n fetcher: solanaFetcher,\n removeTxFromPool: rest.removeTxFromPool,\n pollingInterval: 2500, // Polling interval: 2.5 seconds\n maxRetries: 10, // Max retries: 10 times\n\n /**\n * Success handler - updates the Pulsar store with finalized transaction details.\n *\n * @param {SolanaSignatureStatusResponse} response - The finalized transaction details.\n */\n onSuccess: (response) => {\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Success,\n pending: false,\n isError: false,\n finishedTimestamp: dayjs().unix(),\n fee: response.fee,\n instructions: response.instructions,\n recentBlockhash: response.recentBlockhash,\n confirmations: response.confirmations ?? 1,\n slot: response.slot,\n });\n\n // Trigger global success callbacks, if applicable\n const updatedTx = rest.transactionsPool[tx.txKey];\n if (rest.onSucceedCallbacks && updatedTx) {\n rest.onSucceedCallbacks(updatedTx);\n }\n },\n\n /**\n * Interval handler - updates interim transaction details in the store.\n *\n * @param {SolanaSignatureStatusResponse} response - The latest transaction status update.\n */\n onIntervalTick: (response) => {\n rest.updateTxParams(tx.txKey, {\n confirmations: response.confirmations ?? 0,\n slot: response.slot,\n fee: response.fee,\n instructions: response.instructions,\n recentBlockhash: response.recentBlockhash,\n });\n },\n\n /**\n * Failure handler - updates the store when the transaction fails or times out.\n *\n * @param {SolanaSignatureStatusResponse} response - The failure response details.\n */\n onFailure: (response) => {\n const errorMessage = response?.err\n ? `Transaction failed: ${JSON.stringify(response.err)}`\n : 'Transaction tracking timed out or the transaction was not found.';\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage,\n finishedTimestamp: dayjs().unix(),\n });\n },\n });\n}\n","/**\n * @file This file contains the primary router for initializing transaction trackers.\n */\n\nimport { ITxTrackingStore, Transaction, TransactionStatus } from '@tuwaio/pulsar-core';\n\nimport { solanaTrackerForStore } from '../trackers/solanaTracker';\nimport { SolanaActionTxKey, SolanaTransactionTracker } from '../types';\n\n/**\n * Initializes the correct background tracker for a given Solana transaction.\n * This function acts as a router, selecting the appropriate tracker based on the `tx.tracker` property.\n *\n * @template T - The transaction type, constrained to Solana transactions.\n * @param {object} params - The parameters for initializing the tracker.\n * @param {T} params.tx - The transaction object to be tracked.\n * @param {SolanaTransactionTracker} params.tracker - The specific tracker to use.\n * @param {object} params.rest - The rest of the store's methods and state needed by the tracker.\n * @returns {Promise<void>} A promise that resolves when the tracker has been initialized.\n */\nexport async function checkAndInitializeTrackerInStore<T extends Transaction<SolanaTransactionTracker>>({\n tx,\n tracker,\n ...rest\n}: {\n tx: T;\n tracker: SolanaTransactionTracker;\n} & Pick<\n ITxTrackingStore<SolanaTransactionTracker, T, SolanaActionTxKey>,\n 'transactionsPool' | 'updateTxParams' | 'onSucceedCallbacks' | 'removeTxFromPool'\n>): Promise<void> {\n switch (tracker) {\n case SolanaTransactionTracker.Solana:\n await solanaTrackerForStore({\n tx,\n ...rest,\n });\n break;\n default:\n console.error(`Unknown tracker type for Solana adapter: ${tracker}`);\n // If an unsupported tracker is specified, mark the transaction as failed.\n rest.updateTxParams(tx.txKey, {\n status: TransactionStatus.Failed,\n pending: false,\n isError: true,\n errorMessage: `Unsupported tracker type: \"${tracker}\"`,\n });\n break;\n }\n}\n","/**\n * @file This file contains a utility to verify the connected Solana chain.\n */\n\nimport { SolanaChainMismatchError } from '../errors';\n\n/**\n * Checks if the wallet's current chain matches the required chain for a transaction.\n *\n * This function compares the `chain` property from the Wallet Standard account object\n * with the required chain identifier (e.g., 'solana:mainnet').\n *\n * @param {string} requiredChain - The chain identifier that the transaction requires.\n * @param {string} currentChain - The chain identifier the wallet is currently connected to.\n * @throws {SolanaChainMismatchError} If the connected chain does not match the required chain.\n */\nexport const checkSolanaChain = (requiredChain: string, currentChain: string): void => {\n if (currentChain !== requiredChain) {\n throw new SolanaChainMismatchError(requiredChain, currentChain);\n }\n};\n","/**\n * @file This file contains a utility function for generating Solana transaction explorer links.\n */\n\nimport { getExplorerLink, SolanaClusterMoniker } from 'gill';\n\n/**\n * Generates a full URL to a transaction on a Solana explorer like Solscan.\n *\n * @param {string} baseUrl - The base URL of the explorer (e.g., \"https://solscan.io\").\n * @param {string} txKey - The transaction signature (hash).\n * @param {SolanaCluster} [cluster] - The optional cluster name ('devnet', 'testnet') to add as a query parameter.\n * @returns {string} The full URL to the transaction on the explorer.\n */\nexport const selectSolanaTxExplorerLink = (txKey: string, cluster?: SolanaClusterMoniker): string => {\n // Ensure there are no trailing slashes on the base URL for clean URL construction.\n const baseUrl = getExplorerLink({ cluster });\n const sanitizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n\n // Build the cluster query parameter if provided.\n const clusterParam = cluster ? `?cluster=${cluster}` : '';\n\n return `${sanitizedBaseUrl}/tx/${txKey}${clusterParam}`;\n};\n","/**\n * @file This file contains utility functions for interacting with the Solana Name Service (SNS) provided by Bonfida.\n */\n\nimport { getDomainKeysWithReverses, getRecord, performReverseLookup, Record } from '@bonfida/spl-name-service';\nimport { Connection, PublicKey } from '@solana/web3.js';\n\n/**\n * A cache to store Connection instances for different RPC URLs.\n * This prevents creating a new Connection object for every function call.\n * @type {Map<string, Connection>}\n */\nconst connectionCache = new Map<string, Connection>();\n\n/**\n * A cache to store resolved domain names against wallet addresses.\n * This prevents repeated reverse lookups for the same address.\n * @type {Map<string, string | null>}\n */\nconst domainNameCache = new Map<string, string | null>();\n\n/**\n * Retrieves a cached Connection object or creates a new one if it doesn't exist.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @returns {Connection} An instance of the Connection class.\n */\nconst getConnection = (rpcUrl: string): Connection => {\n if (!connectionCache.has(rpcUrl)) {\n connectionCache.set(rpcUrl, new Connection(rpcUrl));\n }\n return connectionCache.get(rpcUrl)!;\n};\n\n/**\n * Performs a reverse lookup to find the .sol domain name for a given wallet address.\n * Results are cached to avoid redundant network requests.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @param {string} address - The public key of the wallet as a string.\n * @returns {Promise<string | null>} The .sol domain name (e.g., \"bonfida.sol\") or null if not found.\n */\nexport const getSolanaName = async (rpcUrl: string, address: string): Promise<string | null> => {\n // Return the cached domain name if it exists for the given address.\n if (domainNameCache.has(address)) {\n return domainNameCache.get(address)!;\n }\n\n try {\n const connection = getConnection(rpcUrl);\n const pubKey = new PublicKey(address);\n\n const domainKeys = await getDomainKeysWithReverses(connection, pubKey);\n\n if (domainKeys.length === 0) {\n // Cache the null result to prevent future lookups for this address.\n domainNameCache.set(address, null);\n return null;\n }\n\n // @ts-expect-error - domainKeys is an array of PublicKey objects.\n const domainName = await performReverseLookup(connection, domainKeys[0]);\n const fullDomain = `${domainName}.sol`;\n\n // Cache the successful result.\n domainNameCache.set(address, fullDomain);\n return fullDomain;\n } catch {\n // Cache the null result in case of an error.\n domainNameCache.set(address, null);\n return null;\n }\n};\n\n/**\n * Retrieves the avatar URL from the 'pic' record of a .sol domain name.\n * @param {string} rpcUrl - The RPC endpoint URL.\n * @param {string} name - The .sol domain name (e.g., \"bonfida.sol\").\n * @returns {Promise<string | null>} The URL of the avatar or null if not found or set.\n */\nexport const getSolanaAvatar = async (rpcUrl: string, name: string): Promise<string | null> => {\n try {\n const connection = getConnection(rpcUrl);\n const record = await getRecord(connection, name, Record.Pic);\n\n if (!record || !record.data) {\n return null;\n }\n\n return record.data.toString('utf-8');\n } catch {\n // Fails silently if the record doesn't exist.\n return null;\n }\n};\n","/**\n * @file This file contains the factory function for creating the Solana adapter for Pulsar.\n */\nimport type { Transaction, TxAdapter } from '@tuwaio/pulsar-core';\nimport { TransactionAdapter } from '@tuwaio/pulsar-core';\nimport { getExplorerLink, SolanaClusterMoniker } from 'gill';\n\nimport { SolanaChainMismatchError } from '../errors';\nimport { SolanaActionTxKey, SolanaAdapterConfig, SolanaTransactionTracker } from '../types';\nimport { checkAndInitializeTrackerInStore } from '../utils/checkAndInitializeTrackerInStore';\nimport { checkSolanaChain } from '../utils/checkSolanaChain';\nimport { createSolanaRPC } from '../utils/createSolanaRPC';\nimport { selectSolanaTxExplorerLink } from '../utils/selectSolanaTxExplorerLink';\nimport { getSolanaAvatar, getSolanaName } from '../utils/snsUtils';\n\n/**\n * Creates a Solana adapter for the Pulsar transaction tracking engine.\n * This factory function produces a wallet-library-agnostic adapter that can be\n * configured for multiple Solana clusters (e.g., mainnet-beta, devnet) and\n * can operate even without a connected wallet for read-only tasks.\n *\n * @param config The configuration object for the adapter.\n * @returns An object implementing the `TxAdapter` interface for Solana.\n */\nexport function solanaAdapter<T extends Transaction<SolanaTransactionTracker>>(\n config: SolanaAdapterConfig,\n): TxAdapter<SolanaTransactionTracker, T, SolanaActionTxKey> {\n const { wallet, rpcUrls } = config;\n\n /**\n * Safely extracts the cluster moniker from a chain identifier.\n * Handles both full chain IDs ('solana:mainnet-beta') and simple monikers ('mainnet-beta').\n * @param chain The chain identifier or moniker.\n * @returns The extracted cluster moniker.\n */\n const getCluster = (chain?: string): SolanaClusterMoniker => {\n const defaultCluster: SolanaClusterMoniker = 'mainnet';\n if (!chain) {\n return wallet?.walletActiveChain ?? defaultCluster;\n }\n return (chain.includes(':') ? chain.split(':')[1] : chain) as SolanaClusterMoniker;\n };\n\n /**\n * Retrieves the configured RPC URL for a given cluster moniker.\n * @param cluster The target cluster. Defaults to the wallet's active chain.\n * @returns The RPC URL or undefined if not found.\n */\n const getRpcUrlForCluster = (cluster?: SolanaClusterMoniker): string | undefined => {\n const targetCluster = cluster ?? wallet?.walletActiveChain;\n if (!targetCluster) return undefined;\n return rpcUrls[targetCluster];\n };\n\n return {\n key: TransactionAdapter.SOLANA,\n\n getWalletInfo: () => ({\n walletAddress: wallet?.walletAddress ?? '0x0',\n walletType: wallet?.walletType ?? 'disconnected',\n }),\n\n checkChainForTx: async (txChain) => {\n if (!wallet) {\n throw new Error('Wallet not provided. Cannot perform chain check.');\n }\n try {\n checkSolanaChain(txChain as string, wallet.walletActiveChain);\n } catch (e) {\n if (e instanceof SolanaChainMismatchError) throw e;\n throw new Error(`Chain check failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n },\n\n checkTransactionsTracker: (actionTxKey) => ({\n tracker: SolanaTransactionTracker.Solana,\n txKey: actionTxKey,\n }),\n\n checkAndInitializeTrackerInStore: ({ tx, ...rest }) => {\n return checkAndInitializeTrackerInStore({\n tracker: tx.tracker,\n tx,\n ...rest,\n });\n },\n\n getExplorerUrl: () => {\n const cluster = wallet?.walletActiveChain ?? 'mainnet-beta';\n return getExplorerLink({ cluster });\n },\n\n getExplorerTxUrl: (txPool, txKey) => {\n const tx = txPool[txKey];\n const cluster = getCluster(tx?.chainId as string);\n return selectSolanaTxExplorerLink(txKey, cluster);\n },\n\n getName: async (address) => {\n const rpcUrl = getRpcUrlForCluster(wallet?.walletActiveChain);\n if (!rpcUrl) {\n console.warn('Cannot get name: RPC URL for the current chain is not configured.');\n return null;\n }\n return getSolanaName(rpcUrl, address);\n },\n\n getAvatar: async (name) => {\n const rpcUrl = getRpcUrlForCluster(wallet?.walletActiveChain);\n if (!rpcUrl) {\n console.warn('Cannot get avatar: RPC URL for the current chain is not configured.');\n return null;\n }\n return getSolanaAvatar(rpcUrl, name);\n },\n\n retryTxAction: async ({ onClose, txKey, handleTransaction, tx }) => {\n onClose(txKey);\n\n if (!wallet || !wallet.walletAddress || wallet.walletAddress === '0x0') {\n throw new Error('Retry failed: A wallet must be connected.');\n }\n if (!handleTransaction) {\n throw new Error('Retry failed: handleTransaction function is not provided.');\n }\n\n const clusterForRetry = getCluster(tx.desiredChainID as string);\n const rpcUrlForRetry = tx.rpcUrl ?? getRpcUrlForCluster(clusterForRetry);\n if (!rpcUrlForRetry) {\n throw new Error('Retry failed: Could not determine RPC endpoint for the transaction chain.');\n }\n\n const rpcForRetry = createSolanaRPC(rpcUrlForRetry);\n\n await handleTransaction({\n actionFunction: () =>\n tx.actionFunction({\n wallet: config.wallet,\n rpc: rpcForRetry,\n ...tx.payload,\n }),\n params: tx,\n defaultTracker: SolanaTransactionTracker.Solana,\n });\n },\n };\n}\n","/**\n * @file This file contains a utility function for signing and sending Solana transactions.\n * It simplifies the process of creating, signing, and broadcasting a transaction to the network.\n */\n\nimport type { Instruction, SolanaClient, TransactionSendingSigner } from 'gill';\nimport { createTransaction, getBase58Decoder, signAndSendTransactionMessageWithSigners } from 'gill';\n\n/**\n * Creates, signs, and sends a Solana transaction with one or more instructions.\n *\n * This async function orchestrates the common flow for broadcasting a transaction:\n * 1. Fetches the latest blockhash from the RPC.\n * 2. Creates a versioned transaction (`v0`).\n * 3. Signs the transaction with the provided signer.\n * 4. Sends the transaction to the network.\n * 5. Decodes and returns the resulting transaction signature.\n *\n * @param {object} params - The parameters for signing and sending the transaction.\n * @param {SolanaClient} params.client - The Solana client instance for RPC communication.\n * @param {TransactionSendingSigner} params.signer - The signer (e.g., a wallet) responsible for signing the transaction.\n * @param {Instruction | Instruction[]} params.instruction - A single instruction or an array of instructions to include in the transaction.\n * @returns A promise that resolves to the transaction signature.\n * @throws Will throw an error if any of the async operations (fetching blockhash, signing, sending) fail.\n *\n * @example\n * const signature = await signAndSendSolanaTx({\n * client: mySolanaClient,\n * signer: wallet,\n * instruction: myTransferInstruction,\n * });\n * console.log('Transaction sent with signature:', signature);\n */\nexport async function signAndSendSolanaTx({\n client,\n signer,\n instruction,\n}: {\n client: SolanaClient;\n signer: TransactionSendingSigner;\n instruction: Instruction | Instruction[];\n}) {\n // 1. Fetch the latest blockhash to ensure transaction validity.\n const { value: latestBlockhash } = await client.rpc.getLatestBlockhash().send();\n\n // 2. Create a version 0 transaction, which is the current standard.\n const transaction = createTransaction({\n feePayer: signer,\n version: 0,\n latestBlockhash,\n instructions: Array.isArray(instruction) ? instruction : [instruction],\n });\n\n // 3. Sign the transaction message and send it to the network.\n const signature = await signAndSendTransactionMessageWithSigners(transaction);\n\n // 4. Decode the resulting signature into the final format.\n return getBase58Decoder().decode(signature);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuwaio/pulsar-solana",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",
@@ -57,7 +57,7 @@
57
57
  "typescript": "^5.9.2",
58
58
  "vitest": "^3.2.4",
59
59
  "zustand": "^5.0.8",
60
- "@tuwaio/pulsar-core": "^0.1.1"
60
+ "@tuwaio/pulsar-core": "^0.1.3"
61
61
  },
62
62
  "scripts": {
63
63
  "start": "tsup src/index.ts --watch",