@solana/connector 0.1.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +403 -50
- package/dist/chunk-4KD6HQQG.js +69 -0
- package/dist/chunk-4KD6HQQG.js.map +1 -0
- package/dist/chunk-BJAVJQLK.js +230 -0
- package/dist/chunk-BJAVJQLK.js.map +1 -0
- package/dist/{chunk-5HRJKCIL.js → chunk-BZ2VBJCZ.js} +1061 -424
- package/dist/chunk-BZ2VBJCZ.js.map +1 -0
- package/dist/{chunk-WDXEP4AJ.js → chunk-EM4KNOKG.js} +658 -190
- package/dist/chunk-EM4KNOKG.js.map +1 -0
- package/dist/chunk-HN5AJF7F.js +507 -0
- package/dist/chunk-HN5AJF7F.js.map +1 -0
- package/dist/chunk-HO6QNKFM.mjs +61 -0
- package/dist/chunk-HO6QNKFM.mjs.map +1 -0
- package/dist/chunk-HPQ5T32K.mjs +178 -0
- package/dist/chunk-HPQ5T32K.mjs.map +1 -0
- package/dist/{chunk-MAXA3HEP.mjs → chunk-IDTUFDNB.mjs} +962 -344
- package/dist/chunk-IDTUFDNB.mjs.map +1 -0
- package/dist/{chunk-P5LXUDP6.mjs → chunk-RTXUS5KG.mjs} +579 -119
- package/dist/chunk-RTXUS5KG.mjs.map +1 -0
- package/dist/{chunk-DSUCH44G.js → chunk-SITQ4JWM.js} +23 -67
- package/dist/chunk-SITQ4JWM.js.map +1 -0
- package/dist/chunk-UCISIAOG.mjs +501 -0
- package/dist/chunk-UCISIAOG.mjs.map +1 -0
- package/dist/{chunk-J7DHGLW6.mjs → chunk-ZZTY3O4N.mjs} +21 -61
- package/dist/chunk-ZZTY3O4N.mjs.map +1 -0
- package/dist/compat.d.mts +1 -1
- package/dist/compat.d.ts +1 -1
- package/dist/compat.js +10 -9
- package/dist/compat.js.map +1 -1
- package/dist/compat.mjs +2 -1
- package/dist/compat.mjs.map +1 -1
- package/dist/headless.d.mts +239 -104
- package/dist/headless.d.ts +239 -104
- package/dist/headless.js +255 -169
- package/dist/headless.mjs +5 -3
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +316 -206
- package/dist/index.mjs +6 -4
- package/dist/react.d.mts +299 -9
- package/dist/react.d.ts +299 -9
- package/dist/react.js +90 -38
- package/dist/react.mjs +2 -2
- package/dist/{standard-shim-CT49DM5l.d.mts → standard-shim-CGB88PPO.d.mts} +673 -52
- package/dist/{standard-shim-D9guL5fz.d.ts → standard-shim-tmnQelaJ.d.ts} +673 -52
- package/dist/{transaction-signer-T-KVQFi8.d.mts → transaction-signer-7NaYmP5w.d.mts} +1 -0
- package/dist/{transaction-signer-T-KVQFi8.d.ts → transaction-signer-7NaYmP5w.d.ts} +1 -0
- package/dist/walletconnect-447EY3OJ.js +28 -0
- package/dist/walletconnect-447EY3OJ.js.map +1 -0
- package/dist/walletconnect-U455PO4I.mjs +3 -0
- package/dist/walletconnect-U455PO4I.mjs.map +1 -0
- package/package.json +6 -2
- package/dist/chunk-5HRJKCIL.js.map +0 -1
- package/dist/chunk-DSUCH44G.js.map +0 -1
- package/dist/chunk-I6TJLYNA.js +0 -535
- package/dist/chunk-I6TJLYNA.js.map +0 -1
- package/dist/chunk-J7DHGLW6.mjs.map +0 -1
- package/dist/chunk-JOBLG62A.mjs +0 -476
- package/dist/chunk-JOBLG62A.mjs.map +0 -1
- package/dist/chunk-MAXA3HEP.mjs.map +0 -1
- package/dist/chunk-P5LXUDP6.mjs.map +0 -1
- package/dist/chunk-WDXEP4AJ.js.map +0 -1
package/dist/chunk-JOBLG62A.mjs
DELETED
|
@@ -1,476 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_MAX_RETRIES, toClusterId, getClusterType } from './chunk-MAXA3HEP.mjs';
|
|
2
|
-
import { createLogger, __publicField, getExplorerLink } from './chunk-J7DHGLW6.mjs';
|
|
3
|
-
import { Storage, createSolanaMainnet, createSolanaDevnet, createSolanaTestnet, createSolanaLocalnet } from '@wallet-ui/core';
|
|
4
|
-
export { createSolanaDevnet, createSolanaLocalnet, createSolanaMainnet, createSolanaTestnet } from '@wallet-ui/core';
|
|
5
|
-
import { isAddress } from '@solana/addresses';
|
|
6
|
-
export { address } from '@solana/addresses';
|
|
7
|
-
import { z } from 'zod/v4';
|
|
8
|
-
export { createSignableMessage } from '@solana/signers';
|
|
9
|
-
|
|
10
|
-
var logger = createLogger("EnhancedStorage"), STORAGE_VERSION = "v1", EnhancedStorage = class extends Storage {
|
|
11
|
-
constructor(key, initial, options) {
|
|
12
|
-
super(key, initial);
|
|
13
|
-
this.options = options;
|
|
14
|
-
__publicField(this, "errorHandlers", /* @__PURE__ */ new Set());
|
|
15
|
-
__publicField(this, "validators", []);
|
|
16
|
-
__publicField(this, "memoryFallback");
|
|
17
|
-
this.memoryFallback = initial, options?.onError && this.errorHandlers.add(options.onError), options?.validator && this.validators.push(options.validator);
|
|
18
|
-
}
|
|
19
|
-
set(value) {
|
|
20
|
-
try {
|
|
21
|
-
return this.validate(value) ? (super.set(value), this.memoryFallback = value, true) : (logger.warn("Validation failed", { key: this.key }), false);
|
|
22
|
-
} catch (error) {
|
|
23
|
-
return this.handleError(error), this.options?.useMemoryFallback ? (this.memoryFallback = value, true) : false;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
get() {
|
|
27
|
-
try {
|
|
28
|
-
return super.get();
|
|
29
|
-
} catch (error) {
|
|
30
|
-
return this.handleError(error), this.options?.useMemoryFallback ? this.memoryFallback : this.initial;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
validate(value) {
|
|
34
|
-
return this.validators.every((validator) => validator(value));
|
|
35
|
-
}
|
|
36
|
-
addValidator(validator) {
|
|
37
|
-
return this.validators.push(validator), this;
|
|
38
|
-
}
|
|
39
|
-
onError(handler) {
|
|
40
|
-
return this.errorHandlers.add(handler), this;
|
|
41
|
-
}
|
|
42
|
-
transform(transformer) {
|
|
43
|
-
return transformer(this.get());
|
|
44
|
-
}
|
|
45
|
-
reset() {
|
|
46
|
-
this.set(this.initial);
|
|
47
|
-
}
|
|
48
|
-
clear() {
|
|
49
|
-
try {
|
|
50
|
-
typeof window < "u" && window.localStorage && window.localStorage.removeItem(this.key), this.reset();
|
|
51
|
-
} catch (error) {
|
|
52
|
-
this.handleError(error);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
isAvailable() {
|
|
56
|
-
try {
|
|
57
|
-
if (typeof window > "u") return false;
|
|
58
|
-
let testKey = `__storage_test_${this.key}__`;
|
|
59
|
-
return window.localStorage.setItem(testKey, "test"), window.localStorage.removeItem(testKey), true;
|
|
60
|
-
} catch {
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
static migrate(oldKey, newStorage) {
|
|
65
|
-
try {
|
|
66
|
-
if (typeof window > "u") return false;
|
|
67
|
-
let oldValue = window.localStorage.getItem(oldKey);
|
|
68
|
-
if (oldValue) {
|
|
69
|
-
let parsed = JSON.parse(oldValue);
|
|
70
|
-
return newStorage.set(parsed), window.localStorage.removeItem(oldKey), true;
|
|
71
|
-
}
|
|
72
|
-
return false;
|
|
73
|
-
} catch {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
handleError(error) {
|
|
78
|
-
logger.error("Storage error", { key: this.key, error }), this.errorHandlers.forEach((handler) => {
|
|
79
|
-
try {
|
|
80
|
-
handler(error);
|
|
81
|
-
} catch (err) {
|
|
82
|
-
logger.error("Error in error handler", { error: err });
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
function createEnhancedStorageAccount(options) {
|
|
88
|
-
let key = options?.key ?? `connector-kit:${STORAGE_VERSION}:account`;
|
|
89
|
-
return new EnhancedStorage(key, options?.initial, {
|
|
90
|
-
validator: options?.validator,
|
|
91
|
-
onError: options?.onError,
|
|
92
|
-
useMemoryFallback: true
|
|
93
|
-
// Always fallback for SSR
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
function createEnhancedStorageCluster(options) {
|
|
97
|
-
let key = options?.key ?? `connector-kit:${STORAGE_VERSION}:cluster`, storage = new EnhancedStorage(key, options?.initial ?? "solana:mainnet", {
|
|
98
|
-
onError: options?.onError,
|
|
99
|
-
useMemoryFallback: true
|
|
100
|
-
});
|
|
101
|
-
return options?.validClusters && storage.addValidator((clusterId) => options.validClusters.includes(clusterId)), storage;
|
|
102
|
-
}
|
|
103
|
-
function createEnhancedStorageWallet(options) {
|
|
104
|
-
let key = options?.key ?? `connector-kit:${STORAGE_VERSION}:wallet`;
|
|
105
|
-
return new EnhancedStorage(key, options?.initial, {
|
|
106
|
-
onError: options?.onError,
|
|
107
|
-
useMemoryFallback: true
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
var EnhancedStorageAdapter = class {
|
|
111
|
-
constructor(storage) {
|
|
112
|
-
this.storage = storage;
|
|
113
|
-
}
|
|
114
|
-
get() {
|
|
115
|
-
return this.storage.get();
|
|
116
|
-
}
|
|
117
|
-
set(value) {
|
|
118
|
-
this.storage.set(value);
|
|
119
|
-
}
|
|
120
|
-
subscribe(callback) {
|
|
121
|
-
return this.storage.value.subscribe(callback);
|
|
122
|
-
}
|
|
123
|
-
validate(value) {
|
|
124
|
-
return this.storage.validate(value);
|
|
125
|
-
}
|
|
126
|
-
reset() {
|
|
127
|
-
this.storage.reset();
|
|
128
|
-
}
|
|
129
|
-
clear() {
|
|
130
|
-
this.storage.clear();
|
|
131
|
-
}
|
|
132
|
-
isAvailable() {
|
|
133
|
-
return this.storage.isAvailable();
|
|
134
|
-
}
|
|
135
|
-
transform(transformer) {
|
|
136
|
-
return this.storage.transform(transformer);
|
|
137
|
-
}
|
|
138
|
-
addValidator(validator) {
|
|
139
|
-
return this.storage.addValidator(validator), this;
|
|
140
|
-
}
|
|
141
|
-
onError(handler) {
|
|
142
|
-
return this.storage.onError(handler), this;
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
var logger2 = createLogger("DefaultConfig");
|
|
146
|
-
function getDefaultConfig(options) {
|
|
147
|
-
let {
|
|
148
|
-
appName,
|
|
149
|
-
appUrl,
|
|
150
|
-
autoConnect = true,
|
|
151
|
-
debug,
|
|
152
|
-
network = "mainnet-beta",
|
|
153
|
-
enableMobile = true,
|
|
154
|
-
storage,
|
|
155
|
-
clusters,
|
|
156
|
-
customClusters = [],
|
|
157
|
-
persistClusterSelection = true,
|
|
158
|
-
clusterStorageKey,
|
|
159
|
-
enableErrorBoundary = true,
|
|
160
|
-
maxRetries = DEFAULT_MAX_RETRIES,
|
|
161
|
-
onError,
|
|
162
|
-
imageProxy,
|
|
163
|
-
programLabels,
|
|
164
|
-
coingecko
|
|
165
|
-
} = options, defaultClusters = clusters ?? [
|
|
166
|
-
createSolanaMainnet(),
|
|
167
|
-
createSolanaDevnet(),
|
|
168
|
-
createSolanaTestnet(),
|
|
169
|
-
...network === "localnet" ? [createSolanaLocalnet()] : [],
|
|
170
|
-
...customClusters || []
|
|
171
|
-
], validClusterIds = defaultClusters.map((c) => c.id), accountStorage = createEnhancedStorageAccount({
|
|
172
|
-
validator: (address2) => address2 ? isAddress(address2) : true,
|
|
173
|
-
onError: (error) => {
|
|
174
|
-
debug && logger2.error("Account Storage error", { error }), onError && onError(error, {
|
|
175
|
-
componentStack: "account-storage"
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
}), clusterStorage = createEnhancedStorageCluster({
|
|
179
|
-
key: clusterStorageKey,
|
|
180
|
-
initial: getInitialCluster(network),
|
|
181
|
-
validClusters: persistClusterSelection ? validClusterIds : void 0,
|
|
182
|
-
onError: (error) => {
|
|
183
|
-
debug && logger2.error("Cluster Storage error", { error }), onError && onError(error, {
|
|
184
|
-
componentStack: "cluster-storage"
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
}), walletStorage = createEnhancedStorageWallet({
|
|
188
|
-
onError: (error) => {
|
|
189
|
-
debug && logger2.error("Wallet Storage error", { error }), onError && onError(error, {
|
|
190
|
-
componentStack: "wallet-storage"
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
if (typeof window < "u") {
|
|
195
|
-
let oldAccountKey = "connector-kit:account", oldWalletKey = "connector-kit:wallet", oldClusterKey = clusterStorageKey || "connector-kit:cluster";
|
|
196
|
-
EnhancedStorage.migrate(oldAccountKey, accountStorage), EnhancedStorage.migrate(oldWalletKey, walletStorage), EnhancedStorage.migrate(oldClusterKey, clusterStorage);
|
|
197
|
-
}
|
|
198
|
-
let defaultStorage = storage ?? {
|
|
199
|
-
account: new EnhancedStorageAdapter(accountStorage),
|
|
200
|
-
cluster: new EnhancedStorageAdapter(clusterStorage),
|
|
201
|
-
wallet: new EnhancedStorageAdapter(walletStorage)
|
|
202
|
-
};
|
|
203
|
-
return {
|
|
204
|
-
autoConnect,
|
|
205
|
-
debug: debug ?? process.env.NODE_ENV === "development",
|
|
206
|
-
storage: defaultStorage,
|
|
207
|
-
appName,
|
|
208
|
-
appUrl,
|
|
209
|
-
enableMobile,
|
|
210
|
-
network,
|
|
211
|
-
cluster: {
|
|
212
|
-
clusters: defaultClusters,
|
|
213
|
-
persistSelection: persistClusterSelection,
|
|
214
|
-
initialCluster: getInitialCluster(network)
|
|
215
|
-
},
|
|
216
|
-
errorBoundary: {
|
|
217
|
-
enabled: enableErrorBoundary,
|
|
218
|
-
maxRetries,
|
|
219
|
-
onError
|
|
220
|
-
},
|
|
221
|
-
imageProxy,
|
|
222
|
-
programLabels,
|
|
223
|
-
coingecko
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
function getInitialCluster(network = "mainnet-beta") {
|
|
227
|
-
return toClusterId(network);
|
|
228
|
-
}
|
|
229
|
-
function getDefaultMobileConfig(options) {
|
|
230
|
-
let baseUrl = options.appUrl || (typeof window < "u" ? window.location.origin : "https://localhost:3000");
|
|
231
|
-
return {
|
|
232
|
-
appIdentity: {
|
|
233
|
-
name: options.appName,
|
|
234
|
-
uri: baseUrl,
|
|
235
|
-
icon: `${baseUrl}/favicon.ico`
|
|
236
|
-
},
|
|
237
|
-
cluster: options.network || "mainnet-beta"
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
var solanaNetworkSchema = z.enum(["mainnet", "mainnet-beta", "devnet", "testnet", "localnet"]), solanaClusterIdSchema = z.string().regex(/^solana:(mainnet|devnet|testnet|localnet|[a-zA-Z0-9-]+)$/, {
|
|
241
|
-
message: 'Cluster ID must be in format "solana:<network>" (e.g., "solana:mainnet")'
|
|
242
|
-
}), urlSchema = z.string().url("Invalid URL format"), optionalUrlSchema = urlSchema.optional(), coinGeckoConfigSchema = z.strictObject({
|
|
243
|
-
apiKey: z.string().optional(),
|
|
244
|
-
isPro: z.boolean().optional(),
|
|
245
|
-
maxRetries: z.number().int().positive().max(10).optional(),
|
|
246
|
-
baseDelay: z.number().int().positive().max(3e4).optional(),
|
|
247
|
-
maxTimeout: z.number().int().positive().max(12e4).optional()
|
|
248
|
-
}).optional(), storageAdapterSchema = z.looseObject({
|
|
249
|
-
get: z.custom((val) => typeof val == "function"),
|
|
250
|
-
set: z.custom((val) => typeof val == "function")
|
|
251
|
-
}), storageConfigSchema = z.object({
|
|
252
|
-
account: storageAdapterSchema,
|
|
253
|
-
cluster: storageAdapterSchema,
|
|
254
|
-
wallet: storageAdapterSchema
|
|
255
|
-
}).optional(), solanaClusterSchema = z.object({
|
|
256
|
-
id: solanaClusterIdSchema,
|
|
257
|
-
label: z.string().min(1, "Cluster label cannot be empty"),
|
|
258
|
-
url: urlSchema,
|
|
259
|
-
urlWs: urlSchema.optional()
|
|
260
|
-
}), clusterConfigSchema = z.object({
|
|
261
|
-
clusters: z.array(solanaClusterSchema).optional(),
|
|
262
|
-
persistSelection: z.boolean().optional(),
|
|
263
|
-
initialCluster: solanaClusterIdSchema.optional()
|
|
264
|
-
}).optional(), defaultConfigOptionsSchema = z.object({
|
|
265
|
-
// Required
|
|
266
|
-
appName: z.string().min(1, "Application name is required"),
|
|
267
|
-
// Optional strings
|
|
268
|
-
appUrl: optionalUrlSchema,
|
|
269
|
-
imageProxy: z.string().optional(),
|
|
270
|
-
clusterStorageKey: z.string().optional(),
|
|
271
|
-
// Optional booleans
|
|
272
|
-
autoConnect: z.boolean().optional(),
|
|
273
|
-
debug: z.boolean().optional(),
|
|
274
|
-
enableMobile: z.boolean().optional(),
|
|
275
|
-
persistClusterSelection: z.boolean().optional(),
|
|
276
|
-
enableErrorBoundary: z.boolean().optional(),
|
|
277
|
-
// Network
|
|
278
|
-
network: solanaNetworkSchema.optional(),
|
|
279
|
-
// Numbers
|
|
280
|
-
maxRetries: z.number().int().positive().max(10).optional(),
|
|
281
|
-
// Complex types
|
|
282
|
-
storage: storageConfigSchema,
|
|
283
|
-
clusters: z.array(solanaClusterSchema).optional(),
|
|
284
|
-
customClusters: z.array(solanaClusterSchema).optional(),
|
|
285
|
-
programLabels: z.record(z.string(), z.string()).optional(),
|
|
286
|
-
coingecko: coinGeckoConfigSchema,
|
|
287
|
-
// Functions (can't validate implementation, just existence)
|
|
288
|
-
onError: z.custom((val) => typeof val == "function").optional()
|
|
289
|
-
}); z.strictObject({
|
|
290
|
-
autoConnect: z.boolean().optional(),
|
|
291
|
-
debug: z.boolean().optional(),
|
|
292
|
-
storage: storageConfigSchema,
|
|
293
|
-
cluster: clusterConfigSchema,
|
|
294
|
-
imageProxy: z.string().optional(),
|
|
295
|
-
programLabels: z.record(z.string(), z.string()).optional(),
|
|
296
|
-
coingecko: coinGeckoConfigSchema
|
|
297
|
-
}).optional();
|
|
298
|
-
function validateConfigOptions(options) {
|
|
299
|
-
return defaultConfigOptionsSchema.safeParse(options);
|
|
300
|
-
}
|
|
301
|
-
function parseConfigOptions(options) {
|
|
302
|
-
return defaultConfigOptionsSchema.parse(options);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// src/types/wallets.ts
|
|
306
|
-
function isWalletName(value) {
|
|
307
|
-
return typeof value == "string" && value.length > 0;
|
|
308
|
-
}
|
|
309
|
-
function isAccountAddress(value) {
|
|
310
|
-
return typeof value == "string" && value.length >= 32 && value.length <= 44;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// src/lib/connection/types.ts
|
|
314
|
-
function isLegacyConnection(conn) {
|
|
315
|
-
return "rpcEndpoint" in conn && typeof conn.rpcEndpoint == "string";
|
|
316
|
-
}
|
|
317
|
-
function isKitConnection(conn) {
|
|
318
|
-
if ("rpcEndpoint" in conn)
|
|
319
|
-
return false;
|
|
320
|
-
let asKitRpc = conn;
|
|
321
|
-
return typeof asKitRpc.getLatestBlockhash == "function" && typeof asKitRpc.sendTransaction == "function";
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// src/lib/connection/helpers.ts
|
|
325
|
-
async function getLatestBlockhash(connection, commitment = "confirmed") {
|
|
326
|
-
if (isLegacyConnection(connection))
|
|
327
|
-
return await connection.getLatestBlockhash(commitment);
|
|
328
|
-
if (isKitConnection(connection))
|
|
329
|
-
return (await connection.getLatestBlockhash({ commitment }).send()).value;
|
|
330
|
-
throw new Error("Unsupported connection type");
|
|
331
|
-
}
|
|
332
|
-
async function sendRawTransaction(connection, bytes, options) {
|
|
333
|
-
if (isLegacyConnection(connection))
|
|
334
|
-
return await connection.sendRawTransaction(bytes, options);
|
|
335
|
-
if (isKitConnection(connection)) {
|
|
336
|
-
let rpc = connection, base64String = Buffer.from(bytes).toString("base64");
|
|
337
|
-
return await rpc.sendTransaction(base64String, {
|
|
338
|
-
...options?.commitment ? { commitment: options.commitment } : {},
|
|
339
|
-
...options?.skipPreflight !== void 0 ? { skipPreflight: options.skipPreflight } : {},
|
|
340
|
-
...options?.maxRetries !== void 0 ? { maxRetries: options.maxRetries } : {}
|
|
341
|
-
}).send();
|
|
342
|
-
}
|
|
343
|
-
throw new Error("Unsupported connection type");
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// src/utils/chain.ts
|
|
347
|
-
var SOLANA_CHAIN_IDS = {
|
|
348
|
-
mainnet: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
|
|
349
|
-
devnet: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
|
|
350
|
-
testnet: "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z"
|
|
351
|
-
}, CHAIN_ID_TO_CLUSTER_TYPE = {
|
|
352
|
-
[SOLANA_CHAIN_IDS.mainnet]: "mainnet",
|
|
353
|
-
[SOLANA_CHAIN_IDS.devnet]: "devnet",
|
|
354
|
-
[SOLANA_CHAIN_IDS.testnet]: "testnet"
|
|
355
|
-
}, CLUSTER_ID_TO_CHAIN_ID = {
|
|
356
|
-
"solana:mainnet": SOLANA_CHAIN_IDS.mainnet,
|
|
357
|
-
"solana:mainnet-beta": SOLANA_CHAIN_IDS.mainnet,
|
|
358
|
-
"solana:devnet": SOLANA_CHAIN_IDS.devnet,
|
|
359
|
-
"solana:testnet": SOLANA_CHAIN_IDS.testnet
|
|
360
|
-
};
|
|
361
|
-
function getChainIdFromCluster(cluster) {
|
|
362
|
-
let clusterType = getClusterType(cluster);
|
|
363
|
-
return clusterType === "localnet" || clusterType === "custom" ? null : getChainIdFromClusterType(clusterType);
|
|
364
|
-
}
|
|
365
|
-
function getChainIdFromClusterId(clusterId) {
|
|
366
|
-
return CLUSTER_ID_TO_CHAIN_ID[clusterId] || null;
|
|
367
|
-
}
|
|
368
|
-
function getChainIdFromClusterType(type) {
|
|
369
|
-
switch (type) {
|
|
370
|
-
case "mainnet":
|
|
371
|
-
return SOLANA_CHAIN_IDS.mainnet;
|
|
372
|
-
case "devnet":
|
|
373
|
-
return SOLANA_CHAIN_IDS.devnet;
|
|
374
|
-
case "testnet":
|
|
375
|
-
return SOLANA_CHAIN_IDS.testnet;
|
|
376
|
-
case "localnet":
|
|
377
|
-
case "custom":
|
|
378
|
-
return null;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
function getClusterTypeFromChainId(chainId) {
|
|
382
|
-
return CHAIN_ID_TO_CLUSTER_TYPE[chainId] || null;
|
|
383
|
-
}
|
|
384
|
-
function getClusterIdFromChainId(chainId) {
|
|
385
|
-
let clusterType = getClusterTypeFromChainId(chainId);
|
|
386
|
-
if (!clusterType)
|
|
387
|
-
return null;
|
|
388
|
-
switch (clusterType) {
|
|
389
|
-
case "mainnet":
|
|
390
|
-
return "solana:mainnet";
|
|
391
|
-
case "devnet":
|
|
392
|
-
return "solana:devnet";
|
|
393
|
-
case "testnet":
|
|
394
|
-
return "solana:testnet";
|
|
395
|
-
default:
|
|
396
|
-
return null;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
function isSolanaChain(chain) {
|
|
400
|
-
return chain.startsWith("solana:");
|
|
401
|
-
}
|
|
402
|
-
function isKnownSolanaChain(chain) {
|
|
403
|
-
return chain === SOLANA_CHAIN_IDS.mainnet || chain === SOLANA_CHAIN_IDS.devnet || chain === SOLANA_CHAIN_IDS.testnet;
|
|
404
|
-
}
|
|
405
|
-
function validateKnownSolanaChain(chain) {
|
|
406
|
-
if (!isSolanaChain(chain))
|
|
407
|
-
throw new Error(`Invalid chain format: expected 'solana:...', got '${chain}'`);
|
|
408
|
-
if (!isKnownSolanaChain(chain))
|
|
409
|
-
throw new Error(`Unknown Solana chain: ${chain}. Known chains: ${Object.values(SOLANA_CHAIN_IDS).join(", ")}`);
|
|
410
|
-
}
|
|
411
|
-
function getClusterTypeFromConnection(connection) {
|
|
412
|
-
if (!connection)
|
|
413
|
-
return null;
|
|
414
|
-
let rpcUrl = connection.rpcEndpoint || "";
|
|
415
|
-
return rpcUrl.includes("mainnet") || rpcUrl.includes("api.mainnet-beta") ? "mainnet" : rpcUrl.includes("testnet") ? "testnet" : rpcUrl.includes("devnet") ? "devnet" : rpcUrl.includes("localhost") || rpcUrl.includes("127.0.0.1") ? "localnet" : "custom";
|
|
416
|
-
}
|
|
417
|
-
function getChainIdFromConnection(connection, network) {
|
|
418
|
-
if (network)
|
|
419
|
-
return getChainIdFromClusterType(network);
|
|
420
|
-
let clusterType = getClusterTypeFromConnection(connection);
|
|
421
|
-
return clusterType ? getChainIdFromClusterType(clusterType) : null;
|
|
422
|
-
}
|
|
423
|
-
function clusterToChainId(cluster) {
|
|
424
|
-
return getChainIdFromCluster(cluster);
|
|
425
|
-
}
|
|
426
|
-
function chainIdToClusterType(chainId) {
|
|
427
|
-
return getClusterTypeFromChainId(chainId);
|
|
428
|
-
}
|
|
429
|
-
function chainIdToClusterId(chainId) {
|
|
430
|
-
return getClusterIdFromChainId(chainId);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// src/lib/utils/explorer-urls.ts
|
|
434
|
-
function getSolanaExplorerUrl(signature, options = {}) {
|
|
435
|
-
let { cluster = "mainnet", customUrl } = options, normalizedCluster = cluster === "mainnet-beta" ? "mainnet" : cluster;
|
|
436
|
-
if (normalizedCluster === "localnet")
|
|
437
|
-
return `https://explorer.solana.com/tx/${signature}?cluster=custom&customUrl=${encodeURIComponent(customUrl || "http://localhost:8899")}`;
|
|
438
|
-
let explorerCluster = ["mainnet", "devnet", "testnet"].includes(normalizedCluster) ? normalizedCluster : "devnet";
|
|
439
|
-
return getExplorerLink({
|
|
440
|
-
transaction: signature,
|
|
441
|
-
cluster: explorerCluster
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
function getSolscanUrl(signature, options = {}) {
|
|
445
|
-
let { cluster = "mainnet" } = options, normalizedCluster = cluster === "mainnet-beta" ? "mainnet" : cluster;
|
|
446
|
-
return normalizedCluster === "mainnet" ? `https://solscan.io/tx/${signature}` : normalizedCluster === "localnet" ? `https://solscan.io/tx/${signature}?cluster=custom` : `https://solscan.io/tx/${signature}?cluster=${normalizedCluster}`;
|
|
447
|
-
}
|
|
448
|
-
function getXrayUrl(signature) {
|
|
449
|
-
return `https://xray.helius.xyz/tx/${signature}`;
|
|
450
|
-
}
|
|
451
|
-
function getSolanaFmUrl(signature, options = {}) {
|
|
452
|
-
let { cluster = "mainnet" } = options, normalizedCluster = cluster === "mainnet-beta" ? "mainnet" : cluster;
|
|
453
|
-
return normalizedCluster === "mainnet" ? `https://solana.fm/tx/${signature}` : `https://solana.fm/tx/${signature}?cluster=${normalizedCluster}`;
|
|
454
|
-
}
|
|
455
|
-
function getAllExplorerUrls(signature, options = {}) {
|
|
456
|
-
return {
|
|
457
|
-
"solana-explorer": getSolanaExplorerUrl(signature, options),
|
|
458
|
-
solscan: getSolscanUrl(signature, options),
|
|
459
|
-
xray: getXrayUrl(signature),
|
|
460
|
-
"solana-fm": getSolanaFmUrl(signature, options)
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
function formatSignature(signature, chars = 8) {
|
|
464
|
-
return signature.length <= chars * 2 ? signature : `${signature.slice(0, chars)}...${signature.slice(-chars)}`;
|
|
465
|
-
}
|
|
466
|
-
async function copySignature(signature) {
|
|
467
|
-
try {
|
|
468
|
-
return await navigator.clipboard.writeText(signature), true;
|
|
469
|
-
} catch {
|
|
470
|
-
return false;
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
export { EnhancedStorage, EnhancedStorageAdapter, SOLANA_CHAIN_IDS, chainIdToClusterId, chainIdToClusterType, clusterToChainId, copySignature, createEnhancedStorageAccount, createEnhancedStorageCluster, createEnhancedStorageWallet, formatSignature, getAllExplorerUrls, getChainIdFromCluster, getChainIdFromClusterId, getChainIdFromClusterType, getChainIdFromConnection, getClusterIdFromChainId, getClusterTypeFromChainId, getClusterTypeFromConnection, getDefaultConfig, getDefaultMobileConfig, getLatestBlockhash, getSolanaExplorerUrl, getSolanaFmUrl, getSolscanUrl, getXrayUrl, isAccountAddress, isKitConnection, isKnownSolanaChain, isLegacyConnection, isSolanaChain, isWalletName, parseConfigOptions, sendRawTransaction, validateConfigOptions, validateKnownSolanaChain };
|
|
475
|
-
//# sourceMappingURL=chunk-JOBLG62A.mjs.map
|
|
476
|
-
//# sourceMappingURL=chunk-JOBLG62A.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/wallet/enhanced-storage.ts","../src/config/default-config.ts","../src/config/schemas.ts","../src/types/wallets.ts","../src/lib/connection/types.ts","../src/lib/connection/helpers.ts","../src/utils/chain.ts","../src/lib/utils/explorer-urls.ts"],"names":["WalletUiStorage","logger","address"],"mappings":"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","file":"chunk-JOBLG62A.mjs","sourcesContent":["/**\n * Enhanced Storage\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 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 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 validate(value: T): boolean {\n return this.validators.every(validator => validator(value));\n }\n\n addValidator(validator: (value: T) => boolean): this {\n this.validators.push(validator);\n return this;\n }\n\n onError(handler: (error: Error) => void): this {\n this.errorHandlers.add(handler);\n return this;\n }\n\n transform<U>(transformer: (value: T) => U): U {\n return transformer(this.get());\n }\n\n reset(): void {\n this.set(this.initial);\n }\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 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 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\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\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\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\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, CoinGeckoConfig } 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/wallet/enhanced-storage';\nimport { toClusterId } from '../utils/network';\nimport type React from 'react';\nimport { isAddress } from '@solana/addresses';\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 * Image proxy URL prefix for token images.\n * When set, token image URLs will be transformed to: `${imageProxy}${encodeURIComponent(originalUrl)}`\n * This prevents direct image fetching which can leak user IPs to untrusted hosts.\n * @example '/_next/image?w=64&q=75&url=' // Next.js Image Optimization\n * @example '/cdn-cgi/image/width=64,quality=75/' // Cloudflare Image Resizing\n */\n imageProxy?: string;\n /**\n * Optional mapping from program IDs to human-readable program names.\n * Used to enrich transaction history (e.g. showing `Jupiter` instead of a raw program address).\n */\n programLabels?: Record<string, string>;\n /**\n * CoinGecko API configuration for token price fetching.\n * Configure API key for higher rate limits and retry behavior for 429 responses.\n * @see https://docs.coingecko.com/reference/introduction for rate limit details\n */\n coingecko?: CoinGeckoConfig;\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 * Image proxy URL prefix for token images.\n * When set, token image URLs will be transformed to: `${imageProxy}${encodeURIComponent(originalUrl)}`\n * This prevents direct image fetching which can leak user IPs to untrusted hosts.\n */\n imageProxy?: string;\n /**\n * Optional mapping from program IDs to human-readable program names.\n * Used to enrich transaction history (e.g. showing `Jupiter` instead of a raw program address).\n */\n programLabels?: Record<string, string>;\n /**\n * CoinGecko API configuration for token price fetching.\n */\n coingecko?: CoinGeckoConfig;\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 imageProxy,\n programLabels,\n coingecko,\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 imageProxy,\n programLabels,\n coingecko,\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 - Configuration Schemas\n *\n * Zod schemas for runtime validation of configuration options.\n * These schemas provide type-safe validation with helpful error messages.\n */\n\nimport { z } from 'zod/v4';\n\n// ============================================================================\n// Primitive Schemas\n// ============================================================================\n\n/**\n * Valid Solana network values\n */\nexport const solanaNetworkSchema = z.enum(['mainnet', 'mainnet-beta', 'devnet', 'testnet', 'localnet']);\n\n/**\n * Solana cluster ID format (e.g., 'solana:mainnet', 'solana:devnet')\n */\nexport const solanaClusterIdSchema = z.string().regex(/^solana:(mainnet|devnet|testnet|localnet|[a-zA-Z0-9-]+)$/, {\n message: 'Cluster ID must be in format \"solana:<network>\" (e.g., \"solana:mainnet\")',\n});\n\n/**\n * URL validation with protocol check\n */\nexport const urlSchema = z.string().url('Invalid URL format');\n\n/**\n * Optional URL that allows undefined\n */\nexport const optionalUrlSchema = urlSchema.optional();\n\n// ============================================================================\n// CoinGecko Configuration\n// ============================================================================\n\nexport const coinGeckoConfigSchema = z\n .strictObject({\n apiKey: z.string().optional(),\n isPro: z.boolean().optional(),\n maxRetries: z.number().int().positive().max(10).optional(),\n baseDelay: z.number().int().positive().max(30000).optional(),\n maxTimeout: z.number().int().positive().max(120000).optional(),\n })\n .optional();\n\n// ============================================================================\n// Storage Configuration\n// ============================================================================\n\n/**\n * Storage adapter interface schema (validates shape, not implementation)\n */\nexport const storageAdapterSchema = z.looseObject({\n get: z.custom<(...args: unknown[]) => unknown>(val => typeof val === 'function'),\n set: z.custom<(...args: unknown[]) => unknown>(val => typeof val === 'function'),\n});\n\nexport const storageConfigSchema = z\n .object({\n account: storageAdapterSchema,\n cluster: storageAdapterSchema,\n wallet: storageAdapterSchema,\n })\n .optional();\n\n// ============================================================================\n// Cluster Configuration\n// ============================================================================\n\n/**\n * SolanaCluster object schema\n */\nexport const solanaClusterSchema = z.object({\n id: solanaClusterIdSchema,\n label: z.string().min(1, 'Cluster label cannot be empty'),\n url: urlSchema,\n urlWs: urlSchema.optional(),\n});\n\nexport const clusterConfigSchema = z\n .object({\n clusters: z.array(solanaClusterSchema).optional(),\n persistSelection: z.boolean().optional(),\n initialCluster: solanaClusterIdSchema.optional(),\n })\n .optional();\n\n// ============================================================================\n// Default Config Options\n// ============================================================================\n\nexport const defaultConfigOptionsSchema = z.object({\n // Required\n appName: z.string().min(1, 'Application name is required'),\n\n // Optional strings\n appUrl: optionalUrlSchema,\n imageProxy: z.string().optional(),\n clusterStorageKey: z.string().optional(),\n\n // Optional booleans\n autoConnect: z.boolean().optional(),\n debug: z.boolean().optional(),\n enableMobile: z.boolean().optional(),\n persistClusterSelection: z.boolean().optional(),\n enableErrorBoundary: z.boolean().optional(),\n\n // Network\n network: solanaNetworkSchema.optional(),\n\n // Numbers\n maxRetries: z.number().int().positive().max(10).optional(),\n\n // Complex types\n storage: storageConfigSchema,\n clusters: z.array(solanaClusterSchema).optional(),\n customClusters: z.array(solanaClusterSchema).optional(),\n programLabels: z.record(z.string(), z.string()).optional(),\n coingecko: coinGeckoConfigSchema,\n\n // Functions (can't validate implementation, just existence)\n onError: z.custom<(...args: unknown[]) => unknown>(val => typeof val === 'function').optional(),\n});\n\n// ============================================================================\n// Connector Config (for ConnectorClient)\n// ============================================================================\n\nexport const connectorConfigSchema = z\n .strictObject({\n autoConnect: z.boolean().optional(),\n debug: z.boolean().optional(),\n storage: storageConfigSchema,\n cluster: clusterConfigSchema,\n imageProxy: z.string().optional(),\n programLabels: z.record(z.string(), z.string()).optional(),\n coingecko: coinGeckoConfigSchema,\n })\n .optional();\n\n// ============================================================================\n// Type Exports (inferred from schemas)\n// ============================================================================\n\nexport type SolanaNetworkInput = z.input<typeof solanaNetworkSchema>;\nexport type SolanaClusterIdInput = z.input<typeof solanaClusterIdSchema>;\nexport type CoinGeckoConfigInput = z.input<typeof coinGeckoConfigSchema>;\nexport type DefaultConfigOptionsInput = z.input<typeof defaultConfigOptionsSchema>;\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\n/**\n * Validate configuration options and return a result with helpful errors\n *\n * @example\n * ```ts\n * const result = validateConfigOptions({\n * appName: 'My App',\n * network: 'mainnet',\n * });\n *\n * if (!result.success) {\n * console.error('Config validation failed:', result.error.format());\n * }\n * ```\n */\nexport function validateConfigOptions(options: unknown): z.ZodSafeParseResult<DefaultConfigOptionsInput> {\n return defaultConfigOptionsSchema.safeParse(options);\n}\n\n/**\n * Parse and validate config options, throwing on error with formatted message\n *\n * @throws {z.ZodError} If validation fails\n *\n * @example\n * ```ts\n * try {\n * const validOptions = parseConfigOptions(userInput);\n * // validOptions is typed and validated\n * } catch (error) {\n * if (error instanceof z.ZodError) {\n * console.error(error.format());\n * }\n * }\n * ```\n */\nexport function parseConfigOptions(options: unknown): DefaultConfigOptionsInput {\n return defaultConfigOptionsSchema.parse(options);\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 '@solana/addresses' 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 '@solana/addresses' 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","import type { Connection } from '@solana/web3.js';\n\nexport type Commitment = 'processed' | 'confirmed' | 'finalized';\n\nexport interface KitSendTransactionOptions {\n commitment?: Commitment;\n skipPreflight?: boolean;\n maxRetries?: number;\n}\n\nexport type KitRpc = {\n getLatestBlockhash(options?: { commitment?: Commitment }): {\n send(): Promise<{ value: { blockhash: string; lastValidBlockHeight: number } }>;\n };\n sendTransaction(\n bytes: Uint8Array | string,\n options?: KitSendTransactionOptions,\n ): {\n send(): Promise<string>;\n };\n send?: () => unknown;\n};\n\nexport type DualConnection = Connection | KitRpc;\n\nexport function isLegacyConnection(conn: DualConnection): conn is Connection {\n return 'rpcEndpoint' in conn && typeof (conn as Connection).rpcEndpoint === 'string';\n}\n\nexport function isKitConnection(conn: DualConnection): conn is KitRpc {\n if ('rpcEndpoint' in conn) {\n return false;\n }\n\n const asKitRpc = conn as KitRpc;\n return typeof asKitRpc.getLatestBlockhash === 'function' && typeof asKitRpc.sendTransaction === 'function';\n}\n","/**\n * @solana/connector - Connection Helpers\n *\n * Abstraction layer for working with both legacy @solana/web3.js Connection\n * and modern Kit/gill Rpc objects.\n */\n\nimport type { SendOptions } from '@solana/web3.js';\nimport type { DualConnection, Commitment, KitRpc } from './types';\nimport { isLegacyConnection, isKitConnection } from './types';\n\n/**\n * Get latest blockhash from either legacy Connection or Kit Rpc\n *\n * Abstracts the differences between web3.js 1.x and Kit/gill APIs.\n *\n * @param connection - Legacy Connection or Kit Rpc\n * @param commitment - Optional commitment level (default: 'confirmed')\n * @returns Latest blockhash and last valid block height\n *\n * @example\n * ```typescript\n * // Works with both Connection and Rpc\n * const { blockhash, lastValidBlockHeight } = await getLatestBlockhash(connection);\n * ```\n */\nexport async function getLatestBlockhash(\n connection: DualConnection,\n commitment: Commitment = 'confirmed',\n): Promise<{ blockhash: string; lastValidBlockHeight: number }> {\n if (isLegacyConnection(connection)) {\n // Legacy Connection API\n return await connection.getLatestBlockhash(commitment);\n }\n\n if (isKitConnection(connection)) {\n // Kit/gill Rpc API - returns { value: { blockhash, lastValidBlockHeight } }\n const rpc = connection as KitRpc;\n const result = await rpc.getLatestBlockhash({ commitment }).send();\n return result.value;\n }\n\n throw new Error('Unsupported connection type');\n}\n\n/**\n * Send raw transaction bytes to either legacy Connection or Kit Rpc\n *\n * Abstracts the differences between web3.js 1.x and Kit/gill APIs.\n *\n * @param connection - Legacy Connection or Kit Rpc\n * @param bytes - Raw transaction bytes\n * @param options - Optional send options (skipPreflight, maxRetries, etc.)\n * @returns Transaction signature string\n *\n * @example\n * ```typescript\n * // Works with both Connection and Rpc\n * const signature = await sendRawTransaction(connection, transactionBytes, {\n * skipPreflight: false,\n * maxRetries: 3\n * });\n * ```\n */\nexport async function sendRawTransaction(\n connection: DualConnection,\n bytes: Uint8Array,\n options?: SendOptions & { commitment?: Commitment },\n): Promise<string> {\n if (isLegacyConnection(connection)) {\n // Legacy Connection API\n return await connection.sendRawTransaction(bytes, options);\n }\n\n if (isKitConnection(connection)) {\n // Kit/gill Rpc API\n // Note: gill's sendTransaction expects different options format\n const rpc = connection as KitRpc;\n // Convert Uint8Array to base64 string\n const base64String = Buffer.from(bytes).toString('base64');\n const result = await rpc\n .sendTransaction(base64String as Uint8Array | string, {\n ...(options?.commitment ? { commitment: options.commitment } : {}),\n ...(options?.skipPreflight !== undefined ? { skipPreflight: options.skipPreflight } : {}),\n ...(options?.maxRetries !== undefined ? { maxRetries: options.maxRetries } : {}),\n })\n .send();\n\n // Kit Rpc returns signature string directly\n return result;\n }\n\n throw new Error('Unsupported connection type');\n}\n","import type { SolanaCluster, SolanaClusterId } from '@wallet-ui/core';\nimport type { Connection } from '@solana/web3.js';\nimport type { ClusterType } from './cluster';\nimport { getClusterType, isMainnetCluster, isDevnetCluster, isTestnetCluster } from './cluster';\n\nexport const SOLANA_CHAIN_IDS = {\n mainnet: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',\n devnet: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',\n testnet: 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z',\n} as const;\n\nconst CHAIN_ID_TO_CLUSTER_TYPE: Record<string, ClusterType> = {\n [SOLANA_CHAIN_IDS.mainnet]: 'mainnet',\n [SOLANA_CHAIN_IDS.devnet]: 'devnet',\n [SOLANA_CHAIN_IDS.testnet]: 'testnet',\n};\n\nconst CLUSTER_ID_TO_CHAIN_ID: Partial<Record<SolanaClusterId, string>> = {\n 'solana:mainnet': SOLANA_CHAIN_IDS.mainnet,\n 'solana:mainnet-beta': SOLANA_CHAIN_IDS.mainnet,\n 'solana:devnet': SOLANA_CHAIN_IDS.devnet,\n 'solana:testnet': SOLANA_CHAIN_IDS.testnet,\n};\n\nexport function getChainIdFromCluster(cluster: SolanaCluster): `solana:${string}` | null {\n const clusterType = getClusterType(cluster);\n\n if (clusterType === 'localnet' || clusterType === 'custom') {\n return null;\n }\n\n return getChainIdFromClusterType(clusterType);\n}\n\nexport function getChainIdFromClusterId(clusterId: SolanaClusterId): `solana:${string}` | null {\n return (CLUSTER_ID_TO_CHAIN_ID[clusterId] as `solana:${string}` | undefined) || null;\n}\n\nexport function getChainIdFromClusterType(type: ClusterType): `solana:${string}` | null {\n switch (type) {\n case 'mainnet':\n return SOLANA_CHAIN_IDS.mainnet;\n case 'devnet':\n return SOLANA_CHAIN_IDS.devnet;\n case 'testnet':\n return SOLANA_CHAIN_IDS.testnet;\n case 'localnet':\n case 'custom':\n return null;\n }\n}\n\nexport function getClusterTypeFromChainId(chainId: string): ClusterType | null {\n return CHAIN_ID_TO_CLUSTER_TYPE[chainId] || null;\n}\n\nexport function getClusterIdFromChainId(chainId: string): SolanaClusterId | null {\n const clusterType = getClusterTypeFromChainId(chainId);\n if (!clusterType) {\n return null;\n }\n\n switch (clusterType) {\n case 'mainnet':\n return 'solana:mainnet';\n case 'devnet':\n return 'solana:devnet';\n case 'testnet':\n return 'solana:testnet';\n default:\n return null;\n }\n}\n\nexport function isSolanaChain(chain: string): chain is `solana:${string}` {\n return chain.startsWith('solana:');\n}\n\nexport function isKnownSolanaChain(chain: string): boolean {\n return (\n chain === SOLANA_CHAIN_IDS.mainnet || chain === SOLANA_CHAIN_IDS.devnet || chain === SOLANA_CHAIN_IDS.testnet\n );\n}\n\nexport function validateKnownSolanaChain(chain: string): asserts chain is `solana:${string}` {\n if (!isSolanaChain(chain)) {\n throw new Error(`Invalid chain format: expected 'solana:...', got '${chain}'`);\n }\n\n if (!isKnownSolanaChain(chain)) {\n throw new Error(`Unknown Solana chain: ${chain}. Known chains: ${Object.values(SOLANA_CHAIN_IDS).join(', ')}`);\n }\n}\n\nexport function getClusterTypeFromConnection(connection: Connection | null): ClusterType | null {\n if (!connection) {\n return null;\n }\n\n const rpcUrl = connection.rpcEndpoint || '';\n\n if (rpcUrl.includes('mainnet') || rpcUrl.includes('api.mainnet-beta')) {\n return 'mainnet';\n }\n\n if (rpcUrl.includes('testnet')) {\n return 'testnet';\n }\n\n if (rpcUrl.includes('devnet')) {\n return 'devnet';\n }\n\n if (rpcUrl.includes('localhost') || rpcUrl.includes('127.0.0.1')) {\n return 'localnet';\n }\n\n return 'custom';\n}\n\nexport function getChainIdFromConnection(\n connection: Connection | null,\n network?: 'mainnet' | 'devnet' | 'testnet',\n): `solana:${string}` | null {\n if (network) {\n return getChainIdFromClusterType(network);\n }\n\n const clusterType = getClusterTypeFromConnection(connection);\n if (!clusterType) {\n return null;\n }\n\n return getChainIdFromClusterType(clusterType);\n}\n\nexport function clusterToChainId(cluster: SolanaCluster): `solana:${string}` | null {\n return getChainIdFromCluster(cluster);\n}\n\nexport function chainIdToClusterType(chainId: string): ClusterType | null {\n return getClusterTypeFromChainId(chainId);\n}\n\nexport function chainIdToClusterId(chainId: string): SolanaClusterId | null {\n return getClusterIdFromChainId(chainId);\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 '../kit';\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"]}
|