@bit-buccaneers/wallet-abstraction 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +84 -0
- package/dist/dev.js +1287 -0
- package/dist/dev.jsx +1323 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1282 -0
- package/dist/index.jsx +1318 -0
- package/dist/lib/connectors/binance.d.ts +4 -0
- package/dist/lib/connectors/exodus.d.ts +4 -0
- package/dist/lib/connectors/index.d.ts +7 -0
- package/dist/lib/connectors/metamask.d.ts +4 -0
- package/dist/lib/connectors/phantom.d.ts +10 -0
- package/dist/lib/connectors/rainbow.d.ts +2 -0
- package/dist/lib/connectors/shared/constants.d.ts +22 -0
- package/dist/lib/connectors/shared/deeplink.d.ts +67 -0
- package/dist/lib/connectors/shared/index.d.ts +7 -0
- package/dist/lib/connectors/shared/injected.d.ts +4 -0
- package/dist/lib/connectors/shared/parsers.d.ts +23 -0
- package/dist/lib/connectors/shared/utils.d.ts +24 -0
- package/dist/lib/connectors/shared/walletconnect.d.ts +12 -0
- package/dist/lib/connectors/shared/wc-connector-factory.d.ts +10 -0
- package/dist/lib/connectors/solflare.d.ts +11 -0
- package/dist/lib/connectors/trust.d.ts +4 -0
- package/dist/lib/context/WalletContext.d.ts +23 -0
- package/dist/lib/context/hooks/index.d.ts +3 -0
- package/dist/lib/context/hooks/useEvmWallet.d.ts +14 -0
- package/dist/lib/context/hooks/useSolanaWallet.d.ts +11 -0
- package/dist/lib/context/hooks/useWalletConnect.d.ts +16 -0
- package/dist/lib/context/index.d.ts +1 -0
- package/dist/lib/core/constants.d.ts +3 -0
- package/dist/lib/core/helpers.d.ts +7 -0
- package/dist/lib/core/index.d.ts +5 -0
- package/dist/lib/core/storage.d.ts +8 -0
- package/dist/lib/core/types.d.ts +37 -0
- package/dist/lib/core/utils.d.ts +8 -0
- package/dist/lib/evm/config.d.ts +6 -0
- package/dist/lib/evm/connection.d.ts +2 -0
- package/dist/lib/evm/connectors.d.ts +2 -0
- package/dist/lib/evm/index.d.ts +4 -0
- package/dist/lib/evm/types.d.ts +12 -0
- package/dist/lib/index.d.ts +6 -0
- package/dist/lib/solana/connection.d.ts +5 -0
- package/dist/lib/solana/connectors.d.ts +4 -0
- package/dist/lib/solana/index.d.ts +4 -0
- package/dist/lib/solana/reconnect.d.ts +3 -0
- package/dist/lib/solana/types.d.ts +16 -0
- package/dist/lib/walletconnect/client.d.ts +31 -0
- package/dist/lib/walletconnect/index.d.ts +1 -0
- package/dist/lib/wallets/config.d.ts +7 -0
- package/dist/lib/wallets/index.d.ts +2 -0
- package/dist/lib/wallets/mappers.d.ts +2 -0
- package/package.json +111 -0
package/dist/dev.js
ADDED
|
@@ -0,0 +1,1287 @@
|
|
|
1
|
+
import { injected, metaMask, coinbaseWallet } from '@wagmi/connectors';
|
|
2
|
+
import { createConfig, getConnectors, signMessage, disconnect, connect, watchConnections } from '@wagmi/core';
|
|
3
|
+
import { http } from 'viem';
|
|
4
|
+
import { mainnet } from 'viem/chains';
|
|
5
|
+
import bs58 from 'bs58';
|
|
6
|
+
import nacl from 'tweetnacl';
|
|
7
|
+
import { SignClient } from '@walletconnect/sign-client';
|
|
8
|
+
import { isWalletAdapterCompatibleStandardWallet } from '@solana/wallet-adapter-base';
|
|
9
|
+
import { getWallets } from '@wallet-standard/app';
|
|
10
|
+
import { createComponent } from 'solid-js/web';
|
|
11
|
+
import { createContext, useContext, createSignal, onMount, onCleanup } from 'solid-js';
|
|
12
|
+
|
|
13
|
+
// src/lib/evm/config.ts
|
|
14
|
+
var config = null;
|
|
15
|
+
var configuredChains = [mainnet];
|
|
16
|
+
var createEvmConfig = (chains) => {
|
|
17
|
+
if (chains) configuredChains = chains;
|
|
18
|
+
const connectors = [injected(), metaMask(), coinbaseWallet({ appName: "Wallet Abstraction" })];
|
|
19
|
+
const transports = {};
|
|
20
|
+
for (const chain of configuredChains) {
|
|
21
|
+
transports[chain.id] = http();
|
|
22
|
+
}
|
|
23
|
+
config = createConfig({
|
|
24
|
+
chains: configuredChains,
|
|
25
|
+
connectors,
|
|
26
|
+
transports
|
|
27
|
+
});
|
|
28
|
+
return config;
|
|
29
|
+
};
|
|
30
|
+
var getEvmConfig = () => {
|
|
31
|
+
if (!config) config = createEvmConfig();
|
|
32
|
+
return config;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// src/lib/core/constants.ts
|
|
36
|
+
var STORAGE_KEYS = {
|
|
37
|
+
SOLANA_WALLET: "wallet-abstraction:solana-wallet"
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// src/lib/core/helpers.ts
|
|
41
|
+
var connectedResult = (address, options) => ({
|
|
42
|
+
status: "connected",
|
|
43
|
+
address,
|
|
44
|
+
chainId: options?.chainId,
|
|
45
|
+
publicKey: options?.publicKey
|
|
46
|
+
});
|
|
47
|
+
var qrcodeResult = (uri, wait) => ({
|
|
48
|
+
status: "qrcode",
|
|
49
|
+
uri,
|
|
50
|
+
wait
|
|
51
|
+
});
|
|
52
|
+
var pendingResult = () => ({ status: "pending" });
|
|
53
|
+
|
|
54
|
+
// src/lib/core/storage.ts
|
|
55
|
+
var storage = {
|
|
56
|
+
get: (key) => {
|
|
57
|
+
try {
|
|
58
|
+
const value = window.localStorage.getItem(key);
|
|
59
|
+
return value ? JSON.parse(value) : null;
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
getString: (key) => {
|
|
65
|
+
return window.localStorage.getItem(key);
|
|
66
|
+
},
|
|
67
|
+
set: (key, value) => {
|
|
68
|
+
window.localStorage.setItem(key, JSON.stringify(value));
|
|
69
|
+
},
|
|
70
|
+
setString: (key, value) => {
|
|
71
|
+
window.localStorage.setItem(key, value);
|
|
72
|
+
},
|
|
73
|
+
remove: (key) => {
|
|
74
|
+
window.localStorage.removeItem(key);
|
|
75
|
+
},
|
|
76
|
+
has: (key) => {
|
|
77
|
+
return window.localStorage.getItem(key) !== null;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// src/lib/core/utils.ts
|
|
82
|
+
var addFallbackConnectors = (connectors, fallbacks) => {
|
|
83
|
+
for (const { id, create } of fallbacks) {
|
|
84
|
+
if (!connectors.some((c) => c.id === id)) {
|
|
85
|
+
connectors.push(create());
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// src/lib/wallets/config.ts
|
|
91
|
+
var WALLETS = [
|
|
92
|
+
{ id: "metamask", name: "MetaMask" },
|
|
93
|
+
{ id: "phantom", name: "Phantom" },
|
|
94
|
+
{ id: "okx", name: "OKX Wallet" },
|
|
95
|
+
{ id: "coinbase", name: "Coinbase Wallet" },
|
|
96
|
+
{ id: "binance", name: "Binance Wallet" },
|
|
97
|
+
{ id: "bitget", name: "Bitget Wallet" },
|
|
98
|
+
{ id: "solflare", name: "Solflare" },
|
|
99
|
+
{ id: "trust", name: "Trust Wallet" },
|
|
100
|
+
{ id: "rabby", name: "Rabby" },
|
|
101
|
+
{ id: "rainbow", name: "Rainbow" },
|
|
102
|
+
{ id: "exodus", name: "Exodus" }
|
|
103
|
+
];
|
|
104
|
+
|
|
105
|
+
// src/lib/wallets/mappers.ts
|
|
106
|
+
var EVM_WALLET_ID_MAP = {
|
|
107
|
+
"app.phantom": "phantom",
|
|
108
|
+
"app.backpack": "backpack",
|
|
109
|
+
"com.trustwallet.app": "trust",
|
|
110
|
+
"com.binance.wallet": "binance",
|
|
111
|
+
"com.bitget.web3": "bitget",
|
|
112
|
+
"com.okex.wallet": "okx",
|
|
113
|
+
metaMaskSDK: "metamask",
|
|
114
|
+
coinbaseWalletSDK: "coinbase",
|
|
115
|
+
"io.rabby": "rabby",
|
|
116
|
+
"me.rainbow": "rainbow",
|
|
117
|
+
"com.exodus.wallet": "exodus",
|
|
118
|
+
walletConnect: "walletconnect"
|
|
119
|
+
};
|
|
120
|
+
var SOLANA_WALLET_ID_MAP = {
|
|
121
|
+
"binance-wallet": "binance",
|
|
122
|
+
"bitget-wallet": "bitget",
|
|
123
|
+
"okx-wallet": "okx",
|
|
124
|
+
"exodus-wallet": "exodus"
|
|
125
|
+
};
|
|
126
|
+
var normalizeEvmWalletId = (id) => EVM_WALLET_ID_MAP[id] || id.toLowerCase().replace(/sdk$/i, "");
|
|
127
|
+
var normalizeSolanaWalletId = (id) => SOLANA_WALLET_ID_MAP[id] || id.replace(/-wallet$/, "");
|
|
128
|
+
|
|
129
|
+
// src/lib/connectors/shared/constants.ts
|
|
130
|
+
var WC_CHAINS = {
|
|
131
|
+
EVM_MAINNET: "eip155:1",
|
|
132
|
+
SOLANA_MAINNET: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
|
|
133
|
+
};
|
|
134
|
+
var WC_METHODS = {
|
|
135
|
+
EVM: ["eth_sendTransaction", "personal_sign", "eth_signTypedData"],
|
|
136
|
+
SOLANA: ["solana_signTransaction", "solana_signMessage"]
|
|
137
|
+
};
|
|
138
|
+
var WC_EVENTS = {
|
|
139
|
+
EVM: ["chainChanged", "accountsChanged"],
|
|
140
|
+
SOLANA: []
|
|
141
|
+
};
|
|
142
|
+
var EVM_WC_CONFIG = {
|
|
143
|
+
chains: [WC_CHAINS.EVM_MAINNET],
|
|
144
|
+
methods: WC_METHODS.EVM,
|
|
145
|
+
events: WC_EVENTS.EVM
|
|
146
|
+
};
|
|
147
|
+
var SOLANA_WC_CONFIG = {
|
|
148
|
+
chains: [WC_CHAINS.SOLANA_MAINNET],
|
|
149
|
+
methods: WC_METHODS.SOLANA,
|
|
150
|
+
events: WC_EVENTS.SOLANA
|
|
151
|
+
};
|
|
152
|
+
var getDappKeyPair = (storageKey) => {
|
|
153
|
+
const stored = storage.get(storageKey);
|
|
154
|
+
if (stored) {
|
|
155
|
+
return {
|
|
156
|
+
publicKey: new Uint8Array(stored.publicKey),
|
|
157
|
+
secretKey: new Uint8Array(stored.secretKey)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const keyPair = nacl.box.keyPair();
|
|
161
|
+
storage.set(storageKey, {
|
|
162
|
+
publicKey: Array.from(keyPair.publicKey),
|
|
163
|
+
secretKey: Array.from(keyPair.secretKey)
|
|
164
|
+
});
|
|
165
|
+
return keyPair;
|
|
166
|
+
};
|
|
167
|
+
var buildConnectUrl = (config2, params) => {
|
|
168
|
+
const keyPair = getDappKeyPair(`${config2.storageKeyPrefix}_keypair`);
|
|
169
|
+
const url = new URL(config2.connectUrl);
|
|
170
|
+
url.searchParams.set("app_url", params.appUrl);
|
|
171
|
+
url.searchParams.set("dapp_encryption_public_key", bs58.encode(keyPair.publicKey));
|
|
172
|
+
url.searchParams.set("redirect_link", params.redirectUrl);
|
|
173
|
+
if (params.cluster) {
|
|
174
|
+
url.searchParams.set("cluster", params.cluster);
|
|
175
|
+
}
|
|
176
|
+
if (params.chain) {
|
|
177
|
+
url.searchParams.set("chain", params.chain);
|
|
178
|
+
}
|
|
179
|
+
return url.toString();
|
|
180
|
+
};
|
|
181
|
+
var parseConnectResponse = (urlParams, config2) => {
|
|
182
|
+
const walletPublicKey = urlParams.get(config2.encryptionKeyParam);
|
|
183
|
+
const nonce = urlParams.get("nonce");
|
|
184
|
+
const data = urlParams.get("data");
|
|
185
|
+
if (!walletPublicKey || !nonce || !data) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
const keyPair = getDappKeyPair(`${config2.storageKeyPrefix}_keypair`);
|
|
190
|
+
const sharedSecret = nacl.box.before(bs58.decode(walletPublicKey), keyPair.secretKey);
|
|
191
|
+
const decrypted = nacl.box.open.after(bs58.decode(data), bs58.decode(nonce), sharedSecret);
|
|
192
|
+
if (!decrypted) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
const response = JSON.parse(new TextDecoder().decode(decrypted));
|
|
196
|
+
return {
|
|
197
|
+
publicKey: response.public_key,
|
|
198
|
+
session: response.session,
|
|
199
|
+
sharedSecret
|
|
200
|
+
};
|
|
201
|
+
} catch {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
var isWalletResponse = (urlParams, encryptionKeyParam) => urlParams.has(encryptionKeyParam) && urlParams.has("data");
|
|
206
|
+
var handleMobileCallback = (config2, pendingKey, sessionKey) => {
|
|
207
|
+
const params = new URLSearchParams(window.location.search);
|
|
208
|
+
if (!params.has(config2.callbackParam) || !isWalletResponse(params, config2.encryptionKeyParam)) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
if (storage.getString(pendingKey) !== "1") return null;
|
|
212
|
+
const session = parseConnectResponse(params, config2);
|
|
213
|
+
if (!session) {
|
|
214
|
+
storage.remove(pendingKey);
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
const storedSession = {
|
|
218
|
+
publicKey: session.publicKey,
|
|
219
|
+
session: session.session,
|
|
220
|
+
sharedSecret: Array.from(session.sharedSecret)
|
|
221
|
+
};
|
|
222
|
+
storage.set(sessionKey, storedSession);
|
|
223
|
+
storage.remove(pendingKey);
|
|
224
|
+
window.history.replaceState({}, "", window.location.pathname);
|
|
225
|
+
return connectedResult(session.publicKey);
|
|
226
|
+
};
|
|
227
|
+
var restoreMobileSession = (sessionKey) => {
|
|
228
|
+
const session = storage.get(sessionKey);
|
|
229
|
+
if (!session) return null;
|
|
230
|
+
return connectedResult(session.publicKey);
|
|
231
|
+
};
|
|
232
|
+
var getStoredSession = (sessionKey) => {
|
|
233
|
+
return storage.get(sessionKey);
|
|
234
|
+
};
|
|
235
|
+
var buildSignMessageUrl = (signUrl, config2, sessionKey, message, redirectUrl) => {
|
|
236
|
+
const session = getStoredSession(sessionKey);
|
|
237
|
+
if (!session) return null;
|
|
238
|
+
const keyPair = getDappKeyPair(`${config2.storageKeyPrefix}_keypair`);
|
|
239
|
+
const sharedSecret = new Uint8Array(session.sharedSecret);
|
|
240
|
+
const payload = {
|
|
241
|
+
message: bs58.encode(new TextEncoder().encode(message)),
|
|
242
|
+
session: session.session,
|
|
243
|
+
display: "utf8"
|
|
244
|
+
};
|
|
245
|
+
const nonce = nacl.randomBytes(24);
|
|
246
|
+
const encrypted = nacl.box.after(
|
|
247
|
+
new TextEncoder().encode(JSON.stringify(payload)),
|
|
248
|
+
nonce,
|
|
249
|
+
sharedSecret
|
|
250
|
+
);
|
|
251
|
+
const url = new URL(signUrl);
|
|
252
|
+
url.searchParams.set("dapp_encryption_public_key", bs58.encode(keyPair.publicKey));
|
|
253
|
+
url.searchParams.set("nonce", bs58.encode(nonce));
|
|
254
|
+
url.searchParams.set("redirect_link", redirectUrl);
|
|
255
|
+
url.searchParams.set("payload", bs58.encode(encrypted));
|
|
256
|
+
return url.toString();
|
|
257
|
+
};
|
|
258
|
+
var parseSignMessageResponse = (config2, sessionKey) => {
|
|
259
|
+
const params = new URLSearchParams(window.location.search);
|
|
260
|
+
const nonce = params.get("nonce");
|
|
261
|
+
const data = params.get("data");
|
|
262
|
+
if (!nonce || !data) return null;
|
|
263
|
+
const session = getStoredSession(sessionKey);
|
|
264
|
+
if (!session) return null;
|
|
265
|
+
try {
|
|
266
|
+
const sharedSecret = new Uint8Array(session.sharedSecret);
|
|
267
|
+
const decrypted = nacl.box.open.after(bs58.decode(data), bs58.decode(nonce), sharedSecret);
|
|
268
|
+
if (!decrypted) return null;
|
|
269
|
+
const response = JSON.parse(new TextDecoder().decode(decrypted));
|
|
270
|
+
return response.signature;
|
|
271
|
+
} catch {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
var connectEvmInjected = async () => {
|
|
276
|
+
if (!window.ethereum) throw new Error("No injected EVM provider");
|
|
277
|
+
const accounts = await window.ethereum.request({
|
|
278
|
+
method: "eth_requestAccounts"
|
|
279
|
+
});
|
|
280
|
+
if (!accounts[0]) throw new Error("No accounts returned");
|
|
281
|
+
const chainId = await window.ethereum.request({ method: "eth_chainId" });
|
|
282
|
+
return connectedResult(accounts[0], { chainId: parseInt(chainId, 16) });
|
|
283
|
+
};
|
|
284
|
+
var connectSolanaInjected = async () => {
|
|
285
|
+
if (!window.solana) throw new Error("No injected Solana provider");
|
|
286
|
+
const response = await window.solana.connect();
|
|
287
|
+
const publicKey = response.publicKey;
|
|
288
|
+
return connectedResult(publicKey.toBase58(), { publicKey: publicKey.toBytes() });
|
|
289
|
+
};
|
|
290
|
+
var signSolanaInjected = async (message) => {
|
|
291
|
+
if (!window.solana?.signMessage) {
|
|
292
|
+
throw new Error("No injected Solana provider or signMessage not supported");
|
|
293
|
+
}
|
|
294
|
+
const encodedMessage = new TextEncoder().encode(message);
|
|
295
|
+
const result = await window.solana.signMessage(encodedMessage, "utf8");
|
|
296
|
+
return bs58.encode(new Uint8Array(result.signature));
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// src/lib/connectors/shared/parsers.ts
|
|
300
|
+
var parseEvmAccount = (account) => {
|
|
301
|
+
const [, chainIdStr, address] = account.split(":");
|
|
302
|
+
if (!address) throw new Error("Invalid EVM account format");
|
|
303
|
+
return connectedResult(address, { chainId: parseInt(chainIdStr, 10) });
|
|
304
|
+
};
|
|
305
|
+
var parseSolanaAccount = async (account) => {
|
|
306
|
+
const address = account.split(":")[2];
|
|
307
|
+
if (!address) throw new Error("Invalid Solana account format");
|
|
308
|
+
const { default: bs586 } = await import('bs58');
|
|
309
|
+
return connectedResult(address, { publicKey: bs586.decode(address) });
|
|
310
|
+
};
|
|
311
|
+
var getEvmAccountFromSession = (namespaces) => {
|
|
312
|
+
const account = namespaces.eip155?.accounts?.[0];
|
|
313
|
+
if (!account) throw new Error("No EVM accounts returned");
|
|
314
|
+
return parseEvmAccount(account);
|
|
315
|
+
};
|
|
316
|
+
var getSolanaAccountFromSession = async (namespaces) => {
|
|
317
|
+
const account = namespaces.solana?.accounts?.[0];
|
|
318
|
+
if (!account) throw new Error("No Solana accounts returned");
|
|
319
|
+
return parseSolanaAccount(account);
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// src/lib/connectors/shared/utils.ts
|
|
323
|
+
var isMobile = () => {
|
|
324
|
+
return typeof window !== "undefined" && /iPhone|iPad|iPod|Android/i.test(window.navigator.userAgent);
|
|
325
|
+
};
|
|
326
|
+
var isInWalletBrowser = (key) => {
|
|
327
|
+
return typeof window !== "undefined" && !!window.ethereum?.[key];
|
|
328
|
+
};
|
|
329
|
+
var openDeeplink = (url) => {
|
|
330
|
+
const link = document.createElement("a");
|
|
331
|
+
link.href = url;
|
|
332
|
+
link.click();
|
|
333
|
+
};
|
|
334
|
+
var waitForValue = (getValue) => {
|
|
335
|
+
return new Promise((resolve) => {
|
|
336
|
+
const check = () => {
|
|
337
|
+
const value = getValue();
|
|
338
|
+
if (value != null) resolve(value);
|
|
339
|
+
else window.setTimeout(check, 50);
|
|
340
|
+
};
|
|
341
|
+
check();
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
var signClient = null;
|
|
345
|
+
var currentSession = null;
|
|
346
|
+
var sessionChangeCallbacks = /* @__PURE__ */ new Set();
|
|
347
|
+
var notifySessionChange = (session) => {
|
|
348
|
+
sessionChangeCallbacks.forEach((cb) => cb(session));
|
|
349
|
+
};
|
|
350
|
+
var onWalletConnectSessionChange = (callback) => {
|
|
351
|
+
sessionChangeCallbacks.add(callback);
|
|
352
|
+
callback(currentSession);
|
|
353
|
+
return () => sessionChangeCallbacks.delete(callback);
|
|
354
|
+
};
|
|
355
|
+
var initWalletConnect = async (config2) => {
|
|
356
|
+
if (signClient) return;
|
|
357
|
+
signClient = await SignClient.init({
|
|
358
|
+
projectId: config2.projectId,
|
|
359
|
+
metadata: config2.metadata
|
|
360
|
+
});
|
|
361
|
+
const pairings = signClient.core.pairing.pairings.values;
|
|
362
|
+
for (const pairing of pairings) {
|
|
363
|
+
if (!pairing.active) {
|
|
364
|
+
try {
|
|
365
|
+
await signClient.core.pairing.disconnect({ topic: pairing.topic });
|
|
366
|
+
} catch {
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
const sessions = signClient.session.values;
|
|
371
|
+
if (sessions.length > 0) {
|
|
372
|
+
const lastSession = sessions[sessions.length - 1];
|
|
373
|
+
currentSession = {
|
|
374
|
+
topic: lastSession.topic,
|
|
375
|
+
namespaces: lastSession.namespaces
|
|
376
|
+
};
|
|
377
|
+
notifySessionChange(currentSession);
|
|
378
|
+
}
|
|
379
|
+
signClient.on("session_delete", () => {
|
|
380
|
+
currentSession = null;
|
|
381
|
+
notifySessionChange(null);
|
|
382
|
+
});
|
|
383
|
+
signClient.on("session_update", ({ topic }) => {
|
|
384
|
+
const session = signClient.session.get(topic);
|
|
385
|
+
if (session) {
|
|
386
|
+
currentSession = {
|
|
387
|
+
topic: session.topic,
|
|
388
|
+
namespaces: session.namespaces
|
|
389
|
+
};
|
|
390
|
+
notifySessionChange(currentSession);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
if (typeof document !== "undefined") {
|
|
394
|
+
document.addEventListener("visibilitychange", () => {
|
|
395
|
+
if (document.visibilityState === "visible" && signClient) {
|
|
396
|
+
const sessions2 = signClient.session.values;
|
|
397
|
+
if (sessions2.length > 0 && !currentSession) {
|
|
398
|
+
const lastSession = sessions2[sessions2.length - 1];
|
|
399
|
+
currentSession = {
|
|
400
|
+
topic: lastSession.topic,
|
|
401
|
+
namespaces: lastSession.namespaces
|
|
402
|
+
};
|
|
403
|
+
notifySessionChange(currentSession);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
var getCurrentSession = () => currentSession;
|
|
410
|
+
var connectWalletConnect = async (options) => {
|
|
411
|
+
if (!signClient) {
|
|
412
|
+
throw new Error("WalletConnect not initialized. Call initWalletConnect first.");
|
|
413
|
+
}
|
|
414
|
+
const pairings = signClient.core.pairing.pairings.values;
|
|
415
|
+
for (const pairing of pairings) {
|
|
416
|
+
if (!pairing.active) {
|
|
417
|
+
try {
|
|
418
|
+
await signClient.core.pairing.disconnect({ topic: pairing.topic });
|
|
419
|
+
} catch {
|
|
420
|
+
console.log("Failed to disconnect pairing", pairing);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
const namespace = options.chains[0]?.startsWith("solana") ? "solana" : "eip155";
|
|
425
|
+
const { uri, approval } = await signClient.connect({
|
|
426
|
+
optionalNamespaces: {
|
|
427
|
+
[namespace]: {
|
|
428
|
+
methods: options.methods,
|
|
429
|
+
chains: options.chains,
|
|
430
|
+
events: options.events
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
if (uri && options.onQRCode) {
|
|
435
|
+
options.onQRCode(uri);
|
|
436
|
+
}
|
|
437
|
+
const session = await approval();
|
|
438
|
+
currentSession = {
|
|
439
|
+
topic: session.topic,
|
|
440
|
+
namespaces: session.namespaces
|
|
441
|
+
};
|
|
442
|
+
return currentSession;
|
|
443
|
+
};
|
|
444
|
+
var disconnectWalletConnect = async () => {
|
|
445
|
+
if (!signClient || !currentSession) return;
|
|
446
|
+
await signClient.disconnect({
|
|
447
|
+
topic: currentSession.topic,
|
|
448
|
+
reason: { code: 6e3, message: "User disconnected" }
|
|
449
|
+
});
|
|
450
|
+
currentSession = null;
|
|
451
|
+
};
|
|
452
|
+
var requestWalletConnect = async (method, params, chainId) => {
|
|
453
|
+
if (!signClient || !currentSession) {
|
|
454
|
+
throw new Error("No active WalletConnect session");
|
|
455
|
+
}
|
|
456
|
+
try {
|
|
457
|
+
await signClient.ping({ topic: currentSession.topic });
|
|
458
|
+
} catch (e) {
|
|
459
|
+
console.error("WalletConnect session ping failed:", e);
|
|
460
|
+
currentSession = null;
|
|
461
|
+
notifySessionChange(null);
|
|
462
|
+
throw new Error("WalletConnect session expired. Please reconnect.");
|
|
463
|
+
}
|
|
464
|
+
console.log("WC request:", { method, params, chainId, topic: currentSession.topic });
|
|
465
|
+
try {
|
|
466
|
+
const result = await signClient.request({
|
|
467
|
+
topic: currentSession.topic,
|
|
468
|
+
chainId,
|
|
469
|
+
request: {
|
|
470
|
+
method,
|
|
471
|
+
params
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
console.log("WC response:", result);
|
|
475
|
+
return result;
|
|
476
|
+
} catch (e) {
|
|
477
|
+
console.error("WC request failed:", e);
|
|
478
|
+
throw e;
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
// src/lib/connectors/shared/walletconnect.ts
|
|
483
|
+
var connectViaWalletConnect = async (wcConfig, parseSession, getDeeplink) => {
|
|
484
|
+
let qrUri = null;
|
|
485
|
+
const connectionPromise = connectWalletConnect({
|
|
486
|
+
chains: [...wcConfig.chains],
|
|
487
|
+
methods: [...wcConfig.methods],
|
|
488
|
+
events: [...wcConfig.events],
|
|
489
|
+
onQRCode: (uri2) => {
|
|
490
|
+
qrUri = uri2;
|
|
491
|
+
}
|
|
492
|
+
}).then((session) => parseSession(session.namespaces));
|
|
493
|
+
const uri = await waitForValue(() => qrUri);
|
|
494
|
+
if (isMobile() && getDeeplink) {
|
|
495
|
+
openDeeplink(getDeeplink(uri));
|
|
496
|
+
}
|
|
497
|
+
return qrcodeResult(uri, () => connectionPromise);
|
|
498
|
+
};
|
|
499
|
+
var createDeeplink = (baseUrl) => (uri) => `${baseUrl}?uri=${encodeURIComponent(uri)}`;
|
|
500
|
+
var disconnectWc = async () => {
|
|
501
|
+
if (getCurrentSession()) {
|
|
502
|
+
await disconnectWalletConnect();
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
var disconnectWcOrSolana = async () => {
|
|
506
|
+
if (getCurrentSession()) {
|
|
507
|
+
await disconnectWalletConnect();
|
|
508
|
+
} else if (window.solana?.disconnect) {
|
|
509
|
+
await window.solana.disconnect();
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
var createWcEvmConnector = (config2) => {
|
|
513
|
+
const walletConfig = WALLETS.find((w) => w.id === config2.walletId);
|
|
514
|
+
const getDeeplink = createDeeplink(config2.wcDeeplink);
|
|
515
|
+
const isInWallet = () => isInWalletBrowser(config2.injectedKey);
|
|
516
|
+
return {
|
|
517
|
+
...walletConfig,
|
|
518
|
+
type: "evm",
|
|
519
|
+
wallet: {
|
|
520
|
+
_connector: null,
|
|
521
|
+
connect: async () => {
|
|
522
|
+
if (isInWallet() && window.ethereum) {
|
|
523
|
+
return connectEvmInjected();
|
|
524
|
+
}
|
|
525
|
+
return connectViaWalletConnect(EVM_WC_CONFIG, getEvmAccountFromSession, getDeeplink);
|
|
526
|
+
},
|
|
527
|
+
disconnect: disconnectWc,
|
|
528
|
+
signMessage: async (message) => {
|
|
529
|
+
if (isInWallet() && window.ethereum) {
|
|
530
|
+
const accounts = await window.ethereum.request({ method: "eth_accounts" });
|
|
531
|
+
if (!accounts[0]) throw new Error("No account connected");
|
|
532
|
+
const result2 = await window.ethereum.request({
|
|
533
|
+
method: "personal_sign",
|
|
534
|
+
params: [message, accounts[0]]
|
|
535
|
+
});
|
|
536
|
+
return result2;
|
|
537
|
+
}
|
|
538
|
+
const session = getCurrentSession();
|
|
539
|
+
if (!session) {
|
|
540
|
+
throw new Error("No WalletConnect session");
|
|
541
|
+
}
|
|
542
|
+
const account = session.namespaces.eip155?.accounts?.[0];
|
|
543
|
+
if (!account) {
|
|
544
|
+
throw new Error("No EVM account in session");
|
|
545
|
+
}
|
|
546
|
+
const address = account.split(":")[2];
|
|
547
|
+
const result = await requestWalletConnect(
|
|
548
|
+
"personal_sign",
|
|
549
|
+
[message, address],
|
|
550
|
+
WC_CHAINS.EVM_MAINNET
|
|
551
|
+
);
|
|
552
|
+
return result;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
};
|
|
557
|
+
var createWcSolanaConnector = (config2) => {
|
|
558
|
+
const walletConfig = WALLETS.find((w) => w.id === config2.walletId);
|
|
559
|
+
const getDeeplink = createDeeplink(config2.wcDeeplink);
|
|
560
|
+
const isInWallet = () => isInWalletBrowser(config2.injectedKey);
|
|
561
|
+
return {
|
|
562
|
+
...walletConfig,
|
|
563
|
+
type: "solana",
|
|
564
|
+
wallet: {
|
|
565
|
+
_provider: null,
|
|
566
|
+
connect: async () => {
|
|
567
|
+
if (isInWallet() && window.solana) {
|
|
568
|
+
return connectSolanaInjected();
|
|
569
|
+
}
|
|
570
|
+
return connectViaWalletConnect(SOLANA_WC_CONFIG, getSolanaAccountFromSession, getDeeplink);
|
|
571
|
+
},
|
|
572
|
+
disconnect: disconnectWcOrSolana,
|
|
573
|
+
signMessage: async (message) => {
|
|
574
|
+
if (isInWallet()) {
|
|
575
|
+
return signSolanaInjected(message);
|
|
576
|
+
}
|
|
577
|
+
const session = getCurrentSession();
|
|
578
|
+
if (!session) {
|
|
579
|
+
throw new Error("No WalletConnect session");
|
|
580
|
+
}
|
|
581
|
+
const account = session.namespaces.solana?.accounts?.[0];
|
|
582
|
+
if (!account) {
|
|
583
|
+
throw new Error("No Solana account in session");
|
|
584
|
+
}
|
|
585
|
+
const pubkey = account.split(":")[2];
|
|
586
|
+
const messageBytes = new TextEncoder().encode(message);
|
|
587
|
+
const result = await requestWalletConnect(
|
|
588
|
+
"solana_signMessage",
|
|
589
|
+
{ message: bs58.encode(messageBytes), pubkey },
|
|
590
|
+
WC_CHAINS.SOLANA_MAINNET
|
|
591
|
+
);
|
|
592
|
+
return result.signature;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// src/lib/connectors/phantom.ts
|
|
599
|
+
var PHANTOM_CONNECT_URL = "https://phantom.app/ul/v1/connect";
|
|
600
|
+
var PHANTOM_SIGN_MESSAGE_URL = "https://phantom.app/ul/v1/signMessage";
|
|
601
|
+
var PHANTOM_BROWSE_URL = "https://phantom.app/ul/browse";
|
|
602
|
+
var PHANTOM_CONFIG = {
|
|
603
|
+
connectUrl: PHANTOM_CONNECT_URL,
|
|
604
|
+
storageKeyPrefix: "phantom_mobile",
|
|
605
|
+
encryptionKeyParam: "phantom_encryption_public_key",
|
|
606
|
+
callbackParam: "phantom_callback"
|
|
607
|
+
};
|
|
608
|
+
var STORAGE_KEYS2 = {
|
|
609
|
+
PENDING: "phantom_mobile_pending",
|
|
610
|
+
SESSION: "phantom_mobile_session",
|
|
611
|
+
SIGN_PENDING: "phantom_mobile_sign_pending"
|
|
612
|
+
};
|
|
613
|
+
var isInPhantom = () => isInWalletBrowser("isPhantom");
|
|
614
|
+
var phantomWalletConfig = WALLETS.find((i) => i.id === "phantom");
|
|
615
|
+
var createPhantomEvmConnector = () => ({
|
|
616
|
+
...phantomWalletConfig,
|
|
617
|
+
type: "evm",
|
|
618
|
+
wallet: {
|
|
619
|
+
_connector: null,
|
|
620
|
+
connect: async () => {
|
|
621
|
+
const currentUrl = encodeURIComponent(window.location.href);
|
|
622
|
+
window.location.href = `${PHANTOM_BROWSE_URL}/${currentUrl}?ref=${encodeURIComponent(
|
|
623
|
+
window.location.origin
|
|
624
|
+
)}`;
|
|
625
|
+
return pendingResult();
|
|
626
|
+
},
|
|
627
|
+
disconnect: async () => {
|
|
628
|
+
},
|
|
629
|
+
signMessage: async () => {
|
|
630
|
+
throw new Error("signMessage not supported via mobile deeplink");
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
var createPhantomSolanaConnector = () => ({
|
|
635
|
+
...phantomWalletConfig,
|
|
636
|
+
type: "solana",
|
|
637
|
+
wallet: {
|
|
638
|
+
_provider: null,
|
|
639
|
+
connect: async () => {
|
|
640
|
+
if (isInPhantom() && window.solana) {
|
|
641
|
+
return connectSolanaInjected();
|
|
642
|
+
}
|
|
643
|
+
storage.setString(STORAGE_KEYS2.PENDING, "1");
|
|
644
|
+
const redirectUrl = `${window.location.origin}${window.location.pathname}?${PHANTOM_CONFIG.callbackParam}=1`;
|
|
645
|
+
window.location.href = buildConnectUrl(PHANTOM_CONFIG, {
|
|
646
|
+
appUrl: window.location.origin,
|
|
647
|
+
redirectUrl,
|
|
648
|
+
cluster: "mainnet-beta",
|
|
649
|
+
chain: "solana"
|
|
650
|
+
});
|
|
651
|
+
return pendingResult();
|
|
652
|
+
},
|
|
653
|
+
disconnect: async () => {
|
|
654
|
+
storage.remove(STORAGE_KEYS2.SESSION);
|
|
655
|
+
},
|
|
656
|
+
signMessage: async (message) => {
|
|
657
|
+
if (isInPhantom()) {
|
|
658
|
+
return signSolanaInjected(message);
|
|
659
|
+
}
|
|
660
|
+
const redirectUrl = `${window.location.origin}${window.location.pathname}?phantom_sign_callback=1`;
|
|
661
|
+
const signUrl = buildSignMessageUrl(
|
|
662
|
+
PHANTOM_SIGN_MESSAGE_URL,
|
|
663
|
+
PHANTOM_CONFIG,
|
|
664
|
+
STORAGE_KEYS2.SESSION,
|
|
665
|
+
message,
|
|
666
|
+
redirectUrl
|
|
667
|
+
);
|
|
668
|
+
if (!signUrl) {
|
|
669
|
+
throw new Error("No Phantom session for signing");
|
|
670
|
+
}
|
|
671
|
+
storage.setString(STORAGE_KEYS2.SIGN_PENDING, "1");
|
|
672
|
+
window.location.href = signUrl;
|
|
673
|
+
return new Promise(() => {
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
var isPhantomMobilePending = () => storage.getString(STORAGE_KEYS2.PENDING) === "1";
|
|
679
|
+
var handlePhantomMobileCallback = () => handleMobileCallback(PHANTOM_CONFIG, STORAGE_KEYS2.PENDING, STORAGE_KEYS2.SESSION);
|
|
680
|
+
var restorePhantomMobileSession = () => restoreMobileSession(STORAGE_KEYS2.SESSION);
|
|
681
|
+
var isPhantomSignPending = () => storage.getString(STORAGE_KEYS2.SIGN_PENDING) === "1";
|
|
682
|
+
var handlePhantomSignCallback = () => {
|
|
683
|
+
const params = new URLSearchParams(window.location.search);
|
|
684
|
+
if (!params.has("phantom_sign_callback")) return null;
|
|
685
|
+
if (!isPhantomSignPending()) return null;
|
|
686
|
+
const signature = parseSignMessageResponse(PHANTOM_CONFIG, STORAGE_KEYS2.SESSION);
|
|
687
|
+
storage.remove(STORAGE_KEYS2.SIGN_PENDING);
|
|
688
|
+
window.history.replaceState({}, "", window.location.pathname);
|
|
689
|
+
return signature;
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
// src/lib/connectors/metamask.ts
|
|
693
|
+
var METAMASK_CONFIG = {
|
|
694
|
+
walletId: "metamask",
|
|
695
|
+
wcDeeplink: "https://metamask.app.link/wc",
|
|
696
|
+
injectedKey: "isMetaMask"
|
|
697
|
+
};
|
|
698
|
+
var createMetaMaskEvmConnector = () => createWcEvmConnector(METAMASK_CONFIG);
|
|
699
|
+
|
|
700
|
+
// src/lib/connectors/solflare.ts
|
|
701
|
+
var SOLFLARE_CONNECT_URL = "https://solflare.com/ul/v1/connect";
|
|
702
|
+
var SOLFLARE_SIGN_MESSAGE_URL = "https://solflare.com/ul/v1/signMessage";
|
|
703
|
+
var SOLFLARE_CONFIG = {
|
|
704
|
+
connectUrl: SOLFLARE_CONNECT_URL,
|
|
705
|
+
storageKeyPrefix: "solflare_mobile",
|
|
706
|
+
encryptionKeyParam: "solflare_encryption_public_key",
|
|
707
|
+
callbackParam: "solflare_callback"
|
|
708
|
+
};
|
|
709
|
+
var STORAGE_KEYS3 = {
|
|
710
|
+
PENDING: "solflare_mobile_pending",
|
|
711
|
+
SESSION: "solflare_mobile_session",
|
|
712
|
+
SIGN_PENDING: "solflare_mobile_sign_pending"
|
|
713
|
+
};
|
|
714
|
+
var solflareWalletConfig = WALLETS.find((i) => i.id === "solflare");
|
|
715
|
+
var createSolflareSolanaMobileConnector = () => ({
|
|
716
|
+
...solflareWalletConfig,
|
|
717
|
+
type: "solana",
|
|
718
|
+
wallet: {
|
|
719
|
+
_provider: null,
|
|
720
|
+
connect: async () => {
|
|
721
|
+
storage.setString(STORAGE_KEYS3.PENDING, "1");
|
|
722
|
+
const redirectUrl = `${window.location.origin}${window.location.pathname}?${SOLFLARE_CONFIG.callbackParam}=1`;
|
|
723
|
+
window.location.href = buildConnectUrl(SOLFLARE_CONFIG, {
|
|
724
|
+
appUrl: window.location.origin,
|
|
725
|
+
redirectUrl,
|
|
726
|
+
cluster: "mainnet-beta"
|
|
727
|
+
});
|
|
728
|
+
return pendingResult();
|
|
729
|
+
},
|
|
730
|
+
disconnect: async () => {
|
|
731
|
+
storage.remove(STORAGE_KEYS3.SESSION);
|
|
732
|
+
},
|
|
733
|
+
signMessage: async (message) => {
|
|
734
|
+
const redirectUrl = `${window.location.origin}${window.location.pathname}?solflare_sign_callback=1`;
|
|
735
|
+
const signUrl = buildSignMessageUrl(
|
|
736
|
+
SOLFLARE_SIGN_MESSAGE_URL,
|
|
737
|
+
SOLFLARE_CONFIG,
|
|
738
|
+
STORAGE_KEYS3.SESSION,
|
|
739
|
+
message,
|
|
740
|
+
redirectUrl
|
|
741
|
+
);
|
|
742
|
+
if (!signUrl) {
|
|
743
|
+
throw new Error("No Solflare session for signing");
|
|
744
|
+
}
|
|
745
|
+
storage.setString(STORAGE_KEYS3.SIGN_PENDING, "1");
|
|
746
|
+
window.location.href = signUrl;
|
|
747
|
+
return new Promise(() => {
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
var isSolflareMobilePending = () => storage.getString(STORAGE_KEYS3.PENDING) === "1";
|
|
753
|
+
var handleSolflareMobileCallback = () => handleMobileCallback(SOLFLARE_CONFIG, STORAGE_KEYS3.PENDING, STORAGE_KEYS3.SESSION);
|
|
754
|
+
var restoreSolflareMobileSession = () => restoreMobileSession(STORAGE_KEYS3.SESSION);
|
|
755
|
+
var isSolflareSignPending = () => storage.getString(STORAGE_KEYS3.SIGN_PENDING) === "1";
|
|
756
|
+
var handleSolflareSignCallback = () => {
|
|
757
|
+
const params = new URLSearchParams(window.location.search);
|
|
758
|
+
if (!params.has("solflare_sign_callback")) return null;
|
|
759
|
+
if (!isSolflareSignPending()) return null;
|
|
760
|
+
const signature = parseSignMessageResponse(SOLFLARE_CONFIG, STORAGE_KEYS3.SESSION);
|
|
761
|
+
storage.remove(STORAGE_KEYS3.SIGN_PENDING);
|
|
762
|
+
window.history.replaceState({}, "", window.location.pathname);
|
|
763
|
+
return signature;
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
// src/lib/connectors/trust.ts
|
|
767
|
+
var TRUST_CONFIG = {
|
|
768
|
+
walletId: "trust",
|
|
769
|
+
wcDeeplink: "https://link.trustwallet.com/wc",
|
|
770
|
+
injectedKey: "isTrust"
|
|
771
|
+
};
|
|
772
|
+
var createTrustEvmMobileConnector = () => createWcEvmConnector(TRUST_CONFIG);
|
|
773
|
+
var createTrustSolanaMobileConnector = () => createWcSolanaConnector(TRUST_CONFIG);
|
|
774
|
+
|
|
775
|
+
// src/lib/connectors/rainbow.ts
|
|
776
|
+
var RAINBOW_CONFIG = {
|
|
777
|
+
walletId: "rainbow",
|
|
778
|
+
wcDeeplink: "https://rnbwapp.com/wc",
|
|
779
|
+
injectedKey: "isRainbow"
|
|
780
|
+
};
|
|
781
|
+
var createRainbowEvmMobileConnector = () => createWcEvmConnector(RAINBOW_CONFIG);
|
|
782
|
+
|
|
783
|
+
// src/lib/connectors/exodus.ts
|
|
784
|
+
var EXODUS_CONFIG = {
|
|
785
|
+
walletId: "exodus",
|
|
786
|
+
wcDeeplink: "https://exodus.com/wc",
|
|
787
|
+
injectedKey: "isExodus"
|
|
788
|
+
};
|
|
789
|
+
var createExodusEvmMobileConnector = () => createWcEvmConnector(EXODUS_CONFIG);
|
|
790
|
+
var createExodusSolanaMobileConnector = () => createWcSolanaConnector(EXODUS_CONFIG);
|
|
791
|
+
|
|
792
|
+
// src/lib/connectors/binance.ts
|
|
793
|
+
var BINANCE_CONFIG = {
|
|
794
|
+
walletId: "binance",
|
|
795
|
+
wcDeeplink: "bnc://app.binance.com/cedefi/wc",
|
|
796
|
+
injectedKey: "isBinance"
|
|
797
|
+
};
|
|
798
|
+
var createBinanceEvmConnector = () => createWcEvmConnector(BINANCE_CONFIG);
|
|
799
|
+
var createBinanceSolanaConnector = () => createWcSolanaConnector(BINANCE_CONFIG);
|
|
800
|
+
|
|
801
|
+
// src/lib/evm/connectors.ts
|
|
802
|
+
var EVM_FALLBACK_CONNECTORS = [
|
|
803
|
+
{ id: "phantom", create: createPhantomEvmConnector },
|
|
804
|
+
{ id: "metamask", create: createMetaMaskEvmConnector },
|
|
805
|
+
{ id: "trust", create: createTrustEvmMobileConnector },
|
|
806
|
+
{ id: "binance", create: createBinanceEvmConnector },
|
|
807
|
+
{ id: "rainbow", create: createRainbowEvmMobileConnector },
|
|
808
|
+
{ id: "exodus", create: createExodusEvmMobileConnector }
|
|
809
|
+
];
|
|
810
|
+
var getEvmConnectors = () => {
|
|
811
|
+
const wagmiConnectors = getConnectors(getEvmConfig());
|
|
812
|
+
const connectors = wagmiConnectors.map((c) => ({
|
|
813
|
+
id: normalizeEvmWalletId(c.id),
|
|
814
|
+
name: c.name,
|
|
815
|
+
icon: c.icon,
|
|
816
|
+
type: "evm",
|
|
817
|
+
installed: true,
|
|
818
|
+
wallet: {
|
|
819
|
+
_connector: c,
|
|
820
|
+
connect: async () => {
|
|
821
|
+
const result = await connect(getEvmConfig(), { connector: c });
|
|
822
|
+
if (!result.accounts[0]) throw new Error("No accounts returned");
|
|
823
|
+
return connectedResult(result.accounts[0], { chainId: result.chainId });
|
|
824
|
+
},
|
|
825
|
+
disconnect: async () => {
|
|
826
|
+
await disconnect(getEvmConfig());
|
|
827
|
+
},
|
|
828
|
+
signMessage: async (message) => {
|
|
829
|
+
return signMessage(getEvmConfig(), { message });
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}));
|
|
833
|
+
addFallbackConnectors(connectors, EVM_FALLBACK_CONNECTORS);
|
|
834
|
+
return connectors;
|
|
835
|
+
};
|
|
836
|
+
var watchEvmConnections = (onChange) => {
|
|
837
|
+
return watchConnections(getEvmConfig(), { onChange });
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
// src/lib/solana/connection.ts
|
|
841
|
+
var currentConnection = {
|
|
842
|
+
connection: null,
|
|
843
|
+
connector: null
|
|
844
|
+
};
|
|
845
|
+
var connectionListeners = /* @__PURE__ */ new Set();
|
|
846
|
+
var notifyConnectionListeners = () => {
|
|
847
|
+
connectionListeners.forEach((listener) => listener(currentConnection));
|
|
848
|
+
};
|
|
849
|
+
var setConnection = (connection, connector) => {
|
|
850
|
+
currentConnection = { connection, connector };
|
|
851
|
+
notifyConnectionListeners();
|
|
852
|
+
};
|
|
853
|
+
var watchSolanaConnection = (onChange) => {
|
|
854
|
+
connectionListeners.add(onChange);
|
|
855
|
+
onChange(currentConnection);
|
|
856
|
+
return () => {
|
|
857
|
+
connectionListeners.delete(onChange);
|
|
858
|
+
};
|
|
859
|
+
};
|
|
860
|
+
var createSolanaConnector = (provider) => {
|
|
861
|
+
const id = normalizeSolanaWalletId(provider.name.toLowerCase().replace(/\s+/g, "-"));
|
|
862
|
+
const connector = {
|
|
863
|
+
id,
|
|
864
|
+
name: provider.name,
|
|
865
|
+
icon: provider.icon,
|
|
866
|
+
type: "solana",
|
|
867
|
+
installed: true,
|
|
868
|
+
wallet: {
|
|
869
|
+
_provider: provider,
|
|
870
|
+
connect: async () => {
|
|
871
|
+
const feature = provider.features["standard:connect"];
|
|
872
|
+
const result = await feature.connect();
|
|
873
|
+
const account = result.accounts[0];
|
|
874
|
+
if (!account) throw new Error("No account returned from wallet");
|
|
875
|
+
const connectResult = connectedResult(account.address, {
|
|
876
|
+
publicKey: new Uint8Array(account.publicKey)
|
|
877
|
+
});
|
|
878
|
+
storage.setString(STORAGE_KEYS.SOLANA_WALLET, id);
|
|
879
|
+
setConnection(connectResult, connector);
|
|
880
|
+
return connectResult;
|
|
881
|
+
},
|
|
882
|
+
disconnect: async () => {
|
|
883
|
+
const features = provider.features;
|
|
884
|
+
const disconnectFeature = features["standard:disconnect"];
|
|
885
|
+
if (disconnectFeature?.disconnect) {
|
|
886
|
+
await disconnectFeature.disconnect();
|
|
887
|
+
}
|
|
888
|
+
storage.remove(STORAGE_KEYS.SOLANA_WALLET);
|
|
889
|
+
setConnection(null, null);
|
|
890
|
+
},
|
|
891
|
+
signMessage: async (message) => {
|
|
892
|
+
const features = provider.features;
|
|
893
|
+
const signFeature = features["solana:signMessage"];
|
|
894
|
+
if (!signFeature?.signMessage) {
|
|
895
|
+
throw new Error("signMessage not supported by wallet");
|
|
896
|
+
}
|
|
897
|
+
const account = provider.accounts[0];
|
|
898
|
+
if (!account) throw new Error("No account connected");
|
|
899
|
+
const encodedMessage = new TextEncoder().encode(message);
|
|
900
|
+
const result = await signFeature.signMessage({ message: encodedMessage, account });
|
|
901
|
+
const signature = result[0]?.signature;
|
|
902
|
+
if (!signature) throw new Error("No signature returned");
|
|
903
|
+
return bs58.encode(signature);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
};
|
|
907
|
+
return connector;
|
|
908
|
+
};
|
|
909
|
+
var createSolanaMobileConnector = (connector) => ({
|
|
910
|
+
...connector,
|
|
911
|
+
wallet: {
|
|
912
|
+
...connector.wallet,
|
|
913
|
+
disconnect: async () => {
|
|
914
|
+
storage.remove(STORAGE_KEYS.SOLANA_WALLET);
|
|
915
|
+
setConnection(null, null);
|
|
916
|
+
await connector.wallet.disconnect();
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
});
|
|
920
|
+
var SOLANA_FALLBACK_CONNECTORS = [
|
|
921
|
+
{ id: "phantom", create: () => createSolanaMobileConnector(createPhantomSolanaConnector()) },
|
|
922
|
+
// { id: 'metamask', create: () => createSolanaMobileConnector(createMetaMaskSolanaConnector()) },
|
|
923
|
+
{
|
|
924
|
+
id: "solflare",
|
|
925
|
+
create: () => createSolanaMobileConnector(createSolflareSolanaMobileConnector())
|
|
926
|
+
},
|
|
927
|
+
{ id: "trust", create: () => createSolanaMobileConnector(createTrustSolanaMobileConnector()) },
|
|
928
|
+
{ id: "binance", create: () => createSolanaMobileConnector(createBinanceSolanaConnector()) },
|
|
929
|
+
{ id: "exodus", create: () => createSolanaMobileConnector(createExodusSolanaMobileConnector()) }
|
|
930
|
+
];
|
|
931
|
+
var getSolanaWallets = () => {
|
|
932
|
+
const { get } = getWallets();
|
|
933
|
+
const wallets = get();
|
|
934
|
+
const connectors = wallets.filter(isWalletAdapterCompatibleStandardWallet).map(createSolanaConnector);
|
|
935
|
+
addFallbackConnectors(connectors, SOLANA_FALLBACK_CONNECTORS);
|
|
936
|
+
return connectors;
|
|
937
|
+
};
|
|
938
|
+
var onSolanaWalletsChange = (callback) => {
|
|
939
|
+
const { on } = getWallets();
|
|
940
|
+
const handleChange = () => {
|
|
941
|
+
callback(getSolanaWallets());
|
|
942
|
+
};
|
|
943
|
+
const unsubscribeRegister = on("register", handleChange);
|
|
944
|
+
const unsubscribeUnregister = on("unregister", handleChange);
|
|
945
|
+
return () => {
|
|
946
|
+
unsubscribeRegister();
|
|
947
|
+
unsubscribeUnregister();
|
|
948
|
+
};
|
|
949
|
+
};
|
|
950
|
+
var MOBILE_STRATEGIES = [
|
|
951
|
+
{
|
|
952
|
+
id: "phantom",
|
|
953
|
+
isPending: isPhantomMobilePending,
|
|
954
|
+
handleCallback: handlePhantomMobileCallback,
|
|
955
|
+
restoreSession: restorePhantomMobileSession,
|
|
956
|
+
createConnector: () => createSolanaMobileConnector(createPhantomSolanaConnector())
|
|
957
|
+
},
|
|
958
|
+
{
|
|
959
|
+
id: "solflare",
|
|
960
|
+
isPending: isSolflareMobilePending,
|
|
961
|
+
handleCallback: handleSolflareMobileCallback,
|
|
962
|
+
restoreSession: restoreSolflareMobileSession,
|
|
963
|
+
createConnector: () => createSolanaMobileConnector(createSolflareSolanaMobileConnector())
|
|
964
|
+
}
|
|
965
|
+
];
|
|
966
|
+
var tryMobileCallback = () => {
|
|
967
|
+
for (const strategy of MOBILE_STRATEGIES) {
|
|
968
|
+
if (strategy.isPending()) {
|
|
969
|
+
const result = strategy.handleCallback();
|
|
970
|
+
if (result) {
|
|
971
|
+
setConnection(result, strategy.createConnector());
|
|
972
|
+
storage.setString(STORAGE_KEYS.SOLANA_WALLET, strategy.id);
|
|
973
|
+
return true;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
return false;
|
|
978
|
+
};
|
|
979
|
+
var tryRestoreSession = () => {
|
|
980
|
+
for (const strategy of MOBILE_STRATEGIES) {
|
|
981
|
+
const result = strategy.restoreSession();
|
|
982
|
+
if (result) {
|
|
983
|
+
setConnection(result, strategy.createConnector());
|
|
984
|
+
return true;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
return false;
|
|
988
|
+
};
|
|
989
|
+
var tryReconnectSavedWallet = (savedWalletId) => {
|
|
990
|
+
const wallets = getSolanaWallets();
|
|
991
|
+
const savedConnector = wallets.find((c) => c.id === savedWalletId);
|
|
992
|
+
if (savedConnector) {
|
|
993
|
+
savedConnector.wallet.connect().then((result) => {
|
|
994
|
+
if (result.status === "connected") {
|
|
995
|
+
setConnection(result, savedConnector);
|
|
996
|
+
}
|
|
997
|
+
}).catch(() => {
|
|
998
|
+
storage.remove(STORAGE_KEYS.SOLANA_WALLET);
|
|
999
|
+
});
|
|
1000
|
+
return true;
|
|
1001
|
+
}
|
|
1002
|
+
return false;
|
|
1003
|
+
};
|
|
1004
|
+
var reconnectSolana = () => {
|
|
1005
|
+
if (tryMobileCallback()) return;
|
|
1006
|
+
if (tryRestoreSession()) return;
|
|
1007
|
+
const savedWalletId = storage.getString(STORAGE_KEYS.SOLANA_WALLET);
|
|
1008
|
+
if (!savedWalletId) return;
|
|
1009
|
+
if (tryReconnectSavedWallet(savedWalletId)) return;
|
|
1010
|
+
const { on } = getWallets();
|
|
1011
|
+
const unsubscribe = on("register", () => {
|
|
1012
|
+
if (tryReconnectSavedWallet(savedWalletId)) unsubscribe();
|
|
1013
|
+
});
|
|
1014
|
+
window.setTimeout(unsubscribe, 5e3);
|
|
1015
|
+
};
|
|
1016
|
+
var checkPhantomSignCallback = () => {
|
|
1017
|
+
if (!isPhantomSignPending()) return null;
|
|
1018
|
+
return handlePhantomSignCallback();
|
|
1019
|
+
};
|
|
1020
|
+
var checkSolflareSignCallback = () => {
|
|
1021
|
+
if (!isSolflareSignPending()) return null;
|
|
1022
|
+
return handleSolflareSignCallback();
|
|
1023
|
+
};
|
|
1024
|
+
var useEvmWallet = (options) => {
|
|
1025
|
+
const [evmConnectors, setEvmConnectors] = createSignal([]);
|
|
1026
|
+
const [evmConnection, setEvmConnection] = createSignal(null);
|
|
1027
|
+
const [connectedConnector, setConnectedConnector] = createSignal(null);
|
|
1028
|
+
onMount(() => {
|
|
1029
|
+
createEvmConfig(options.chains);
|
|
1030
|
+
setEvmConnectors(getEvmConnectors());
|
|
1031
|
+
const unsubscribe = watchEvmConnections((connections) => {
|
|
1032
|
+
const connection = connections[0];
|
|
1033
|
+
if (connection && connection.accounts[0]) {
|
|
1034
|
+
setEvmConnection(connectedResult(connection.accounts[0], { chainId: connection.chainId }));
|
|
1035
|
+
} else {
|
|
1036
|
+
setEvmConnection(null);
|
|
1037
|
+
}
|
|
1038
|
+
});
|
|
1039
|
+
onCleanup(unsubscribe);
|
|
1040
|
+
});
|
|
1041
|
+
const connectEvm = async (connector) => {
|
|
1042
|
+
const result = await connector.wallet.connect();
|
|
1043
|
+
setConnectedConnector(connector);
|
|
1044
|
+
if (result.status === "connected") {
|
|
1045
|
+
setEvmConnection(result);
|
|
1046
|
+
} else if (result.status === "qrcode") {
|
|
1047
|
+
result.wait().then((connectedResult2) => setEvmConnection(connectedResult2)).catch(() => {
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
return result;
|
|
1051
|
+
};
|
|
1052
|
+
const disconnectEvm = async () => {
|
|
1053
|
+
const connector = connectedConnector();
|
|
1054
|
+
if (connector) {
|
|
1055
|
+
await connector.wallet.disconnect();
|
|
1056
|
+
setConnectedConnector(null);
|
|
1057
|
+
}
|
|
1058
|
+
setEvmConnection(null);
|
|
1059
|
+
};
|
|
1060
|
+
return {
|
|
1061
|
+
evmConnectors,
|
|
1062
|
+
evmConnection,
|
|
1063
|
+
setEvmConnection,
|
|
1064
|
+
connectEvm,
|
|
1065
|
+
disconnectEvm,
|
|
1066
|
+
connectedEvmConnector: connectedConnector
|
|
1067
|
+
};
|
|
1068
|
+
};
|
|
1069
|
+
var useSolanaWallet = () => {
|
|
1070
|
+
const [solanaConnectors, setSolanaConnectors] = createSignal([]);
|
|
1071
|
+
const [solanaConnection, setSolanaConnection] = createSignal(null);
|
|
1072
|
+
const [connectedConnector, setConnectedConnector] = createSignal(
|
|
1073
|
+
null
|
|
1074
|
+
);
|
|
1075
|
+
onMount(() => {
|
|
1076
|
+
setSolanaConnectors(getSolanaWallets());
|
|
1077
|
+
const unsubscribeWallets = onSolanaWalletsChange(setSolanaConnectors);
|
|
1078
|
+
const unsubscribeConnection = watchSolanaConnection((state) => {
|
|
1079
|
+
setSolanaConnection(state.connection);
|
|
1080
|
+
if (state.connector) {
|
|
1081
|
+
setConnectedConnector(state.connector);
|
|
1082
|
+
}
|
|
1083
|
+
});
|
|
1084
|
+
reconnectSolana();
|
|
1085
|
+
onCleanup(() => {
|
|
1086
|
+
unsubscribeWallets();
|
|
1087
|
+
unsubscribeConnection();
|
|
1088
|
+
});
|
|
1089
|
+
});
|
|
1090
|
+
const connectSolana = async (connector) => {
|
|
1091
|
+
setConnectedConnector(connector);
|
|
1092
|
+
const result = await connector.wallet.connect();
|
|
1093
|
+
if (result.status === "connected") {
|
|
1094
|
+
setSolanaConnection(result);
|
|
1095
|
+
} else if (result.status === "qrcode") {
|
|
1096
|
+
result.wait().then((connectedResult2) => setSolanaConnection(connectedResult2)).catch(() => {
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
return result;
|
|
1100
|
+
};
|
|
1101
|
+
const disconnectSolana = async () => {
|
|
1102
|
+
const connector = connectedConnector();
|
|
1103
|
+
if (connector) {
|
|
1104
|
+
await connector.wallet.disconnect();
|
|
1105
|
+
setConnectedConnector(null);
|
|
1106
|
+
setSolanaConnection(null);
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
const wallets = getSolanaWallets();
|
|
1110
|
+
for (const wallet of wallets) {
|
|
1111
|
+
if (wallet.wallet._provider?.accounts?.length > 0) {
|
|
1112
|
+
await wallet.wallet.disconnect();
|
|
1113
|
+
setSolanaConnection(null);
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
};
|
|
1118
|
+
return {
|
|
1119
|
+
solanaConnectors,
|
|
1120
|
+
solanaConnection,
|
|
1121
|
+
setSolanaConnection,
|
|
1122
|
+
connectSolana,
|
|
1123
|
+
disconnectSolana,
|
|
1124
|
+
connectedSolanaConnector: connectedConnector
|
|
1125
|
+
};
|
|
1126
|
+
};
|
|
1127
|
+
var useWalletConnect = (options) => {
|
|
1128
|
+
onMount(async () => {
|
|
1129
|
+
if (!options.config) return;
|
|
1130
|
+
await initWalletConnect(options.config);
|
|
1131
|
+
const handleSession = (session) => {
|
|
1132
|
+
if (!session) return;
|
|
1133
|
+
if (session.namespaces.eip155?.accounts?.[0] && options.onEvmConnection) {
|
|
1134
|
+
options.onEvmConnection(getEvmAccountFromSession(session.namespaces));
|
|
1135
|
+
}
|
|
1136
|
+
if (session.namespaces.solana?.accounts?.[0] && options.onSolanaConnection) {
|
|
1137
|
+
getSolanaAccountFromSession(session.namespaces).then(options.onSolanaConnection).catch((err) => console.error("Solana session parse error:", err));
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
const existingSession = getCurrentSession();
|
|
1141
|
+
if (existingSession) {
|
|
1142
|
+
handleSession(existingSession);
|
|
1143
|
+
}
|
|
1144
|
+
const unsubscribe = onWalletConnectSessionChange(handleSession);
|
|
1145
|
+
onCleanup(unsubscribe);
|
|
1146
|
+
});
|
|
1147
|
+
const hasWcEvmSession = () => {
|
|
1148
|
+
return !!getCurrentSession()?.namespaces.eip155;
|
|
1149
|
+
};
|
|
1150
|
+
const hasWcSolanaSession = () => {
|
|
1151
|
+
return !!getCurrentSession()?.namespaces.solana;
|
|
1152
|
+
};
|
|
1153
|
+
const disconnectWcEvm = async () => {
|
|
1154
|
+
if (hasWcEvmSession()) {
|
|
1155
|
+
await disconnectWalletConnect();
|
|
1156
|
+
}
|
|
1157
|
+
};
|
|
1158
|
+
const disconnectWcSolana = async () => {
|
|
1159
|
+
if (hasWcSolanaSession()) {
|
|
1160
|
+
await disconnectWalletConnect();
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
const signWcEvmMessage = async (message) => {
|
|
1164
|
+
const session = getCurrentSession();
|
|
1165
|
+
if (!session) throw new Error("No WalletConnect session");
|
|
1166
|
+
const account = session.namespaces.eip155?.accounts?.[0];
|
|
1167
|
+
if (!account) throw new Error("No EVM account in session");
|
|
1168
|
+
const address = account.split(":")[2];
|
|
1169
|
+
return requestWalletConnect("personal_sign", [message, address], WC_CHAINS.EVM_MAINNET);
|
|
1170
|
+
};
|
|
1171
|
+
const signWcSolanaMessage = async (message) => {
|
|
1172
|
+
const session = getCurrentSession();
|
|
1173
|
+
if (!session) throw new Error("No WalletConnect session");
|
|
1174
|
+
const account = session.namespaces.solana?.accounts?.[0];
|
|
1175
|
+
if (!account) throw new Error("No Solana account in session");
|
|
1176
|
+
const pubkey = account.split(":")[2];
|
|
1177
|
+
const messageBytes = new TextEncoder().encode(message);
|
|
1178
|
+
const result = await requestWalletConnect(
|
|
1179
|
+
"solana_signMessage",
|
|
1180
|
+
{ message: bs58.encode(messageBytes), pubkey },
|
|
1181
|
+
WC_CHAINS.SOLANA_MAINNET
|
|
1182
|
+
);
|
|
1183
|
+
return result.signature;
|
|
1184
|
+
};
|
|
1185
|
+
return {
|
|
1186
|
+
disconnectWcEvm,
|
|
1187
|
+
disconnectWcSolana,
|
|
1188
|
+
hasWcEvmSession,
|
|
1189
|
+
hasWcSolanaSession,
|
|
1190
|
+
signWcEvmMessage,
|
|
1191
|
+
signWcSolanaMessage
|
|
1192
|
+
};
|
|
1193
|
+
};
|
|
1194
|
+
|
|
1195
|
+
// src/lib/context/WalletContext.tsx
|
|
1196
|
+
var WalletContext = createContext();
|
|
1197
|
+
var WalletProvider = (props) => {
|
|
1198
|
+
const evm = useEvmWallet({
|
|
1199
|
+
chains: props.evmChains
|
|
1200
|
+
});
|
|
1201
|
+
const solana = useSolanaWallet();
|
|
1202
|
+
const wc = useWalletConnect({
|
|
1203
|
+
config: props.walletConnect,
|
|
1204
|
+
onEvmConnection: evm.setEvmConnection,
|
|
1205
|
+
onSolanaConnection: solana.setSolanaConnection
|
|
1206
|
+
});
|
|
1207
|
+
const disconnectEvm = async () => {
|
|
1208
|
+
if (evm.connectedEvmConnector()) {
|
|
1209
|
+
await evm.disconnectEvm();
|
|
1210
|
+
} else {
|
|
1211
|
+
await wc.disconnectWcEvm();
|
|
1212
|
+
evm.setEvmConnection(null);
|
|
1213
|
+
}
|
|
1214
|
+
};
|
|
1215
|
+
const disconnectSolana = async () => {
|
|
1216
|
+
if (solana.connectedSolanaConnector()) {
|
|
1217
|
+
await solana.disconnectSolana();
|
|
1218
|
+
} else if (wc.hasWcSolanaSession()) {
|
|
1219
|
+
await wc.disconnectWcSolana();
|
|
1220
|
+
solana.setSolanaConnection(null);
|
|
1221
|
+
} else {
|
|
1222
|
+
await solana.disconnectSolana();
|
|
1223
|
+
}
|
|
1224
|
+
};
|
|
1225
|
+
const groupedWallets = () => {
|
|
1226
|
+
const evmMap = new Map(evm.evmConnectors().map((c) => [c.id, c]));
|
|
1227
|
+
const solanaMap = new Map(solana.solanaConnectors().map((c) => [c.id, c]));
|
|
1228
|
+
return WALLETS.map((config2) => {
|
|
1229
|
+
const evm2 = evmMap.get(config2.id);
|
|
1230
|
+
const solana2 = solanaMap.get(config2.id);
|
|
1231
|
+
return {
|
|
1232
|
+
id: config2.id,
|
|
1233
|
+
name: config2.name,
|
|
1234
|
+
evm: evm2,
|
|
1235
|
+
solana: solana2
|
|
1236
|
+
};
|
|
1237
|
+
});
|
|
1238
|
+
};
|
|
1239
|
+
const signMessage = async (chainType, message) => {
|
|
1240
|
+
if (chainType === "evm") {
|
|
1241
|
+
const connector = evm.connectedEvmConnector();
|
|
1242
|
+
if (connector) {
|
|
1243
|
+
return connector.wallet.signMessage(message);
|
|
1244
|
+
}
|
|
1245
|
+
if (wc.hasWcEvmSession()) {
|
|
1246
|
+
return wc.signWcEvmMessage(message);
|
|
1247
|
+
}
|
|
1248
|
+
throw new Error("EVM wallet not connected");
|
|
1249
|
+
} else {
|
|
1250
|
+
const connector = solana.connectedSolanaConnector();
|
|
1251
|
+
if (connector) {
|
|
1252
|
+
return connector.wallet.signMessage(message);
|
|
1253
|
+
}
|
|
1254
|
+
if (wc.hasWcSolanaSession()) {
|
|
1255
|
+
return wc.signWcSolanaMessage(message);
|
|
1256
|
+
}
|
|
1257
|
+
throw new Error("Solana wallet not connected");
|
|
1258
|
+
}
|
|
1259
|
+
};
|
|
1260
|
+
const value = {
|
|
1261
|
+
evmConnectors: evm.evmConnectors,
|
|
1262
|
+
evmConnection: evm.evmConnection,
|
|
1263
|
+
solanaConnectors: solana.solanaConnectors,
|
|
1264
|
+
solanaConnection: solana.solanaConnection,
|
|
1265
|
+
groupedWallets,
|
|
1266
|
+
connectEvm: evm.connectEvm,
|
|
1267
|
+
disconnectEvm,
|
|
1268
|
+
connectSolana: solana.connectSolana,
|
|
1269
|
+
disconnectSolana,
|
|
1270
|
+
signMessage
|
|
1271
|
+
};
|
|
1272
|
+
return createComponent(WalletContext.Provider, {
|
|
1273
|
+
value,
|
|
1274
|
+
get children() {
|
|
1275
|
+
return props.children;
|
|
1276
|
+
}
|
|
1277
|
+
});
|
|
1278
|
+
};
|
|
1279
|
+
function useWallet() {
|
|
1280
|
+
const context = useContext(WalletContext);
|
|
1281
|
+
if (!context) {
|
|
1282
|
+
throw new Error("useWallet must be used within a WalletProvider");
|
|
1283
|
+
}
|
|
1284
|
+
return context;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
export { WALLETS, WalletProvider, checkPhantomSignCallback, checkSolflareSignCallback, createEvmConfig, getEvmConfig, getEvmConnectors, getSolanaWallets, initWalletConnect, onSolanaWalletsChange, reconnectSolana, useWallet, watchEvmConnections, watchSolanaConnection };
|