@tuwaio/pulsar-solana 0.6.9 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,13 +4,13 @@
4
4
  [![License](https://img.shields.io/npm/l/@tuwaio/pulsar-solana.svg)](./LICENSE)
5
5
  [![Build Status](https://img.shields.io/github/actions/workflow/status/TuwaIO/pulsar-core/release.yml?branch=main)](https://github.com/TuwaIO/pulsar-core/actions)
6
6
 
7
- Layer 4 (L4) of the TUWA Ecosystem. Low-level Solana block state monitors and RPC cluster lifecycle indexers powered strictly by gill.
7
+ Layer 4 (L4) of the TUWA Ecosystem. Low-level Solana block state monitors and RPC cluster lifecycle indexers powered strictly by @solana/kit and @tuwaio/orbit-solana.
8
8
 
9
9
  ---
10
10
 
11
11
  ## 🏛️ What is `@tuwaio/pulsar-solana`?
12
12
 
13
- This package is the low-level Solana block state monitor and RPC cluster lifecycle indexing adapter for `@tuwaio/pulsar-core`. It leverages **Wallet Standard** for deep integration with modern Solana wallet environments, performing fast-block signature status tracking, signature swap detection, and cluster manager alignment using `gill` primitives.
13
+ This package is the low-level Solana block state monitor and RPC cluster lifecycle indexing adapter for `@tuwaio/pulsar-core`. It leverages **Wallet Standard** for deep integration with modern Solana wallet environments, performing fast-block signature status tracking, signature swap detection, and cluster manager alignment using `@solana/kit` and `@tuwaio/orbit-solana` primitives.
14
14
 
15
15
  The architecture is designed for multi-chain robustness. You can provide RPC endpoints for different Solana clusters (e.g., Mainnet Beta, Devnet), and the adapter will automatically use the correct one based on the user's connected wallet state.
16
16
 
@@ -30,7 +30,7 @@ The architecture is designed for multi-chain robustness. You can provide RPC end
30
30
 
31
31
  ```bash
32
32
  # Using pnpm (recommended), but you can use npm, yarn or bun as well
33
- pnpm add @tuwaio/pulsar-solana @tuwaio/pulsar-core gill @tuwaio/orbit-core @tuwaio/orbit-solana zustand immer dayjs @wallet-standard/app @wallet-standard/ui-registry @wallet-standard/ui-core
33
+ pnpm add @tuwaio/pulsar-solana @tuwaio/pulsar-core @solana/kit @tuwaio/orbit-core @tuwaio/orbit-solana zustand immer dayjs @wallet-standard/app @wallet-standard/ui-registry @wallet-standard/ui-core
34
34
  ```
35
35
 
36
36
  ---
@@ -101,7 +101,8 @@ import { TransactionAdapter } from '@tuwaio/pulsar-core';
101
101
  import { useSatelliteConnectStore } from '@tuwaio/nova-connect/satellite';
102
102
  // The action function receives the wallet and client from the adapter.
103
103
  import { signAndSendSolanaTx } from '@tuwaio/pulsar-solana';
104
- import { Address, SolanaClient, TransactionSendingSigner } from 'gill';
104
+ import type { Address, TransactionSendingSigner } from '@solana/kit';
105
+ import type { SolanaClient } from '@tuwaio/orbit-solana';
105
106
  import { useWalletAccountTransactionSendingSigner } from '@solana/react';
106
107
  import { Wallet } from '@tuwaio/nova-connect/satellite';
107
108
  import { OrbitAdapter } from '@tuwaio/orbit-core';
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Transaction, TxAdapter, PollingTrackerConfig, ITxTrackingStore, TrackerCallbacks, TransactionTracker } from '@tuwaio/pulsar-core';
2
- import { SolanaClusterMoniker, TransactionError, SolanaClient, TransactionSendingSigner, Instruction } from 'gill';
2
+ import { SolanaClusterMoniker, SolanaClient } from '@tuwaio/orbit-solana';
3
+ import { TransactionError, TransactionSendingSigner, Instruction } from '@solana/kit';
3
4
 
4
5
  /**
5
6
  * @file Defines the core types and enums specific to the @tuwaio/pulsar-solana package.
@@ -154,7 +155,7 @@ declare const checkSolanaChain: (requiredChain: string, currentChain: string) =>
154
155
  *
155
156
  * This async function orchestrates the common flow for broadcasting a transaction:
156
157
  * 1. Fetches the latest blockhash from the RPC.
157
- * 2. Creates a versioned transaction (`v0`).
158
+ * 2. Creates a versioned transaction message (`v0`).
158
159
  * 3. Signs the transaction with the provided signer.
159
160
  * 4. Sends the transaction to the network.
160
161
  * 5. Decodes and returns the resulting transaction signature.
@@ -168,9 +169,9 @@ declare const checkSolanaChain: (requiredChain: string, currentChain: string) =>
168
169
  *
169
170
  * @example
170
171
  * const signature = await signAndSendSolanaTx({
171
- * client: mySolanaClient,
172
- * signer: wallet,
173
- * instruction: myTransferInstruction,
172
+ * client: mySolanaClient,
173
+ * signer: wallet,
174
+ * instruction: myTransferInstruction,
174
175
  * });
175
176
  * console.log('Transaction sent with signature:', signature);
176
177
  */
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Transaction, TxAdapter, PollingTrackerConfig, ITxTrackingStore, TrackerCallbacks, TransactionTracker } from '@tuwaio/pulsar-core';
2
- import { SolanaClusterMoniker, TransactionError, SolanaClient, TransactionSendingSigner, Instruction } from 'gill';
2
+ import { SolanaClusterMoniker, SolanaClient } from '@tuwaio/orbit-solana';
3
+ import { TransactionError, TransactionSendingSigner, Instruction } from '@solana/kit';
3
4
 
4
5
  /**
5
6
  * @file Defines the core types and enums specific to the @tuwaio/pulsar-solana package.
@@ -154,7 +155,7 @@ declare const checkSolanaChain: (requiredChain: string, currentChain: string) =>
154
155
  *
155
156
  * This async function orchestrates the common flow for broadcasting a transaction:
156
157
  * 1. Fetches the latest blockhash from the RPC.
157
- * 2. Creates a versioned transaction (`v0`).
158
+ * 2. Creates a versioned transaction message (`v0`).
158
159
  * 3. Signs the transaction with the provided signer.
159
160
  * 4. Sends the transaction to the network.
160
161
  * 5. Decodes and returns the resulting transaction signature.
@@ -168,9 +169,9 @@ declare const checkSolanaChain: (requiredChain: string, currentChain: string) =>
168
169
  *
169
170
  * @example
170
171
  * const signature = await signAndSendSolanaTx({
171
- * client: mySolanaClient,
172
- * signer: wallet,
173
- * instruction: myTransferInstruction,
172
+ * client: mySolanaClient,
173
+ * signer: wallet,
174
+ * instruction: myTransferInstruction,
174
175
  * });
175
176
  * console.log('Transaction sent with signature:', signature);
176
177
  */
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var orbitCore=require('@tuwaio/orbit-core'),orbitSolana=require('@tuwaio/orbit-solana'),pulsarCore=require('@tuwaio/pulsar-core'),d=require('dayjs'),gill=require('gill');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var d__default=/*#__PURE__*/_interopDefault(d);var l=class extends Error{name="SolanaChainMismatchError";requiredChain;currentChain;constructor(o,r){let t=`Wrong chain. The transaction requires ${o}, but you are connected to ${r}.`;super(t),this.requiredChain=o,this.currentChain=r;}};async function R({tx:e,stopPolling:o,onSuccess:r,onFailure:t,onIntervalTick:n}){if(e.adapter!==orbitCore.OrbitAdapter.SOLANA)throw new Error('Tx adapter is not Solana. Please set the adapter to "solana" in the transaction object.');try{let a=orbitSolana.createSolanaRPC({rpcUrlOrMoniker:e.rpcUrl??orbitSolana.getCluster({cluster:e.chainId})}),i=(await a.getSignatureStatuses([e.txKey]).send())?.value?.[0];if(!i)return;let{fee:u,recentBlockhash:c,instructions:m}=e;if(!u||!c||!m){let A=await a.getTransaction(e.txKey,{encoding:"json",maxSupportedTransactionVersion:0}).send(),{meta:p,transaction:f}=A||{};if(!p||!f)return;u=Number(p.fee??0),c=f.message.recentBlockhash?.toString(),m=f.message.instructions;}let s={...i,slot:Number(i.slot),confirmations:Number(i.confirmations??0),fee:u,recentBlockhash:c,instructions:m};if(n?.(s),s.err){t(s),o({withoutRemoving:!0});return}if(s.confirmationStatus==="finalized"){r(s),o({withoutRemoving:!0});return}d__default.default().diff(d__default.default.unix(e.localTimestamp),"hour")>=1&&(t(s),o());}catch(a){console.error("Error in solanaFetcher:",a),t({err:a}),o();}}async function h({tx:e,onSuccess:o,onError:r,...t}){return pulsarCore.initializePollingTracker({tx:e,fetcher:R,removeTxFromPool:t.removeTxFromPool,pollingInterval:2500,maxRetries:10,onSuccess:n=>{t.updateTxParams(e.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,finishedTimestamp:d__default.default().unix(),fee:n.fee,instructions:n.instructions,recentBlockhash:n.recentBlockhash,confirmations:"MAX",slot:n.slot});let a=t.transactionsPool[e.txKey];o&&a&&o(a);},onIntervalTick:n=>{t.updateTxParams(e.txKey,{confirmations:n.confirmations??0,slot:n.slot,fee:n.fee,instructions:n.instructions,recentBlockhash:n.recentBlockhash});},onFailure:n=>{t.updateTxParams(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,error:orbitCore.normalizeError(n?.err??new Error("Transaction tracking timed out or the transaction was not found.")),finishedTimestamp:d__default.default().unix()});let a=t.transactionsPool[e.txKey];r&&a&&r(n?.err??new Error("Transaction tracking timed out or the transaction was not found."),a);}})}async function g({tx:e,tracker:o,onSuccess:r,onError:t,...n}){o===pulsarCore.TransactionTracker.Solana?await h({tx:e,onSuccess:r,onError:t,...n}):(console.error(`Unknown tracker type for Solana adapter: ${o}`),n.updateTxParams(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,error:orbitCore.normalizeError(new Error(`Unsupported tracker type: "${o}"`))}));}var S=(e,o)=>{if(o!==e)throw new l(e,o)};function gr(e){let{rpcUrls:o}=e;return {key:orbitCore.OrbitAdapter.SOLANA,getConnectorInfo:()=>{let r=orbitSolana.getConnectedSolanaConnector();return {walletAddress:orbitCore.lastConnectedConnectorHelpers.getLastConnectedConnector()?.address??r.accounts[0].address??"0x0",connectorType:orbitCore.getConnectorTypeFromName(orbitCore.OrbitAdapter.SOLANA,r.name)}},checkChainForTx:async r=>{if(!orbitSolana.getConnectedSolanaConnector())throw new Error("Wallet not provided. Cannot perform chain check.");try{S(r,orbitCore.lastConnectedConnectorHelpers.getLastConnectedConnector()?.chainId??"");}catch(n){throw n instanceof l?n:new Error(`Chain check failed: ${n instanceof Error?n.message:String(n)}`,{cause:n})}},checkTransactionsTracker:({actionTxKey:r,tracker:t})=>({tracker:t??pulsarCore.TransactionTracker.Solana,txKey:r}),checkAndInitializeTrackerInStore:({tx:r,...t})=>g({tracker:r.tracker,tx:r,...t}),getExplorerUrl:(r,t)=>orbitSolana.getSolanaExplorerLink(r,t),getExplorerTxUrl:r=>orbitSolana.getSolanaExplorerLink(`/tx/${r.txKey}`,r.chainId),retryTxAction:async({onClose:r,txKey:t,executeTxAction:n,tx:a})=>{r(t);let i=orbitSolana.getAvailableSolanaConnectors().filter(s=>s.accounts.length>0)[0];if(!i||!i.accounts[0].address||i.accounts[0].address==="0x0")throw new Error("Retry failed: A wallet must be connected.");if(!n)throw new Error("Retry failed: executeTxAction function is not provided.");let u=orbitSolana.getCluster({cluster:a?.desiredChainID}),c=a.rpcUrl??orbitSolana.getRpcUrlForCluster({cluster:u,rpcUrls:o});if(!c)throw new Error("Retry failed: Could not determine RPC endpoint for the transaction chain.");let m=orbitSolana.createSolanaClientWithCache({rpcUrlOrMoniker:c,rpcUrls:o});await n({actionFunction:()=>a.actionFunction({client:m,...a.payload}),params:a,defaultTracker:pulsarCore.TransactionTracker.Solana});}}}async function xr({client:e,signer:o,instruction:r}){let{value:t}=await e.rpc.getLatestBlockhash().send(),n=gill.createTransaction({feePayer:o,version:0,latestBlockhash:t,instructions:Array.isArray(r)?r:[r]}),a=await gill.signAndSendTransactionMessageWithSigners(n);return gill.getBase58Decoder().decode(a)}exports.SolanaChainMismatchError=l;exports.checkAndInitializeTrackerInStore=g;exports.checkSolanaChain=S;exports.pulsarSolanaAdapter=gr;exports.signAndSendSolanaTx=xr;exports.solanaFetcher=R;exports.solanaTrackerForStore=h;
1
+ 'use strict';var orbitCore=require('@tuwaio/orbit-core'),orbitSolana=require('@tuwaio/orbit-solana'),pulsarCore=require('@tuwaio/pulsar-core'),p=require('dayjs'),kit=require('@solana/kit');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var p__default=/*#__PURE__*/_interopDefault(p);var u=class extends Error{name="SolanaChainMismatchError";requiredChain;currentChain;constructor(a,r){let t=`Wrong chain. The transaction requires ${a}, but you are connected to ${r}.`;super(t),this.requiredChain=a,this.currentChain=r;}};async function R({tx:e,stopPolling:a,onSuccess:r,onFailure:t,onIntervalTick:n}){if(e.adapter!==orbitCore.OrbitAdapter.SOLANA)throw new Error('Tx adapter is not Solana. Please set the adapter to "solana" in the transaction object.');try{let o=orbitSolana.createSolanaRPC({rpcUrlOrMoniker:e.rpcUrl??orbitSolana.getCluster({cluster:e.chainId})}),s=(await o.getSignatureStatuses([e.txKey]).send())?.value?.[0];if(!s)return;let{fee:m,recentBlockhash:l,instructions:d}=e;if(!m||!l||!d){let A=await o.getTransaction(e.txKey,{encoding:"json",maxSupportedTransactionVersion:0}).send(),{meta:T,transaction:f}=A||{};if(!T||!f)return;m=Number(T.fee??0),l=f.message.recentBlockhash?.toString(),d=f.message.instructions;}let i={...s,slot:Number(s.slot),confirmations:Number(s.confirmations??0),fee:m,recentBlockhash:l,instructions:d};if(n?.(i),i.err){t(i),a({withoutRemoving:!0});return}if(i.confirmationStatus==="finalized"){r(i),a({withoutRemoving:!0});return}p__default.default().diff(p__default.default.unix(e.localTimestamp),"hour")>=1&&(t(i),a());}catch(o){console.error("Error in solanaFetcher:",o),t({err:o}),a();}}async function h({tx:e,onSuccess:a,onError:r,...t}){return pulsarCore.initializePollingTracker({tx:e,fetcher:R,removeTxFromPool:t.removeTxFromPool,pollingInterval:2500,maxRetries:10,onSuccess:n=>{t.updateTxParams(e.txKey,{status:pulsarCore.TransactionStatus.Success,pending:false,isError:false,finishedTimestamp:p__default.default().unix(),fee:n.fee,instructions:n.instructions,recentBlockhash:n.recentBlockhash,confirmations:"MAX",slot:n.slot});let o=t.transactionsPool[e.txKey];a&&o&&a(o);},onIntervalTick:n=>{t.updateTxParams(e.txKey,{confirmations:n.confirmations??0,slot:n.slot,fee:n.fee,instructions:n.instructions,recentBlockhash:n.recentBlockhash});},onFailure:n=>{t.updateTxParams(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,error:orbitCore.normalizeError(n?.err??new Error("Transaction tracking timed out or the transaction was not found.")),finishedTimestamp:p__default.default().unix()});let o=t.transactionsPool[e.txKey];r&&o&&r(n?.err??new Error("Transaction tracking timed out or the transaction was not found."),o);}})}async function S({tx:e,tracker:a,onSuccess:r,onError:t,...n}){a===pulsarCore.TransactionTracker.Solana?await h({tx:e,onSuccess:r,onError:t,...n}):(console.error(`Unknown tracker type for Solana adapter: ${a}`),n.updateTxParams(e.txKey,{status:pulsarCore.TransactionStatus.Failed,pending:false,isError:true,error:orbitCore.normalizeError(new Error(`Unsupported tracker type: "${a}"`))}));}var k=(e,a)=>{if(a!==e)throw new u(e,a)};function Cr(e){let{rpcUrls:a}=e;return {key:orbitCore.OrbitAdapter.SOLANA,getConnectorInfo:()=>{let r=orbitSolana.getConnectedSolanaConnector();return {walletAddress:orbitCore.lastConnectedConnectorHelpers.getLastConnectedConnector()?.address??r.accounts[0].address??"0x0",connectorType:orbitCore.getConnectorTypeFromName(orbitCore.OrbitAdapter.SOLANA,r.name)}},checkChainForTx:async r=>{if(!orbitSolana.getConnectedSolanaConnector())throw new Error("Wallet not provided. Cannot perform chain check.");try{k(r,orbitCore.lastConnectedConnectorHelpers.getLastConnectedConnector()?.chainId??"");}catch(n){throw n instanceof u?n:new Error(`Chain check failed: ${n instanceof Error?n.message:String(n)}`,{cause:n})}},checkTransactionsTracker:({actionTxKey:r,tracker:t})=>({tracker:t??pulsarCore.TransactionTracker.Solana,txKey:r}),checkAndInitializeTrackerInStore:({tx:r,...t})=>S({tracker:r.tracker,tx:r,...t}),getExplorerUrl:(r,t)=>orbitSolana.getSolanaExplorerLink(r,t),getExplorerTxUrl:r=>orbitSolana.getSolanaExplorerLink(`/tx/${r.txKey}`,r.chainId),retryTxAction:async({onClose:r,txKey:t,executeTxAction:n,tx:o})=>{r(t);let s=orbitSolana.getAvailableSolanaConnectors().filter(i=>i.accounts.length>0)[0];if(!s||!s.accounts[0].address||s.accounts[0].address==="0x0")throw new Error("Retry failed: A wallet must be connected.");if(!n)throw new Error("Retry failed: executeTxAction function is not provided.");let m=orbitSolana.getCluster({cluster:o?.desiredChainID}),l=o.rpcUrl??orbitSolana.getRpcUrlForCluster({cluster:m,rpcUrls:a});if(!l)throw new Error("Retry failed: Could not determine RPC endpoint for the transaction chain.");let d=orbitSolana.createSolanaClientWithCache({rpcUrlOrMoniker:l,rpcUrls:a});await n({actionFunction:()=>o.actionFunction({client:d,...o.payload}),params:o,defaultTracker:pulsarCore.TransactionTracker.Solana});}}}async function Pr({client:e,signer:a,instruction:r}){let{value:t}=await e.rpc.getLatestBlockhash().send(),n=kit.pipe(kit.createTransactionMessage({version:0}),c=>kit.setTransactionMessageFeePayerSigner(a,c),c=>kit.setTransactionMessageLifetimeUsingBlockhash(t,c),c=>kit.appendTransactionMessageInstructions(Array.isArray(r)?r:[r],c)),o=await kit.signAndSendTransactionMessageWithSigners(n);return kit.getBase58Decoder().decode(o)}exports.SolanaChainMismatchError=u;exports.checkAndInitializeTrackerInStore=S;exports.checkSolanaChain=k;exports.pulsarSolanaAdapter=Cr;exports.signAndSendSolanaTx=Pr;exports.solanaFetcher=R;exports.solanaTrackerForStore=h;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import {OrbitAdapter,normalizeError,lastConnectedConnectorHelpers,getConnectorTypeFromName}from'@tuwaio/orbit-core';import {createSolanaRPC,getCluster,getAvailableSolanaConnectors,getRpcUrlForCluster,createSolanaClientWithCache,getSolanaExplorerLink,getConnectedSolanaConnector}from'@tuwaio/orbit-solana';import {initializePollingTracker,TransactionStatus,TransactionTracker}from'@tuwaio/pulsar-core';import d from'dayjs';import {createTransaction,signAndSendTransactionMessageWithSigners,getBase58Decoder}from'gill';var l=class extends Error{name="SolanaChainMismatchError";requiredChain;currentChain;constructor(o,r){let t=`Wrong chain. The transaction requires ${o}, but you are connected to ${r}.`;super(t),this.requiredChain=o,this.currentChain=r;}};async function R({tx:e,stopPolling:o,onSuccess:r,onFailure:t,onIntervalTick:n}){if(e.adapter!==OrbitAdapter.SOLANA)throw new Error('Tx adapter is not Solana. Please set the adapter to "solana" in the transaction object.');try{let a=createSolanaRPC({rpcUrlOrMoniker:e.rpcUrl??getCluster({cluster:e.chainId})}),i=(await a.getSignatureStatuses([e.txKey]).send())?.value?.[0];if(!i)return;let{fee:u,recentBlockhash:c,instructions:m}=e;if(!u||!c||!m){let A=await a.getTransaction(e.txKey,{encoding:"json",maxSupportedTransactionVersion:0}).send(),{meta:p,transaction:f}=A||{};if(!p||!f)return;u=Number(p.fee??0),c=f.message.recentBlockhash?.toString(),m=f.message.instructions;}let s={...i,slot:Number(i.slot),confirmations:Number(i.confirmations??0),fee:u,recentBlockhash:c,instructions:m};if(n?.(s),s.err){t(s),o({withoutRemoving:!0});return}if(s.confirmationStatus==="finalized"){r(s),o({withoutRemoving:!0});return}d().diff(d.unix(e.localTimestamp),"hour")>=1&&(t(s),o());}catch(a){console.error("Error in solanaFetcher:",a),t({err:a}),o();}}async function h({tx:e,onSuccess:o,onError:r,...t}){return initializePollingTracker({tx:e,fetcher:R,removeTxFromPool:t.removeTxFromPool,pollingInterval:2500,maxRetries:10,onSuccess:n=>{t.updateTxParams(e.txKey,{status:TransactionStatus.Success,pending:false,isError:false,finishedTimestamp:d().unix(),fee:n.fee,instructions:n.instructions,recentBlockhash:n.recentBlockhash,confirmations:"MAX",slot:n.slot});let a=t.transactionsPool[e.txKey];o&&a&&o(a);},onIntervalTick:n=>{t.updateTxParams(e.txKey,{confirmations:n.confirmations??0,slot:n.slot,fee:n.fee,instructions:n.instructions,recentBlockhash:n.recentBlockhash});},onFailure:n=>{t.updateTxParams(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,error:normalizeError(n?.err??new Error("Transaction tracking timed out or the transaction was not found.")),finishedTimestamp:d().unix()});let a=t.transactionsPool[e.txKey];r&&a&&r(n?.err??new Error("Transaction tracking timed out or the transaction was not found."),a);}})}async function g({tx:e,tracker:o,onSuccess:r,onError:t,...n}){o===TransactionTracker.Solana?await h({tx:e,onSuccess:r,onError:t,...n}):(console.error(`Unknown tracker type for Solana adapter: ${o}`),n.updateTxParams(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,error:normalizeError(new Error(`Unsupported tracker type: "${o}"`))}));}var S=(e,o)=>{if(o!==e)throw new l(e,o)};function gr(e){let{rpcUrls:o}=e;return {key:OrbitAdapter.SOLANA,getConnectorInfo:()=>{let r=getConnectedSolanaConnector();return {walletAddress:lastConnectedConnectorHelpers.getLastConnectedConnector()?.address??r.accounts[0].address??"0x0",connectorType:getConnectorTypeFromName(OrbitAdapter.SOLANA,r.name)}},checkChainForTx:async r=>{if(!getConnectedSolanaConnector())throw new Error("Wallet not provided. Cannot perform chain check.");try{S(r,lastConnectedConnectorHelpers.getLastConnectedConnector()?.chainId??"");}catch(n){throw n instanceof l?n:new Error(`Chain check failed: ${n instanceof Error?n.message:String(n)}`,{cause:n})}},checkTransactionsTracker:({actionTxKey:r,tracker:t})=>({tracker:t??TransactionTracker.Solana,txKey:r}),checkAndInitializeTrackerInStore:({tx:r,...t})=>g({tracker:r.tracker,tx:r,...t}),getExplorerUrl:(r,t)=>getSolanaExplorerLink(r,t),getExplorerTxUrl:r=>getSolanaExplorerLink(`/tx/${r.txKey}`,r.chainId),retryTxAction:async({onClose:r,txKey:t,executeTxAction:n,tx:a})=>{r(t);let i=getAvailableSolanaConnectors().filter(s=>s.accounts.length>0)[0];if(!i||!i.accounts[0].address||i.accounts[0].address==="0x0")throw new Error("Retry failed: A wallet must be connected.");if(!n)throw new Error("Retry failed: executeTxAction function is not provided.");let u=getCluster({cluster:a?.desiredChainID}),c=a.rpcUrl??getRpcUrlForCluster({cluster:u,rpcUrls:o});if(!c)throw new Error("Retry failed: Could not determine RPC endpoint for the transaction chain.");let m=createSolanaClientWithCache({rpcUrlOrMoniker:c,rpcUrls:o});await n({actionFunction:()=>a.actionFunction({client:m,...a.payload}),params:a,defaultTracker:TransactionTracker.Solana});}}}async function xr({client:e,signer:o,instruction:r}){let{value:t}=await e.rpc.getLatestBlockhash().send(),n=createTransaction({feePayer:o,version:0,latestBlockhash:t,instructions:Array.isArray(r)?r:[r]}),a=await signAndSendTransactionMessageWithSigners(n);return getBase58Decoder().decode(a)}export{l as SolanaChainMismatchError,g as checkAndInitializeTrackerInStore,S as checkSolanaChain,gr as pulsarSolanaAdapter,xr as signAndSendSolanaTx,R as solanaFetcher,h as solanaTrackerForStore};
1
+ import {OrbitAdapter,normalizeError,lastConnectedConnectorHelpers,getConnectorTypeFromName}from'@tuwaio/orbit-core';import {createSolanaRPC,getCluster,getAvailableSolanaConnectors,getRpcUrlForCluster,createSolanaClientWithCache,getSolanaExplorerLink,getConnectedSolanaConnector}from'@tuwaio/orbit-solana';import {initializePollingTracker,TransactionStatus,TransactionTracker}from'@tuwaio/pulsar-core';import p from'dayjs';import {pipe,createTransactionMessage,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,appendTransactionMessageInstructions,signAndSendTransactionMessageWithSigners,getBase58Decoder}from'@solana/kit';var u=class extends Error{name="SolanaChainMismatchError";requiredChain;currentChain;constructor(a,r){let t=`Wrong chain. The transaction requires ${a}, but you are connected to ${r}.`;super(t),this.requiredChain=a,this.currentChain=r;}};async function R({tx:e,stopPolling:a,onSuccess:r,onFailure:t,onIntervalTick:n}){if(e.adapter!==OrbitAdapter.SOLANA)throw new Error('Tx adapter is not Solana. Please set the adapter to "solana" in the transaction object.');try{let o=createSolanaRPC({rpcUrlOrMoniker:e.rpcUrl??getCluster({cluster:e.chainId})}),s=(await o.getSignatureStatuses([e.txKey]).send())?.value?.[0];if(!s)return;let{fee:m,recentBlockhash:l,instructions:d}=e;if(!m||!l||!d){let A=await o.getTransaction(e.txKey,{encoding:"json",maxSupportedTransactionVersion:0}).send(),{meta:T,transaction:f}=A||{};if(!T||!f)return;m=Number(T.fee??0),l=f.message.recentBlockhash?.toString(),d=f.message.instructions;}let i={...s,slot:Number(s.slot),confirmations:Number(s.confirmations??0),fee:m,recentBlockhash:l,instructions:d};if(n?.(i),i.err){t(i),a({withoutRemoving:!0});return}if(i.confirmationStatus==="finalized"){r(i),a({withoutRemoving:!0});return}p().diff(p.unix(e.localTimestamp),"hour")>=1&&(t(i),a());}catch(o){console.error("Error in solanaFetcher:",o),t({err:o}),a();}}async function h({tx:e,onSuccess:a,onError:r,...t}){return initializePollingTracker({tx:e,fetcher:R,removeTxFromPool:t.removeTxFromPool,pollingInterval:2500,maxRetries:10,onSuccess:n=>{t.updateTxParams(e.txKey,{status:TransactionStatus.Success,pending:false,isError:false,finishedTimestamp:p().unix(),fee:n.fee,instructions:n.instructions,recentBlockhash:n.recentBlockhash,confirmations:"MAX",slot:n.slot});let o=t.transactionsPool[e.txKey];a&&o&&a(o);},onIntervalTick:n=>{t.updateTxParams(e.txKey,{confirmations:n.confirmations??0,slot:n.slot,fee:n.fee,instructions:n.instructions,recentBlockhash:n.recentBlockhash});},onFailure:n=>{t.updateTxParams(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,error:normalizeError(n?.err??new Error("Transaction tracking timed out or the transaction was not found.")),finishedTimestamp:p().unix()});let o=t.transactionsPool[e.txKey];r&&o&&r(n?.err??new Error("Transaction tracking timed out or the transaction was not found."),o);}})}async function S({tx:e,tracker:a,onSuccess:r,onError:t,...n}){a===TransactionTracker.Solana?await h({tx:e,onSuccess:r,onError:t,...n}):(console.error(`Unknown tracker type for Solana adapter: ${a}`),n.updateTxParams(e.txKey,{status:TransactionStatus.Failed,pending:false,isError:true,error:normalizeError(new Error(`Unsupported tracker type: "${a}"`))}));}var k=(e,a)=>{if(a!==e)throw new u(e,a)};function Cr(e){let{rpcUrls:a}=e;return {key:OrbitAdapter.SOLANA,getConnectorInfo:()=>{let r=getConnectedSolanaConnector();return {walletAddress:lastConnectedConnectorHelpers.getLastConnectedConnector()?.address??r.accounts[0].address??"0x0",connectorType:getConnectorTypeFromName(OrbitAdapter.SOLANA,r.name)}},checkChainForTx:async r=>{if(!getConnectedSolanaConnector())throw new Error("Wallet not provided. Cannot perform chain check.");try{k(r,lastConnectedConnectorHelpers.getLastConnectedConnector()?.chainId??"");}catch(n){throw n instanceof u?n:new Error(`Chain check failed: ${n instanceof Error?n.message:String(n)}`,{cause:n})}},checkTransactionsTracker:({actionTxKey:r,tracker:t})=>({tracker:t??TransactionTracker.Solana,txKey:r}),checkAndInitializeTrackerInStore:({tx:r,...t})=>S({tracker:r.tracker,tx:r,...t}),getExplorerUrl:(r,t)=>getSolanaExplorerLink(r,t),getExplorerTxUrl:r=>getSolanaExplorerLink(`/tx/${r.txKey}`,r.chainId),retryTxAction:async({onClose:r,txKey:t,executeTxAction:n,tx:o})=>{r(t);let s=getAvailableSolanaConnectors().filter(i=>i.accounts.length>0)[0];if(!s||!s.accounts[0].address||s.accounts[0].address==="0x0")throw new Error("Retry failed: A wallet must be connected.");if(!n)throw new Error("Retry failed: executeTxAction function is not provided.");let m=getCluster({cluster:o?.desiredChainID}),l=o.rpcUrl??getRpcUrlForCluster({cluster:m,rpcUrls:a});if(!l)throw new Error("Retry failed: Could not determine RPC endpoint for the transaction chain.");let d=createSolanaClientWithCache({rpcUrlOrMoniker:l,rpcUrls:a});await n({actionFunction:()=>o.actionFunction({client:d,...o.payload}),params:o,defaultTracker:TransactionTracker.Solana});}}}async function Pr({client:e,signer:a,instruction:r}){let{value:t}=await e.rpc.getLatestBlockhash().send(),n=pipe(createTransactionMessage({version:0}),c=>setTransactionMessageFeePayerSigner(a,c),c=>setTransactionMessageLifetimeUsingBlockhash(t,c),c=>appendTransactionMessageInstructions(Array.isArray(r)?r:[r],c)),o=await signAndSendTransactionMessageWithSigners(n);return getBase58Decoder().decode(o)}export{u as SolanaChainMismatchError,S as checkAndInitializeTrackerInStore,k as checkSolanaChain,Cr as pulsarSolanaAdapter,Pr as signAndSendSolanaTx,R as solanaFetcher,h as solanaTrackerForStore};
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@tuwaio/pulsar-solana",
3
- "version": "0.6.9",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",
7
- "description": "Layer 4 (L4) of the TUWA Ecosystem. Low-level Solana block state monitors and RPC cluster lifecycle indexers powered strictly by gill.",
7
+ "description": "Layer 4 (L4) of the TUWA Ecosystem. Low-level Solana block state monitors and RPC cluster lifecycle indexers powered strictly by @solana/kit.",
8
8
  "main": "./dist/index.js",
9
9
  "module": "./dist/index.mjs",
10
10
  "types": "./dist/index.d.ts",
@@ -20,7 +20,7 @@
20
20
  "solana",
21
21
  "transaction",
22
22
  "tracking",
23
- "gill",
23
+ "@solana/kit",
24
24
  "zustand"
25
25
  ],
26
26
  "repository": {
@@ -39,36 +39,36 @@
39
39
  }
40
40
  ],
41
41
  "peerDependencies": {
42
- "@tuwaio/orbit-core": ">=0.2.8",
43
- "@tuwaio/orbit-solana": ">=0.2.4",
44
- "@tuwaio/pulsar-core": ">=0.5",
42
+ "@tuwaio/orbit-core": ">=0.3",
43
+ "@tuwaio/orbit-solana": ">=0.3",
44
+ "@tuwaio/pulsar-core": ">=0.7",
45
45
  "@wallet-standard/app": "1.x.x",
46
46
  "@wallet-standard/ui-core": "1.x.x",
47
47
  "@wallet-standard/ui-registry": "1.1.x",
48
- "gill": ">=0.14",
48
+ "@solana/kit": ">=8.2",
49
49
  "dayjs": "1.x.x",
50
50
  "immer": "11.x.x",
51
51
  "zustand": "5.x.x"
52
52
  },
53
53
  "devDependencies": {
54
- "@tuwaio/orbit-core": "^0.2.15",
55
- "@tuwaio/orbit-solana": "^0.2.13",
54
+ "@tuwaio/pulsar-core": "^0.7.0",
55
+ "@tuwaio/orbit-core": "^0.3.0",
56
+ "@tuwaio/orbit-solana": "^0.3.0",
56
57
  "@wallet-standard/app": "^1.1.1",
57
58
  "@wallet-standard/ui-core": "^1.0.1",
58
59
  "@wallet-standard/ui-registry": "^1.1.1",
59
- "dayjs": "^1.11.21",
60
- "gill": "^0.14.0",
61
- "immer": "^11.1.15",
60
+ "dayjs": "^1.11.23",
61
+ "@solana/kit": "^8.2.0",
62
+ "immer": "^11.1.18",
62
63
  "jsdom": "^30.0.1",
63
64
  "tsup": "^8.5.1",
64
- "typescript": "^6.0.3",
65
- "vitest": "^4.1.10",
66
- "zustand": "^5.0.14",
67
- "@tuwaio/pulsar-core": "^0.6.9"
65
+ "typescript": "6.0.3",
66
+ "vitest": "^5.0.0",
67
+ "zustand": "^5.0.15"
68
68
  },
69
69
  "scripts": {
70
70
  "start": "tsup src/index.ts --watch",
71
71
  "build": "tsup",
72
- "test": "vitest"
72
+ "test": "vitest run"
73
73
  }
74
74
  }