@tuwaio/orbit-solana 0.3.0 → 0.3.1

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
@@ -1,19 +1,20 @@
1
1
  # @tuwaio/orbit-solana
2
2
 
3
3
  [![NPM Version](https://img.shields.io/npm/v/@tuwaio/orbit-solana.svg)](https://www.npmjs.com/package/@tuwaio/orbit-solana)
4
- [![License](https://img.shields.io/npm/l/@tuwaio/orbit-solana.svg)](./LICENSE)
4
+ [![License](https://img.shields.io/npm/l/@tuwaio/orbit-solana.svg)](https://github.com/TuwaIO/orbit/blob/main/packages/orbit-solana/LICENSE)
5
5
 
6
- `@tuwaio/orbit-solana` provides concrete implementations of low-level Solana-specific communication primitives for Layer 2 (L2) of the TUWA Orbit stack. Engineered strictly on top of **`@solana/kit`** (the official modern high-performance modular Solana JavaScript SDK), this package integrates Wallet Standard capabilities for discovery and persistent caching of RPC connections. It is fully compatible with instructions generated by **Codama** (`@codama/renderers-js`), completely eradicating legacy dependencies such as `gill` or `@solana/web3.js`.
6
+ `@tuwaio/orbit-solana` is the Solana Layer 2 (L2) package of **Orbit Utils**, the Stage 1 primitives layer of the TUWA ecosystem. It is built on **`@solana/kit`** and the **Wallet Standard** (`@wallet-standard/*`), and provides cached RPC clients, wallet discovery, cluster and explorer helpers, and SNS name and avatar lookups. It does not use the legacy `@solana/web3.js` or `gill`.
7
7
 
8
8
  ---
9
9
 
10
10
  ## 🏛️ Core Capabilities
11
11
 
12
- - **Modular Solana RPC Caching:** Creates and caches high-performance Solana RPC connections (`createSolanaClientWithCache`, `createSolanaRPC`) powered by `@solana/kit` to optimize transaction dispatching and query pipelines.
13
- - **Wallet Standard Integration:** Low-level discovery routines (`getAvailableSolanaConnectors`, `getConnectedSolanaConnector`) that strictly align with the `@wallet-standard/app` specifications.
14
- - **Codama Program Architecture:** Seamlessly executes instructions rendered by Codama (`kitImportStrategy: 'rootOnly'`) across Solana Devnet, Testnet, and Mainnet.
15
- - **Profile Metadata Engine:** Resolves user-defined account descriptors (names, avatars, SNS resolution) directly from Solana accounts.
16
- - **Cluster Parameter Resolution:** Maps Solana RPC clusters (mainnet, devnet, testnet) to explorer endpoints and RPC configurations.
12
+ - **RPC clients:** `createSolanaClientWithCache` returns a cached `{ rpc, rpcSubscriptions }` pair (the WebSocket URL is derived from the HTTP URL); `createSolanaRPC` returns a cached `rpc` only. Both accept a full URL or a cluster moniker (`mainnet`, `devnet`, `testnet`, `localnet`).
13
+ - **Wallet Standard discovery:** `getAvailableSolanaConnectors` lists installed wallets that support every feature Orbit relies on (`standard:connect`, `standard:disconnect`, `standard:events`, `solana:signAndSendTransaction`, `solana:signTransaction`, `solana:signMessage`) and only Solana chains. `getConnectedSolanaConnector` finds the wallet that holds the last connected address stored by `@tuwaio/orbit-core`.
14
+ - **Clusters and explorer links:** `getCluster`, `getRpcUrlForCluster`, `getSolanaClusters`, `getAvailableSolanaClusters`, `isValidSolanaCluster`, `isSolanaChainList`, and `getSolanaExplorerLink` for [Solana Explorer](https://explorer.solana.com) URLs.
15
+ - **Names and avatars:** `getSolanaAddressName` resolves an address to its favorite SNS (`.sol`) domain; `getSolanaAddressAvatar` returns the SNS profile image or a generated identicon. Both cache results in memory (`clear…Cache`, `get…CacheSize`, `preloadSolanaAvatar`).
16
+
17
+ Transactions are built and sent with `@solana/kit` itself, so any kit-compatible instruction builder works with the `rpc` returned here, including program clients generated by [Codama](https://github.com/codama-idl/codama).
17
18
 
18
19
  ---
19
20
 
@@ -24,65 +25,69 @@ pnpm add @tuwaio/orbit-solana @tuwaio/orbit-core @solana/kit @wallet-standard/ap
24
25
  ```
25
26
 
26
27
  > [!IMPORTANT]
27
- > `@tuwaio/orbit-core` (>=0.2), `@solana/kit` (>=8.2), and `@wallet-standard` packages (v1.x) are peer dependencies and must be installed alongside `@tuwaio/orbit-solana`.
28
+ > `@tuwaio/orbit-core` (>=0.2), `@solana/kit` (>=8.2) and the `@wallet-standard` packages (1.x) are peer dependencies and must be installed alongside `@tuwaio/orbit-solana`.
28
29
 
29
30
  ---
30
31
 
31
- ## 🚀 Technical Integration
32
-
33
- ### Cached RPC Connection
32
+ ## 🚀 Usage
34
33
 
35
- Establish cached RPC endpoints dynamically:
34
+ ### Cached RPC client
36
35
 
37
36
  ```typescript
37
+ import { address } from '@solana/kit';
38
38
  import { createSolanaClientWithCache } from '@tuwaio/orbit-solana';
39
39
 
40
- // Obtain cached connection primitive
41
- const client = createSolanaClientWithCache({ rpcUrlOrMoniker: 'mainnet' });
40
+ const { rpc } = createSolanaClientWithCache({
41
+ rpcUrlOrMoniker: 'devnet',
42
+ rpcUrls: { devnet: 'https://devnet.my-rpc-provider.example' }, // optional; falls back to the public endpoint
43
+ });
44
+
45
+ const { value: lamports } = await rpc.getBalance(address('So11111111111111111111111111111111111111112')).send();
42
46
  ```
43
47
 
44
- ### Wallet Standard Discovery
48
+ Clients are cached by the `rpcUrlOrMoniker` string. `localnet` has no default URL, so pass it in `rpcUrls`. The public `api.*.solana.com` endpoints are rate-limited; use your own RPC provider in production.
45
49
 
46
- Query the browser runtime for installed Wallet Standard adapters:
50
+ ### Wallet discovery
47
51
 
48
52
  ```typescript
49
53
  import { getAvailableSolanaConnectors } from '@tuwaio/orbit-solana';
50
54
 
51
- const connectors = getAvailableSolanaConnectors();
52
- console.log(
53
- 'Available Standard Adapters:',
54
- connectors.map((c) => c.name),
55
- );
55
+ const wallets = getAvailableSolanaConnectors(); // UiWallet[] from @wallet-standard/ui-registry
56
+ console.log(wallets.map((wallet) => wallet.name));
56
57
  ```
57
58
 
58
- ### Working with Codama Generated Instructions
59
-
60
- Use Codama (`@codama/renderers-js`) to generate type-safe instruction builders, then dispatch them using `@solana/kit` and `@tuwaio/orbit-solana`:
59
+ ### Names, avatars and explorer links
61
60
 
62
61
  ```typescript
63
- import { createSolanaClientWithCache } from '@tuwaio/orbit-solana';
64
- import { pipe } from '@solana/kit';
65
- // Instruction generated via Codama
66
- // import { getIncrementInstruction } from './generated';
62
+ import { getSolanaAddressAvatar, getSolanaAddressName, getSolanaExplorerLink } from '@tuwaio/orbit-solana';
67
63
 
68
- const client = createSolanaClientWithCache({ rpcUrlOrMoniker: 'devnet' });
69
- // Send and confirm using client.rpc and standard signers
64
+ const owner = 'So11111111111111111111111111111111111111112';
65
+
66
+ const name = await getSolanaAddressName(owner); // "name.sol", or the address itself if no SNS domain is set
67
+ const avatarUrl = await getSolanaAddressAvatar(name);
68
+
69
+ getSolanaExplorerLink(`/address/${owner}`, 'solana:devnet'); // "https://explorer.solana.com/address/…?cluster=devnet"
70
70
  ```
71
71
 
72
72
  ---
73
73
 
74
- ## 🔧 API & Module Architecture
74
+ ## 🌐 External Services
75
75
 
76
- `@tuwaio/orbit-solana` exposes the following modules:
76
+ Some helpers call public third-party HTTP services. The address or domain being looked up is sent to these hosts:
77
77
 
78
- - **RPC Factory:** `createSolanaClientWithCache`, `createSolanaRPC`.
79
- - **Connector Discovery:** `getAvailableSolanaConnectors`, `getConnectedSolanaConnector`.
80
- - **Account Resolvers:** `getSolanaAddressName`, `getSolanaAddressAvatar`.
81
- - **Network Helpers:** `getCluster`, `getRpcUrlForCluster`.
82
- - **Explorer Helpers:** `getSolanaExplorerLink`.
78
+ | Helper | Host | Purpose |
79
+ | -------------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------ |
80
+ | RPC clients (default URLs) | `api.mainnet-beta.solana.com`, `api.devnet.solana.com`, `api.testnet.solana.com` | Public Solana RPC, used when no custom URL is configured |
81
+ | `getSolanaAddressName` | `sns-api.bonfida.com` | Favorite SNS domain of an address |
82
+ | `getSolanaAddressAvatar` | `image-api.bonfida.com` | SNS profile image of a `.sol` domain |
83
+ | `getSolanaAddressAvatar` | `api.dicebear.com` | Fallback identicon URL (loaded by the browser when rendered) |
83
84
 
84
85
  ---
85
86
 
87
+ ## 📚 API Reference
88
+
89
+ Every export, with signatures and types generated from the source, is documented at **[orbit.docs.tuwa.io/packages/orbit-solana](https://orbit.docs.tuwa.io/packages/orbit-solana)**.
90
+
86
91
  ## 📄 License
87
92
 
88
- Licensed under the **Apache-2.0 License**. See the [LICENSE](./LICENSE) file for details.
93
+ Licensed under the **Apache-2.0 License**. See the [LICENSE](https://github.com/TuwaIO/orbit/blob/main/packages/orbit-solana/LICENSE) file for details.
package/dist/index.d.mts CHANGED
@@ -25,28 +25,43 @@ interface SolanaClient {
25
25
  }
26
26
 
27
27
  /**
28
- * Get Solana clusters from configuration
28
+ * Resolves the Solana clusters an app can use.
29
+ *
30
+ * @param solanaRPCUrls - Optional mapping of cluster monikers to RPC URLs. When provided, only these clusters are allowed.
31
+ * @param chains - Optional chain identifiers (e.g. `'solana:devnet'`, `'solana:mainnet-beta'`); when provided, only
32
+ * clusters present in this list (and allowed by `solanaRPCUrls`) are returned.
33
+ * @returns Cluster monikers, e.g. `['mainnet', 'devnet']`. Defaults to every cluster with a default RPC URL.
29
34
  */
30
35
  declare function getSolanaClusters(solanaRPCUrls?: Partial<Record<SolanaClusterMoniker, string>>, chains?: ChainIdentifierArray): string[];
31
36
  /**
32
- * Type guard to check if a chain list contains Solana cluster names
37
+ * Type guard to check if a chain list contains Solana cluster names.
38
+ *
39
+ * @param chains - Mixed list of chain identifiers.
40
+ * @returns `true` if the list is non-empty and contains only strings.
33
41
  */
34
42
  declare function isSolanaChainList(chains: (string | number)[]): chains is string[];
35
43
  /**
36
- * Gets available Solana clusters from the default configuration
44
+ * Gets the Solana clusters that have a default public RPC URL.
45
+ *
46
+ * @returns `['mainnet', 'devnet', 'testnet']`.
37
47
  */
38
48
  declare function getAvailableSolanaClusters(): SolanaClusterMoniker[];
39
49
  /**
40
- * Validates if a string is a valid Solana cluster moniker
50
+ * Validates if a string is a Solana cluster moniker with a default RPC URL.
51
+ *
52
+ * @param cluster - Value to check.
53
+ * @returns `true` for `'mainnet'`, `'devnet'` and `'testnet'`.
41
54
  */
42
55
  declare function isValidSolanaCluster(cluster: string): boolean;
43
56
 
44
57
  /**
45
58
  * Safely extracts the cluster moniker from a chain identifier.
46
59
  * Handles both full chain IDs ('solana:mainnet-beta') and simple monikers ('mainnet-beta').
47
- * @returns The extracted cluster moniker.
48
- * @param walletCluster
49
- * @param cluster
60
+ *
61
+ * @param params - Cluster sources.
62
+ * @param params.cluster - Chain identifier or cluster moniker. Takes precedence when provided.
63
+ * @param params.walletCluster - Cluster of the connected wallet, used when `cluster` is omitted.
64
+ * @returns The extracted cluster moniker, falling back to `walletCluster` and then to `'mainnet'`.
50
65
  */
51
66
  declare const getCluster: ({ cluster, walletCluster }: {
52
67
  cluster?: string;
@@ -54,8 +69,12 @@ declare const getCluster: ({ cluster, walletCluster }: {
54
69
  }) => string;
55
70
  /**
56
71
  * Retrieves the configured RPC URL for a given cluster moniker.
57
- * @param cluster The target cluster. Defaults to the wallet's active chain.
58
- * @returns The RPC URL or undefined if not found.
72
+ *
73
+ * @param params - Cluster selection and the configured RPC URLs.
74
+ * @param params.cluster - The target cluster, used when `walletCluster` is not provided.
75
+ * @param params.walletCluster - The cluster of the connected wallet. Takes precedence over `cluster`.
76
+ * @param params.rpcUrls - Mapping of cluster monikers to RPC URLs.
77
+ * @returns The configured RPC URL, or the public mainnet-beta endpoint if the cluster has no URL configured.
59
78
  */
60
79
  declare const getRpcUrlForCluster: ({ cluster, walletCluster, rpcUrls, }: {
61
80
  cluster: SolanaClusterMoniker;
@@ -121,8 +140,26 @@ declare const clearSolanaRpcCache: () => void;
121
140
  */
122
141
  declare const defaultRpcUrlsByMoniker: Partial<Record<SolanaClusterMoniker, string>>;
123
142
 
143
+ /**
144
+ * Lists the Solana wallets registered through the Wallet Standard that Orbit can work with.
145
+ *
146
+ * A wallet is included only if it supports `standard:connect`, `standard:disconnect`, `standard:events`,
147
+ * `solana:signAndSendTransaction`, `solana:signTransaction` and `solana:signMessage`, and every chain it
148
+ * declares is a `solana:*` chain. Wallets registered more than once are deduplicated by name.
149
+ *
150
+ * @returns The matching wallets as `UiWallet` objects from `@wallet-standard/ui-registry`
151
+ * (empty on the server, where no wallets are registered).
152
+ */
124
153
  declare function getAvailableSolanaConnectors(): _wallet_standard_ui_core.UiWallet[];
125
154
 
155
+ /**
156
+ * Finds the Wallet Standard wallet that holds the last connected address.
157
+ * The address is read from `lastConnectedConnectorHelpers` in `@tuwaio/orbit-core` (localStorage) and matched
158
+ * case-insensitively against the accounts of {@link getAvailableSolanaConnectors}.
159
+ *
160
+ * @returns The connected wallet as a `UiWallet`.
161
+ * @throws {Error} "Connector not provided. Cannot perform chain check." if no available wallet holds that address.
162
+ */
126
163
  declare function getConnectedSolanaConnector(): _wallet_standard_ui_core.UiWallet;
127
164
 
128
165
  /**
@@ -178,7 +215,8 @@ declare const getSolanaNameCacheSize: () => number;
178
215
  * Generates a full URL to an account, transaction, or block on the Solana explorer.
179
216
  *
180
217
  * @param url - The path after baseUrl (e.g. '/tx/...' or '/address/...').
181
- * @param chainId - Chain ID or cluster name.
218
+ * @param chainId - Chain ID or cluster name (e.g. 'devnet' or 'solana:devnet').
219
+ * Mainnet ('mainnet', 'mainnet-beta') or an omitted value produces a link without a `cluster` query parameter.
182
220
  * @returns The full URL on the Solana explorer.
183
221
  */
184
222
  declare const getSolanaExplorerLink: (url?: string, chainId?: string | number | undefined) => string;
package/dist/index.d.ts CHANGED
@@ -25,28 +25,43 @@ interface SolanaClient {
25
25
  }
26
26
 
27
27
  /**
28
- * Get Solana clusters from configuration
28
+ * Resolves the Solana clusters an app can use.
29
+ *
30
+ * @param solanaRPCUrls - Optional mapping of cluster monikers to RPC URLs. When provided, only these clusters are allowed.
31
+ * @param chains - Optional chain identifiers (e.g. `'solana:devnet'`, `'solana:mainnet-beta'`); when provided, only
32
+ * clusters present in this list (and allowed by `solanaRPCUrls`) are returned.
33
+ * @returns Cluster monikers, e.g. `['mainnet', 'devnet']`. Defaults to every cluster with a default RPC URL.
29
34
  */
30
35
  declare function getSolanaClusters(solanaRPCUrls?: Partial<Record<SolanaClusterMoniker, string>>, chains?: ChainIdentifierArray): string[];
31
36
  /**
32
- * Type guard to check if a chain list contains Solana cluster names
37
+ * Type guard to check if a chain list contains Solana cluster names.
38
+ *
39
+ * @param chains - Mixed list of chain identifiers.
40
+ * @returns `true` if the list is non-empty and contains only strings.
33
41
  */
34
42
  declare function isSolanaChainList(chains: (string | number)[]): chains is string[];
35
43
  /**
36
- * Gets available Solana clusters from the default configuration
44
+ * Gets the Solana clusters that have a default public RPC URL.
45
+ *
46
+ * @returns `['mainnet', 'devnet', 'testnet']`.
37
47
  */
38
48
  declare function getAvailableSolanaClusters(): SolanaClusterMoniker[];
39
49
  /**
40
- * Validates if a string is a valid Solana cluster moniker
50
+ * Validates if a string is a Solana cluster moniker with a default RPC URL.
51
+ *
52
+ * @param cluster - Value to check.
53
+ * @returns `true` for `'mainnet'`, `'devnet'` and `'testnet'`.
41
54
  */
42
55
  declare function isValidSolanaCluster(cluster: string): boolean;
43
56
 
44
57
  /**
45
58
  * Safely extracts the cluster moniker from a chain identifier.
46
59
  * Handles both full chain IDs ('solana:mainnet-beta') and simple monikers ('mainnet-beta').
47
- * @returns The extracted cluster moniker.
48
- * @param walletCluster
49
- * @param cluster
60
+ *
61
+ * @param params - Cluster sources.
62
+ * @param params.cluster - Chain identifier or cluster moniker. Takes precedence when provided.
63
+ * @param params.walletCluster - Cluster of the connected wallet, used when `cluster` is omitted.
64
+ * @returns The extracted cluster moniker, falling back to `walletCluster` and then to `'mainnet'`.
50
65
  */
51
66
  declare const getCluster: ({ cluster, walletCluster }: {
52
67
  cluster?: string;
@@ -54,8 +69,12 @@ declare const getCluster: ({ cluster, walletCluster }: {
54
69
  }) => string;
55
70
  /**
56
71
  * Retrieves the configured RPC URL for a given cluster moniker.
57
- * @param cluster The target cluster. Defaults to the wallet's active chain.
58
- * @returns The RPC URL or undefined if not found.
72
+ *
73
+ * @param params - Cluster selection and the configured RPC URLs.
74
+ * @param params.cluster - The target cluster, used when `walletCluster` is not provided.
75
+ * @param params.walletCluster - The cluster of the connected wallet. Takes precedence over `cluster`.
76
+ * @param params.rpcUrls - Mapping of cluster monikers to RPC URLs.
77
+ * @returns The configured RPC URL, or the public mainnet-beta endpoint if the cluster has no URL configured.
59
78
  */
60
79
  declare const getRpcUrlForCluster: ({ cluster, walletCluster, rpcUrls, }: {
61
80
  cluster: SolanaClusterMoniker;
@@ -121,8 +140,26 @@ declare const clearSolanaRpcCache: () => void;
121
140
  */
122
141
  declare const defaultRpcUrlsByMoniker: Partial<Record<SolanaClusterMoniker, string>>;
123
142
 
143
+ /**
144
+ * Lists the Solana wallets registered through the Wallet Standard that Orbit can work with.
145
+ *
146
+ * A wallet is included only if it supports `standard:connect`, `standard:disconnect`, `standard:events`,
147
+ * `solana:signAndSendTransaction`, `solana:signTransaction` and `solana:signMessage`, and every chain it
148
+ * declares is a `solana:*` chain. Wallets registered more than once are deduplicated by name.
149
+ *
150
+ * @returns The matching wallets as `UiWallet` objects from `@wallet-standard/ui-registry`
151
+ * (empty on the server, where no wallets are registered).
152
+ */
124
153
  declare function getAvailableSolanaConnectors(): _wallet_standard_ui_core.UiWallet[];
125
154
 
155
+ /**
156
+ * Finds the Wallet Standard wallet that holds the last connected address.
157
+ * The address is read from `lastConnectedConnectorHelpers` in `@tuwaio/orbit-core` (localStorage) and matched
158
+ * case-insensitively against the accounts of {@link getAvailableSolanaConnectors}.
159
+ *
160
+ * @returns The connected wallet as a `UiWallet`.
161
+ * @throws {Error} "Connector not provided. Cannot perform chain check." if no available wallet holds that address.
162
+ */
126
163
  declare function getConnectedSolanaConnector(): _wallet_standard_ui_core.UiWallet;
127
164
 
128
165
  /**
@@ -178,7 +215,8 @@ declare const getSolanaNameCacheSize: () => number;
178
215
  * Generates a full URL to an account, transaction, or block on the Solana explorer.
179
216
  *
180
217
  * @param url - The path after baseUrl (e.g. '/tx/...' or '/address/...').
181
- * @param chainId - Chain ID or cluster name.
218
+ * @param chainId - Chain ID or cluster name (e.g. 'devnet' or 'solana:devnet').
219
+ * Mainnet ('mainnet', 'mainnet-beta') or an omitted value produces a link without a `cluster` query parameter.
182
220
  * @returns The full URL on the Solana explorer.
183
221
  */
184
222
  declare const getSolanaExplorerLink: (url?: string, chainId?: string | number | undefined) => string;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var kit=require('@solana/kit'),orbitCore=require('@tuwaio/orbit-core'),app=require('@wallet-standard/app'),uiRegistry=require('@wallet-standard/ui-registry');var s={mainnet:"https://api.mainnet-beta.solana.com",devnet:"https://api.devnet.solana.com",testnet:"https://api.testnet.solana.com"};function d(t){let e=t.split(":");if(e.length<2)return null;let r=e[1];r==="mainnet-beta"&&(r="mainnet");let a=r;return a in s?a:null}function S(t,e){let r={},a=Object.keys(e||s);for(let n of t){if(typeof n!="string")continue;let o=d(n);if(!o||!a.includes(o))continue;let f=e?.[o]??s[o];f&&(r[o]=f);}return r}function j(t,e){if(e&&e.length>0){let r=S(e,t);return Object.keys(r)}return Object.keys(t||s)}function z(t){return t.length>0&&t.every(e=>typeof e=="string")}function T(){return Object.keys(s)}function W(t){return t in s}var m=({cluster:t,walletCluster:e})=>{let r="mainnet";return t?t.includes(":")?t.split(":")[1]:t:e??r},q=({cluster:t,walletCluster:e,rpcUrls:r})=>r[e??t]??"https://api.mainnet-beta.solana.com/";function h(t){try{return new URL(t),!0}catch{return false}}function R(t){return t.replace(/^http/,"ws")}var l=new Map,X=({rpcUrlOrMoniker:t,rpcUrls:e})=>{if(l.has(t))return l.get(t);let r=h(t)?t:e?e[t]??s[t]:s[t];if(!r)throw new Error(`Unable to resolve RPC URL for input: "${t}". Ensure it's a valid URL or known moniker.`);let a=kit.createSolanaRpc(r),n;try{n=kit.createSolanaRpcSubscriptions(R(r));}catch{}let o={rpc:a,...n?{rpcSubscriptions:n}:{}};return l.set(t,o),o},G=()=>{l.clear();};function v(t){try{return new URL(t),!0}catch{return false}}var c=new Map,Z=({rpcUrlOrMoniker:t,rpcUrls:e})=>{if(c.has(t))return c.get(t);let r=v(t)?t:e?e[t]??s[t]:s[t];if(!r)throw new Error(`Unable to resolve RPC URL for input: "${t}". Ensure it's a valid URL or known moniker.`);let a=kit.createSolanaRpc(r);return c.set(t,a),a},O=()=>{c.clear();};function g(){return orbitCore.filterUniqueByKey(app.getWallets().get().map(uiRegistry.getOrCreateUiWalletForStandardWallet),"name").filter(t=>{try{return !t||!Array.isArray(t.chains)||!t.features||!Array.isArray(t.features)||!["standard:connect","standard:disconnect","standard:events","solana:signAndSendTransaction","solana:signTransaction","solana:signMessage"].every(a=>t.features.includes(a))?!1:t.chains.every(a=>{try{if(typeof a!="string")return !1;let n=a.split(":");return n.length>=1&&n[0]==="solana"}catch(n){return console.warn("Error parsing chain:",a,n),!1}})}catch(e){return console.warn("Error filtering wallet:",e),false}})}function it(){let t=orbitCore.lastConnectedConnectorHelpers.getLastConnectedConnector(),r=g().find(a=>a.accounts.find(n=>n.address.toLowerCase()===t?.address?.toLowerCase()));if(!r)throw new Error("Connector not provided. Cannot perform chain check.");return r}var u=new Map,P="https://image-api.bonfida.com",N=t=>/^[a-z0-9-]+\.sol$/.test(t.toLowerCase()),L=async t=>{try{let e=await fetch(`${P}/image?domain=${encodeURIComponent(t)}`);if(!e.ok)return null;let r=await e.json();return r.result&&Array.isArray(r.result)&&r.result.length>0?r.result.find(n=>n.domain===t)?.image??r.result[0]?.image??null:null}catch(e){return console.warn("Failed to fetch SNS avatar:",e),null}},i=t=>`https://api.dicebear.com/7.x/identicon/svg?seed=${encodeURIComponent(t)}`,M=async t=>{if(!t)return i("default");let e=t.trim();if(!e)return i("default");let r=e.toLowerCase(),a=u.get(r);if(a!==void 0)return a;let n;try{if(N(e)){let o=await L(e);o?n=o:n=i(e);}else kit.isAddress(e),n=i(e);}catch(o){console.warn("Error resolving avatar:",o),n=i(e);}return u.set(r,n),n},ut=()=>{u.clear();},pt=()=>u.size,ft=async t=>{try{await M(t);}catch(e){console.warn("Failed to preload avatar:",e);}};var p=new Map,$="https://sns-api.bonfida.com",I=async t=>{try{let e=await fetch(`${$}/v2/user/fav-domains/${t}`);if(!e.ok)return null;let r=await e.json();return r.result&&typeof r.result=="object"&&t in r.result?r.result[t]:null}catch(e){return console.warn("Failed to fetch SNS name:",e),null}},dt=async t=>{if(!t)return t||"";let e=t.trim();if(!kit.isAddress(e))return t;let r=e.toLowerCase(),a=p.get(r);if(a!==void 0)return a;let n=t;try{let o=await I(e);o&&(n=o);}catch(o){console.warn("Error resolving address name:",o);}return p.set(r,n),n},St=()=>{p.clear();},Ct=()=>p.size;var B="https://explorer.solana.com",Rt=(t,e)=>{let r=m({cluster:String(e)})??"mainnet",a=B,n=r&&r!=="mainnet"?`?cluster=${r}`:"",o=t?t.startsWith("/")?t:`/${t}`:"/";return `${a}${o}${n}`};
2
- exports.clearSolanaAvatarCache=ut;exports.clearSolanaClientCache=G;exports.clearSolanaNameCache=St;exports.clearSolanaRpcCache=O;exports.createSolanaClientWithCache=X;exports.createSolanaRPC=Z;exports.defaultRpcUrlsByMoniker=s;exports.getAvailableSolanaClusters=T;exports.getAvailableSolanaConnectors=g;exports.getCluster=m;exports.getConnectedSolanaConnector=it;exports.getRpcUrlForCluster=q;exports.getSolanaAddressAvatar=M;exports.getSolanaAddressName=dt;exports.getSolanaAvatarCacheSize=pt;exports.getSolanaClusters=j;exports.getSolanaExplorerLink=Rt;exports.getSolanaNameCacheSize=Ct;exports.isSolanaChainList=z;exports.isValidSolanaCluster=W;exports.preloadSolanaAvatar=ft;
1
+ 'use strict';var kit=require('@solana/kit'),orbitCore=require('@tuwaio/orbit-core'),app=require('@wallet-standard/app'),uiRegistry=require('@wallet-standard/ui-registry');var s={mainnet:"https://api.mainnet-beta.solana.com",devnet:"https://api.devnet.solana.com",testnet:"https://api.testnet.solana.com"};function d(t){let e=t.split(":");if(e.length<2)return null;let r=e[1];r==="mainnet-beta"&&(r="mainnet");let a=r;return a in s?a:null}function S(t,e){let r={},a=Object.keys(e||s);for(let n of t){if(typeof n!="string")continue;let o=d(n);if(!o||!a.includes(o))continue;let f=e?.[o]??s[o];f&&(r[o]=f);}return r}function z(t,e){if(e&&e.length>0){let r=S(e,t);return Object.keys(r)}return Object.keys(t||s)}function T(t){return t.length>0&&t.every(e=>typeof e=="string")}function W(){return Object.keys(s)}function D(t){return t in s}var m=({cluster:t,walletCluster:e})=>{let r="mainnet";return t?t.includes(":")?t.split(":")[1]:t:e??r},q=({cluster:t,walletCluster:e,rpcUrls:r})=>r[e??t]??"https://api.mainnet-beta.solana.com/";function h(t){try{return new URL(t),!0}catch{return false}}function R(t){return t.replace(/^http/,"ws")}var l=new Map,G=({rpcUrlOrMoniker:t,rpcUrls:e})=>{if(l.has(t))return l.get(t);let r=h(t)?t:e?e[t]??s[t]:s[t];if(!r)throw new Error(`Unable to resolve RPC URL for input: "${t}". Ensure it's a valid URL or known moniker.`);let a=kit.createSolanaRpc(r),n;try{n=kit.createSolanaRpcSubscriptions(R(r));}catch{}let o={rpc:a,...n?{rpcSubscriptions:n}:{}};return l.set(t,o),o},J=()=>{l.clear();};function v(t){try{return new URL(t),!0}catch{return false}}var c=new Map,O=({rpcUrlOrMoniker:t,rpcUrls:e})=>{if(c.has(t))return c.get(t);let r=v(t)?t:e?e[t]??s[t]:s[t];if(!r)throw new Error(`Unable to resolve RPC URL for input: "${t}". Ensure it's a valid URL or known moniker.`);let a=kit.createSolanaRpc(r);return c.set(t,a),a},tt=()=>{c.clear();};function g(){return orbitCore.filterUniqueByKey(app.getWallets().get().map(uiRegistry.getOrCreateUiWalletForStandardWallet),"name").filter(t=>{try{return !t||!Array.isArray(t.chains)||!t.features||!Array.isArray(t.features)||!["standard:connect","standard:disconnect","standard:events","solana:signAndSendTransaction","solana:signTransaction","solana:signMessage"].every(a=>t.features.includes(a))?!1:t.chains.every(a=>{try{if(typeof a!="string")return !1;let n=a.split(":");return n.length>=1&&n[0]==="solana"}catch(n){return console.warn("Error parsing chain:",a,n),!1}})}catch(e){return console.warn("Error filtering wallet:",e),false}})}function lt(){let t=orbitCore.lastConnectedConnectorHelpers.getLastConnectedConnector(),r=g().find(a=>a.accounts.find(n=>n.address.toLowerCase()===t?.address?.toLowerCase()));if(!r)throw new Error("Connector not provided. Cannot perform chain check.");return r}var u=new Map,L="https://image-api.bonfida.com",P=t=>/^[a-z0-9-]+\.sol$/.test(t.toLowerCase()),N=async t=>{try{let e=await fetch(`${L}/image?domain=${encodeURIComponent(t)}`);if(!e.ok)return null;let r=await e.json();return r.result&&Array.isArray(r.result)&&r.result.length>0?r.result.find(n=>n.domain===t)?.image??r.result[0]?.image??null:null}catch(e){return console.warn("Failed to fetch SNS avatar:",e),null}},i=t=>`https://api.dicebear.com/7.x/identicon/svg?seed=${encodeURIComponent(t)}`,E=async t=>{if(!t)return i("default");let e=t.trim();if(!e)return i("default");let r=e.toLowerCase(),a=u.get(r);if(a!==void 0)return a;let n;try{if(P(e)){let o=await N(e);o?n=o:n=i(e);}else kit.isAddress(e),n=i(e);}catch(o){console.warn("Error resolving avatar:",o),n=i(e);}return u.set(r,n),n},pt=()=>{u.clear();},ft=()=>u.size,mt=async t=>{try{await E(t);}catch(e){console.warn("Failed to preload avatar:",e);}};var p=new Map,$="https://sns-api.bonfida.com",I=async t=>{try{let e=await fetch(`${$}/v2/user/fav-domains/${t}`);if(!e.ok)return null;let r=await e.json();return r.result&&typeof r.result=="object"&&t in r.result?r.result[t]:null}catch(e){return console.warn("Failed to fetch SNS name:",e),null}},St=async t=>{if(!t)return t||"";let e=t.trim();if(!kit.isAddress(e))return t;let r=e.toLowerCase(),a=p.get(r);if(a!==void 0)return a;let n=t;try{let o=await I(e);o&&(n=o);}catch(o){console.warn("Error resolving address name:",o);}return p.set(r,n),n},Ct=()=>{p.clear();},yt=()=>p.size;var _="https://explorer.solana.com",F=new Set(["mainnet","mainnet-beta"]),At=(t,e)=>{let r=m({cluster:e===void 0?void 0:String(e)}),a=_,n=F.has(r)?"":`?cluster=${r}`,o=t?t.startsWith("/")?t:`/${t}`:"/";return `${a}${o}${n}`};
2
+ exports.clearSolanaAvatarCache=pt;exports.clearSolanaClientCache=J;exports.clearSolanaNameCache=Ct;exports.clearSolanaRpcCache=tt;exports.createSolanaClientWithCache=G;exports.createSolanaRPC=O;exports.defaultRpcUrlsByMoniker=s;exports.getAvailableSolanaClusters=W;exports.getAvailableSolanaConnectors=g;exports.getCluster=m;exports.getConnectedSolanaConnector=lt;exports.getRpcUrlForCluster=q;exports.getSolanaAddressAvatar=E;exports.getSolanaAddressName=St;exports.getSolanaAvatarCacheSize=ft;exports.getSolanaClusters=z;exports.getSolanaExplorerLink=At;exports.getSolanaNameCacheSize=yt;exports.isSolanaChainList=T;exports.isValidSolanaCluster=D;exports.preloadSolanaAvatar=mt;
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import {createSolanaRpc,createSolanaRpcSubscriptions,isAddress}from'@solana/kit';import {filterUniqueByKey,lastConnectedConnectorHelpers}from'@tuwaio/orbit-core';import {getWallets}from'@wallet-standard/app';import {getOrCreateUiWalletForStandardWallet}from'@wallet-standard/ui-registry';var s={mainnet:"https://api.mainnet-beta.solana.com",devnet:"https://api.devnet.solana.com",testnet:"https://api.testnet.solana.com"};function d(t){let e=t.split(":");if(e.length<2)return null;let r=e[1];r==="mainnet-beta"&&(r="mainnet");let a=r;return a in s?a:null}function S(t,e){let r={},a=Object.keys(e||s);for(let n of t){if(typeof n!="string")continue;let o=d(n);if(!o||!a.includes(o))continue;let f=e?.[o]??s[o];f&&(r[o]=f);}return r}function j(t,e){if(e&&e.length>0){let r=S(e,t);return Object.keys(r)}return Object.keys(t||s)}function z(t){return t.length>0&&t.every(e=>typeof e=="string")}function T(){return Object.keys(s)}function W(t){return t in s}var m=({cluster:t,walletCluster:e})=>{let r="mainnet";return t?t.includes(":")?t.split(":")[1]:t:e??r},q=({cluster:t,walletCluster:e,rpcUrls:r})=>r[e??t]??"https://api.mainnet-beta.solana.com/";function h(t){try{return new URL(t),!0}catch{return false}}function R(t){return t.replace(/^http/,"ws")}var l=new Map,X=({rpcUrlOrMoniker:t,rpcUrls:e})=>{if(l.has(t))return l.get(t);let r=h(t)?t:e?e[t]??s[t]:s[t];if(!r)throw new Error(`Unable to resolve RPC URL for input: "${t}". Ensure it's a valid URL or known moniker.`);let a=createSolanaRpc(r),n;try{n=createSolanaRpcSubscriptions(R(r));}catch{}let o={rpc:a,...n?{rpcSubscriptions:n}:{}};return l.set(t,o),o},G=()=>{l.clear();};function v(t){try{return new URL(t),!0}catch{return false}}var c=new Map,Z=({rpcUrlOrMoniker:t,rpcUrls:e})=>{if(c.has(t))return c.get(t);let r=v(t)?t:e?e[t]??s[t]:s[t];if(!r)throw new Error(`Unable to resolve RPC URL for input: "${t}". Ensure it's a valid URL or known moniker.`);let a=createSolanaRpc(r);return c.set(t,a),a},O=()=>{c.clear();};function g(){return filterUniqueByKey(getWallets().get().map(getOrCreateUiWalletForStandardWallet),"name").filter(t=>{try{return !t||!Array.isArray(t.chains)||!t.features||!Array.isArray(t.features)||!["standard:connect","standard:disconnect","standard:events","solana:signAndSendTransaction","solana:signTransaction","solana:signMessage"].every(a=>t.features.includes(a))?!1:t.chains.every(a=>{try{if(typeof a!="string")return !1;let n=a.split(":");return n.length>=1&&n[0]==="solana"}catch(n){return console.warn("Error parsing chain:",a,n),!1}})}catch(e){return console.warn("Error filtering wallet:",e),false}})}function it(){let t=lastConnectedConnectorHelpers.getLastConnectedConnector(),r=g().find(a=>a.accounts.find(n=>n.address.toLowerCase()===t?.address?.toLowerCase()));if(!r)throw new Error("Connector not provided. Cannot perform chain check.");return r}var u=new Map,P="https://image-api.bonfida.com",N=t=>/^[a-z0-9-]+\.sol$/.test(t.toLowerCase()),L=async t=>{try{let e=await fetch(`${P}/image?domain=${encodeURIComponent(t)}`);if(!e.ok)return null;let r=await e.json();return r.result&&Array.isArray(r.result)&&r.result.length>0?r.result.find(n=>n.domain===t)?.image??r.result[0]?.image??null:null}catch(e){return console.warn("Failed to fetch SNS avatar:",e),null}},i=t=>`https://api.dicebear.com/7.x/identicon/svg?seed=${encodeURIComponent(t)}`,M=async t=>{if(!t)return i("default");let e=t.trim();if(!e)return i("default");let r=e.toLowerCase(),a=u.get(r);if(a!==void 0)return a;let n;try{if(N(e)){let o=await L(e);o?n=o:n=i(e);}else isAddress(e),n=i(e);}catch(o){console.warn("Error resolving avatar:",o),n=i(e);}return u.set(r,n),n},ut=()=>{u.clear();},pt=()=>u.size,ft=async t=>{try{await M(t);}catch(e){console.warn("Failed to preload avatar:",e);}};var p=new Map,$="https://sns-api.bonfida.com",I=async t=>{try{let e=await fetch(`${$}/v2/user/fav-domains/${t}`);if(!e.ok)return null;let r=await e.json();return r.result&&typeof r.result=="object"&&t in r.result?r.result[t]:null}catch(e){return console.warn("Failed to fetch SNS name:",e),null}},dt=async t=>{if(!t)return t||"";let e=t.trim();if(!isAddress(e))return t;let r=e.toLowerCase(),a=p.get(r);if(a!==void 0)return a;let n=t;try{let o=await I(e);o&&(n=o);}catch(o){console.warn("Error resolving address name:",o);}return p.set(r,n),n},St=()=>{p.clear();},Ct=()=>p.size;var B="https://explorer.solana.com",Rt=(t,e)=>{let r=m({cluster:String(e)})??"mainnet",a=B,n=r&&r!=="mainnet"?`?cluster=${r}`:"",o=t?t.startsWith("/")?t:`/${t}`:"/";return `${a}${o}${n}`};
2
- export{ut as clearSolanaAvatarCache,G as clearSolanaClientCache,St as clearSolanaNameCache,O as clearSolanaRpcCache,X as createSolanaClientWithCache,Z as createSolanaRPC,s as defaultRpcUrlsByMoniker,T as getAvailableSolanaClusters,g as getAvailableSolanaConnectors,m as getCluster,it as getConnectedSolanaConnector,q as getRpcUrlForCluster,M as getSolanaAddressAvatar,dt as getSolanaAddressName,pt as getSolanaAvatarCacheSize,j as getSolanaClusters,Rt as getSolanaExplorerLink,Ct as getSolanaNameCacheSize,z as isSolanaChainList,W as isValidSolanaCluster,ft as preloadSolanaAvatar};
1
+ import {createSolanaRpc,createSolanaRpcSubscriptions,isAddress}from'@solana/kit';import {filterUniqueByKey,lastConnectedConnectorHelpers}from'@tuwaio/orbit-core';import {getWallets}from'@wallet-standard/app';import {getOrCreateUiWalletForStandardWallet}from'@wallet-standard/ui-registry';var s={mainnet:"https://api.mainnet-beta.solana.com",devnet:"https://api.devnet.solana.com",testnet:"https://api.testnet.solana.com"};function d(t){let e=t.split(":");if(e.length<2)return null;let r=e[1];r==="mainnet-beta"&&(r="mainnet");let a=r;return a in s?a:null}function S(t,e){let r={},a=Object.keys(e||s);for(let n of t){if(typeof n!="string")continue;let o=d(n);if(!o||!a.includes(o))continue;let f=e?.[o]??s[o];f&&(r[o]=f);}return r}function z(t,e){if(e&&e.length>0){let r=S(e,t);return Object.keys(r)}return Object.keys(t||s)}function T(t){return t.length>0&&t.every(e=>typeof e=="string")}function W(){return Object.keys(s)}function D(t){return t in s}var m=({cluster:t,walletCluster:e})=>{let r="mainnet";return t?t.includes(":")?t.split(":")[1]:t:e??r},q=({cluster:t,walletCluster:e,rpcUrls:r})=>r[e??t]??"https://api.mainnet-beta.solana.com/";function h(t){try{return new URL(t),!0}catch{return false}}function R(t){return t.replace(/^http/,"ws")}var l=new Map,G=({rpcUrlOrMoniker:t,rpcUrls:e})=>{if(l.has(t))return l.get(t);let r=h(t)?t:e?e[t]??s[t]:s[t];if(!r)throw new Error(`Unable to resolve RPC URL for input: "${t}". Ensure it's a valid URL or known moniker.`);let a=createSolanaRpc(r),n;try{n=createSolanaRpcSubscriptions(R(r));}catch{}let o={rpc:a,...n?{rpcSubscriptions:n}:{}};return l.set(t,o),o},J=()=>{l.clear();};function v(t){try{return new URL(t),!0}catch{return false}}var c=new Map,O=({rpcUrlOrMoniker:t,rpcUrls:e})=>{if(c.has(t))return c.get(t);let r=v(t)?t:e?e[t]??s[t]:s[t];if(!r)throw new Error(`Unable to resolve RPC URL for input: "${t}". Ensure it's a valid URL or known moniker.`);let a=createSolanaRpc(r);return c.set(t,a),a},tt=()=>{c.clear();};function g(){return filterUniqueByKey(getWallets().get().map(getOrCreateUiWalletForStandardWallet),"name").filter(t=>{try{return !t||!Array.isArray(t.chains)||!t.features||!Array.isArray(t.features)||!["standard:connect","standard:disconnect","standard:events","solana:signAndSendTransaction","solana:signTransaction","solana:signMessage"].every(a=>t.features.includes(a))?!1:t.chains.every(a=>{try{if(typeof a!="string")return !1;let n=a.split(":");return n.length>=1&&n[0]==="solana"}catch(n){return console.warn("Error parsing chain:",a,n),!1}})}catch(e){return console.warn("Error filtering wallet:",e),false}})}function lt(){let t=lastConnectedConnectorHelpers.getLastConnectedConnector(),r=g().find(a=>a.accounts.find(n=>n.address.toLowerCase()===t?.address?.toLowerCase()));if(!r)throw new Error("Connector not provided. Cannot perform chain check.");return r}var u=new Map,L="https://image-api.bonfida.com",P=t=>/^[a-z0-9-]+\.sol$/.test(t.toLowerCase()),N=async t=>{try{let e=await fetch(`${L}/image?domain=${encodeURIComponent(t)}`);if(!e.ok)return null;let r=await e.json();return r.result&&Array.isArray(r.result)&&r.result.length>0?r.result.find(n=>n.domain===t)?.image??r.result[0]?.image??null:null}catch(e){return console.warn("Failed to fetch SNS avatar:",e),null}},i=t=>`https://api.dicebear.com/7.x/identicon/svg?seed=${encodeURIComponent(t)}`,E=async t=>{if(!t)return i("default");let e=t.trim();if(!e)return i("default");let r=e.toLowerCase(),a=u.get(r);if(a!==void 0)return a;let n;try{if(P(e)){let o=await N(e);o?n=o:n=i(e);}else isAddress(e),n=i(e);}catch(o){console.warn("Error resolving avatar:",o),n=i(e);}return u.set(r,n),n},pt=()=>{u.clear();},ft=()=>u.size,mt=async t=>{try{await E(t);}catch(e){console.warn("Failed to preload avatar:",e);}};var p=new Map,$="https://sns-api.bonfida.com",I=async t=>{try{let e=await fetch(`${$}/v2/user/fav-domains/${t}`);if(!e.ok)return null;let r=await e.json();return r.result&&typeof r.result=="object"&&t in r.result?r.result[t]:null}catch(e){return console.warn("Failed to fetch SNS name:",e),null}},St=async t=>{if(!t)return t||"";let e=t.trim();if(!isAddress(e))return t;let r=e.toLowerCase(),a=p.get(r);if(a!==void 0)return a;let n=t;try{let o=await I(e);o&&(n=o);}catch(o){console.warn("Error resolving address name:",o);}return p.set(r,n),n},Ct=()=>{p.clear();},yt=()=>p.size;var _="https://explorer.solana.com",F=new Set(["mainnet","mainnet-beta"]),At=(t,e)=>{let r=m({cluster:e===void 0?void 0:String(e)}),a=_,n=F.has(r)?"":`?cluster=${r}`,o=t?t.startsWith("/")?t:`/${t}`:"/";return `${a}${o}${n}`};
2
+ export{pt as clearSolanaAvatarCache,J as clearSolanaClientCache,Ct as clearSolanaNameCache,tt as clearSolanaRpcCache,G as createSolanaClientWithCache,O as createSolanaRPC,s as defaultRpcUrlsByMoniker,W as getAvailableSolanaClusters,g as getAvailableSolanaConnectors,m as getCluster,lt as getConnectedSolanaConnector,q as getRpcUrlForCluster,E as getSolanaAddressAvatar,St as getSolanaAddressName,ft as getSolanaAvatarCacheSize,z as getSolanaClusters,At as getSolanaExplorerLink,yt as getSolanaNameCacheSize,T as isSolanaChainList,D as isValidSolanaCluster,mt as preloadSolanaAvatar};
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@tuwaio/orbit-solana",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",
7
- "description": "Layer 2 (L2) of the TUWA Ecosystem. Low-level Solana-specific communication primitives and RPC caching utilities powered strictly by @solana/kit.",
7
+ "description": "L2 Solana package of Orbit Utils (TUWA): cached @solana/kit RPC clients, Wallet Standard discovery, cluster and explorer helpers, and SNS name/avatar lookups.",
8
8
  "main": "./dist/index.js",
9
9
  "module": "./dist/index.mjs",
10
10
  "types": "./dist/index.d.ts",
@@ -16,9 +16,14 @@
16
16
  "socket.json"
17
17
  ],
18
18
  "keywords": [
19
+ "tuwa",
20
+ "orbit",
19
21
  "web3",
20
- "typescript",
21
22
  "solana",
23
+ "@solana/kit",
24
+ "wallet-standard",
25
+ "sns",
26
+ "typescript",
22
27
  "headless"
23
28
  ],
24
29
  "repository": {
@@ -44,10 +49,10 @@
44
49
  "@wallet-standard/ui-registry": "1.x.x"
45
50
  },
46
51
  "devDependencies": {
47
- "@tuwaio/orbit-core": "^0.3.0",
52
+ "@tuwaio/orbit-core": "^0.3.1",
48
53
  "tsup": "^8.5.1",
49
- "typescript": "^6.0.3",
50
- "@solana/kit": "^8.2.0",
54
+ "typescript": "6.0.3",
55
+ "@solana/kit": "^8.3.0",
51
56
  "@wallet-standard/app": "^1.1.1",
52
57
  "@wallet-standard/ui-core": "^1.0.1",
53
58
  "@wallet-standard/ui-registry": "^1.1.1"