@solana/connector 0.1.0 → 0.1.2

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 (41) hide show
  1. package/dist/{chunk-52WUWW5R.mjs → chunk-4K6QY4HR.mjs} +60 -174
  2. package/dist/chunk-4K6QY4HR.mjs.map +1 -0
  3. package/dist/{chunk-7TADXRFD.mjs → chunk-F2QJH5ED.mjs} +3 -3
  4. package/dist/chunk-F2QJH5ED.mjs.map +1 -0
  5. package/dist/chunk-JS4KJ2KK.js +706 -0
  6. package/dist/chunk-JS4KJ2KK.js.map +1 -0
  7. package/dist/{chunk-ZLPQUOFK.js → chunk-RIBOPAOD.js} +61 -173
  8. package/dist/chunk-RIBOPAOD.js.map +1 -0
  9. package/dist/{chunk-SGAIPK7Q.js → chunk-SJEZHNYF.js} +11 -11
  10. package/dist/chunk-SJEZHNYF.js.map +1 -0
  11. package/dist/chunk-WXYUUCSD.mjs +635 -0
  12. package/dist/chunk-WXYUUCSD.mjs.map +1 -0
  13. package/dist/compat.d.mts +1 -60
  14. package/dist/compat.d.ts +1 -60
  15. package/dist/compat.js.map +1 -1
  16. package/dist/compat.mjs.map +1 -1
  17. package/dist/headless.d.mts +222 -107
  18. package/dist/headless.d.ts +222 -107
  19. package/dist/headless.js +201 -81
  20. package/dist/headless.mjs +2 -2
  21. package/dist/index.d.mts +7 -3
  22. package/dist/index.d.ts +7 -3
  23. package/dist/index.js +216 -96
  24. package/dist/index.mjs +3 -3
  25. package/dist/react.d.mts +5 -154
  26. package/dist/react.d.ts +5 -154
  27. package/dist/react.js +16 -16
  28. package/dist/react.mjs +2 -2
  29. package/dist/{transaction-signer-BtJPGXIg.d.ts → transaction-signer-D3csM_Mf.d.mts} +1 -175
  30. package/dist/{transaction-signer-BtJPGXIg.d.mts → transaction-signer-D3csM_Mf.d.ts} +1 -175
  31. package/dist/{wallet-standard-shim-BGlvGRbB.d.ts → wallet-standard-shim-C1tisl9S.d.ts} +5 -169
  32. package/dist/{wallet-standard-shim-Af7ejSld.d.mts → wallet-standard-shim-Cg0GVGwu.d.mts} +5 -169
  33. package/package.json +7 -1
  34. package/dist/chunk-52WUWW5R.mjs.map +0 -1
  35. package/dist/chunk-5NSUFMCB.js +0 -393
  36. package/dist/chunk-5NSUFMCB.js.map +0 -1
  37. package/dist/chunk-7TADXRFD.mjs.map +0 -1
  38. package/dist/chunk-ACFSCMUI.mjs +0 -359
  39. package/dist/chunk-ACFSCMUI.mjs.map +0 -1
  40. package/dist/chunk-SGAIPK7Q.js.map +0 -1
  41. package/dist/chunk-ZLPQUOFK.js.map +0 -1
@@ -1,393 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkZLPQUOFK_js = require('./chunk-ZLPQUOFK.js');
4
- var chunkSMUUAKC3_js = require('./chunk-SMUUAKC3.js');
5
- var core = require('@wallet-ui/core');
6
- var gill = require('gill');
7
-
8
- var logger = chunkSMUUAKC3_js.createLogger("EnhancedStorage"), STORAGE_VERSION = "v1", EnhancedStorage = class extends core.Storage {
9
- constructor(key, initial, options) {
10
- super(key, initial);
11
- this.options = options;
12
- chunkSMUUAKC3_js.__publicField(this, "errorHandlers", /* @__PURE__ */ new Set());
13
- chunkSMUUAKC3_js.__publicField(this, "validators", []);
14
- chunkSMUUAKC3_js.__publicField(this, "memoryFallback");
15
- this.memoryFallback = initial, options?.onError && this.errorHandlers.add(options.onError), options?.validator && this.validators.push(options.validator);
16
- }
17
- /**
18
- * Enhanced set with validation and error handling
19
- * @returns boolean indicating success
20
- */
21
- set(value) {
22
- try {
23
- return this.validate(value) ? (super.set(value), this.memoryFallback = value, true) : (logger.warn("Validation failed", { key: this.key }), false);
24
- } catch (error) {
25
- return this.handleError(error), this.options?.useMemoryFallback ? (this.memoryFallback = value, true) : false;
26
- }
27
- }
28
- /**
29
- * Enhanced get with error handling and fallback
30
- */
31
- get() {
32
- try {
33
- return super.get();
34
- } catch (error) {
35
- return this.handleError(error), this.options?.useMemoryFallback ? this.memoryFallback : this.initial;
36
- }
37
- }
38
- /**
39
- * Validate a value against all registered validators
40
- */
41
- validate(value) {
42
- return this.validators.every((validator) => validator(value));
43
- }
44
- /**
45
- * Add a validation rule (chainable)
46
- *
47
- * @example
48
- * ```ts
49
- * storage
50
- * .addValidator((addr) => addr?.length === 44)
51
- * .addValidator((addr) => addr?.startsWith('5'))
52
- * ```
53
- */
54
- addValidator(validator) {
55
- return this.validators.push(validator), this;
56
- }
57
- /**
58
- * Add error handler (chainable)
59
- */
60
- onError(handler) {
61
- return this.errorHandlers.add(handler), this;
62
- }
63
- /**
64
- * Transform the stored value
65
- *
66
- * @example
67
- * ```ts
68
- * const formatted = storage.transform(
69
- * (address) => address ? formatAddress(address) : ''
70
- * )
71
- * ```
72
- */
73
- transform(transformer) {
74
- return transformer(this.get());
75
- }
76
- /**
77
- * Reset to initial value
78
- */
79
- reset() {
80
- this.set(this.initial);
81
- }
82
- /**
83
- * Clear storage (remove from localStorage)
84
- */
85
- clear() {
86
- try {
87
- typeof window < "u" && window.localStorage && window.localStorage.removeItem(this.key), this.reset();
88
- } catch (error) {
89
- this.handleError(error);
90
- }
91
- }
92
- /**
93
- * Check if storage is available (not in private mode, quota not exceeded)
94
- */
95
- isAvailable() {
96
- try {
97
- if (typeof window > "u") return false;
98
- let testKey = `__storage_test_${this.key}__`;
99
- return window.localStorage.setItem(testKey, "test"), window.localStorage.removeItem(testKey), true;
100
- } catch {
101
- return false;
102
- }
103
- }
104
- /**
105
- * Migrate from old key to new key
106
- *
107
- * @example
108
- * ```ts
109
- * EnhancedStorage.migrate(
110
- * 'old-connector:account',
111
- * createEnhancedStorageAccount()
112
- * )
113
- * ```
114
- */
115
- static migrate(oldKey, newStorage) {
116
- try {
117
- if (typeof window > "u") return false;
118
- let oldValue = window.localStorage.getItem(oldKey);
119
- if (oldValue) {
120
- let parsed = JSON.parse(oldValue);
121
- return newStorage.set(parsed), window.localStorage.removeItem(oldKey), true;
122
- }
123
- return false;
124
- } catch {
125
- return false;
126
- }
127
- }
128
- handleError(error) {
129
- logger.error("Storage error", { key: this.key, error }), this.errorHandlers.forEach((handler) => {
130
- try {
131
- handler(error);
132
- } catch (err) {
133
- logger.error("Error in error handler", { error: err });
134
- }
135
- });
136
- }
137
- };
138
- function createEnhancedStorageAccount(options) {
139
- let key = options?.key ?? `connector-kit:${STORAGE_VERSION}:account`;
140
- return new EnhancedStorage(key, options?.initial, {
141
- validator: options?.validator,
142
- onError: options?.onError,
143
- useMemoryFallback: true
144
- // Always fallback for SSR
145
- });
146
- }
147
- function createEnhancedStorageCluster(options) {
148
- let key = options?.key ?? `connector-kit:${STORAGE_VERSION}:cluster`, storage = new EnhancedStorage(key, options?.initial ?? "solana:mainnet", {
149
- onError: options?.onError,
150
- useMemoryFallback: true
151
- });
152
- return options?.validClusters && storage.addValidator((clusterId) => options.validClusters.includes(clusterId)), storage;
153
- }
154
- function createEnhancedStorageWallet(options) {
155
- let key = options?.key ?? `connector-kit:${STORAGE_VERSION}:wallet`;
156
- return new EnhancedStorage(key, options?.initial, {
157
- onError: options?.onError,
158
- useMemoryFallback: true
159
- });
160
- }
161
- var EnhancedStorageAdapter = class {
162
- constructor(storage) {
163
- this.storage = storage;
164
- }
165
- get() {
166
- return this.storage.get();
167
- }
168
- set(value) {
169
- this.storage.set(value);
170
- }
171
- subscribe(callback) {
172
- return this.storage.value.subscribe(callback);
173
- }
174
- validate(value) {
175
- return this.storage.validate(value);
176
- }
177
- reset() {
178
- this.storage.reset();
179
- }
180
- clear() {
181
- this.storage.clear();
182
- }
183
- isAvailable() {
184
- return this.storage.isAvailable();
185
- }
186
- transform(transformer) {
187
- return this.storage.transform(transformer);
188
- }
189
- addValidator(validator) {
190
- return this.storage.addValidator(validator), this;
191
- }
192
- onError(handler) {
193
- return this.storage.onError(handler), this;
194
- }
195
- };
196
- var logger2 = chunkSMUUAKC3_js.createLogger("DefaultConfig");
197
- function getDefaultConfig(options) {
198
- let {
199
- appName,
200
- appUrl,
201
- autoConnect = true,
202
- debug,
203
- network = "mainnet-beta",
204
- enableMobile = true,
205
- storage,
206
- clusters,
207
- customClusters = [],
208
- persistClusterSelection = true,
209
- clusterStorageKey,
210
- enableErrorBoundary = true,
211
- maxRetries = chunkZLPQUOFK_js.DEFAULT_MAX_RETRIES,
212
- onError
213
- } = options, defaultClusters = clusters ?? [
214
- core.createSolanaMainnet(),
215
- core.createSolanaDevnet(),
216
- core.createSolanaTestnet(),
217
- ...network === "localnet" ? [core.createSolanaLocalnet()] : [],
218
- ...customClusters || []
219
- ], validClusterIds = defaultClusters.map((c) => c.id), accountStorage = createEnhancedStorageAccount({
220
- validator: (address) => address ? gill.isAddress(address) : true,
221
- onError: (error) => {
222
- debug && logger2.error("Account Storage error", { error }), onError && onError(error, {
223
- componentStack: "account-storage"
224
- });
225
- }
226
- }), clusterStorage = createEnhancedStorageCluster({
227
- key: clusterStorageKey,
228
- initial: getInitialCluster(network),
229
- validClusters: persistClusterSelection ? validClusterIds : void 0,
230
- onError: (error) => {
231
- debug && logger2.error("Cluster Storage error", { error }), onError && onError(error, {
232
- componentStack: "cluster-storage"
233
- });
234
- }
235
- }), walletStorage = createEnhancedStorageWallet({
236
- onError: (error) => {
237
- debug && logger2.error("Wallet Storage error", { error }), onError && onError(error, {
238
- componentStack: "wallet-storage"
239
- });
240
- }
241
- });
242
- if (typeof window < "u") {
243
- let oldAccountKey = "connector-kit:account", oldWalletKey = "connector-kit:wallet", oldClusterKey = clusterStorageKey || "connector-kit:cluster";
244
- EnhancedStorage.migrate(oldAccountKey, accountStorage), EnhancedStorage.migrate(oldWalletKey, walletStorage), EnhancedStorage.migrate(oldClusterKey, clusterStorage);
245
- }
246
- let defaultStorage = storage ?? {
247
- account: new EnhancedStorageAdapter(accountStorage),
248
- cluster: new EnhancedStorageAdapter(clusterStorage),
249
- wallet: new EnhancedStorageAdapter(walletStorage)
250
- };
251
- return {
252
- autoConnect,
253
- debug: debug ?? process.env.NODE_ENV === "development",
254
- storage: defaultStorage,
255
- appName,
256
- appUrl,
257
- enableMobile,
258
- network,
259
- cluster: {
260
- clusters: defaultClusters,
261
- persistSelection: persistClusterSelection,
262
- initialCluster: getInitialCluster(network)
263
- },
264
- errorBoundary: {
265
- enabled: enableErrorBoundary,
266
- maxRetries,
267
- onError
268
- }
269
- };
270
- }
271
- function getInitialCluster(network = "mainnet-beta") {
272
- return chunkZLPQUOFK_js.toClusterId(network);
273
- }
274
- function getDefaultMobileConfig(options) {
275
- let baseUrl = options.appUrl || (typeof window < "u" ? window.location.origin : "https://localhost:3000");
276
- return {
277
- appIdentity: {
278
- name: options.appName,
279
- uri: baseUrl,
280
- icon: `${baseUrl}/favicon.ico`
281
- },
282
- cluster: options.network || "mainnet-beta"
283
- };
284
- }
285
-
286
- // src/config/unified-config.ts
287
- function createConfig(options) {
288
- let { network = "mainnet-beta", rpcUrl: customRpcUrl, ...connectorOptions } = options, normalizedNetwork = chunkZLPQUOFK_js.normalizeNetwork(typeof network == "string" ? network : "mainnet-beta"), rpcUrl = customRpcUrl || chunkZLPQUOFK_js.getDefaultRpcUrl(normalizedNetwork), rpcNetwork = normalizedNetwork === "mainnet" ? "mainnet-beta" : normalizedNetwork, connectorConfig = getDefaultConfig({
289
- ...connectorOptions,
290
- network: rpcNetwork
291
- }), mobile = options.enableMobile !== false && normalizedNetwork !== "localnet" ? getDefaultMobileConfig({
292
- appName: options.appName,
293
- appUrl: connectorConfig.appUrl,
294
- network: rpcNetwork
295
- }) : void 0;
296
- return {
297
- connectorConfig,
298
- mobile,
299
- network: normalizedNetwork,
300
- rpcUrl,
301
- app: {
302
- name: options.appName,
303
- url: connectorConfig.appUrl || (typeof window < "u" ? window.location.origin : "https://localhost:3000")
304
- }
305
- };
306
- }
307
- function isUnifiedConfig(config) {
308
- return !!(config && typeof config == "object" && "connectorConfig" in config && "network" in config && "rpcUrl" in config && "app" in config);
309
- }
310
-
311
- // src/types/wallets.ts
312
- function isWalletName(value) {
313
- return typeof value == "string" && value.length > 0;
314
- }
315
- function isAccountAddress(value) {
316
- return typeof value == "string" && value.length >= 32 && value.length <= 44;
317
- }
318
- function getSolanaExplorerUrl(signature, options = {}) {
319
- let { cluster = "mainnet", customUrl } = options, normalizedCluster = cluster === "mainnet-beta" ? "mainnet" : cluster;
320
- if (normalizedCluster === "localnet")
321
- return `https://explorer.solana.com/tx/${signature}?cluster=custom&customUrl=${encodeURIComponent(customUrl || "http://localhost:8899")}`;
322
- let explorerCluster = ["mainnet", "devnet", "testnet"].includes(normalizedCluster) ? normalizedCluster : "devnet";
323
- return gill.getExplorerLink({
324
- transaction: signature,
325
- cluster: explorerCluster
326
- });
327
- }
328
- function getSolscanUrl(signature, options = {}) {
329
- let { cluster = "mainnet" } = options, normalizedCluster = cluster === "mainnet-beta" ? "mainnet" : cluster;
330
- return normalizedCluster === "mainnet" ? `https://solscan.io/tx/${signature}` : normalizedCluster === "localnet" ? `https://solscan.io/tx/${signature}?cluster=custom` : `https://solscan.io/tx/${signature}?cluster=${normalizedCluster}`;
331
- }
332
- function getXrayUrl(signature) {
333
- return `https://xray.helius.xyz/tx/${signature}`;
334
- }
335
- function getSolanaFmUrl(signature, options = {}) {
336
- let { cluster = "mainnet" } = options, normalizedCluster = cluster === "mainnet-beta" ? "mainnet" : cluster;
337
- return normalizedCluster === "mainnet" ? `https://solana.fm/tx/${signature}` : `https://solana.fm/tx/${signature}?cluster=${normalizedCluster}`;
338
- }
339
- function getAllExplorerUrls(signature, options = {}) {
340
- return {
341
- "solana-explorer": getSolanaExplorerUrl(signature, options),
342
- solscan: getSolscanUrl(signature, options),
343
- xray: getXrayUrl(signature),
344
- "solana-fm": getSolanaFmUrl(signature, options)
345
- };
346
- }
347
- function formatSignature(signature, chars = 8) {
348
- return signature.length <= chars * 2 ? signature : `${signature.slice(0, chars)}...${signature.slice(-chars)}`;
349
- }
350
- async function copySignature(signature) {
351
- try {
352
- return await navigator.clipboard.writeText(signature), true;
353
- } catch {
354
- return false;
355
- }
356
- }
357
-
358
- Object.defineProperty(exports, "createSolanaDevnet", {
359
- enumerable: true,
360
- get: function () { return core.createSolanaDevnet; }
361
- });
362
- Object.defineProperty(exports, "createSolanaLocalnet", {
363
- enumerable: true,
364
- get: function () { return core.createSolanaLocalnet; }
365
- });
366
- Object.defineProperty(exports, "createSolanaMainnet", {
367
- enumerable: true,
368
- get: function () { return core.createSolanaMainnet; }
369
- });
370
- Object.defineProperty(exports, "createSolanaTestnet", {
371
- enumerable: true,
372
- get: function () { return core.createSolanaTestnet; }
373
- });
374
- exports.EnhancedStorage = EnhancedStorage;
375
- exports.EnhancedStorageAdapter = EnhancedStorageAdapter;
376
- exports.copySignature = copySignature;
377
- exports.createConfig = createConfig;
378
- exports.createEnhancedStorageAccount = createEnhancedStorageAccount;
379
- exports.createEnhancedStorageCluster = createEnhancedStorageCluster;
380
- exports.createEnhancedStorageWallet = createEnhancedStorageWallet;
381
- exports.formatSignature = formatSignature;
382
- exports.getAllExplorerUrls = getAllExplorerUrls;
383
- exports.getDefaultConfig = getDefaultConfig;
384
- exports.getDefaultMobileConfig = getDefaultMobileConfig;
385
- exports.getSolanaExplorerUrl = getSolanaExplorerUrl;
386
- exports.getSolanaFmUrl = getSolanaFmUrl;
387
- exports.getSolscanUrl = getSolscanUrl;
388
- exports.getXrayUrl = getXrayUrl;
389
- exports.isAccountAddress = isAccountAddress;
390
- exports.isUnifiedConfig = isUnifiedConfig;
391
- exports.isWalletName = isWalletName;
392
- //# sourceMappingURL=chunk-5NSUFMCB.js.map
393
- //# sourceMappingURL=chunk-5NSUFMCB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/adapters/enhanced-storage.ts","../src/config/default-config.ts","../src/config/unified-config.ts","../src/types/wallets.ts","../src/lib/utils/explorer-urls.ts"],"names":["createLogger","WalletUiStorage","__publicField","logger","DEFAULT_MAX_RETRIES","createSolanaMainnet","createSolanaDevnet","createSolanaTestnet","createSolanaLocalnet","isAddress","toClusterId","normalizeNetwork","getDefaultRpcUrl","getExplorerLink"],"mappings":"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","file":"chunk-5NSUFMCB.js","sourcesContent":["/**\n * @solana/connector - Enhanced Storage\n *\n * Extended version of @wallet-ui/core Storage with additional features:\n * - Validation hooks\n * - Error handling and recovery\n * - SSR/memory fallback\n * - Transform utilities\n * - Migration support\n * - Storage availability checks\n */\n\nimport { Storage as WalletUiStorage } from '@wallet-ui/core';\nimport type { SolanaClusterId } from '@wallet-ui/core';\nimport type {\n StorageOptions,\n StorageAdapter,\n EnhancedStorageAccountOptions,\n EnhancedStorageClusterOptions,\n EnhancedStorageWalletOptions,\n} from '../../types/storage';\nimport { createLogger } from '../utils/secure-logger';\n\nconst logger = createLogger('EnhancedStorage');\n\n/**\n * Storage version for migration support\n * Increment when making breaking changes to storage format\n */\nexport const STORAGE_VERSION = 'v1';\n\n/**\n * Enhanced version of wallet-ui's Storage class\n * Extends the base Storage with validation, error handling, and SSR support\n */\nexport class EnhancedStorage<T> extends WalletUiStorage<T> {\n private errorHandlers: Set<(error: Error) => void> = new Set();\n private validators: ((value: T) => boolean)[] = [];\n private memoryFallback: T;\n\n constructor(\n key: string,\n initial: T,\n private options?: StorageOptions<T>,\n ) {\n super(key, initial);\n this.memoryFallback = initial;\n\n if (options?.onError) {\n this.errorHandlers.add(options.onError);\n }\n if (options?.validator) {\n this.validators.push(options.validator);\n }\n }\n\n /**\n * Enhanced set with validation and error handling\n * @returns boolean indicating success\n */\n override set(value: T): boolean {\n try {\n if (!this.validate(value)) {\n logger.warn('Validation failed', { key: this.key });\n return false;\n }\n\n super.set(value);\n\n this.memoryFallback = value;\n return true;\n } catch (error) {\n this.handleError(error as Error);\n\n if (this.options?.useMemoryFallback) {\n this.memoryFallback = value;\n return true;\n }\n\n return false;\n }\n }\n\n /**\n * Enhanced get with error handling and fallback\n */\n override get(): T {\n try {\n return super.get();\n } catch (error) {\n this.handleError(error as Error);\n\n if (this.options?.useMemoryFallback) {\n return this.memoryFallback;\n }\n\n return this.initial;\n }\n }\n\n /**\n * Validate a value against all registered validators\n */\n validate(value: T): boolean {\n return this.validators.every(validator => validator(value));\n }\n\n /**\n * Add a validation rule (chainable)\n *\n * @example\n * ```ts\n * storage\n * .addValidator((addr) => addr?.length === 44)\n * .addValidator((addr) => addr?.startsWith('5'))\n * ```\n */\n addValidator(validator: (value: T) => boolean): this {\n this.validators.push(validator);\n return this;\n }\n\n /**\n * Add error handler (chainable)\n */\n onError(handler: (error: Error) => void): this {\n this.errorHandlers.add(handler);\n return this;\n }\n\n /**\n * Transform the stored value\n *\n * @example\n * ```ts\n * const formatted = storage.transform(\n * (address) => address ? formatAddress(address) : ''\n * )\n * ```\n */\n transform<U>(transformer: (value: T) => U): U {\n return transformer(this.get());\n }\n\n /**\n * Reset to initial value\n */\n reset(): void {\n this.set(this.initial);\n }\n\n /**\n * Clear storage (remove from localStorage)\n */\n clear(): void {\n try {\n if (typeof window !== 'undefined' && window.localStorage) {\n window.localStorage.removeItem(this.key);\n }\n this.reset();\n } catch (error) {\n this.handleError(error as Error);\n }\n }\n\n /**\n * Check if storage is available (not in private mode, quota not exceeded)\n */\n isAvailable(): boolean {\n try {\n if (typeof window === 'undefined') return false;\n const testKey = `__storage_test_${this.key}__`;\n window.localStorage.setItem(testKey, 'test');\n window.localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Migrate from old key to new key\n *\n * @example\n * ```ts\n * EnhancedStorage.migrate(\n * 'old-connector:account',\n * createEnhancedStorageAccount()\n * )\n * ```\n */\n static migrate<T>(oldKey: string, newStorage: EnhancedStorage<T>): boolean {\n try {\n if (typeof window === 'undefined') return false;\n\n const oldValue = window.localStorage.getItem(oldKey);\n if (oldValue) {\n const parsed = JSON.parse(oldValue) as T;\n newStorage.set(parsed);\n window.localStorage.removeItem(oldKey);\n return true;\n }\n return false;\n } catch {\n return false;\n }\n }\n\n private handleError(error: Error): void {\n logger.error('Storage error', { key: this.key, error });\n this.errorHandlers.forEach(handler => {\n try {\n handler(error);\n } catch (err) {\n logger.error('Error in error handler', { error: err });\n }\n });\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a storage instance for wallet account persistence\n *\n * @example\n * ```ts\n * const storage = createEnhancedStorageAccount({\n * validator: (address) => {\n * if (!address) return true\n * return isAddress(address)\n * }\n * })\n * ```\n */\nexport function createEnhancedStorageAccount(\n options?: EnhancedStorageAccountOptions,\n): EnhancedStorage<string | undefined> {\n const key = options?.key ?? `connector-kit:${STORAGE_VERSION}:account`;\n return new EnhancedStorage(key, options?.initial, {\n validator: options?.validator,\n onError: options?.onError,\n useMemoryFallback: true, // Always fallback for SSR\n });\n}\n\n/**\n * Create a storage instance for cluster selection persistence\n *\n * @example\n * ```ts\n * const storage = createEnhancedStorageCluster({\n * initial: 'solana:mainnet',\n * validClusters: ['solana:mainnet', 'solana:devnet']\n * })\n * ```\n */\nexport function createEnhancedStorageCluster(\n options?: EnhancedStorageClusterOptions,\n): EnhancedStorage<SolanaClusterId> {\n const key = options?.key ?? `connector-kit:${STORAGE_VERSION}:cluster`;\n const storage = new EnhancedStorage(key, options?.initial ?? 'solana:mainnet', {\n onError: options?.onError,\n useMemoryFallback: true,\n });\n\n if (options?.validClusters) {\n storage.addValidator(clusterId => options.validClusters!.includes(clusterId));\n }\n\n return storage;\n}\n\n/**\n * Create a storage instance for wallet name persistence\n *\n * @example\n * ```ts\n * const storage = createEnhancedStorageWallet({\n * onError: (error) => console.error('Wallet storage error:', error)\n * })\n * ```\n */\nexport function createEnhancedStorageWallet(\n options?: EnhancedStorageWalletOptions,\n): EnhancedStorage<string | undefined> {\n const key = options?.key ?? `connector-kit:${STORAGE_VERSION}:wallet`;\n return new EnhancedStorage(key, options?.initial, {\n onError: options?.onError,\n useMemoryFallback: true,\n });\n}\n\n// ============================================================================\n// Storage Adapter Interface\n// ============================================================================\n\n/**\n * Adapter to make EnhancedStorage compatible with StorageAdapter interface\n * Exposes both the basic interface and enhanced methods for advanced usage\n */\nexport class EnhancedStorageAdapter<T> implements StorageAdapter<T> {\n constructor(private storage: EnhancedStorage<T>) {}\n\n get(): T {\n return this.storage.get();\n }\n\n set(value: T): void {\n this.storage.set(value);\n }\n\n subscribe(callback: (value: T) => void): () => void {\n return this.storage.value.subscribe(callback);\n }\n\n validate(value: T): boolean {\n return this.storage.validate(value);\n }\n\n reset(): void {\n this.storage.reset();\n }\n\n clear(): void {\n this.storage.clear();\n }\n\n isAvailable(): boolean {\n return this.storage.isAvailable();\n }\n\n transform<U>(transformer: (value: T) => U): U {\n return this.storage.transform(transformer);\n }\n\n addValidator(validator: (value: T) => boolean): this {\n this.storage.addValidator(validator);\n return this;\n }\n\n onError(handler: (error: Error) => void): this {\n this.storage.onError(handler);\n return this;\n }\n}\n","import type { ConnectorConfig } from '../types/connector';\nimport type { SolanaCluster, SolanaClusterId } from '@wallet-ui/core';\nimport { createSolanaMainnet, createSolanaDevnet, createSolanaTestnet, createSolanaLocalnet } from '@wallet-ui/core';\nimport {\n createEnhancedStorageAccount,\n createEnhancedStorageCluster,\n createEnhancedStorageWallet,\n EnhancedStorageAdapter,\n EnhancedStorage,\n} from '../lib/adapters/enhanced-storage';\nimport { toClusterId } from '../utils/network';\nimport type React from 'react';\nimport { isAddress } from 'gill';\nimport { DEFAULT_MAX_RETRIES } from '../lib/constants';\nimport { createLogger } from '../lib/utils/secure-logger';\n\nconst logger = createLogger('DefaultConfig');\n\nexport interface DefaultConfigOptions {\n /** Application name shown in wallet connection prompts */\n appName: string;\n /** Application URL for wallet connection metadata */\n appUrl?: string;\n /** Enable automatic wallet reconnection on page load */\n autoConnect?: boolean;\n /** Enable debug logging */\n debug?: boolean;\n /** Solana network to connect to (accepts both 'mainnet' and 'mainnet-beta' conventions) */\n network?: 'mainnet' | 'mainnet-beta' | 'devnet' | 'testnet' | 'localnet';\n /** Enable Mobile Wallet Adapter support */\n enableMobile?: boolean;\n /** Custom storage implementation */\n storage?: ConnectorConfig['storage'];\n /** Custom cluster configuration - overrides network if provided */\n clusters?: SolanaCluster[];\n /** Additional custom clusters to add to the default list */\n customClusters?: SolanaCluster[];\n /** Persist cluster selection across sessions */\n persistClusterSelection?: boolean;\n /** Custom storage key for cluster persistence */\n clusterStorageKey?: string;\n /** Enable error boundaries for automatic error handling (default: true) */\n enableErrorBoundary?: boolean;\n /** Maximum retry attempts for error recovery (default: 3) */\n maxRetries?: number;\n /** Custom error handler */\n onError?: (error: Error, errorInfo: React.ErrorInfo) => void;\n}\n\n/** Extended ConnectorConfig with app metadata */\nexport interface ExtendedConnectorConfig extends ConnectorConfig {\n /** Application name for display and metadata */\n appName?: string;\n /** Application URL for metadata */\n appUrl?: string;\n /** Whether mobile wallet adapter is enabled */\n enableMobile?: boolean;\n /** Selected network for convenience (accepts both 'mainnet' and 'mainnet-beta' conventions) */\n network?: 'mainnet' | 'mainnet-beta' | 'devnet' | 'testnet' | 'localnet';\n /** Error boundary configuration */\n errorBoundary?: {\n /** Enable error boundaries (default: true) */\n enabled?: boolean;\n /** Maximum retry attempts (default: 3) */\n maxRetries?: number;\n /** Custom error handler */\n onError?: (error: Error, errorInfo: React.ErrorInfo) => void;\n /** Custom fallback component */\n fallback?: (error: Error, retry: () => void) => React.ReactNode;\n };\n}\n\n/**\n * Creates a default connector configuration with sensible defaults for Solana applications\n */\nexport function getDefaultConfig(options: DefaultConfigOptions): ExtendedConnectorConfig {\n const {\n appName,\n appUrl,\n autoConnect = true,\n debug,\n network = 'mainnet-beta',\n enableMobile = true,\n storage,\n clusters,\n customClusters = [],\n persistClusterSelection = true,\n clusterStorageKey,\n enableErrorBoundary = true,\n maxRetries = DEFAULT_MAX_RETRIES,\n onError,\n } = options;\n\n const defaultClusters: SolanaCluster[] = clusters ?? [\n createSolanaMainnet(),\n createSolanaDevnet(),\n createSolanaTestnet(),\n ...(network === 'localnet' ? [createSolanaLocalnet()] : []),\n ...(customClusters || []),\n ];\n\n const validClusterIds = defaultClusters.map(c => c.id);\n\n const accountStorage = createEnhancedStorageAccount({\n validator: address => {\n if (!address) return true;\n return isAddress(address);\n },\n onError: error => {\n if (debug) {\n logger.error('Account Storage error', { error });\n }\n if (onError) {\n onError(error, {\n componentStack: 'account-storage',\n });\n }\n },\n });\n\n const clusterStorage = createEnhancedStorageCluster({\n key: clusterStorageKey,\n initial: getInitialCluster(network),\n validClusters: persistClusterSelection ? validClusterIds : undefined,\n onError: error => {\n if (debug) {\n logger.error('Cluster Storage error', { error });\n }\n if (onError) {\n onError(error, {\n componentStack: 'cluster-storage',\n });\n }\n },\n });\n\n const walletStorage = createEnhancedStorageWallet({\n onError: error => {\n if (debug) {\n logger.error('Wallet Storage error', { error });\n }\n if (onError) {\n onError(error, {\n componentStack: 'wallet-storage',\n });\n }\n },\n });\n\n // Migrate old storage keys to new versioned format (v1)\n // This allows seamless upgrades from old versions without losing user data\n if (typeof window !== 'undefined') {\n // Old keys (pre-v1): 'connector-kit:account', 'connector-kit:wallet', 'connector-kit:cluster'\n // New keys (v1): 'connector-kit:v1:account', 'connector-kit:v1:wallet', 'connector-kit:v1:cluster'\n const oldAccountKey = 'connector-kit:account';\n const oldWalletKey = 'connector-kit:wallet';\n const oldClusterKey = clusterStorageKey || 'connector-kit:cluster';\n\n EnhancedStorage.migrate(oldAccountKey, accountStorage);\n EnhancedStorage.migrate(oldWalletKey, walletStorage);\n EnhancedStorage.migrate(oldClusterKey, clusterStorage);\n }\n\n const defaultStorage: ConnectorConfig['storage'] = storage ?? {\n account: new EnhancedStorageAdapter(accountStorage),\n cluster: new EnhancedStorageAdapter(clusterStorage),\n wallet: new EnhancedStorageAdapter(walletStorage),\n };\n\n const config: ExtendedConnectorConfig = {\n autoConnect,\n debug: debug ?? process.env.NODE_ENV === 'development',\n storage: defaultStorage,\n appName,\n appUrl,\n enableMobile,\n network,\n cluster: {\n clusters: defaultClusters,\n persistSelection: persistClusterSelection,\n initialCluster: getInitialCluster(network),\n },\n errorBoundary: {\n enabled: enableErrorBoundary,\n maxRetries,\n onError,\n },\n };\n\n return config;\n}\n\n/**\n * Helper to convert network string to cluster ID\n * Uses network utility for consistent translation\n */\nfunction getInitialCluster(\n network: 'mainnet' | 'mainnet-beta' | 'devnet' | 'testnet' | 'localnet' = 'mainnet-beta',\n): SolanaClusterId {\n return toClusterId(network);\n}\n\n/**\n * Default Mobile Wallet Adapter configuration for Solana applications\n */\nexport function getDefaultMobileConfig(options: {\n appName: string;\n appUrl?: string;\n network?: 'mainnet' | 'mainnet-beta' | 'devnet' | 'testnet';\n}) {\n const baseUrl =\n options.appUrl || (typeof window !== 'undefined' ? window.location.origin : 'https://localhost:3000');\n\n return {\n appIdentity: {\n name: options.appName,\n uri: baseUrl,\n icon: `${baseUrl}/favicon.ico`,\n },\n cluster: options.network || 'mainnet-beta',\n };\n}\n","/**\n * @solana/connector - Unified configuration\n *\n * Simplified configuration for apps using ConnectorKit\n * Eliminates config duplication and provides a single source of truth\n */\n\nimport type { ExtendedConnectorConfig, DefaultConfigOptions } from './default-config';\nimport type { MobileWalletAdapterConfig } from '../ui/connector-provider';\nimport { getDefaultConfig, getDefaultMobileConfig } from './default-config';\nimport { normalizeNetwork, getDefaultRpcUrl, type SolanaNetwork } from '../utils/network';\n\n/**\n * Options for creating a unified configuration\n * Maintains type safety while providing flexibility\n */\nexport interface UnifiedConfigOptions extends DefaultConfigOptions {\n /**\n * Custom RPC URL (optional - overrides default for network)\n * Note: For production apps, use environment variables to avoid exposing API keys\n * @see packages/connector/src/utils/cluster.ts for secure RPC URL patterns\n */\n rpcUrl?: string;\n}\n\n/**\n * Unified configuration output\n * Contains all configs needed for ConnectorKit and integrations\n *\n * Important: The `rpcUrl` property is intended for:\n * 1. Server-side rendering (SSR) setup\n * 2. Passing to external libraries that need RPC configuration\n * 3. Development/testing environments\n *\n * For production client-side code, use the connector client's `getRpcUrl()` method\n * which supports environment variable patterns and proxy configurations.\n */\nexport interface UnifiedConfig {\n /** ConnectorKit configuration */\n connectorConfig: ExtendedConnectorConfig;\n /** Mobile Wallet Adapter configuration (optional) */\n mobile?: MobileWalletAdapterConfig;\n /** Normalized network name ('mainnet', 'devnet', 'testnet', 'localnet') */\n network: SolanaNetwork;\n /**\n * RPC endpoint URL\n * For external library integration only - client code should use connector client\n * @deprecated in client components - use `useConnectorClient().getRpcUrl()` instead\n */\n rpcUrl: string;\n /** Application metadata */\n app: {\n name: string;\n url: string;\n };\n}\n\n/**\n * Create a unified configuration for ConnectorKit\n *\n * This helper eliminates configuration duplication by creating all necessary\n * configs from a single source of truth. It automatically handles network\n * name translation between different conventions.\n *\n * @example Basic usage\n * ```tsx\n * import { createConfig, AppProvider } from '@solana/connector';\n *\n * const config = createConfig({\n * appName: 'My App',\n * network: 'mainnet', // Works with 'mainnet' or 'mainnet-beta'\n * enableMobile: true\n * });\n *\n * <AppProvider config={config}>\n * {children}\n * </AppProvider>\n * ```\n *\n * @example Integration with external libraries\n * ```tsx\n * import { createConfig, AppProvider } from '@solana/connector';\n * import { ArmaProvider } from '@armadura/sdk';\n *\n * const config = createConfig({\n * appName: 'My App',\n * network: 'mainnet',\n * });\n *\n * <AppProvider config={config}>\n * <ArmaProvider\n * config={{\n * network: config.network,\n * rpcUrl: config.rpcUrl, // Safe - for external library initialization\n * providers: [...]\n * }}\n * useConnector=\"auto\"\n * >\n * {children}\n * </ArmaProvider>\n * </AppProvider>\n * ```\n *\n * @example Production with environment variables\n * ```tsx\n * // Use environment variables to avoid exposing API keys\n * const config = createConfig({\n * appName: 'My App',\n * network: 'mainnet',\n * // RPC URL comes from process.env on server\n * // Client-side code should use connector client's getRpcUrl()\n * });\n * ```\n *\n * @example Custom clusters\n * ```tsx\n * const config = createConfig({\n * appName: 'My App',\n * network: 'mainnet',\n * customClusters: [\n * {\n * id: 'solana:custom',\n * label: 'Custom RPC',\n * url: process.env.CUSTOM_RPC_URL || 'https://...'\n * }\n * ]\n * });\n * ```\n */\nexport function createConfig(options: UnifiedConfigOptions): UnifiedConfig {\n // Extract network and rpcUrl, use remaining options for connector config\n const { network = 'mainnet-beta', rpcUrl: customRpcUrl, ...connectorOptions } = options;\n\n // Normalize network name for consistency\n const normalizedNetwork = normalizeNetwork(typeof network === 'string' ? network : 'mainnet-beta');\n\n // Get RPC URL (custom or default)\n const rpcUrl = customRpcUrl || getDefaultRpcUrl(normalizedNetwork);\n\n // Convert normalized network to RPC format (mainnet -> mainnet-beta)\n const rpcNetwork = normalizedNetwork === 'mainnet' ? 'mainnet-beta' : normalizedNetwork;\n\n // Create connector configuration\n const connectorConfig = getDefaultConfig({\n ...connectorOptions,\n network: rpcNetwork,\n });\n\n // Create mobile configuration (if enabled)\n const mobile =\n options.enableMobile !== false && normalizedNetwork !== 'localnet'\n ? getDefaultMobileConfig({\n appName: options.appName,\n appUrl: connectorConfig.appUrl,\n network: rpcNetwork as 'mainnet-beta' | 'devnet' | 'testnet',\n })\n : undefined;\n\n return {\n connectorConfig,\n mobile,\n network: normalizedNetwork,\n rpcUrl,\n app: {\n name: options.appName,\n url:\n connectorConfig.appUrl ||\n (typeof window !== 'undefined' ? window.location.origin : 'https://localhost:3000'),\n },\n };\n}\n\n/**\n * Type guard to check if a config is a unified config\n *\n * @example\n * ```ts\n * if (isUnifiedConfig(someConfig)) {\n * // TypeScript knows this is UnifiedConfig\n * console.log(someConfig.network, someConfig.rpcUrl);\n * }\n * ```\n */\nexport function isUnifiedConfig(config: unknown): config is UnifiedConfig {\n return Boolean(\n config &&\n typeof config === 'object' &&\n 'connectorConfig' in config &&\n 'network' in config &&\n 'rpcUrl' in config &&\n 'app' in config,\n );\n}\n","/**\n * Wallet-related types\n * Re-exports from @wallet-standard/base and custom wallet types\n */\n\nimport type { Wallet, WalletAccount } from '@wallet-standard/base';\n\n// Re-export standard types\nexport type { Wallet, WalletAccount };\n\n/**\n * Wallet name as a branded string for type safety\n * Represents the unique identifier for a wallet (e.g., \"Phantom\", \"Solflare\")\n */\nexport type WalletName = string & { readonly __brand: 'WalletName' };\n\n/**\n * Account address as a branded string for type safety\n * Represents a Solana address (base58-encoded public key)\n *\n * @deprecated Use `Address` from 'gill' instead for consistent address typing\n */\nexport type AccountAddress = string & { readonly __brand: 'AccountAddress' };\n\n/**\n * Type guard to check if a string is a valid wallet name\n */\nexport function isWalletName(value: string): value is WalletName {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * Type guard to check if a string is a valid account address\n *\n * @deprecated Use `isAddress` from 'gill' instead for proper address validation\n */\nexport function isAccountAddress(value: string): value is AccountAddress {\n // Basic validation: Solana addresses are typically 32-44 characters\n return typeof value === 'string' && value.length >= 32 && value.length <= 44;\n}\n\n/**\n * Extended wallet information with capability metadata\n */\nexport interface WalletInfo {\n /** The Wallet Standard wallet object */\n wallet: Wallet;\n /** Whether the wallet extension is installed */\n installed: boolean;\n /** Precomputed capability flag for UI convenience */\n connectable?: boolean;\n}\n","/**\n * @solana/connector - Explorer URL Utilities\n *\n * Generate URLs for various Solana block explorers to view transactions,\n * accounts, and other on-chain data.\n */\n\nimport { getExplorerLink } from 'gill';\n\nexport type ExplorerType = 'solana-explorer' | 'solscan' | 'xray' | 'solana-fm';\n\nexport interface ExplorerOptions {\n /** Cluster to use for the explorer link */\n cluster?: string;\n /** Custom RPC URL for localnet */\n customUrl?: string;\n}\n\n/**\n * Generate Solana Explorer URL for a transaction signature\n */\nexport function getSolanaExplorerUrl(signature: string, options: ExplorerOptions = {}): string {\n const { cluster = 'mainnet', customUrl } = options;\n const normalizedCluster = cluster === 'mainnet-beta' ? 'mainnet' : cluster;\n\n // Handle localnet with custom URL - gill doesn't support this specific case\n if (normalizedCluster === 'localnet') {\n const url = customUrl || 'http://localhost:8899';\n return `https://explorer.solana.com/tx/${signature}?cluster=custom&customUrl=${encodeURIComponent(url)}`;\n }\n\n // Map to valid gill cluster types (custom clusters default to devnet)\n const validClusters = ['mainnet', 'devnet', 'testnet'] as const;\n const explorerCluster = validClusters.includes(normalizedCluster as 'mainnet' | 'devnet' | 'testnet')\n ? (normalizedCluster as 'mainnet' | 'devnet' | 'testnet')\n : 'devnet';\n\n // Use gill's getExplorerLink for standard clusters\n return getExplorerLink({\n transaction: signature,\n cluster: explorerCluster,\n });\n}\n\n/**\n * Generate Solscan URL for a transaction signature\n */\nexport function getSolscanUrl(signature: string, options: ExplorerOptions = {}): string {\n const { cluster = 'mainnet' } = options;\n const normalizedCluster = cluster === 'mainnet-beta' ? 'mainnet' : cluster;\n\n if (normalizedCluster === 'mainnet') {\n return `https://solscan.io/tx/${signature}`;\n }\n\n if (normalizedCluster === 'localnet') {\n return `https://solscan.io/tx/${signature}?cluster=custom`;\n }\n\n return `https://solscan.io/tx/${signature}?cluster=${normalizedCluster}`;\n}\n\n/**\n * Generate XRAY (Helius) URL for a transaction signature\n * Note: XRAY works best with mainnet transactions\n */\nexport function getXrayUrl(signature: string): string {\n return `https://xray.helius.xyz/tx/${signature}`;\n}\n\n/**\n * Generate SolanaFM URL for a transaction signature\n */\nexport function getSolanaFmUrl(signature: string, options: ExplorerOptions = {}): string {\n const { cluster = 'mainnet' } = options;\n const normalizedCluster = cluster === 'mainnet-beta' ? 'mainnet' : cluster;\n\n if (normalizedCluster === 'mainnet') {\n return `https://solana.fm/tx/${signature}`;\n }\n\n return `https://solana.fm/tx/${signature}?cluster=${normalizedCluster}`;\n}\n\n/**\n * Get all explorer URLs for a transaction\n */\nexport function getAllExplorerUrls(signature: string, options: ExplorerOptions = {}): Record<ExplorerType, string> {\n return {\n 'solana-explorer': getSolanaExplorerUrl(signature, options),\n solscan: getSolscanUrl(signature, options),\n xray: getXrayUrl(signature),\n 'solana-fm': getSolanaFmUrl(signature, options),\n };\n}\n\n/**\n * Format a transaction signature for display (truncated)\n */\nexport function formatSignature(signature: string, chars = 8): string {\n if (signature.length <= chars * 2) return signature;\n return `${signature.slice(0, chars)}...${signature.slice(-chars)}`;\n}\n\n/**\n * Copy signature to clipboard with enhanced error handling\n *\n * @deprecated Use copySignatureToClipboard from utils/clipboard instead\n * This is maintained for backwards compatibility but will be removed in a future version\n */\nexport async function copySignature(signature: string): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(signature);\n return true;\n } catch {\n return false;\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/ui/connector-provider.tsx","../src/ui/unified-provider.tsx","../src/hooks/use-cluster.ts","../src/hooks/use-account.ts","../src/hooks/use-wallet-info.ts","../src/hooks/use-transaction-signer.ts","../src/hooks/use-gill-transaction-signer.ts","../src/hooks/use-gill-solana-client.ts","../src/hooks/use-transaction-preparer.ts"],"names":["jsx","useMemo","React","logger","useCallback"],"mappings":"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","file":"chunk-7TADXRFD.mjs","sourcesContent":["'use client';\n\nimport React, { createContext, useContext, useMemo, useRef, useSyncExternalStore } from 'react';\nimport type { ReactNode } from 'react';\nimport { ConnectorClient } from '../lib/core/connector-client';\nimport type { ConnectorConfig } from '../types/connector';\nimport type { ExtendedConnectorConfig } from '../config/default-config';\nimport { ConnectorErrorBoundary } from './error-boundary';\nimport { installPolyfills } from '../lib/utils/polyfills';\nimport { createLogger } from '../lib/utils/secure-logger';\n\nconst logger = createLogger('ConnectorProvider');\n\n// Install browser compatibility polyfills immediately when module loads\n// This ensures crypto operations work across all browser environments\ninstallPolyfills();\n\n// Global connector client declaration for auto-detection\ndeclare global {\n interface Window {\n __connectorClient?: ConnectorClient;\n }\n}\n\nexport type ConnectorSnapshot = ReturnType<ConnectorClient['getSnapshot']> & {\n select: (walletName: string) => Promise<void>;\n disconnect: () => Promise<void>;\n selectAccount: (address: string) => Promise<void>;\n};\n\nexport const ConnectorContext = createContext<ConnectorClient | null>(null);\nConnectorContext.displayName = 'ConnectorContext';\n\nexport interface MobileWalletAdapterConfig {\n appIdentity: {\n name: string;\n uri?: string;\n icon?: string;\n };\n remoteHostAuthority?: string;\n chains?: readonly string[];\n authorizationCache?: unknown;\n chainSelector?: unknown;\n onWalletNotFound?: (wallet: unknown) => Promise<void>;\n}\n\n// Internal provider without error boundary\nfunction ConnectorProviderInternal({\n children,\n config,\n mobile,\n}: {\n children: ReactNode;\n config?: ConnectorConfig;\n mobile?: MobileWalletAdapterConfig;\n}) {\n const clientRef = useRef<ConnectorClient | null>(null);\n\n // Lazy initialization - only create client once on first render\n // This prevents double-initialization in React 19 strict mode\n const getClient = React.useCallback(() => {\n if (!clientRef.current) {\n try {\n clientRef.current = new ConnectorClient(config);\n\n // ✅ Set window.__connectorClient IMMEDIATELY for auto-detection\n if (typeof window !== 'undefined') {\n window.__connectorClient = clientRef.current;\n }\n\n // Log successful initialization in debug mode\n if (config?.debug) {\n logger.info('Client initialized successfully');\n }\n } catch (error) {\n const err = error as Error;\n logger.error('Failed to initialize client', { error: err });\n\n // Call config error handler if provided\n const extendedConfig = config as ExtendedConnectorConfig;\n if (extendedConfig?.errorBoundary?.onError) {\n extendedConfig.errorBoundary.onError(err, {\n componentStack: 'client-initialization',\n digest: `constructor-${new Date().toISOString()}`,\n });\n }\n\n // Return null to allow graceful degradation\n // Components can check for null client and show fallback UI\n return null;\n }\n }\n return clientRef.current;\n }, [config]);\n\n // Get client reference (memoized)\n const client = getClient();\n\n // On client mount, ensure wallet detection runs (run only once)\n React.useEffect(() => {\n const currentClient = clientRef.current;\n\n if (currentClient) {\n // Force re-initialization if client was created during SSR\n // This ensures wallets are detected even if client was created before window existed\n const privateClient = currentClient as unknown as { initialize?: () => void };\n if (privateClient.initialize && typeof privateClient.initialize === 'function') {\n privateClient.initialize();\n }\n }\n\n return () => {\n // Cleanup global reference and client on unmount\n if (typeof window !== 'undefined') {\n window.__connectorClient = undefined;\n }\n if (currentClient && typeof currentClient.destroy === 'function') {\n currentClient.destroy();\n }\n };\n }, []); // Empty dependency array - run only once\n\n // Optionally register Mobile Wallet Adapter on the client\n React.useEffect(() => {\n if (!mobile) return;\n let cancelled = false;\n (async () => {\n try {\n const mod = (await import(\n '@solana-mobile/wallet-standard-mobile'\n )) as typeof import('@solana-mobile/wallet-standard-mobile');\n if (cancelled) return;\n const {\n registerMwa,\n createDefaultAuthorizationCache,\n createDefaultChainSelector,\n createDefaultWalletNotFoundHandler,\n } = mod;\n const defaultChains: readonly `${string}:${string}`[] = [\n 'solana:mainnet',\n 'solana:devnet',\n 'solana:testnet',\n ];\n registerMwa({\n appIdentity: mobile.appIdentity,\n authorizationCache: mobile.authorizationCache ?? (createDefaultAuthorizationCache() as any),\n chains: (mobile.chains ?? defaultChains) as `${string}:${string}`[],\n chainSelector: mobile.chainSelector ?? (createDefaultChainSelector() as any),\n remoteHostAuthority: mobile.remoteHostAuthority,\n onWalletNotFound: mobile.onWalletNotFound ?? createDefaultWalletNotFoundHandler(),\n });\n } catch (e) {\n // Failed to register Mobile Wallet Adapter\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [mobile]);\n\n return <ConnectorContext.Provider value={client}>{children}</ConnectorContext.Provider>;\n}\n\n// Enhanced provider with optional error boundary\nexport function ConnectorProvider({\n children,\n config,\n mobile,\n}: {\n children: ReactNode;\n config?: ExtendedConnectorConfig;\n mobile?: MobileWalletAdapterConfig;\n}) {\n const extendedConfig = config as ExtendedConnectorConfig;\n const errorBoundaryConfig = extendedConfig?.errorBoundary;\n\n // If error boundary is disabled, use internal provider directly\n if (!errorBoundaryConfig?.enabled) {\n return (\n <ConnectorProviderInternal config={config} mobile={mobile}>\n {children}\n </ConnectorProviderInternal>\n );\n }\n\n // Wrap with error boundary for enhanced error handling\n return (\n <ConnectorErrorBoundary\n maxRetries={errorBoundaryConfig.maxRetries ?? 3}\n onError={errorBoundaryConfig.onError}\n fallback={errorBoundaryConfig.fallback}\n >\n <ConnectorProviderInternal config={config} mobile={mobile}>\n {children}\n </ConnectorProviderInternal>\n </ConnectorErrorBoundary>\n );\n}\n\nexport function useConnector(): ConnectorSnapshot {\n const client = useContext(ConnectorContext);\n if (!client) {\n throw new Error(\n 'useConnector must be used within ConnectorProvider. ' +\n 'Wrap your app with <ConnectorProvider> or <UnifiedProvider> to use connector hooks.',\n );\n }\n\n // Subscribe to state changes\n const state = useSyncExternalStore(\n React.useCallback(cb => client.subscribe(cb), [client]),\n React.useCallback(() => client.getSnapshot(), [client]),\n React.useCallback(() => client.getSnapshot(), [client]),\n );\n\n // Stable method references that don't change when state changes\n // These are bound once and reused across renders\n const methods = useMemo(\n () => ({\n select: client.select.bind(client),\n disconnect: client.disconnect.bind(client),\n selectAccount: client.selectAccount.bind(client),\n }),\n [client],\n );\n\n // Optimized: Only create new object when state actually changes\n return useMemo(\n () => ({\n ...state,\n ...methods,\n }),\n [state, methods],\n );\n}\n\n/**\n * Get the connector client instance\n * Returns null if not within ConnectorProvider or if initialization failed\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const client = useConnectorClient()\n *\n * if (!client) {\n * return <div>Connector not available</div>\n * }\n *\n * // Use client methods directly\n * const health = client.getHealth()\n * }\n * ```\n */\nexport function useConnectorClient(): ConnectorClient | null {\n return useContext(ConnectorContext);\n}\n","'use client';\n\nimport type { ReactNode, ComponentType, PropsWithChildren } from 'react';\nimport { ConnectorProvider } from './connector-provider';\nimport type { MobileWalletAdapterConfig } from './connector-provider';\nimport type { ConnectorConfig } from '../types/connector';\nimport type { UnifiedConfig } from '../config/unified-config';\n\nexport interface UnifiedProviderProps {\n children: ReactNode;\n\n // NEW: Option 1 - Pass UnifiedConfig directly (recommended)\n config?: UnifiedConfig;\n\n // OLD: Option 2 - Pass configs separately (backward compatible)\n connectorConfig?: ConnectorConfig;\n mobile?: MobileWalletAdapterConfig;\n\n // Optional additional providers to wrap around children\n providers?: Array<{\n component: ComponentType<PropsWithChildren>;\n props?: Record<string, unknown>;\n }>;\n}\n\nexport function UnifiedProvider({ children, config, connectorConfig, mobile, providers = [] }: UnifiedProviderProps) {\n // Handle both new and old patterns\n const actualConnectorConfig = config?.connectorConfig ?? connectorConfig;\n const actualMobile = config?.mobile ?? mobile;\n\n // Start with connector provider as the base\n let content = (\n <ConnectorProvider config={actualConnectorConfig} mobile={actualMobile}>\n {children}\n </ConnectorProvider>\n );\n\n // Wrap with additional providers in reverse order\n // so they nest properly (first provider is outermost)\n for (let i = providers.length - 1; i >= 0; i--) {\n const { component: Provider, props = {} } = providers[i];\n content = <Provider {...props}>{content}</Provider>;\n }\n\n return content;\n}\n\n// Export with practical alias\nexport { UnifiedProvider as AppProvider };\n","/**\n * @solana/connector - useCluster hook\n *\n * React hook for managing Solana cluster (network) state\n */\n\n'use client';\n\nimport { useMemo } from 'react';\nimport type { SolanaCluster, SolanaClusterId } from '@wallet-ui/core';\nimport { useConnector, useConnectorClient } from '../ui/connector-provider';\nimport {\n getClusterExplorerUrl,\n isMainnetCluster,\n isDevnetCluster,\n isTestnetCluster,\n isLocalCluster,\n getClusterType,\n type ClusterType,\n} from '../utils/cluster';\n\nexport interface UseClusterReturn {\n /** Currently active cluster */\n cluster: SolanaCluster | null;\n /** All available clusters */\n clusters: SolanaCluster[];\n /** Set the active cluster */\n setCluster: (id: SolanaClusterId) => Promise<void>;\n /** Whether the current cluster is mainnet */\n isMainnet: boolean;\n /** Whether the current cluster is devnet */\n isDevnet: boolean;\n /** Whether the current cluster is testnet */\n isTestnet: boolean;\n /** Whether the current cluster is running locally */\n isLocal: boolean;\n /** Solana Explorer base URL for the current cluster */\n explorerUrl: string;\n /** Cluster type (mainnet, devnet, testnet, localnet, custom) */\n type: ClusterType | null;\n}\n\n/**\n * Hook for managing Solana cluster (network) selection\n *\n * @example\n * ```tsx\n * function ClusterSwitcher() {\n * const { cluster, clusters, setCluster, isMainnet } = useCluster()\n *\n * return (\n * <select\n * value={cluster?.id}\n * onChange={(e) => setCluster(e.target.value as SolanaClusterId)}\n * >\n * {clusters.map(c => (\n * <option key={c.id} value={c.id}>{c.label}</option>\n * ))}\n * </select>\n * )\n * }\n * ```\n */\nexport function useCluster(): UseClusterReturn {\n const { cluster, clusters } = useConnector();\n const client = useConnectorClient();\n\n if (!client) {\n throw new Error('useCluster must be used within ConnectorProvider');\n }\n\n const setCluster = useMemo(\n () => async (id: SolanaClusterId) => {\n await client.setCluster(id);\n },\n [client],\n );\n\n return useMemo(() => {\n const isMainnet = cluster ? isMainnetCluster(cluster) : false;\n const isDevnet = cluster ? isDevnetCluster(cluster) : false;\n const isTestnet = cluster ? isTestnetCluster(cluster) : false;\n const isLocal = cluster ? isLocalCluster(cluster) : false;\n const explorerUrl = cluster ? getClusterExplorerUrl(cluster) : '';\n const type = cluster ? getClusterType(cluster) : null;\n\n return {\n cluster,\n clusters,\n setCluster,\n isMainnet,\n isDevnet,\n isTestnet,\n isLocal,\n explorerUrl,\n type,\n };\n }, [cluster, clusters, setCluster]);\n}\n","/**\n * @solana/connector - useAccount hook\n *\n * React hook for working with the connected wallet account\n */\n\n'use client';\n\nimport React, { useState, useCallback, useMemo } from 'react';\nimport { useConnector } from '../ui/connector-provider';\nimport { copyAddressToClipboard, formatAddress, ClipboardErrorType, type ClipboardResult } from '../utils';\nimport type { AccountInfo } from '../types/accounts';\nimport { COPY_FEEDBACK_DURATION_MS } from '../lib/constants';\n\nexport interface UseAccountReturn {\n /** The connected wallet address */\n address: string | null;\n /** Full account info object */\n account: AccountInfo | null;\n /** Whether a wallet is connected */\n connected: boolean;\n /** Shortened formatted address for display */\n formatted: string;\n /** Copy the address to clipboard with enhanced result */\n copy: () => Promise<ClipboardResult>;\n /** Whether the address was recently copied */\n copied: boolean;\n /** All available accounts from the connected wallet */\n accounts: AccountInfo[];\n /** Select a different account from the connected wallet */\n selectAccount: (address: string) => Promise<void>;\n}\n\n/**\n * Hook for working with the connected wallet account\n * Provides formatted address, clipboard copying, and account selection\n *\n * @example\n * ```tsx\n * function AccountDisplay() {\n * const { address, formatted, copy, copied, connected } = useAccount()\n *\n * if (!connected) return <p>Not connected</p>\n *\n * return (\n * <button onClick={copy}>\n * {formatted} {copied && '✓'}\n * </button>\n * )\n * }\n * ```\n */\nexport function useAccount(): UseAccountReturn {\n const { selectedAccount, accounts, connected, selectAccount } = useConnector();\n const [copied, setCopied] = useState(false);\n const copyTimeoutRef = React.useRef<NodeJS.Timeout | undefined>(undefined);\n\n const account = useMemo(\n () => accounts.find((a: AccountInfo) => a.address === selectedAccount) ?? null,\n [accounts, selectedAccount],\n );\n\n const formatted = useMemo(() => (selectedAccount ? formatAddress(selectedAccount) : ''), [selectedAccount]);\n\n const copy = useCallback(async (): Promise<ClipboardResult> => {\n if (!selectedAccount) {\n return {\n success: false,\n error: ClipboardErrorType.EMPTY_VALUE,\n errorMessage: 'No account selected',\n };\n }\n\n if (copyTimeoutRef.current) {\n clearTimeout(copyTimeoutRef.current);\n }\n\n const result = await copyAddressToClipboard(selectedAccount, {\n onSuccess: () => {\n setCopied(true);\n copyTimeoutRef.current = setTimeout(() => setCopied(false), COPY_FEEDBACK_DURATION_MS);\n },\n });\n\n return result;\n }, [selectedAccount]);\n\n React.useEffect(() => {\n return () => {\n if (copyTimeoutRef.current) {\n clearTimeout(copyTimeoutRef.current);\n }\n };\n }, []);\n\n return useMemo(\n () => ({\n address: selectedAccount,\n account,\n connected,\n formatted,\n copy,\n copied,\n accounts,\n selectAccount,\n }),\n [selectedAccount, account, connected, formatted, copy, copied, accounts, selectAccount],\n );\n}\n","/**\n * @solana/connector - useWalletInfo hook\n *\n * React hook for getting information about the connected wallet\n */\n\n'use client';\n\nimport { useMemo } from 'react';\nimport { useConnector } from '../ui/connector-provider';\nimport type { WalletInfo } from '../types/wallets';\n\n/**\n * Simplified wallet information for display purposes\n */\nexport interface WalletDisplayInfo {\n /** Wallet name */\n name: string;\n /** Wallet icon/logo URL if available */\n icon?: string;\n /** Whether the wallet extension is installed */\n installed: boolean;\n /** Whether the wallet supports Solana connections */\n connectable?: boolean;\n}\n\n/**\n * Return value from useWalletInfo hook\n */\nexport interface UseWalletInfoReturn {\n /** Name of the connected wallet (e.g., 'Phantom', 'Solflare') */\n name: string | null;\n /** Wallet icon/logo URL if available */\n icon: string | null;\n /** Whether the wallet extension is installed */\n installed: boolean;\n /** Whether the wallet supports Solana connections */\n connectable: boolean;\n /** Whether currently connected to the wallet */\n connected: boolean;\n /** Whether a connection attempt is in progress */\n connecting: boolean;\n /** All available wallets */\n wallets: WalletDisplayInfo[];\n}\n\n/**\n * Hook for getting information about the connected wallet\n * Provides wallet metadata, connection status, and capabilities\n *\n * @example\n * ```tsx\n * function WalletBadge() {\n * const { name, icon, connected, connecting } = useWalletInfo()\n *\n * if (connecting) return <p>Connecting...</p>\n * if (!connected) return <p>No wallet connected</p>\n *\n * return (\n * <div>\n * {icon && <img src={icon} alt={name} />}\n * <span>{name}</span>\n * </div>\n * )\n * }\n * ```\n */\nexport function useWalletInfo(): UseWalletInfoReturn {\n const { selectedWallet, wallets, connected, connecting } = useConnector();\n\n // Map WalletInfo[] to WalletDisplayInfo[] for simplified consumption\n const mappedWallets = useMemo<WalletDisplayInfo[]>(\n () =>\n wallets.map(\n (walletInfo: WalletInfo): WalletDisplayInfo => ({\n name: walletInfo.wallet.name,\n icon: walletInfo.wallet.icon,\n installed: walletInfo.installed,\n connectable: walletInfo.connectable,\n }),\n ),\n [wallets],\n );\n\n // Extract information about the currently selected wallet\n const selectedWalletInfo = useMemo(() => {\n if (!selectedWallet) {\n return {\n name: null,\n icon: null,\n installed: false,\n connectable: false,\n };\n }\n\n // Find the WalletInfo for the selected wallet\n const walletInfo = wallets.find((w: WalletInfo) => w.wallet.name === selectedWallet.name);\n\n return {\n name: selectedWallet.name,\n icon: selectedWallet.icon ?? null,\n installed: walletInfo?.installed ?? false,\n connectable: walletInfo?.connectable ?? false,\n };\n }, [selectedWallet, wallets]);\n\n return useMemo(\n () => ({\n ...selectedWalletInfo,\n connected,\n connecting,\n wallets: mappedWallets,\n }),\n [selectedWalletInfo, connected, connecting, mappedWallets],\n );\n}\n","/**\n * @solana/connector - useTransactionSigner hook\n *\n * React hook for transaction signing operations\n * Provides a clean interface for signing and sending transactions\n * with automatic signer creation and lifecycle management\n */\n\n'use client';\n\nimport { useMemo } from 'react';\nimport { useConnector } from '../ui/connector-provider';\nimport { useConnectorClient } from '../ui/connector-provider';\nimport { createTransactionSigner, type TransactionSigner } from '../lib/transaction/transaction-signer';\nimport type { TransactionSignerCapabilities } from '../types/transactions';\n\n/**\n * Return value from useTransactionSigner hook\n */\nexport interface UseTransactionSignerReturn {\n /**\n * Transaction signer instance (null if not connected)\n * Use this to sign and send transactions\n */\n signer: TransactionSigner | null;\n\n /**\n * Whether a signer is available and ready to use\n * Useful for disabling transaction buttons\n */\n ready: boolean;\n\n /**\n * Current wallet address that will sign transactions\n * Null if no wallet connected\n */\n address: string | null;\n\n /**\n * Signer capabilities (what operations are supported)\n * Always available even if signer is null (shows all false)\n */\n capabilities: TransactionSignerCapabilities;\n}\n\n/**\n * Hook for transaction signing operations\n *\n * Automatically creates a TransactionSigner when a wallet is connected,\n * and provides convenient state for building transaction UIs.\n *\n * The signer is automatically recreated when:\n * - Wallet connection state changes\n * - Selected account changes\n * - Active cluster/network changes\n *\n * @example\n * ```tsx\n * function SendTransaction() {\n * const { signer, ready, capabilities } = useTransactionSigner()\n * const [txSignature, setTxSignature] = useState<string | null>(null)\n * const [error, setError] = useState<string | null>(null)\n *\n * const handleSend = async () => {\n * if (!signer) return\n *\n * try {\n * const signature = await signer.signAndSendTransaction(transaction)\n * setTxSignature(signature)\n * setError(null)\n * } catch (err) {\n * setError(err instanceof Error ? err.message : 'Transaction failed')\n * }\n * }\n *\n * return (\n * <div>\n * <button onClick={handleSend} disabled={!ready}>\n * {ready ? 'Send Transaction' : 'Connect Wallet'}\n * </button>\n *\n * {!capabilities.canSend && ready && (\n * <p className=\"warning\">\n * Your wallet doesn't support direct sending.\n * Transaction must be signed and broadcast separately.\n * </p>\n * )}\n *\n * {txSignature && (\n * <p>Transaction sent: {txSignature}</p>\n * )}\n *\n * {error && (\n * <p className=\"error\">{error}</p>\n * )}\n * </div>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Using with multiple transactions\n * function SendBatch() {\n * const { signer, ready, capabilities } = useTransactionSigner()\n *\n * const handleSendBatch = async () => {\n * if (!signer) return\n *\n * const transactions = [tx1, tx2, tx3]\n *\n * // Check if batch signing is supported\n * if (capabilities.supportsBatchSigning) {\n * // More efficient: sign all at once\n * const signed = await signer.signAllTransactions(transactions)\n * // ... send signed transactions\n * } else {\n * // Fallback: sign and send one by one\n * const signatures = await signer.signAndSendTransactions(transactions)\n * console.log('All sent:', signatures)\n * }\n * }\n *\n * return (\n * <button onClick={handleSendBatch} disabled={!ready}>\n * Send {capabilities.supportsBatchSigning ? 'Batch' : 'Sequential'}\n * </button>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Using with message signing for authentication\n * function SignInWithWallet() {\n * const { signer, ready, capabilities } = useTransactionSigner()\n *\n * const handleSignIn = async () => {\n * if (!signer || !capabilities.canSignMessage) {\n * alert('Wallet does not support message signing')\n * return\n * }\n *\n * const message = new TextEncoder().encode('Sign in to MyApp')\n * const signature = await signer.signMessage!(message)\n *\n * // Send signature to backend for verification\n * await fetch('/api/auth/verify', {\n * method: 'POST',\n * body: JSON.stringify({\n * message: Array.from(message),\n * signature: Array.from(signature),\n * address: signer.address\n * })\n * })\n * }\n *\n * if (!capabilities.canSignMessage) {\n * return <p>Message signing not supported</p>\n * }\n *\n * return (\n * <button onClick={handleSignIn} disabled={!ready}>\n * Sign In with Wallet\n * </button>\n * )\n * }\n * ```\n */\nexport function useTransactionSigner(): UseTransactionSignerReturn {\n const { selectedWallet, selectedAccount, accounts, cluster, connected } = useConnector();\n const client = useConnectorClient();\n\n const account = useMemo(\n () => accounts.find(a => a.address === selectedAccount)?.raw ?? null,\n [accounts, selectedAccount],\n );\n\n const signer = useMemo(() => {\n if (!connected || !selectedWallet || !account) {\n return null;\n }\n\n return createTransactionSigner({\n wallet: selectedWallet,\n account,\n cluster: cluster ?? undefined,\n eventEmitter: client\n ? {\n emit: (event: unknown) => {\n // Use the public emitEvent method\n client.emitEvent(event as import('../types/events').ConnectorEvent);\n },\n }\n : undefined,\n });\n }, [connected, selectedWallet, account, cluster, client]);\n\n const capabilities = useMemo(\n () =>\n signer?.getCapabilities() ?? {\n canSign: false,\n canSend: false,\n canSignMessage: false,\n supportsBatchSigning: false,\n },\n [signer],\n );\n\n return {\n signer,\n ready: Boolean(signer),\n address: selectedAccount,\n capabilities,\n };\n}\n","/**\n * @solana/connector - useGillTransactionSigner hook\n *\n * React hook for gill-compatible transaction signing\n * Use this when working with modern Solana libraries (@solana/kit, gill)\n */\n\n'use client';\n\nimport { useMemo } from 'react';\nimport type { TransactionModifyingSigner } from 'gill';\nimport { useTransactionSigner } from './use-transaction-signer';\nimport { createGillTransactionSigner } from '../lib/transaction/gill-transaction-signer';\n\n/**\n * Return value from useGillTransactionSigner hook\n */\nexport interface UseGillTransactionSignerReturn {\n /**\n * Gill-compatible TransactionModifyingSigner instance (null if not connected)\n * Use this with modern Solana libraries (@solana/kit, gill)\n */\n signer: TransactionModifyingSigner | null;\n\n /**\n * Whether a signer is available and ready to use\n * Useful for disabling transaction buttons\n */\n ready: boolean;\n}\n\n/**\n * Hook for gill-compatible transaction signing\n *\n * Creates a TransactionPartialSigner that's compatible with @solana/kit and gill,\n * enabling seamless integration with modern Solana development patterns.\n *\n * This hook wraps the standard useTransactionSigner and adapts it to gill's\n * interface, allowing you to use modern libraries without type incompatibilities.\n *\n * @example\n * ```tsx\n * import { useGillTransactionSigner } from '@solana/connector';\n * import { getTransferSolInstruction } from 'gill/programs';\n * import { address, pipe, createTransactionMessage } from 'gill';\n *\n * function ModernTransfer() {\n * const { signer, ready } = useGillTransactionSigner();\n *\n * const handleTransfer = async (recipient: string, amount: number) => {\n * if (!signer) return;\n *\n * // Fully type-safe with gill!\n * const instruction = getTransferSolInstruction({\n * source: signer, // No type errors\n * destination: address(recipient),\n * amount\n * });\n *\n * const txMessage = pipe(\n * createTransactionMessage({ version: 0 }),\n * (tx) => setTransactionMessageFeePayerSigner(signer, tx), // Works!\n * // ...\n * );\n * };\n *\n * return (\n * <button onClick={handleTransfer} disabled={!ready}>\n * Send with Gill\n * </button>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // For backward compatibility, continue using useTransactionSigner\n * import { useTransactionSigner } from '@solana/connector';\n *\n * function LegacyTransfer() {\n * const { signer } = useTransactionSigner(); // Wallet adapter compatible\n * // Works with @solana/web3.js v1 and wallet-adapter\n * }\n * ```\n */\nexport function useGillTransactionSigner(): UseGillTransactionSignerReturn {\n const { signer: connectorSigner, ready } = useTransactionSigner();\n\n const gillSigner = useMemo(() => {\n if (!connectorSigner) return null;\n return createGillTransactionSigner(connectorSigner);\n }, [connectorSigner]);\n\n return {\n signer: gillSigner,\n ready,\n };\n}\n","/**\n * @solana/connector - useGillSolanaClient hook\n *\n * React hook for Gill's SolanaClient with built-in RPC and WebSocket subscriptions\n * Provides rpc, rpcSubscriptions, sendAndConfirmTransaction, and simulateTransaction\n */\n\n'use client';\n\nimport { useMemo } from 'react';\nimport { createSolanaClient, type SolanaClient, type ModifiedClusterUrl } from 'gill';\nimport { useCluster } from './use-cluster';\nimport { useConnectorClient } from '../ui/connector-provider';\nimport type { ClusterType } from '../utils/cluster';\nimport { createLogger } from '../lib/utils/secure-logger';\n\nconst logger = createLogger('useGillSolanaClient');\n\n/**\n * Return value from useGillSolanaClient hook\n */\nexport interface UseGillSolanaClientReturn {\n /**\n * Gill SolanaClient instance with RPC and subscriptions (null if not available)\n * Includes: rpc, rpcSubscriptions, sendAndConfirmTransaction, simulateTransaction\n */\n client: SolanaClient | null;\n\n /**\n * Whether a client is available and ready to use\n */\n ready: boolean;\n\n /**\n * Cluster type (mainnet, devnet, testnet, localnet, custom)\n */\n clusterType: ClusterType | null;\n}\n\n/**\n * Hook for Gill's SolanaClient with automatic RPC and WebSocket subscription management\n *\n * Creates a fully configured SolanaClient based on the current cluster, providing:\n * - Type-safe RPC client\n * - WebSocket subscription client\n * - Built-in sendAndConfirmTransaction helper\n * - Built-in simulateTransaction helper\n *\n * The client is automatically recreated when the cluster changes.\n *\n * @example\n * ```tsx\n * import { useGillSolanaClient, useGillTransactionSigner } from '@solana/connector';\n * import { signTransactionMessageWithSigners } from 'gill';\n *\n * function SendTransaction() {\n * const { client, ready } = useGillSolanaClient();\n * const { signer } = useGillTransactionSigner();\n *\n * const handleSend = async (transaction) => {\n * if (!client || !signer) return;\n *\n * // Sign the transaction\n * const signed = await signTransactionMessageWithSigners(transaction);\n *\n * // Send and confirm using Gill's built-in helper\n * await client.sendAndConfirmTransaction(signed, {\n * commitment: 'confirmed'\n * });\n * };\n *\n * return (\n * <button onClick={handleSend} disabled={!ready}>\n * Send Transaction\n * </button>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Simulating a transaction\n * function SimulateTransaction() {\n * const { client } = useGillSolanaClient();\n *\n * const handleSimulate = async (transaction) => {\n * if (!client) return;\n *\n * const simulation = await client.simulateTransaction(transaction, {\n * sigVerify: false,\n * commitment: 'processed'\n * });\n *\n * console.log('Simulation result:', simulation);\n * };\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Direct RPC access\n * function GetBalance() {\n * const { client } = useGillSolanaClient();\n *\n * const fetchBalance = async (address: Address) => {\n * if (!client) return;\n *\n * const balance = await client.rpc.getBalance(address).send();\n * console.log('Balance:', balance);\n * };\n * }\n * ```\n */\nexport function useGillSolanaClient(): UseGillSolanaClientReturn {\n const { type } = useCluster();\n const connectorClient = useConnectorClient();\n\n const client = useMemo(() => {\n if (!type || !connectorClient) return null;\n\n try {\n // For non-custom clusters, use moniker\n if (type !== 'custom') {\n return createSolanaClient({\n urlOrMoniker: type,\n });\n }\n\n // For custom clusters, get RPC URL from connector client\n const rpcUrl = connectorClient.getRpcUrl();\n if (!rpcUrl) return null;\n\n return createSolanaClient({\n urlOrMoniker: rpcUrl as ModifiedClusterUrl,\n });\n } catch (error) {\n logger.error('Failed to create Gill Solana client', { error });\n return null;\n }\n }, [type, connectorClient]);\n\n return {\n client,\n ready: Boolean(client),\n clusterType: type,\n };\n}\n","/**\n * @solana/connector - useTransactionPreparer hook\n *\n * React hook for preparing transactions with automatic optimization\n * Handles blockhash fetching, compute unit limits, and transaction simulation\n */\n\n'use client';\n\nimport { useCallback } from 'react';\nimport {\n prepareTransaction,\n type PrepareTransactionConfig,\n type CompilableTransactionMessage,\n type TransactionMessageWithBlockhashLifetime,\n} from 'gill';\nimport { useGillSolanaClient } from './use-gill-solana-client';\nimport { NetworkError } from '../lib/errors';\n\n/**\n * Options for transaction preparation\n */\nexport interface TransactionPrepareOptions {\n /**\n * Multiplier applied to the simulated compute unit value\n * @default 1.1 (10% buffer)\n */\n computeUnitLimitMultiplier?: number;\n\n /**\n * Whether to force reset the compute unit limit value (if one is already set)\n * using the simulation response and computeUnitLimitMultiplier\n * @default false\n */\n computeUnitLimitReset?: boolean;\n\n /**\n * Whether to force reset the latest blockhash (if one is already set)\n * @default true\n */\n blockhashReset?: boolean;\n}\n\n/**\n * Return value from useTransactionPreparer hook\n */\nexport interface UseTransactionPreparerReturn {\n /**\n * Prepare a transaction for sending\n * Automatically adds:\n * - Compute unit limit (via simulation with optional multiplier)\n * - Latest blockhash (if not already set)\n *\n * @param transaction - The transaction to prepare\n * @param options - Optional preparation settings\n * @returns Prepared transaction with blockhash lifetime set\n */\n prepare: <TMessage extends CompilableTransactionMessage>(\n transaction: TMessage,\n options?: TransactionPrepareOptions,\n ) => Promise<TMessage & TransactionMessageWithBlockhashLifetime>;\n\n /**\n * Whether the preparer is ready to use\n * False if Solana client is not available\n */\n ready: boolean;\n}\n\n/**\n * Hook for preparing transactions with automatic optimization\n *\n * Uses Gill's prepareTransaction utility to:\n * 1. Simulate the transaction to determine optimal compute units\n * 2. Set compute unit limit (with configurable multiplier for safety margin)\n * 3. Fetch and set the latest blockhash (if not already present)\n *\n * This significantly improves transaction landing rates by ensuring proper\n * compute budget allocation and fresh blockhashes.\n *\n * @example\n * ```tsx\n * import { useTransactionPreparer, useGillTransactionSigner } from '@solana/connector';\n * import { pipe, createTransactionMessage, appendTransactionMessageInstructions } from 'gill';\n * import { getTransferSolInstruction } from 'gill/programs';\n *\n * function SendOptimizedTransaction() {\n * const { prepare, ready } = useTransactionPreparer();\n * const { signer } = useGillTransactionSigner();\n * const { client } = useGillSolanaClient();\n *\n * const handleSend = async (recipient: string, amount: bigint) => {\n * if (!ready || !signer || !client) return;\n *\n * // Build transaction message\n * const tx = pipe(\n * createTransactionMessage({ version: 0 }),\n * tx => setTransactionMessageFeePayerSigner(signer, tx),\n * tx => appendTransactionMessageInstructions([\n * getTransferSolInstruction({\n * source: signer,\n * destination: address(recipient),\n * amount: lamports(amount),\n * })\n * ], tx)\n * );\n *\n * // Prepare: auto-adds compute units + blockhash\n * const prepared = await prepare(tx);\n *\n * // Sign\n * const signed = await signTransactionMessageWithSigners(prepared);\n *\n * // Send and confirm\n * await client.sendAndConfirmTransaction(signed);\n * };\n *\n * return (\n * <button onClick={handleSend} disabled={!ready}>\n * Send Optimized Transaction\n * </button>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With custom compute unit multiplier for high-priority transactions\n * const { prepare } = useTransactionPreparer();\n *\n * const prepared = await prepare(transaction, {\n * computeUnitLimitMultiplier: 1.3, // 30% buffer instead of default 10%\n * blockhashReset: true // Always fetch fresh blockhash\n * });\n * ```\n *\n * @example\n * ```tsx\n * // Force reset compute units even if already set\n * const { prepare } = useTransactionPreparer();\n *\n * const prepared = await prepare(transaction, {\n * computeUnitLimitReset: true, // Re-simulate and reset compute units\n * computeUnitLimitMultiplier: 1.2\n * });\n * ```\n */\nexport function useTransactionPreparer(): UseTransactionPreparerReturn {\n const { client, ready } = useGillSolanaClient();\n\n const prepare = useCallback(\n async <TMessage extends CompilableTransactionMessage>(\n transaction: TMessage,\n options: TransactionPrepareOptions = {},\n ): Promise<TMessage & TransactionMessageWithBlockhashLifetime> => {\n if (!client) {\n throw new NetworkError('RPC_ERROR', 'Solana client not available. Cannot prepare transaction.');\n }\n\n return prepareTransaction({\n transaction,\n rpc: client.rpc,\n computeUnitLimitMultiplier: options.computeUnitLimitMultiplier,\n computeUnitLimitReset: options.computeUnitLimitReset,\n blockhashReset: options.blockhashReset,\n });\n },\n [client],\n );\n\n return {\n prepare,\n ready,\n };\n}\n"]}