@algobright/solana-connector-kit 1.0.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.
Files changed (35) hide show
  1. package/dist/Avatar.module-P7KEBP7R.module.css +42 -0
  2. package/dist/Button.module-7TPMDOJN.module.css +145 -0
  3. package/dist/Collapsible.module-NXSN3MGI.module.css +24 -0
  4. package/dist/ConnectButton.d.mts +14 -0
  5. package/dist/ConnectButton.d.ts +14 -0
  6. package/dist/ConnectButton.js +1248 -0
  7. package/dist/ConnectButton.js.map +1 -0
  8. package/dist/ConnectButton.mjs +1216 -0
  9. package/dist/ConnectButton.mjs.map +1 -0
  10. package/dist/ConnectButton.module-UWQKSVTP.module.css +8 -0
  11. package/dist/CustomQRCode.module-FOXENMZG.module.css +176 -0
  12. package/dist/Dialog.module-HCRT743N.module.css +136 -0
  13. package/dist/Menu.module-GV627ZLI.module.css +79 -0
  14. package/dist/Spinner.module-G7GUQJZJ.module.css +16 -0
  15. package/dist/WalletDropdown.d.mts +14 -0
  16. package/dist/WalletDropdown.d.ts +14 -0
  17. package/dist/WalletDropdown.js +346 -0
  18. package/dist/WalletDropdown.js.map +1 -0
  19. package/dist/WalletDropdown.mjs +314 -0
  20. package/dist/WalletDropdown.mjs.map +1 -0
  21. package/dist/WalletDropdown.module-342MM7XM.module.css +220 -0
  22. package/dist/WalletModal.d.mts +13 -0
  23. package/dist/WalletModal.d.ts +13 -0
  24. package/dist/WalletModal.js +838 -0
  25. package/dist/WalletModal.js.map +1 -0
  26. package/dist/WalletModal.mjs +806 -0
  27. package/dist/WalletModal.mjs.map +1 -0
  28. package/dist/WalletModal.module-PVV5PRXU.module.css +341 -0
  29. package/dist/index.d.mts +70 -0
  30. package/dist/index.d.ts +70 -0
  31. package/dist/index.js +242 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/index.mjs +222 -0
  34. package/dist/index.mjs.map +1 -0
  35. package/package.json +70 -0
package/dist/index.js ADDED
@@ -0,0 +1,242 @@
1
+ "use client";
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var src_exports = {};
23
+ __export(src_exports, {
24
+ SolanaWrapper: () => SolanaWrapper,
25
+ useRpcProvider: () => useRpcProvider
26
+ });
27
+ module.exports = __toCommonJS(src_exports);
28
+
29
+ // src/providers/RpcProvider.tsx
30
+ var import_react = require("react");
31
+ var import_jsx_runtime = require("react/jsx-runtime");
32
+ var DEFAULT_RPCS = {
33
+ mainnet: ["https://api.mainnet.solana.com"],
34
+ devnet: ["https://api.devnet.solana.com"],
35
+ testnet: ["https://api.testnet.solana.com"],
36
+ localnet: ["http://localhost:8899"]
37
+ };
38
+ var RpcContext = (0, import_react.createContext)(null);
39
+ function RpcProvider(props) {
40
+ const {
41
+ children,
42
+ defaultRpcList = DEFAULT_RPCS,
43
+ defaultRpcUrl = DEFAULT_RPCS.mainnet[0],
44
+ LS_KEY_RPC_LIST = "all-rpc-urls",
45
+ LS_KEY_RPC_DEFAULT = "curr-rpc",
46
+ LS_KEY_CLUSTER = "solana-cluster",
47
+ persistClusterSelection = true,
48
+ MAX_RPC_RETRIES = 3
49
+ } = props;
50
+ const [allRpcUrls, setAllRpcUrls] = (0, import_react.useState)(defaultRpcList);
51
+ const [rpcUrl, setRpcUrlState] = (0, import_react.useState)(defaultRpcUrl);
52
+ (0, import_react.useEffect)(() => {
53
+ const savedHistory = localStorage.getItem(LS_KEY_RPC_LIST);
54
+ const savedRpc = localStorage.getItem(LS_KEY_RPC_DEFAULT);
55
+ if (savedRpc && savedRpc !== rpcUrl) {
56
+ setRpcUrlState(savedRpc);
57
+ }
58
+ if (savedHistory) {
59
+ try {
60
+ const parsed = JSON.parse(savedHistory);
61
+ setAllRpcUrls({
62
+ mainnet: Array.from(/* @__PURE__ */ new Set([...DEFAULT_RPCS.mainnet, ...parsed.mainnet || []])),
63
+ devnet: Array.from(/* @__PURE__ */ new Set([...DEFAULT_RPCS.devnet, ...parsed.devnet || []])),
64
+ testnet: Array.from(/* @__PURE__ */ new Set([...DEFAULT_RPCS.testnet, ...parsed.testnet || []])),
65
+ localnet: Array.from(/* @__PURE__ */ new Set([...DEFAULT_RPCS.localnet, ...parsed.localnet || []]))
66
+ });
67
+ } catch (e) {
68
+ console.error(e);
69
+ }
70
+ }
71
+ }, []);
72
+ const setRpcUrl = (0, import_react.useCallback)((url) => {
73
+ setRpcUrlState(url);
74
+ localStorage.setItem(LS_KEY_RPC_DEFAULT, url);
75
+ }, []);
76
+ const addRpcUrl = (0, import_react.useCallback)((network, url) => {
77
+ if (!url) return;
78
+ setAllRpcUrls((prev) => {
79
+ const newList = Array.from(/* @__PURE__ */ new Set([...prev[network], url]));
80
+ const newState = { ...prev, [network]: newList };
81
+ localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));
82
+ return newState;
83
+ });
84
+ setRpcUrl(url);
85
+ }, [setRpcUrl]);
86
+ const removeRpcUrl = (0, import_react.useCallback)((network, url) => {
87
+ setAllRpcUrls((prev) => {
88
+ let newList = prev[network].filter((rpc) => rpc !== url);
89
+ if (newList.length === 0) {
90
+ newList = [...DEFAULT_RPCS[network]];
91
+ }
92
+ const newState = { ...prev, [network]: newList };
93
+ localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));
94
+ return newState;
95
+ });
96
+ }, [LS_KEY_RPC_LIST]);
97
+ const value = (0, import_react.useMemo)(() => ({
98
+ persistClusterSelection,
99
+ clusterStorageKey: LS_KEY_CLUSTER,
100
+ maxRPCRetries: MAX_RPC_RETRIES,
101
+ rpcUrl,
102
+ setRpcUrl,
103
+ allRpcUrls,
104
+ addRpcUrl,
105
+ removeRpcUrl
106
+ }), [rpcUrl, allRpcUrls, setRpcUrl, addRpcUrl, removeRpcUrl]);
107
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RpcContext.Provider, { value, children });
108
+ }
109
+ var useRpcProvider = () => {
110
+ const context = (0, import_react.useContext)(RpcContext);
111
+ if (!context) {
112
+ throw new Error("useRpcProvider must be used within RpcProvider");
113
+ }
114
+ return context;
115
+ };
116
+
117
+ // src/providers/SolanaWalletProvider.tsx
118
+ var import_react2 = require("react");
119
+ var import_react3 = require("@solana/connector/react");
120
+ var import_jsx_runtime2 = require("react/jsx-runtime");
121
+ function SolanaWalletProvider(props) {
122
+ const {
123
+ children,
124
+ appName = "Solana Kit",
125
+ appUrl,
126
+ autoConnect = true,
127
+ enableMobile = true,
128
+ walletConnect = true,
129
+ additionalWallets = [],
130
+ coingecko,
131
+ walletsDisplayConfig
132
+ } = props;
133
+ const {
134
+ persistClusterSelection,
135
+ clusterStorageKey,
136
+ maxRPCRetries,
137
+ rpcUrl,
138
+ allRpcUrls
139
+ } = useRpcProvider();
140
+ const appOrigin = appUrl || (typeof window !== "undefined" ? window.location.origin : "");
141
+ const activeNetwork = (0, import_react2.useMemo)(() => {
142
+ if (allRpcUrls.devnet.includes(rpcUrl)) return "devnet";
143
+ else if (allRpcUrls.testnet.includes(rpcUrl)) return "testnet";
144
+ else if (allRpcUrls.localnet.includes(rpcUrl)) return "localnet";
145
+ return "mainnet";
146
+ }, [rpcUrl, allRpcUrls]);
147
+ const connectorConfig = (0, import_react2.useMemo)(() => {
148
+ const clusters = [
149
+ {
150
+ id: "solana:mainnet",
151
+ label: "Mainnet",
152
+ url: activeNetwork === "mainnet" ? rpcUrl : allRpcUrls.mainnet[0]
153
+ },
154
+ {
155
+ id: "solana:localnet",
156
+ label: "Localnet",
157
+ url: activeNetwork === "localnet" ? rpcUrl : allRpcUrls.localnet[0]
158
+ },
159
+ {
160
+ id: "solana:devnet",
161
+ label: "Devnet",
162
+ url: activeNetwork === "devnet" ? rpcUrl : allRpcUrls.devnet[0]
163
+ },
164
+ {
165
+ id: "solana:testnet",
166
+ label: "Testnet",
167
+ url: activeNetwork === "testnet" ? rpcUrl : allRpcUrls.testnet[0]
168
+ }
169
+ ];
170
+ return (0, import_react3.getDefaultConfig)({
171
+ appName,
172
+ appUrl: appOrigin,
173
+ autoConnect,
174
+ network: activeNetwork,
175
+ enableMobile,
176
+ // from RPC settings
177
+ clusters,
178
+ persistClusterSelection,
179
+ clusterStorageKey,
180
+ maxRetries: maxRPCRetries,
181
+ walletConnect,
182
+ additionalWallets,
183
+ coingecko,
184
+ wallets: walletsDisplayConfig
185
+ });
186
+ }, [appName, appOrigin, autoConnect, enableMobile, walletConnect, coingecko]);
187
+ const mobile = (0, import_react2.useMemo)(
188
+ () => (0, import_react3.getDefaultMobileConfig)({
189
+ appName,
190
+ appUrl: appOrigin,
191
+ network: activeNetwork === "localnet" ? "devnet" : activeNetwork
192
+ }),
193
+ [appName, appOrigin, activeNetwork]
194
+ );
195
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react3.AppProvider, { connectorConfig, mobile, children });
196
+ }
197
+
198
+ // src/providers/SolanaWrapper.tsx
199
+ var import_jsx_runtime3 = require("react/jsx-runtime");
200
+ function SolanaWrapper(props) {
201
+ const {
202
+ children,
203
+ appName,
204
+ appUrl,
205
+ autoConnect,
206
+ enableMobile,
207
+ walletConnect,
208
+ defaultRpcList,
209
+ defaultRpcUrl,
210
+ LS_KEY_RPC_LIST,
211
+ LS_KEY_RPC_DEFAULT,
212
+ LS_KEY_CLUSTER,
213
+ persistClusterSelection,
214
+ MAX_RPC_RETRIES
215
+ } = props;
216
+ const RPC_PROVIDER_PROPS = {
217
+ defaultRpcList,
218
+ defaultRpcUrl,
219
+ LS_KEY_RPC_LIST,
220
+ LS_KEY_RPC_DEFAULT,
221
+ LS_KEY_CLUSTER,
222
+ persistClusterSelection,
223
+ MAX_RPC_RETRIES
224
+ };
225
+ const solanaWalletProviderProps = {
226
+ appName,
227
+ appUrl,
228
+ autoConnect,
229
+ enableMobile,
230
+ walletConnect,
231
+ additionalWallets: [],
232
+ coingecko: void 0,
233
+ walletsDisplayConfig: void 0
234
+ };
235
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RpcProvider, { ...RPC_PROVIDER_PROPS, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SolanaWalletProvider, { ...solanaWalletProviderProps, children }) });
236
+ }
237
+ // Annotate the CommonJS export names for ESM import in node:
238
+ 0 && (module.exports = {
239
+ SolanaWrapper,
240
+ useRpcProvider
241
+ });
242
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/providers/RpcProvider.tsx","../src/providers/SolanaWalletProvider.tsx","../src/providers/SolanaWrapper.tsx"],"sourcesContent":["import { SolanaWrapper } from '@providers/SolanaWrapper';\nimport { useRpcProvider } from '@providers/RpcProvider';\n\nexport {\n SolanaWrapper,\n useRpcProvider,\n};","'use client';\r\n\r\nimport {\r\n createContext,\r\n useContext,\r\n useEffect,\r\n useState,\r\n useCallback,\r\n useMemo,\r\n type ReactNode\r\n} from 'react';\r\nimport { Network, RpcMap } from '../types';\r\n\r\n\r\nconst DEFAULT_RPCS: RpcMap = {\r\n mainnet: ['https://api.mainnet.solana.com'],\r\n devnet: ['https://api.devnet.solana.com'],\r\n testnet: ['https://api.testnet.solana.com'],\r\n localnet: ['http://localhost:8899'],\r\n};\r\n\r\ninterface RpcContextType {\r\n rpcUrl: string;\r\n setRpcUrl: (url: string) => void;\r\n\r\n persistClusterSelection: boolean;\r\n clusterStorageKey: string;\r\n maxRPCRetries: number;\r\n\r\n allRpcUrls: RpcMap;\r\n addRpcUrl: (network: Network, url: string) => void;\r\n removeRpcUrl: (network: Network, url: string) => void;\r\n}\r\nconst RpcContext = createContext<RpcContextType | null>(null);\r\n\r\n\r\ntype RpcProviderProps = {\r\n children: ReactNode;\r\n\r\n defaultRpcList?: RpcMap;\r\n defaultRpcUrl?: string;\r\n\r\n LS_KEY_RPC_LIST?: string;\r\n LS_KEY_RPC_DEFAULT?: string;\r\n LS_KEY_CLUSTER?: string;\r\n persistClusterSelection?: boolean;\r\n MAX_RPC_RETRIES?: number;\r\n};\r\nexport function RpcProvider(props: RpcProviderProps) {\r\n const {\r\n children,\r\n defaultRpcList = DEFAULT_RPCS,\r\n defaultRpcUrl = DEFAULT_RPCS.mainnet[0],\r\n LS_KEY_RPC_LIST = 'all-rpc-urls',\r\n LS_KEY_RPC_DEFAULT = 'curr-rpc',\r\n LS_KEY_CLUSTER = 'solana-cluster',\r\n persistClusterSelection = true,\r\n MAX_RPC_RETRIES = 3,\r\n } = props;\r\n\r\n const [allRpcUrls, setAllRpcUrls] = useState<RpcMap>(defaultRpcList);\r\n const [rpcUrl, setRpcUrlState] = useState<string>(defaultRpcUrl);\r\n\r\n useEffect(() => {\r\n const savedHistory = localStorage.getItem(LS_KEY_RPC_LIST);\r\n const savedRpc = localStorage.getItem(LS_KEY_RPC_DEFAULT);\r\n\r\n if (savedRpc && savedRpc !== rpcUrl) {\r\n setRpcUrlState(savedRpc);\r\n }\r\n\r\n if (savedHistory) {\r\n try {\r\n const parsed = JSON.parse(savedHistory) as RpcMap;\r\n setAllRpcUrls({\r\n mainnet: Array.from(new Set([...DEFAULT_RPCS.mainnet, ...(parsed.mainnet || [])])),\r\n devnet: Array.from(new Set([...DEFAULT_RPCS.devnet, ...(parsed.devnet || [])])),\r\n testnet: Array.from(new Set([...DEFAULT_RPCS.testnet, ...(parsed.testnet || [])])),\r\n localnet: Array.from(new Set([...DEFAULT_RPCS.localnet, ...(parsed.localnet || [])])),\r\n });\r\n } catch (e) {\r\n console.error(e);\r\n }\r\n }\r\n }, []);\r\n\r\n const setRpcUrl = useCallback((url: string) => {\r\n setRpcUrlState(url);\r\n localStorage.setItem(LS_KEY_RPC_DEFAULT, url);\r\n }, []);\r\n\r\n const addRpcUrl = useCallback((network: Network, url: string) => {\r\n if (!url) return;\r\n\r\n setAllRpcUrls((prev) => {\r\n const newList = Array.from(new Set([...prev[network], url]));\r\n const newState = { ...prev, [network]: newList };\r\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\r\n return newState;\r\n });\r\n\r\n setRpcUrl(url);\r\n }, [setRpcUrl]);\r\n\r\n const removeRpcUrl = useCallback((network: Network, url: string) => {\r\n setAllRpcUrls((prev) => {\r\n let newList = prev[network].filter((rpc) => rpc !== url);\r\n\r\n if (newList.length === 0) {\r\n newList = [...DEFAULT_RPCS[network]];\r\n }\r\n\r\n const newState = { ...prev, [network]: newList };\r\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\r\n return newState;\r\n });\r\n }, [LS_KEY_RPC_LIST]);\r\n\r\n const value = useMemo<RpcContextType>(() => ({\r\n persistClusterSelection: persistClusterSelection,\r\n clusterStorageKey: LS_KEY_CLUSTER,\r\n maxRPCRetries: MAX_RPC_RETRIES,\r\n rpcUrl,\r\n setRpcUrl,\r\n allRpcUrls,\r\n addRpcUrl,\r\n removeRpcUrl\r\n }), [rpcUrl, allRpcUrls, setRpcUrl, addRpcUrl, removeRpcUrl]);\r\n\r\n\r\n return (\r\n <RpcContext.Provider value={value}>\r\n {children}\r\n </RpcContext.Provider>\r\n );\r\n}\r\n\r\nexport const useRpcProvider = () => {\r\n const context = useContext(RpcContext);\r\n if (!context) {\r\n throw new Error('useRpcProvider must be used within RpcProvider');\r\n }\r\n return context;\r\n};","'use client';\r\n\r\nimport type { ReactNode } from 'react';\r\nimport { useMemo } from 'react';\r\nimport { AppProvider, getDefaultConfig, getDefaultMobileConfig, Wallet, WalletDisplayConfig } from '@solana/connector/react';\r\nimport { Network } from '../types';\r\nimport { CoinGeckoConfig, SolanaCluster } from '@solana/connector';\r\nimport { useRpcProvider } from './RpcProvider';\r\n\r\ntype SolanaWalletProviderProps = {\r\n children: ReactNode;\r\n\r\n appName?: string;\r\n appUrl?: string;\r\n\r\n autoConnect?: boolean;\r\n enableMobile?: boolean;\r\n\r\n walletConnect?: boolean;\r\n additionalWallets?: Wallet[];\r\n coingecko?: CoinGeckoConfig;\r\n walletsDisplayConfig?: WalletDisplayConfig;\r\n};\r\n\r\nexport function SolanaWalletProvider(props: SolanaWalletProviderProps) {\r\n const {\r\n children,\r\n appName = \"Solana Kit\",\r\n appUrl,\r\n autoConnect = true,\r\n enableMobile = true,\r\n walletConnect = true,\r\n additionalWallets = [],\r\n coingecko,\r\n walletsDisplayConfig\r\n } = props;\r\n\r\n const {\r\n persistClusterSelection,\r\n clusterStorageKey,\r\n maxRPCRetries,\r\n rpcUrl, allRpcUrls\r\n } = useRpcProvider();\r\n\r\n const appOrigin = appUrl || (typeof window !== 'undefined' ? window.location.origin : '');\r\n\r\n const activeNetwork: Network = useMemo(() => {\r\n if (allRpcUrls.devnet.includes(rpcUrl)) return 'devnet';\r\n else if (allRpcUrls.testnet.includes(rpcUrl)) return 'testnet';\r\n else if (allRpcUrls.localnet.includes(rpcUrl)) return 'localnet';\r\n return 'mainnet';\r\n }, [rpcUrl, allRpcUrls]);\r\n\r\n const connectorConfig = useMemo(() => {\r\n\r\n const clusters: SolanaCluster[] = [\r\n {\r\n id: 'solana:mainnet',\r\n label: 'Mainnet',\r\n url: activeNetwork === 'mainnet' ? rpcUrl : allRpcUrls.mainnet[0],\r\n },\r\n {\r\n id: 'solana:localnet',\r\n label: 'Localnet',\r\n url: activeNetwork === 'localnet' ? rpcUrl : allRpcUrls.localnet[0],\r\n },\r\n {\r\n id: 'solana:devnet',\r\n label: 'Devnet',\r\n url: activeNetwork === 'devnet' ? rpcUrl : allRpcUrls.devnet[0],\r\n },\r\n {\r\n id: 'solana:testnet',\r\n label: 'Testnet',\r\n url: activeNetwork === 'testnet' ? rpcUrl : allRpcUrls.testnet[0],\r\n },\r\n ];\r\n\r\n return getDefaultConfig({\r\n appName: appName,\r\n appUrl: appOrigin,\r\n autoConnect: autoConnect,\r\n\r\n network: activeNetwork,\r\n enableMobile: enableMobile,\r\n\r\n // from RPC settings\r\n clusters,\r\n persistClusterSelection: persistClusterSelection,\r\n clusterStorageKey: clusterStorageKey,\r\n maxRetries: maxRPCRetries,\r\n\r\n walletConnect: walletConnect,\r\n additionalWallets: additionalWallets,\r\n coingecko: coingecko,\r\n wallets: walletsDisplayConfig\r\n\r\n });\r\n }, [appName, appOrigin, autoConnect, enableMobile, walletConnect, coingecko]);\r\n\r\n const mobile = useMemo(\r\n () =>\r\n getDefaultMobileConfig({\r\n appName: appName,\r\n appUrl: appOrigin,\r\n network: activeNetwork === 'localnet' ? 'devnet' : activeNetwork,\r\n }),\r\n [appName, appOrigin, activeNetwork],\r\n );\r\n\r\n\r\n return (\r\n <AppProvider connectorConfig={connectorConfig} mobile={mobile}>\r\n {children}\r\n </AppProvider>\r\n );\r\n}","\"use client\";\r\n\r\nimport { RpcMap } from \"../types\";\r\nimport { RpcProvider } from \"./RpcProvider\";\r\nimport { SolanaWalletProvider } from \"./SolanaWalletProvider\";\r\n\r\ntype SolanaWrapperProps = {\r\n children: React.ReactNode;\r\n\r\n /** * Name of your app (displayed in wallet connection modals) \r\n * @default \"Solana Kit\"\r\n */\r\n appName?: string;\r\n\r\n /** * URL of your app (used for deep linking) \r\n */\r\n appUrl?: string;\r\n\r\n /** * Automatically connect to the last used wallet on load.\r\n * @default true\r\n */\r\n autoConnect?: boolean;\r\n\r\n /** * Enable mobile wallets (e.g. Phantom on iOS/Android) \r\n * @default true\r\n */\r\n enableMobile?: boolean;\r\n\r\n /** * Enable WalletConnect support \r\n * @default true\r\n */\r\n walletConnect?: boolean;\r\n\r\n /** * List of default RPC endpoints mapped by network \r\n * @default DEFAULT_RPCS\r\n */\r\n defaultRpcList?: RpcMap;\r\n\r\n /** * The default RPC endpoint to use if none is selected \r\n * @default DEFAULT_RPCS.mainnet[0]\r\n */\r\n defaultRpcUrl?: string;\r\n\r\n /** * LocalStorage key for saving custom RPC list \r\n * @default 'all-rpc-urls'\r\n */\r\n LS_KEY_RPC_LIST?: string;\r\n\r\n /** * LocalStorage key for saving default RPC endpoint \r\n * @default 'curr-rpc'\r\n */\r\n LS_KEY_RPC_DEFAULT?: string;\r\n\r\n /** * LocalStorage key for saving selected cluster \r\n * @default 'solana-cluster'\r\n */\r\n LS_KEY_CLUSTER?: string;\r\n\r\n /** * Persist cluster selection in LocalStorage \r\n * @default true\r\n */\r\n persistClusterSelection?: boolean;\r\n\r\n /** * Maximum number of retries for RPC requests \r\n * @default 3\r\n */\r\n MAX_RPC_RETRIES?: number;\r\n}\r\n\r\nexport function SolanaWrapper(props: SolanaWrapperProps) {\r\n const {\r\n children,\r\n\r\n appName,\r\n appUrl,\r\n\r\n autoConnect,\r\n enableMobile,\r\n walletConnect,\r\n\r\n defaultRpcList,\r\n defaultRpcUrl,\r\n LS_KEY_RPC_LIST,\r\n LS_KEY_RPC_DEFAULT,\r\n LS_KEY_CLUSTER,\r\n persistClusterSelection,\r\n MAX_RPC_RETRIES,\r\n\r\n } = props\r\n\r\n\r\n const RPC_PROVIDER_PROPS = {\r\n defaultRpcList,\r\n defaultRpcUrl,\r\n LS_KEY_RPC_LIST,\r\n LS_KEY_RPC_DEFAULT,\r\n LS_KEY_CLUSTER,\r\n persistClusterSelection,\r\n MAX_RPC_RETRIES,\r\n\r\n }\r\n\r\n const solanaWalletProviderProps = {\r\n appName,\r\n appUrl,\r\n\r\n autoConnect,\r\n enableMobile,\r\n\r\n walletConnect,\r\n additionalWallets: [],\r\n coingecko: undefined,\r\n walletsDisplayConfig: undefined\r\n }\r\n\r\n return (\r\n <RpcProvider {...RPC_PROVIDER_PROPS}>\r\n <SolanaWalletProvider {...solanaWalletProviderProps}>\r\n {children}\r\n </SolanaWalletProvider>\r\n </RpcProvider>\r\n )\r\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,mBAQO;AAyHC;AArHR,IAAM,eAAuB;AAAA,EACzB,SAAS,CAAC,gCAAgC;AAAA,EAC1C,QAAQ,CAAC,+BAA+B;AAAA,EACxC,SAAS,CAAC,gCAAgC;AAAA,EAC1C,UAAU,CAAC,uBAAuB;AACtC;AAcA,IAAM,iBAAa,4BAAqC,IAAI;AAerD,SAAS,YAAY,OAAyB;AACjD,QAAM;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,IACjB,gBAAgB,aAAa,QAAQ,CAAC;AAAA,IACtC,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,IACjB,0BAA0B;AAAA,IAC1B,kBAAkB;AAAA,EACtB,IAAI;AAEJ,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAiB,cAAc;AACnE,QAAM,CAAC,QAAQ,cAAc,QAAI,uBAAiB,aAAa;AAE/D,8BAAU,MAAM;AACZ,UAAM,eAAe,aAAa,QAAQ,eAAe;AACzD,UAAM,WAAW,aAAa,QAAQ,kBAAkB;AAExD,QAAI,YAAY,aAAa,QAAQ;AACjC,qBAAe,QAAQ;AAAA,IAC3B;AAEA,QAAI,cAAc;AACd,UAAI;AACA,cAAM,SAAS,KAAK,MAAM,YAAY;AACtC,sBAAc;AAAA,UACV,SAAS,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,aAAa,SAAS,GAAI,OAAO,WAAW,CAAC,CAAE,CAAC,CAAC;AAAA,UACjF,QAAQ,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,aAAa,QAAQ,GAAI,OAAO,UAAU,CAAC,CAAE,CAAC,CAAC;AAAA,UAC9E,SAAS,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,aAAa,SAAS,GAAI,OAAO,WAAW,CAAC,CAAE,CAAC,CAAC;AAAA,UACjF,UAAU,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,aAAa,UAAU,GAAI,OAAO,YAAY,CAAC,CAAE,CAAC,CAAC;AAAA,QACxF,CAAC;AAAA,MACL,SAAS,GAAG;AACR,gBAAQ,MAAM,CAAC;AAAA,MACnB;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAY,0BAAY,CAAC,QAAgB;AAC3C,mBAAe,GAAG;AAClB,iBAAa,QAAQ,oBAAoB,GAAG;AAAA,EAChD,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAY,0BAAY,CAAC,SAAkB,QAAgB;AAC7D,QAAI,CAAC,IAAK;AAEV,kBAAc,CAAC,SAAS;AACpB,YAAM,UAAU,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,KAAK,OAAO,GAAG,GAAG,CAAC,CAAC;AAC3D,YAAM,WAAW,EAAE,GAAG,MAAM,CAAC,OAAO,GAAG,QAAQ;AAC/C,mBAAa,QAAQ,iBAAiB,KAAK,UAAU,QAAQ,CAAC;AAC9D,aAAO;AAAA,IACX,CAAC;AAED,cAAU,GAAG;AAAA,EACjB,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,mBAAe,0BAAY,CAAC,SAAkB,QAAgB;AAChE,kBAAc,CAAC,SAAS;AACpB,UAAI,UAAU,KAAK,OAAO,EAAE,OAAO,CAAC,QAAQ,QAAQ,GAAG;AAEvD,UAAI,QAAQ,WAAW,GAAG;AACtB,kBAAU,CAAC,GAAG,aAAa,OAAO,CAAC;AAAA,MACvC;AAEA,YAAM,WAAW,EAAE,GAAG,MAAM,CAAC,OAAO,GAAG,QAAQ;AAC/C,mBAAa,QAAQ,iBAAiB,KAAK,UAAU,QAAQ,CAAC;AAC9D,aAAO;AAAA,IACX,CAAC;AAAA,EACL,GAAG,CAAC,eAAe,CAAC;AAEpB,QAAM,YAAQ,sBAAwB,OAAO;AAAA,IACzC;AAAA,IACA,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ,IAAI,CAAC,QAAQ,YAAY,WAAW,WAAW,YAAY,CAAC;AAG5D,SACI,4CAAC,WAAW,UAAX,EAAoB,OAChB,UACL;AAER;AAEO,IAAM,iBAAiB,MAAM;AAChC,QAAM,cAAU,yBAAW,UAAU;AACrC,MAAI,CAAC,SAAS;AACV,UAAM,IAAI,MAAM,gDAAgD;AAAA,EACpE;AACA,SAAO;AACX;;;AC5IA,IAAAA,gBAAwB;AACxB,IAAAA,gBAAmG;AA4G3F,IAAAC,sBAAA;AAxFD,SAAS,qBAAqB,OAAkC;AACnE,QAAM;AAAA,IACF;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,cAAc;AAAA,IACd,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,oBAAoB,CAAC;AAAA,IACrB;AAAA,IACA;AAAA,EACJ,IAAI;AAEJ,QAAM;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAAQ;AAAA,EACZ,IAAI,eAAe;AAEnB,QAAM,YAAY,WAAW,OAAO,WAAW,cAAc,OAAO,SAAS,SAAS;AAEtF,QAAM,oBAAyB,uBAAQ,MAAM;AACzC,QAAI,WAAW,OAAO,SAAS,MAAM,EAAG,QAAO;AAAA,aACtC,WAAW,QAAQ,SAAS,MAAM,EAAG,QAAO;AAAA,aAC5C,WAAW,SAAS,SAAS,MAAM,EAAG,QAAO;AACtD,WAAO;AAAA,EACX,GAAG,CAAC,QAAQ,UAAU,CAAC;AAEvB,QAAM,sBAAkB,uBAAQ,MAAM;AAElC,UAAM,WAA4B;AAAA,MAC9B;AAAA,QACI,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK,kBAAkB,YAAY,SAAS,WAAW,QAAQ,CAAC;AAAA,MACpE;AAAA,MACA;AAAA,QACI,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK,kBAAkB,aAAa,SAAS,WAAW,SAAS,CAAC;AAAA,MACtE;AAAA,MACA;AAAA,QACI,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK,kBAAkB,WAAW,SAAS,WAAW,OAAO,CAAC;AAAA,MAClE;AAAA,MACA;AAAA,QACI,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK,kBAAkB,YAAY,SAAS,WAAW,QAAQ,CAAC;AAAA,MACpE;AAAA,IACJ;AAEA,eAAO,gCAAiB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MAEA,SAAS;AAAA,MACT;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MAEZ;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IAEb,CAAC;AAAA,EACL,GAAG,CAAC,SAAS,WAAW,aAAa,cAAc,eAAe,SAAS,CAAC;AAE5E,QAAM,aAAS;AAAA,IACX,UACI,sCAAuB;AAAA,MACnB;AAAA,MACA,QAAQ;AAAA,MACR,SAAS,kBAAkB,aAAa,WAAW;AAAA,IACvD,CAAC;AAAA,IACL,CAAC,SAAS,WAAW,aAAa;AAAA,EACtC;AAGA,SACI,6CAAC,6BAAY,iBAAkC,QAC1C,UACL;AAER;;;ACCY,IAAAC,sBAAA;AAhDL,SAAS,cAAc,OAA2B;AACrD,QAAM;AAAA,IACF;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAEJ,IAAI;AAGJ,QAAM,qBAAqB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAEJ;AAEA,QAAM,4BAA4B;AAAA,IAC9B;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA,mBAAmB,CAAC;AAAA,IACpB,WAAW;AAAA,IACX,sBAAsB;AAAA,EAC1B;AAEA,SACI,6CAAC,eAAa,GAAG,oBACb,uDAAC,wBAAsB,GAAG,2BACrB,UACL,GACJ;AAER;","names":["import_react","import_jsx_runtime","import_jsx_runtime"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,222 @@
1
+ "use client";
2
+
3
+ // src/providers/RpcProvider.tsx
4
+ import {
5
+ createContext,
6
+ useContext,
7
+ useEffect,
8
+ useState,
9
+ useCallback,
10
+ useMemo
11
+ } from "react";
12
+ import { jsx } from "react/jsx-runtime";
13
+ var DEFAULT_RPCS = {
14
+ mainnet: ["https://api.mainnet.solana.com"],
15
+ devnet: ["https://api.devnet.solana.com"],
16
+ testnet: ["https://api.testnet.solana.com"],
17
+ localnet: ["http://localhost:8899"]
18
+ };
19
+ var RpcContext = createContext(null);
20
+ function RpcProvider(props) {
21
+ const {
22
+ children,
23
+ defaultRpcList = DEFAULT_RPCS,
24
+ defaultRpcUrl = DEFAULT_RPCS.mainnet[0],
25
+ LS_KEY_RPC_LIST = "all-rpc-urls",
26
+ LS_KEY_RPC_DEFAULT = "curr-rpc",
27
+ LS_KEY_CLUSTER = "solana-cluster",
28
+ persistClusterSelection = true,
29
+ MAX_RPC_RETRIES = 3
30
+ } = props;
31
+ const [allRpcUrls, setAllRpcUrls] = useState(defaultRpcList);
32
+ const [rpcUrl, setRpcUrlState] = useState(defaultRpcUrl);
33
+ useEffect(() => {
34
+ const savedHistory = localStorage.getItem(LS_KEY_RPC_LIST);
35
+ const savedRpc = localStorage.getItem(LS_KEY_RPC_DEFAULT);
36
+ if (savedRpc && savedRpc !== rpcUrl) {
37
+ setRpcUrlState(savedRpc);
38
+ }
39
+ if (savedHistory) {
40
+ try {
41
+ const parsed = JSON.parse(savedHistory);
42
+ setAllRpcUrls({
43
+ mainnet: Array.from(/* @__PURE__ */ new Set([...DEFAULT_RPCS.mainnet, ...parsed.mainnet || []])),
44
+ devnet: Array.from(/* @__PURE__ */ new Set([...DEFAULT_RPCS.devnet, ...parsed.devnet || []])),
45
+ testnet: Array.from(/* @__PURE__ */ new Set([...DEFAULT_RPCS.testnet, ...parsed.testnet || []])),
46
+ localnet: Array.from(/* @__PURE__ */ new Set([...DEFAULT_RPCS.localnet, ...parsed.localnet || []]))
47
+ });
48
+ } catch (e) {
49
+ console.error(e);
50
+ }
51
+ }
52
+ }, []);
53
+ const setRpcUrl = useCallback((url) => {
54
+ setRpcUrlState(url);
55
+ localStorage.setItem(LS_KEY_RPC_DEFAULT, url);
56
+ }, []);
57
+ const addRpcUrl = useCallback((network, url) => {
58
+ if (!url) return;
59
+ setAllRpcUrls((prev) => {
60
+ const newList = Array.from(/* @__PURE__ */ new Set([...prev[network], url]));
61
+ const newState = { ...prev, [network]: newList };
62
+ localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));
63
+ return newState;
64
+ });
65
+ setRpcUrl(url);
66
+ }, [setRpcUrl]);
67
+ const removeRpcUrl = useCallback((network, url) => {
68
+ setAllRpcUrls((prev) => {
69
+ let newList = prev[network].filter((rpc) => rpc !== url);
70
+ if (newList.length === 0) {
71
+ newList = [...DEFAULT_RPCS[network]];
72
+ }
73
+ const newState = { ...prev, [network]: newList };
74
+ localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));
75
+ return newState;
76
+ });
77
+ }, [LS_KEY_RPC_LIST]);
78
+ const value = useMemo(() => ({
79
+ persistClusterSelection,
80
+ clusterStorageKey: LS_KEY_CLUSTER,
81
+ maxRPCRetries: MAX_RPC_RETRIES,
82
+ rpcUrl,
83
+ setRpcUrl,
84
+ allRpcUrls,
85
+ addRpcUrl,
86
+ removeRpcUrl
87
+ }), [rpcUrl, allRpcUrls, setRpcUrl, addRpcUrl, removeRpcUrl]);
88
+ return /* @__PURE__ */ jsx(RpcContext.Provider, { value, children });
89
+ }
90
+ var useRpcProvider = () => {
91
+ const context = useContext(RpcContext);
92
+ if (!context) {
93
+ throw new Error("useRpcProvider must be used within RpcProvider");
94
+ }
95
+ return context;
96
+ };
97
+
98
+ // src/providers/SolanaWalletProvider.tsx
99
+ import { useMemo as useMemo2 } from "react";
100
+ import { AppProvider, getDefaultConfig, getDefaultMobileConfig } from "@solana/connector/react";
101
+ import { jsx as jsx2 } from "react/jsx-runtime";
102
+ function SolanaWalletProvider(props) {
103
+ const {
104
+ children,
105
+ appName = "Solana Kit",
106
+ appUrl,
107
+ autoConnect = true,
108
+ enableMobile = true,
109
+ walletConnect = true,
110
+ additionalWallets = [],
111
+ coingecko,
112
+ walletsDisplayConfig
113
+ } = props;
114
+ const {
115
+ persistClusterSelection,
116
+ clusterStorageKey,
117
+ maxRPCRetries,
118
+ rpcUrl,
119
+ allRpcUrls
120
+ } = useRpcProvider();
121
+ const appOrigin = appUrl || (typeof window !== "undefined" ? window.location.origin : "");
122
+ const activeNetwork = useMemo2(() => {
123
+ if (allRpcUrls.devnet.includes(rpcUrl)) return "devnet";
124
+ else if (allRpcUrls.testnet.includes(rpcUrl)) return "testnet";
125
+ else if (allRpcUrls.localnet.includes(rpcUrl)) return "localnet";
126
+ return "mainnet";
127
+ }, [rpcUrl, allRpcUrls]);
128
+ const connectorConfig = useMemo2(() => {
129
+ const clusters = [
130
+ {
131
+ id: "solana:mainnet",
132
+ label: "Mainnet",
133
+ url: activeNetwork === "mainnet" ? rpcUrl : allRpcUrls.mainnet[0]
134
+ },
135
+ {
136
+ id: "solana:localnet",
137
+ label: "Localnet",
138
+ url: activeNetwork === "localnet" ? rpcUrl : allRpcUrls.localnet[0]
139
+ },
140
+ {
141
+ id: "solana:devnet",
142
+ label: "Devnet",
143
+ url: activeNetwork === "devnet" ? rpcUrl : allRpcUrls.devnet[0]
144
+ },
145
+ {
146
+ id: "solana:testnet",
147
+ label: "Testnet",
148
+ url: activeNetwork === "testnet" ? rpcUrl : allRpcUrls.testnet[0]
149
+ }
150
+ ];
151
+ return getDefaultConfig({
152
+ appName,
153
+ appUrl: appOrigin,
154
+ autoConnect,
155
+ network: activeNetwork,
156
+ enableMobile,
157
+ // from RPC settings
158
+ clusters,
159
+ persistClusterSelection,
160
+ clusterStorageKey,
161
+ maxRetries: maxRPCRetries,
162
+ walletConnect,
163
+ additionalWallets,
164
+ coingecko,
165
+ wallets: walletsDisplayConfig
166
+ });
167
+ }, [appName, appOrigin, autoConnect, enableMobile, walletConnect, coingecko]);
168
+ const mobile = useMemo2(
169
+ () => getDefaultMobileConfig({
170
+ appName,
171
+ appUrl: appOrigin,
172
+ network: activeNetwork === "localnet" ? "devnet" : activeNetwork
173
+ }),
174
+ [appName, appOrigin, activeNetwork]
175
+ );
176
+ return /* @__PURE__ */ jsx2(AppProvider, { connectorConfig, mobile, children });
177
+ }
178
+
179
+ // src/providers/SolanaWrapper.tsx
180
+ import { jsx as jsx3 } from "react/jsx-runtime";
181
+ function SolanaWrapper(props) {
182
+ const {
183
+ children,
184
+ appName,
185
+ appUrl,
186
+ autoConnect,
187
+ enableMobile,
188
+ walletConnect,
189
+ defaultRpcList,
190
+ defaultRpcUrl,
191
+ LS_KEY_RPC_LIST,
192
+ LS_KEY_RPC_DEFAULT,
193
+ LS_KEY_CLUSTER,
194
+ persistClusterSelection,
195
+ MAX_RPC_RETRIES
196
+ } = props;
197
+ const RPC_PROVIDER_PROPS = {
198
+ defaultRpcList,
199
+ defaultRpcUrl,
200
+ LS_KEY_RPC_LIST,
201
+ LS_KEY_RPC_DEFAULT,
202
+ LS_KEY_CLUSTER,
203
+ persistClusterSelection,
204
+ MAX_RPC_RETRIES
205
+ };
206
+ const solanaWalletProviderProps = {
207
+ appName,
208
+ appUrl,
209
+ autoConnect,
210
+ enableMobile,
211
+ walletConnect,
212
+ additionalWallets: [],
213
+ coingecko: void 0,
214
+ walletsDisplayConfig: void 0
215
+ };
216
+ return /* @__PURE__ */ jsx3(RpcProvider, { ...RPC_PROVIDER_PROPS, children: /* @__PURE__ */ jsx3(SolanaWalletProvider, { ...solanaWalletProviderProps, children }) });
217
+ }
218
+ export {
219
+ SolanaWrapper,
220
+ useRpcProvider
221
+ };
222
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/providers/RpcProvider.tsx","../src/providers/SolanaWalletProvider.tsx","../src/providers/SolanaWrapper.tsx"],"sourcesContent":["'use client';\r\n\r\nimport {\r\n createContext,\r\n useContext,\r\n useEffect,\r\n useState,\r\n useCallback,\r\n useMemo,\r\n type ReactNode\r\n} from 'react';\r\nimport { Network, RpcMap } from '../types';\r\n\r\n\r\nconst DEFAULT_RPCS: RpcMap = {\r\n mainnet: ['https://api.mainnet.solana.com'],\r\n devnet: ['https://api.devnet.solana.com'],\r\n testnet: ['https://api.testnet.solana.com'],\r\n localnet: ['http://localhost:8899'],\r\n};\r\n\r\ninterface RpcContextType {\r\n rpcUrl: string;\r\n setRpcUrl: (url: string) => void;\r\n\r\n persistClusterSelection: boolean;\r\n clusterStorageKey: string;\r\n maxRPCRetries: number;\r\n\r\n allRpcUrls: RpcMap;\r\n addRpcUrl: (network: Network, url: string) => void;\r\n removeRpcUrl: (network: Network, url: string) => void;\r\n}\r\nconst RpcContext = createContext<RpcContextType | null>(null);\r\n\r\n\r\ntype RpcProviderProps = {\r\n children: ReactNode;\r\n\r\n defaultRpcList?: RpcMap;\r\n defaultRpcUrl?: string;\r\n\r\n LS_KEY_RPC_LIST?: string;\r\n LS_KEY_RPC_DEFAULT?: string;\r\n LS_KEY_CLUSTER?: string;\r\n persistClusterSelection?: boolean;\r\n MAX_RPC_RETRIES?: number;\r\n};\r\nexport function RpcProvider(props: RpcProviderProps) {\r\n const {\r\n children,\r\n defaultRpcList = DEFAULT_RPCS,\r\n defaultRpcUrl = DEFAULT_RPCS.mainnet[0],\r\n LS_KEY_RPC_LIST = 'all-rpc-urls',\r\n LS_KEY_RPC_DEFAULT = 'curr-rpc',\r\n LS_KEY_CLUSTER = 'solana-cluster',\r\n persistClusterSelection = true,\r\n MAX_RPC_RETRIES = 3,\r\n } = props;\r\n\r\n const [allRpcUrls, setAllRpcUrls] = useState<RpcMap>(defaultRpcList);\r\n const [rpcUrl, setRpcUrlState] = useState<string>(defaultRpcUrl);\r\n\r\n useEffect(() => {\r\n const savedHistory = localStorage.getItem(LS_KEY_RPC_LIST);\r\n const savedRpc = localStorage.getItem(LS_KEY_RPC_DEFAULT);\r\n\r\n if (savedRpc && savedRpc !== rpcUrl) {\r\n setRpcUrlState(savedRpc);\r\n }\r\n\r\n if (savedHistory) {\r\n try {\r\n const parsed = JSON.parse(savedHistory) as RpcMap;\r\n setAllRpcUrls({\r\n mainnet: Array.from(new Set([...DEFAULT_RPCS.mainnet, ...(parsed.mainnet || [])])),\r\n devnet: Array.from(new Set([...DEFAULT_RPCS.devnet, ...(parsed.devnet || [])])),\r\n testnet: Array.from(new Set([...DEFAULT_RPCS.testnet, ...(parsed.testnet || [])])),\r\n localnet: Array.from(new Set([...DEFAULT_RPCS.localnet, ...(parsed.localnet || [])])),\r\n });\r\n } catch (e) {\r\n console.error(e);\r\n }\r\n }\r\n }, []);\r\n\r\n const setRpcUrl = useCallback((url: string) => {\r\n setRpcUrlState(url);\r\n localStorage.setItem(LS_KEY_RPC_DEFAULT, url);\r\n }, []);\r\n\r\n const addRpcUrl = useCallback((network: Network, url: string) => {\r\n if (!url) return;\r\n\r\n setAllRpcUrls((prev) => {\r\n const newList = Array.from(new Set([...prev[network], url]));\r\n const newState = { ...prev, [network]: newList };\r\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\r\n return newState;\r\n });\r\n\r\n setRpcUrl(url);\r\n }, [setRpcUrl]);\r\n\r\n const removeRpcUrl = useCallback((network: Network, url: string) => {\r\n setAllRpcUrls((prev) => {\r\n let newList = prev[network].filter((rpc) => rpc !== url);\r\n\r\n if (newList.length === 0) {\r\n newList = [...DEFAULT_RPCS[network]];\r\n }\r\n\r\n const newState = { ...prev, [network]: newList };\r\n localStorage.setItem(LS_KEY_RPC_LIST, JSON.stringify(newState));\r\n return newState;\r\n });\r\n }, [LS_KEY_RPC_LIST]);\r\n\r\n const value = useMemo<RpcContextType>(() => ({\r\n persistClusterSelection: persistClusterSelection,\r\n clusterStorageKey: LS_KEY_CLUSTER,\r\n maxRPCRetries: MAX_RPC_RETRIES,\r\n rpcUrl,\r\n setRpcUrl,\r\n allRpcUrls,\r\n addRpcUrl,\r\n removeRpcUrl\r\n }), [rpcUrl, allRpcUrls, setRpcUrl, addRpcUrl, removeRpcUrl]);\r\n\r\n\r\n return (\r\n <RpcContext.Provider value={value}>\r\n {children}\r\n </RpcContext.Provider>\r\n );\r\n}\r\n\r\nexport const useRpcProvider = () => {\r\n const context = useContext(RpcContext);\r\n if (!context) {\r\n throw new Error('useRpcProvider must be used within RpcProvider');\r\n }\r\n return context;\r\n};","'use client';\r\n\r\nimport type { ReactNode } from 'react';\r\nimport { useMemo } from 'react';\r\nimport { AppProvider, getDefaultConfig, getDefaultMobileConfig, Wallet, WalletDisplayConfig } from '@solana/connector/react';\r\nimport { Network } from '../types';\r\nimport { CoinGeckoConfig, SolanaCluster } from '@solana/connector';\r\nimport { useRpcProvider } from './RpcProvider';\r\n\r\ntype SolanaWalletProviderProps = {\r\n children: ReactNode;\r\n\r\n appName?: string;\r\n appUrl?: string;\r\n\r\n autoConnect?: boolean;\r\n enableMobile?: boolean;\r\n\r\n walletConnect?: boolean;\r\n additionalWallets?: Wallet[];\r\n coingecko?: CoinGeckoConfig;\r\n walletsDisplayConfig?: WalletDisplayConfig;\r\n};\r\n\r\nexport function SolanaWalletProvider(props: SolanaWalletProviderProps) {\r\n const {\r\n children,\r\n appName = \"Solana Kit\",\r\n appUrl,\r\n autoConnect = true,\r\n enableMobile = true,\r\n walletConnect = true,\r\n additionalWallets = [],\r\n coingecko,\r\n walletsDisplayConfig\r\n } = props;\r\n\r\n const {\r\n persistClusterSelection,\r\n clusterStorageKey,\r\n maxRPCRetries,\r\n rpcUrl, allRpcUrls\r\n } = useRpcProvider();\r\n\r\n const appOrigin = appUrl || (typeof window !== 'undefined' ? window.location.origin : '');\r\n\r\n const activeNetwork: Network = useMemo(() => {\r\n if (allRpcUrls.devnet.includes(rpcUrl)) return 'devnet';\r\n else if (allRpcUrls.testnet.includes(rpcUrl)) return 'testnet';\r\n else if (allRpcUrls.localnet.includes(rpcUrl)) return 'localnet';\r\n return 'mainnet';\r\n }, [rpcUrl, allRpcUrls]);\r\n\r\n const connectorConfig = useMemo(() => {\r\n\r\n const clusters: SolanaCluster[] = [\r\n {\r\n id: 'solana:mainnet',\r\n label: 'Mainnet',\r\n url: activeNetwork === 'mainnet' ? rpcUrl : allRpcUrls.mainnet[0],\r\n },\r\n {\r\n id: 'solana:localnet',\r\n label: 'Localnet',\r\n url: activeNetwork === 'localnet' ? rpcUrl : allRpcUrls.localnet[0],\r\n },\r\n {\r\n id: 'solana:devnet',\r\n label: 'Devnet',\r\n url: activeNetwork === 'devnet' ? rpcUrl : allRpcUrls.devnet[0],\r\n },\r\n {\r\n id: 'solana:testnet',\r\n label: 'Testnet',\r\n url: activeNetwork === 'testnet' ? rpcUrl : allRpcUrls.testnet[0],\r\n },\r\n ];\r\n\r\n return getDefaultConfig({\r\n appName: appName,\r\n appUrl: appOrigin,\r\n autoConnect: autoConnect,\r\n\r\n network: activeNetwork,\r\n enableMobile: enableMobile,\r\n\r\n // from RPC settings\r\n clusters,\r\n persistClusterSelection: persistClusterSelection,\r\n clusterStorageKey: clusterStorageKey,\r\n maxRetries: maxRPCRetries,\r\n\r\n walletConnect: walletConnect,\r\n additionalWallets: additionalWallets,\r\n coingecko: coingecko,\r\n wallets: walletsDisplayConfig\r\n\r\n });\r\n }, [appName, appOrigin, autoConnect, enableMobile, walletConnect, coingecko]);\r\n\r\n const mobile = useMemo(\r\n () =>\r\n getDefaultMobileConfig({\r\n appName: appName,\r\n appUrl: appOrigin,\r\n network: activeNetwork === 'localnet' ? 'devnet' : activeNetwork,\r\n }),\r\n [appName, appOrigin, activeNetwork],\r\n );\r\n\r\n\r\n return (\r\n <AppProvider connectorConfig={connectorConfig} mobile={mobile}>\r\n {children}\r\n </AppProvider>\r\n );\r\n}","\"use client\";\r\n\r\nimport { RpcMap } from \"../types\";\r\nimport { RpcProvider } from \"./RpcProvider\";\r\nimport { SolanaWalletProvider } from \"./SolanaWalletProvider\";\r\n\r\ntype SolanaWrapperProps = {\r\n children: React.ReactNode;\r\n\r\n /** * Name of your app (displayed in wallet connection modals) \r\n * @default \"Solana Kit\"\r\n */\r\n appName?: string;\r\n\r\n /** * URL of your app (used for deep linking) \r\n */\r\n appUrl?: string;\r\n\r\n /** * Automatically connect to the last used wallet on load.\r\n * @default true\r\n */\r\n autoConnect?: boolean;\r\n\r\n /** * Enable mobile wallets (e.g. Phantom on iOS/Android) \r\n * @default true\r\n */\r\n enableMobile?: boolean;\r\n\r\n /** * Enable WalletConnect support \r\n * @default true\r\n */\r\n walletConnect?: boolean;\r\n\r\n /** * List of default RPC endpoints mapped by network \r\n * @default DEFAULT_RPCS\r\n */\r\n defaultRpcList?: RpcMap;\r\n\r\n /** * The default RPC endpoint to use if none is selected \r\n * @default DEFAULT_RPCS.mainnet[0]\r\n */\r\n defaultRpcUrl?: string;\r\n\r\n /** * LocalStorage key for saving custom RPC list \r\n * @default 'all-rpc-urls'\r\n */\r\n LS_KEY_RPC_LIST?: string;\r\n\r\n /** * LocalStorage key for saving default RPC endpoint \r\n * @default 'curr-rpc'\r\n */\r\n LS_KEY_RPC_DEFAULT?: string;\r\n\r\n /** * LocalStorage key for saving selected cluster \r\n * @default 'solana-cluster'\r\n */\r\n LS_KEY_CLUSTER?: string;\r\n\r\n /** * Persist cluster selection in LocalStorage \r\n * @default true\r\n */\r\n persistClusterSelection?: boolean;\r\n\r\n /** * Maximum number of retries for RPC requests \r\n * @default 3\r\n */\r\n MAX_RPC_RETRIES?: number;\r\n}\r\n\r\nexport function SolanaWrapper(props: SolanaWrapperProps) {\r\n const {\r\n children,\r\n\r\n appName,\r\n appUrl,\r\n\r\n autoConnect,\r\n enableMobile,\r\n walletConnect,\r\n\r\n defaultRpcList,\r\n defaultRpcUrl,\r\n LS_KEY_RPC_LIST,\r\n LS_KEY_RPC_DEFAULT,\r\n LS_KEY_CLUSTER,\r\n persistClusterSelection,\r\n MAX_RPC_RETRIES,\r\n\r\n } = props\r\n\r\n\r\n const RPC_PROVIDER_PROPS = {\r\n defaultRpcList,\r\n defaultRpcUrl,\r\n LS_KEY_RPC_LIST,\r\n LS_KEY_RPC_DEFAULT,\r\n LS_KEY_CLUSTER,\r\n persistClusterSelection,\r\n MAX_RPC_RETRIES,\r\n\r\n }\r\n\r\n const solanaWalletProviderProps = {\r\n appName,\r\n appUrl,\r\n\r\n autoConnect,\r\n enableMobile,\r\n\r\n walletConnect,\r\n additionalWallets: [],\r\n coingecko: undefined,\r\n walletsDisplayConfig: undefined\r\n }\r\n\r\n return (\r\n <RpcProvider {...RPC_PROVIDER_PROPS}>\r\n <SolanaWalletProvider {...solanaWalletProviderProps}>\r\n {children}\r\n </SolanaWalletProvider>\r\n </RpcProvider>\r\n )\r\n}"],"mappings":";;;AAEA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEG;AAyHC;AArHR,IAAM,eAAuB;AAAA,EACzB,SAAS,CAAC,gCAAgC;AAAA,EAC1C,QAAQ,CAAC,+BAA+B;AAAA,EACxC,SAAS,CAAC,gCAAgC;AAAA,EAC1C,UAAU,CAAC,uBAAuB;AACtC;AAcA,IAAM,aAAa,cAAqC,IAAI;AAerD,SAAS,YAAY,OAAyB;AACjD,QAAM;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,IACjB,gBAAgB,aAAa,QAAQ,CAAC;AAAA,IACtC,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,IACjB,0BAA0B;AAAA,IAC1B,kBAAkB;AAAA,EACtB,IAAI;AAEJ,QAAM,CAAC,YAAY,aAAa,IAAI,SAAiB,cAAc;AACnE,QAAM,CAAC,QAAQ,cAAc,IAAI,SAAiB,aAAa;AAE/D,YAAU,MAAM;AACZ,UAAM,eAAe,aAAa,QAAQ,eAAe;AACzD,UAAM,WAAW,aAAa,QAAQ,kBAAkB;AAExD,QAAI,YAAY,aAAa,QAAQ;AACjC,qBAAe,QAAQ;AAAA,IAC3B;AAEA,QAAI,cAAc;AACd,UAAI;AACA,cAAM,SAAS,KAAK,MAAM,YAAY;AACtC,sBAAc;AAAA,UACV,SAAS,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,aAAa,SAAS,GAAI,OAAO,WAAW,CAAC,CAAE,CAAC,CAAC;AAAA,UACjF,QAAQ,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,aAAa,QAAQ,GAAI,OAAO,UAAU,CAAC,CAAE,CAAC,CAAC;AAAA,UAC9E,SAAS,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,aAAa,SAAS,GAAI,OAAO,WAAW,CAAC,CAAE,CAAC,CAAC;AAAA,UACjF,UAAU,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,aAAa,UAAU,GAAI,OAAO,YAAY,CAAC,CAAE,CAAC,CAAC;AAAA,QACxF,CAAC;AAAA,MACL,SAAS,GAAG;AACR,gBAAQ,MAAM,CAAC;AAAA,MACnB;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,QAAM,YAAY,YAAY,CAAC,QAAgB;AAC3C,mBAAe,GAAG;AAClB,iBAAa,QAAQ,oBAAoB,GAAG;AAAA,EAChD,GAAG,CAAC,CAAC;AAEL,QAAM,YAAY,YAAY,CAAC,SAAkB,QAAgB;AAC7D,QAAI,CAAC,IAAK;AAEV,kBAAc,CAAC,SAAS;AACpB,YAAM,UAAU,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,KAAK,OAAO,GAAG,GAAG,CAAC,CAAC;AAC3D,YAAM,WAAW,EAAE,GAAG,MAAM,CAAC,OAAO,GAAG,QAAQ;AAC/C,mBAAa,QAAQ,iBAAiB,KAAK,UAAU,QAAQ,CAAC;AAC9D,aAAO;AAAA,IACX,CAAC;AAED,cAAU,GAAG;AAAA,EACjB,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,eAAe,YAAY,CAAC,SAAkB,QAAgB;AAChE,kBAAc,CAAC,SAAS;AACpB,UAAI,UAAU,KAAK,OAAO,EAAE,OAAO,CAAC,QAAQ,QAAQ,GAAG;AAEvD,UAAI,QAAQ,WAAW,GAAG;AACtB,kBAAU,CAAC,GAAG,aAAa,OAAO,CAAC;AAAA,MACvC;AAEA,YAAM,WAAW,EAAE,GAAG,MAAM,CAAC,OAAO,GAAG,QAAQ;AAC/C,mBAAa,QAAQ,iBAAiB,KAAK,UAAU,QAAQ,CAAC;AAC9D,aAAO;AAAA,IACX,CAAC;AAAA,EACL,GAAG,CAAC,eAAe,CAAC;AAEpB,QAAM,QAAQ,QAAwB,OAAO;AAAA,IACzC;AAAA,IACA,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ,IAAI,CAAC,QAAQ,YAAY,WAAW,WAAW,YAAY,CAAC;AAG5D,SACI,oBAAC,WAAW,UAAX,EAAoB,OAChB,UACL;AAER;AAEO,IAAM,iBAAiB,MAAM;AAChC,QAAM,UAAU,WAAW,UAAU;AACrC,MAAI,CAAC,SAAS;AACV,UAAM,IAAI,MAAM,gDAAgD;AAAA,EACpE;AACA,SAAO;AACX;;;AC5IA,SAAS,WAAAA,gBAAe;AACxB,SAAS,aAAa,kBAAkB,8BAA2D;AA4G3F,gBAAAC,YAAA;AAxFD,SAAS,qBAAqB,OAAkC;AACnE,QAAM;AAAA,IACF;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,cAAc;AAAA,IACd,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,oBAAoB,CAAC;AAAA,IACrB;AAAA,IACA;AAAA,EACJ,IAAI;AAEJ,QAAM;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAAQ;AAAA,EACZ,IAAI,eAAe;AAEnB,QAAM,YAAY,WAAW,OAAO,WAAW,cAAc,OAAO,SAAS,SAAS;AAEtF,QAAM,gBAAyBC,SAAQ,MAAM;AACzC,QAAI,WAAW,OAAO,SAAS,MAAM,EAAG,QAAO;AAAA,aACtC,WAAW,QAAQ,SAAS,MAAM,EAAG,QAAO;AAAA,aAC5C,WAAW,SAAS,SAAS,MAAM,EAAG,QAAO;AACtD,WAAO;AAAA,EACX,GAAG,CAAC,QAAQ,UAAU,CAAC;AAEvB,QAAM,kBAAkBA,SAAQ,MAAM;AAElC,UAAM,WAA4B;AAAA,MAC9B;AAAA,QACI,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK,kBAAkB,YAAY,SAAS,WAAW,QAAQ,CAAC;AAAA,MACpE;AAAA,MACA;AAAA,QACI,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK,kBAAkB,aAAa,SAAS,WAAW,SAAS,CAAC;AAAA,MACtE;AAAA,MACA;AAAA,QACI,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK,kBAAkB,WAAW,SAAS,WAAW,OAAO,CAAC;AAAA,MAClE;AAAA,MACA;AAAA,QACI,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK,kBAAkB,YAAY,SAAS,WAAW,QAAQ,CAAC;AAAA,MACpE;AAAA,IACJ;AAEA,WAAO,iBAAiB;AAAA,MACpB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MAEA,SAAS;AAAA,MACT;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MAEZ;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IAEb,CAAC;AAAA,EACL,GAAG,CAAC,SAAS,WAAW,aAAa,cAAc,eAAe,SAAS,CAAC;AAE5E,QAAM,SAASA;AAAA,IACX,MACI,uBAAuB;AAAA,MACnB;AAAA,MACA,QAAQ;AAAA,MACR,SAAS,kBAAkB,aAAa,WAAW;AAAA,IACvD,CAAC;AAAA,IACL,CAAC,SAAS,WAAW,aAAa;AAAA,EACtC;AAGA,SACI,gBAAAD,KAAC,eAAY,iBAAkC,QAC1C,UACL;AAER;;;ACCY,gBAAAE,YAAA;AAhDL,SAAS,cAAc,OAA2B;AACrD,QAAM;AAAA,IACF;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAEJ,IAAI;AAGJ,QAAM,qBAAqB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAEJ;AAEA,QAAM,4BAA4B;AAAA,IAC9B;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA,mBAAmB,CAAC;AAAA,IACpB,WAAW;AAAA,IACX,sBAAsB;AAAA,EAC1B;AAEA,SACI,gBAAAA,KAAC,eAAa,GAAG,oBACb,0BAAAA,KAAC,wBAAsB,GAAG,2BACrB,UACL,GACJ;AAER;","names":["useMemo","jsx","useMemo","jsx"]}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@algobright/solana-connector-kit",
3
+ "version": "1.0.0",
4
+ "description": "AlgoBright Solana Wallet Connector",
5
+ "license": "Apache-2.0",
6
+ "author": "AlgoBright Tech Private Limited",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/algobright/solana-connector-kit.git"
10
+ },
11
+ "sideEffects": false,
12
+ "main": "./dist/index.js",
13
+ "module": "./dist/index.mjs",
14
+ "types": "./dist/index.d.ts",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.mjs",
22
+ "require": "./dist/index.js"
23
+ },
24
+ "./ConnectButton": {
25
+ "types": "./dist/ConnectButton.d.ts",
26
+ "import": "./dist/ConnectButton.mjs",
27
+ "require": "./dist/ConnectButton.js"
28
+ },
29
+ "./WalletModal": {
30
+ "types": "./dist/WalletModal.d.ts",
31
+ "import": "./dist/WalletModal.mjs",
32
+ "require": "./dist/WalletModal.js"
33
+ }
34
+ },
35
+ "scripts": {
36
+ "build": "tsup --clean",
37
+ "dev": "tsup --watch --clean --onSuccess \"yalc push\"",
38
+ "local:refresh": "npm run build && yalc publish --push",
39
+ "prepublishOnly": "npm run build"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public",
43
+ "registry": "https://registry.npmjs.org/"
44
+ },
45
+ "dependencies": {
46
+ "@base-ui/react": "^1.1.0",
47
+ "@solana/kit": "^5.4.0",
48
+ "@types/qrcode": "^1.5.6",
49
+ "clsx": "^2.1.1",
50
+ "esbuild-css-modules-plugin": "^3.1.5",
51
+ "lucide-react": "^0.563.0",
52
+ "motion": "^12.29.0",
53
+ "qrcode": "^1.5.4",
54
+ "react-icons": "^5.5.0"
55
+ },
56
+ "peerDependencies": {
57
+ "react": ">=18.0.0",
58
+ "react-dom": ">=18.0.0"
59
+ },
60
+ "devDependencies": {
61
+ "@solana/connector": "^0.2.3",
62
+ "@types/react": "^19.0.0",
63
+ "@types/react-dom": "^19.0.0",
64
+ "postcss": "^8.5.6",
65
+ "react": "^19.0.0",
66
+ "react-dom": "^19.0.0",
67
+ "tsup": "^8.5.1",
68
+ "typescript": "^5.9.3"
69
+ }
70
+ }