@kheopskit/core 1.0.1 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATING_TO_V4.md +259 -0
- package/README.md +67 -0
- package/dist/chunk-4ENHC7G4.js +210 -0
- package/dist/chunk-4ENHC7G4.js.map +1 -0
- package/dist/chunk-6XAZANB5.mjs +450 -0
- package/dist/chunk-6XAZANB5.mjs.map +1 -0
- package/dist/chunk-7QSGAJ4A.mjs +210 -0
- package/dist/chunk-7QSGAJ4A.mjs.map +1 -0
- package/dist/chunk-B4L6GAYD.js +179 -0
- package/dist/chunk-B4L6GAYD.js.map +1 -0
- package/dist/chunk-BWUUHUDK.mjs +24 -0
- package/dist/chunk-BWUUHUDK.mjs.map +1 -0
- package/dist/chunk-D3EQMFZ2.js +24 -0
- package/dist/chunk-D3EQMFZ2.js.map +1 -0
- package/dist/chunk-XQWJM3KC.js +450 -0
- package/dist/chunk-XQWJM3KC.js.map +1 -0
- package/dist/chunk-YDLCHYHH.mjs +179 -0
- package/dist/chunk-YDLCHYHH.mjs.map +1 -0
- package/dist/ethereum.d.mts +61 -0
- package/dist/ethereum.d.ts +61 -0
- package/dist/ethereum.js +351 -0
- package/dist/ethereum.js.map +1 -0
- package/dist/ethereum.mjs +351 -0
- package/dist/ethereum.mjs.map +1 -0
- package/dist/getCachedObservable-C4E8dfMp.d.mts +20 -0
- package/dist/getCachedObservable-C4E8dfMp.d.ts +20 -0
- package/dist/index.d.mts +55 -267
- package/dist/index.d.ts +55 -267
- package/dist/index.js +327 -1355
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +263 -1325
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.mts +86 -0
- package/dist/internal.d.ts +86 -0
- package/dist/internal.js +32 -0
- package/dist/internal.js.map +1 -0
- package/dist/internal.mjs +32 -0
- package/dist/internal.mjs.map +1 -0
- package/dist/polkadot.d.mts +70 -0
- package/dist/polkadot.d.ts +70 -0
- package/dist/polkadot.js +303 -0
- package/dist/polkadot.js.map +1 -0
- package/dist/polkadot.mjs +303 -0
- package/dist/polkadot.mjs.map +1 -0
- package/dist/solana.d.mts +98 -0
- package/dist/solana.d.ts +98 -0
- package/dist/solana.js +461 -0
- package/dist/solana.js.map +1 -0
- package/dist/solana.mjs +461 -0
- package/dist/solana.mjs.map +1 -0
- package/dist/types-C7V7DGlg.d.mts +349 -0
- package/dist/types-C7V7DGlg.d.ts +349 -0
- package/package.json +104 -18
package/dist/index.mjs
CHANGED
|
@@ -1,479 +1,225 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// src/utils/isWalletPlatform.ts
|
|
35
|
-
var isWalletPlatform = (platform) => typeof platform === "string" && ["polkadot", "ethereum"].includes(platform);
|
|
36
|
-
|
|
37
|
-
// src/utils/WalletId.ts
|
|
38
|
-
var getWalletId = (platform, identifier) => {
|
|
39
|
-
if (!isWalletPlatform(platform)) throw new Error("Invalid platform");
|
|
40
|
-
if (!identifier) throw new Error("Invalid name");
|
|
41
|
-
return `${platform}:${identifier}`;
|
|
42
|
-
};
|
|
43
|
-
var parseWalletId = (walletId) => {
|
|
44
|
-
if (!walletId) throw new Error("Invalid walletId");
|
|
45
|
-
const [platform, identifier] = walletId.split(":");
|
|
46
|
-
if (!isWalletPlatform(platform)) throw new Error("Invalid platform");
|
|
47
|
-
if (!identifier) throw new Error("Invalid address");
|
|
48
|
-
return { platform, identifier };
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
// src/utils/hydrateState.ts
|
|
52
|
-
var lookupWalletIcon = (platform, identifier) => {
|
|
53
|
-
if (platform === "polkadot") {
|
|
54
|
-
return POLKADOT_EXTENSIONS[identifier]?.icon ?? "";
|
|
55
|
-
}
|
|
56
|
-
return "";
|
|
57
|
-
};
|
|
58
|
-
var PendingWalletError = class extends Error {
|
|
59
|
-
constructor(walletId) {
|
|
60
|
-
super(
|
|
61
|
-
`Wallet ${walletId} is still loading. Wait for isHydrating to be false before calling connect/disconnect.`
|
|
62
|
-
);
|
|
63
|
-
this.name = "PendingWalletError";
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
var hydrateWallet = (cached) => {
|
|
67
|
-
const { platform, identifier } = parseWalletId(cached.id);
|
|
68
|
-
const throwPending = () => {
|
|
69
|
-
throw new PendingWalletError(cached.id);
|
|
70
|
-
};
|
|
71
|
-
const icon = lookupWalletIcon(platform, identifier);
|
|
72
|
-
if (platform === "polkadot") {
|
|
73
|
-
return {
|
|
74
|
-
id: cached.id,
|
|
75
|
-
platform: "polkadot",
|
|
76
|
-
type: "injected",
|
|
77
|
-
extensionId: identifier,
|
|
78
|
-
extension: void 0,
|
|
79
|
-
name: cached.name,
|
|
80
|
-
icon,
|
|
81
|
-
isConnected: cached.isConnected,
|
|
82
|
-
connect: throwPending,
|
|
83
|
-
disconnect: throwPending
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
if (platform === "ethereum") {
|
|
87
|
-
return {
|
|
88
|
-
id: cached.id,
|
|
89
|
-
platform: "ethereum",
|
|
90
|
-
type: "injected",
|
|
91
|
-
providerId: identifier,
|
|
92
|
-
provider: {},
|
|
93
|
-
// Placeholder - will be replaced by real wallet
|
|
94
|
-
name: cached.name,
|
|
95
|
-
icon,
|
|
96
|
-
isConnected: cached.isConnected,
|
|
97
|
-
connect: throwPending,
|
|
98
|
-
disconnect: throwPending
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
throw new Error(`Unknown platform: ${platform}`);
|
|
102
|
-
};
|
|
103
|
-
var hydrateAccount = (cached) => {
|
|
104
|
-
if (cached.platform === "polkadot") {
|
|
105
|
-
return {
|
|
106
|
-
id: cached.id,
|
|
107
|
-
platform: "polkadot",
|
|
108
|
-
type: cached.polkadotAccountType ?? "sr25519",
|
|
109
|
-
address: cached.address,
|
|
110
|
-
name: cached.name,
|
|
111
|
-
walletId: cached.walletId,
|
|
112
|
-
walletName: cached.walletName,
|
|
113
|
-
// PolkadotSigner is required but we can't provide a real one
|
|
114
|
-
// This is a placeholder that will be replaced by the real account
|
|
115
|
-
polkadotSigner: {}
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
if (cached.platform === "ethereum") {
|
|
119
|
-
return {
|
|
120
|
-
id: cached.id,
|
|
121
|
-
platform: "ethereum",
|
|
122
|
-
address: cached.address,
|
|
123
|
-
chainId: cached.chainId,
|
|
124
|
-
walletId: cached.walletId,
|
|
125
|
-
walletName: cached.walletName,
|
|
126
|
-
isWalletDefault: false,
|
|
127
|
-
client: {}
|
|
128
|
-
// Placeholder
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
throw new Error(`Unknown platform: ${cached.platform}`);
|
|
132
|
-
};
|
|
133
|
-
var serializeWallet = (wallet) => ({
|
|
134
|
-
id: wallet.id,
|
|
135
|
-
platform: wallet.platform,
|
|
136
|
-
type: wallet.type,
|
|
137
|
-
name: wallet.name,
|
|
138
|
-
// Note: icon is NOT stored to save cookie space
|
|
139
|
-
isConnected: wallet.isConnected
|
|
140
|
-
});
|
|
141
|
-
var serializeAccount = (account) => ({
|
|
142
|
-
id: account.id,
|
|
143
|
-
platform: account.platform,
|
|
144
|
-
address: account.address,
|
|
145
|
-
name: "name" in account ? account.name : void 0,
|
|
146
|
-
chainId: account.platform === "ethereum" ? account.chainId : void 0,
|
|
147
|
-
polkadotAccountType: account.platform === "polkadot" ? account.type : void 0,
|
|
148
|
-
walletId: account.walletId,
|
|
149
|
-
walletName: account.walletName
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// src/utils/storage.ts
|
|
153
|
-
var noopStorage = {
|
|
154
|
-
getItem: () => null,
|
|
155
|
-
setItem: () => {
|
|
156
|
-
},
|
|
157
|
-
removeItem: () => {
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
var _safeLocalStorage = null;
|
|
161
|
-
var createSafeLocalStorage = () => {
|
|
162
|
-
if (typeof window === "undefined") return noopStorage;
|
|
163
|
-
try {
|
|
164
|
-
const testKey = "__kheopskit_test__";
|
|
165
|
-
window.localStorage.setItem(testKey, testKey);
|
|
166
|
-
window.localStorage.removeItem(testKey);
|
|
167
|
-
return {
|
|
168
|
-
getItem: (key) => window.localStorage.getItem(key),
|
|
169
|
-
setItem: (key, value) => window.localStorage.setItem(key, value),
|
|
170
|
-
removeItem: (key) => window.localStorage.removeItem(key),
|
|
171
|
-
subscribe: (key, callback) => {
|
|
172
|
-
const handler = (event) => {
|
|
173
|
-
if (event.key === key) {
|
|
174
|
-
callback(event.newValue);
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
window.addEventListener("storage", handler);
|
|
178
|
-
return () => window.removeEventListener("storage", handler);
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
} catch {
|
|
182
|
-
return noopStorage;
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
var getSafeLocalStorage = () => {
|
|
186
|
-
if (_safeLocalStorage === null) {
|
|
187
|
-
_safeLocalStorage = createSafeLocalStorage();
|
|
188
|
-
}
|
|
189
|
-
return _safeLocalStorage;
|
|
190
|
-
};
|
|
191
|
-
var safeLocalStorage = {
|
|
192
|
-
getItem: (key) => getSafeLocalStorage().getItem(key),
|
|
193
|
-
setItem: (key, value) => getSafeLocalStorage().setItem(key, value),
|
|
194
|
-
removeItem: (key) => getSafeLocalStorage().removeItem(key),
|
|
195
|
-
subscribe: (key, callback) => {
|
|
196
|
-
const storage = getSafeLocalStorage();
|
|
197
|
-
return storage.subscribe?.(key, callback) ?? (() => {
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
var parseCookie = (cookieString, key) => {
|
|
202
|
-
if (!cookieString) return null;
|
|
203
|
-
for (const cookie of cookieString.split(";")) {
|
|
204
|
-
const [k, ...v] = cookie.split("=");
|
|
205
|
-
const cookieKey = k?.trim();
|
|
206
|
-
if (cookieKey === key) {
|
|
207
|
-
try {
|
|
208
|
-
return decodeURIComponent(v.join("=").trim());
|
|
209
|
-
} catch {
|
|
210
|
-
return null;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
return null;
|
|
215
|
-
};
|
|
216
|
-
var COOKIE_MAX_SIZE = 3 * 1024;
|
|
217
|
-
var BROADCAST_CHANNEL_NAME = "kheopskit-storage-sync";
|
|
218
|
-
var sharedBroadcastChannel = null;
|
|
219
|
-
var getBroadcastChannel = () => {
|
|
220
|
-
if (sharedBroadcastChannel) return sharedBroadcastChannel;
|
|
221
|
-
if (typeof BroadcastChannel === "undefined") return null;
|
|
222
|
-
try {
|
|
223
|
-
sharedBroadcastChannel = new BroadcastChannel(BROADCAST_CHANNEL_NAME);
|
|
224
|
-
} catch {
|
|
225
|
-
}
|
|
226
|
-
return sharedBroadcastChannel;
|
|
227
|
-
};
|
|
228
|
-
var isSecureConnection = () => typeof window !== "undefined" && window.location.protocol === "https:";
|
|
229
|
-
var cookieStorage = (initialCookies) => {
|
|
230
|
-
return {
|
|
231
|
-
getItem: (key) => {
|
|
232
|
-
const cookieString = typeof document !== "undefined" ? document.cookie : initialCookies;
|
|
233
|
-
return parseCookie(cookieString, key);
|
|
234
|
-
},
|
|
235
|
-
setItem: (key, value) => {
|
|
236
|
-
if (typeof document === "undefined") return;
|
|
237
|
-
const encodedValue = encodeURIComponent(value);
|
|
238
|
-
if (encodedValue.length > COOKIE_MAX_SIZE) {
|
|
239
|
-
console.warn(
|
|
240
|
-
`[kheopskit] Cookie value for "${key}" exceeds recommended size limit (${encodedValue.length} > ${COOKIE_MAX_SIZE} bytes). This may cause issues with cookie storage. Consider reducing the number of connected wallets.`
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
const expires = /* @__PURE__ */ new Date();
|
|
244
|
-
expires.setFullYear(expires.getFullYear() + 1);
|
|
245
|
-
let cookieStr = `${key}=${encodedValue};expires=${expires.toUTCString()};path=/;SameSite=Lax`;
|
|
246
|
-
if (isSecureConnection()) {
|
|
247
|
-
cookieStr += ";Secure";
|
|
248
|
-
}
|
|
249
|
-
document.cookie = cookieStr;
|
|
250
|
-
getBroadcastChannel()?.postMessage({ type: "set", key, value });
|
|
251
|
-
},
|
|
252
|
-
removeItem: (key) => {
|
|
253
|
-
if (typeof document === "undefined") return;
|
|
254
|
-
let cookieStr = `${key}=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/;SameSite=Lax`;
|
|
255
|
-
if (isSecureConnection()) {
|
|
256
|
-
cookieStr += ";Secure";
|
|
257
|
-
}
|
|
258
|
-
document.cookie = cookieStr;
|
|
259
|
-
getBroadcastChannel()?.postMessage({ type: "remove", key });
|
|
260
|
-
},
|
|
261
|
-
subscribe: (key, callback) => {
|
|
262
|
-
const channel = getBroadcastChannel();
|
|
263
|
-
if (!channel) return () => {
|
|
264
|
-
};
|
|
265
|
-
const handler = (event) => {
|
|
266
|
-
const data = event.data;
|
|
267
|
-
if (data.key === key) {
|
|
268
|
-
if (data.type === "set") {
|
|
269
|
-
callback(data.value ?? null);
|
|
270
|
-
} else if (data.type === "remove") {
|
|
271
|
-
callback(null);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
channel.addEventListener("message", handler);
|
|
276
|
-
return () => {
|
|
277
|
-
channel.removeEventListener("message", handler);
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
};
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
// src/utils/iconCache.ts
|
|
284
|
-
var ICON_CACHE_KEY = "kheopskit-icons";
|
|
285
|
-
var memoryCache = null;
|
|
286
|
-
var loadCache = () => {
|
|
287
|
-
if (memoryCache !== null) return memoryCache;
|
|
288
|
-
try {
|
|
289
|
-
const stored = safeLocalStorage.getItem(ICON_CACHE_KEY);
|
|
290
|
-
memoryCache = stored ? JSON.parse(stored) : {};
|
|
291
|
-
} catch {
|
|
292
|
-
memoryCache = {};
|
|
293
|
-
}
|
|
294
|
-
return memoryCache;
|
|
295
|
-
};
|
|
296
|
-
var saveCache = (cache) => {
|
|
297
|
-
try {
|
|
298
|
-
safeLocalStorage.setItem(ICON_CACHE_KEY, JSON.stringify(cache));
|
|
299
|
-
memoryCache = cache;
|
|
300
|
-
} catch {
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
var getCachedIcon = (walletId) => {
|
|
304
|
-
const cache = loadCache();
|
|
305
|
-
return cache[walletId] || void 0;
|
|
306
|
-
};
|
|
307
|
-
var setCachedIcons = (icons) => {
|
|
308
|
-
const cache = loadCache();
|
|
309
|
-
let changed = false;
|
|
310
|
-
for (const [walletId, icon] of Object.entries(icons)) {
|
|
311
|
-
if (icon && cache[walletId] !== icon) {
|
|
312
|
-
cache[walletId] = icon;
|
|
313
|
-
changed = true;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
if (changed) {
|
|
317
|
-
saveCache(cache);
|
|
318
|
-
}
|
|
319
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
acceptsCachedAccount,
|
|
3
|
+
getCachedIcon,
|
|
4
|
+
hydrateAccount,
|
|
5
|
+
hydrateWallet,
|
|
6
|
+
serializeAccount,
|
|
7
|
+
serializeWallet,
|
|
8
|
+
setCachedIcons,
|
|
9
|
+
sortAccounts,
|
|
10
|
+
sortWallets
|
|
11
|
+
} from "./chunk-YDLCHYHH.mjs";
|
|
12
|
+
import "./chunk-BWUUHUDK.mjs";
|
|
13
|
+
import {
|
|
14
|
+
DEFAULT_STORAGE_KEY,
|
|
15
|
+
KheopskitError,
|
|
16
|
+
createKheopskitStore,
|
|
17
|
+
getDefaultStore,
|
|
18
|
+
getWalletAccountId,
|
|
19
|
+
isValidAddress,
|
|
20
|
+
parseWalletAccountId,
|
|
21
|
+
resolveConfig,
|
|
22
|
+
store
|
|
23
|
+
} from "./chunk-6XAZANB5.mjs";
|
|
24
|
+
import {
|
|
25
|
+
WALLET_CONNECT_WALLET_ID,
|
|
26
|
+
clearAllCachedObservables,
|
|
27
|
+
clearCachedObservablesByPrefix,
|
|
28
|
+
getWalletId,
|
|
29
|
+
isInjectedWallet,
|
|
30
|
+
isValidWalletId,
|
|
31
|
+
isWalletConnectWallet,
|
|
32
|
+
parseWalletId
|
|
33
|
+
} from "./chunk-7QSGAJ4A.mjs";
|
|
320
34
|
|
|
321
35
|
// src/api/appKit.ts
|
|
322
36
|
import {
|
|
323
37
|
BehaviorSubject,
|
|
324
|
-
combineLatest,
|
|
325
38
|
distinctUntilChanged,
|
|
326
39
|
from,
|
|
327
40
|
map,
|
|
328
41
|
Observable,
|
|
329
42
|
of,
|
|
330
43
|
shareReplay,
|
|
331
|
-
switchMap
|
|
44
|
+
switchMap,
|
|
45
|
+
tap
|
|
332
46
|
} from "rxjs";
|
|
333
47
|
var loadAppKit = async () => {
|
|
334
|
-
|
|
335
|
-
|
|
48
|
+
try {
|
|
49
|
+
const { createAppKit } = await import("@reown/appkit/core");
|
|
50
|
+
return createAppKit;
|
|
51
|
+
} catch (cause) {
|
|
52
|
+
console.error(
|
|
53
|
+
"[kheopskit] WalletConnect is configured but @reown/appkit could not be loaded. Install it with `pnpm add @reown/appkit` (or remove config.walletConnect). WalletConnect wallets are disabled; injected wallets still work.",
|
|
54
|
+
cause
|
|
55
|
+
);
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
336
58
|
};
|
|
337
59
|
var WALLET_CONNECT_ICON = "data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjQwMCIgdmlld0JveD0iMCAwIDQwMCA0MDAiIHdpZHRoPSI0MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxjbGlwUGF0aCBpZD0iYSI+PHBhdGggZD0ibTAgMGg0MDB2NDAwaC00MDB6Ii8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjYSkiPjxjaXJjbGUgY3g9IjIwMCIgY3k9IjIwMCIgZmlsbD0iIzMzOTZmZiIgcj0iMTk5LjUiIHN0cm9rZT0iIzY2YjFmZiIvPjxwYXRoIGQ9Im0xMjIuNTE5IDE0OC45NjVjNDIuNzkxLTQxLjcyOSAxMTIuMTcxLTQxLjcyOSAxNTQuOTYyIDBsNS4xNSA1LjAyMmMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtMTcuNjE3IDE3LjE4Yy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTcuMDg3LTYuOTExYy0yOS44NTMtMjkuMTExLTc4LjI1My0yOS4xMTEtMTA4LjEwNiAwbC03LjU5IDcuNDAxYy0xLjA3IDEuMDQzLTIuODA0IDEuMDQzLTMuODc0IDBsLTE3LjYxNy0xNy4xOGMtMi4xNC0yLjA4Ni0yLjE0LTUuNDY5IDAtNy41NTV6bTE5MS4zOTcgMzUuNTI5IDE1LjY3OSAxNS4yOWMyLjE0IDIuMDg2IDIuMTQgNS40NjkgMCA3LjU1NWwtNzAuNyA2OC45NDRjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTUwLjE3OC00OC45MzFjLS41MzUtLjUyMi0xLjQwMi0uNTIyLTEuOTM3IDBsLTUwLjE3OCA0OC45MzFjLTIuMTM5IDIuMDg3LTUuNjA4IDIuMDg3LTcuNzQ4IDBsLTcwLjcwMTUtNjguOTQ1Yy0yLjEzOTYtMi4wODYtMi4xMzk2LTUuNDY5IDAtNy41NTVsMTUuNjc5NS0xNS4yOWMyLjEzOTYtMi4wODYgNS42MDg1LTIuMDg2IDcuNzQ4MSAwbDUwLjE3ODkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3Ny00OC45MzJjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMGw1MC4xNzkgNDguOTMyYy41MzUuNTIyIDEuNDAyLjUyMiAxLjkzNyAwbDUwLjE3OS00OC45MzFjMi4xMzktMi4wODcgNS42MDgtMi4wODcgNy43NDggMHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+";
|
|
338
|
-
var
|
|
60
|
+
var APPKIT_SYMBOL = /* @__PURE__ */ Symbol.for("kheopskit.cachedAppKit");
|
|
61
|
+
var APPKIT_PROJECT_ID_SYMBOL = /* @__PURE__ */ Symbol.for("kheopskit.cachedAppKitProjectId");
|
|
62
|
+
var getCachedAppKit = () => globalThis[APPKIT_SYMBOL];
|
|
63
|
+
var getCachedAppKitProjectId = () => globalThis[APPKIT_PROJECT_ID_SYMBOL];
|
|
64
|
+
var setCachedAppKit = (value, projectId) => {
|
|
65
|
+
globalThis[APPKIT_SYMBOL] = value;
|
|
66
|
+
globalThis[APPKIT_PROJECT_ID_SYMBOL] = projectId;
|
|
67
|
+
};
|
|
339
68
|
var resetAppKitCache = () => {
|
|
340
|
-
|
|
69
|
+
setCachedAppKit(void 0);
|
|
70
|
+
};
|
|
71
|
+
var dropAccountsCache = (platform) => {
|
|
72
|
+
clearCachedObservablesByPrefix(
|
|
73
|
+
`accounts:${WALLET_CONNECT_WALLET_ID}:${platform}:`
|
|
74
|
+
);
|
|
341
75
|
};
|
|
342
|
-
var
|
|
343
|
-
if (!config.walletConnect) return of(
|
|
344
|
-
if (typeof window === "undefined") return of(
|
|
76
|
+
var getWalletConnectWallet$ = (config) => {
|
|
77
|
+
if (!config.walletConnect) return of(null);
|
|
78
|
+
if (typeof window === "undefined") return of(null);
|
|
345
79
|
const walletConnect = config.walletConnect;
|
|
80
|
+
const cachedProjectId = getCachedAppKitProjectId();
|
|
81
|
+
if (cachedProjectId !== void 0 && cachedProjectId !== walletConnect.projectId) {
|
|
82
|
+
console.warn(
|
|
83
|
+
"[kheopskit] WalletConnect is already initialised with projectId %s; AppKit is a process-wide singleton, so the first configuration wins and projectId %s is ignored. Call resetAppKitCache() before re-initialising if the WalletConnect config must change.",
|
|
84
|
+
cachedProjectId,
|
|
85
|
+
walletConnect.projectId
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
let cachedAppKit = getCachedAppKit();
|
|
346
89
|
if (!cachedAppKit) {
|
|
347
90
|
cachedAppKit = from(loadAppKit()).pipe(
|
|
348
91
|
switchMap((createAppKit) => {
|
|
92
|
+
if (!createAppKit) return of(null);
|
|
349
93
|
return new Observable((subscriber) => {
|
|
350
94
|
const appKit = createAppKit({
|
|
351
95
|
projectId: walletConnect.projectId,
|
|
352
96
|
metadata: walletConnect.metadata,
|
|
97
|
+
// Loosely typed in WalletConnectConfig to keep @reown/appkit's
|
|
98
|
+
// types out of core; forwarded to AppKit verbatim.
|
|
353
99
|
networks: walletConnect.networks,
|
|
354
100
|
themeMode: walletConnect.themeMode,
|
|
355
101
|
themeVariables: walletConnect.themeVariables,
|
|
356
102
|
universalProviderConfigOverride: {
|
|
357
103
|
methods: {
|
|
358
|
-
polkadot: ["polkadot_signTransaction", "polkadot_signMessage"]
|
|
104
|
+
polkadot: ["polkadot_signTransaction", "polkadot_signMessage"],
|
|
105
|
+
solana: [
|
|
106
|
+
"solana_signTransaction",
|
|
107
|
+
"solana_signMessage",
|
|
108
|
+
"solana_signAndSendTransaction"
|
|
109
|
+
]
|
|
359
110
|
}
|
|
360
111
|
},
|
|
361
112
|
allWallets: "HIDE",
|
|
362
113
|
debug: config.debug,
|
|
363
114
|
allowUnsupportedChain: true
|
|
364
115
|
});
|
|
116
|
+
const appKitInstance = appKit;
|
|
365
117
|
const status$ = new BehaviorSubject({
|
|
366
118
|
isPolkadotConnected: false,
|
|
367
|
-
isEthereumConnected: false
|
|
119
|
+
isEthereumConnected: false,
|
|
120
|
+
isSolanaConnected: false
|
|
368
121
|
});
|
|
369
122
|
const unsubProviders = appKit.subscribeProviders((providers) => {
|
|
370
123
|
status$.next({
|
|
371
124
|
isPolkadotConnected: !!providers.polkadot,
|
|
372
|
-
isEthereumConnected: !!providers.eip155
|
|
125
|
+
isEthereumConnected: !!providers.eip155,
|
|
126
|
+
isSolanaConnected: !!providers.solana
|
|
373
127
|
});
|
|
374
128
|
});
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
129
|
+
const namespaceOf = {
|
|
130
|
+
polkadot: "polkadot",
|
|
131
|
+
ethereum: "eip155",
|
|
132
|
+
solana: "solana"
|
|
133
|
+
};
|
|
134
|
+
const allPlatforms = [
|
|
135
|
+
"polkadot",
|
|
136
|
+
"ethereum",
|
|
137
|
+
"solana"
|
|
138
|
+
];
|
|
139
|
+
const enabledPlatforms = allPlatforms.filter(
|
|
140
|
+
(p) => appKit.chainNamespaces.includes(namespaceOf[p])
|
|
141
|
+
);
|
|
142
|
+
let prevConnected = {
|
|
143
|
+
polkadot: false,
|
|
144
|
+
ethereum: false,
|
|
145
|
+
solana: false
|
|
146
|
+
};
|
|
147
|
+
const sub = status$.pipe(
|
|
148
|
+
map((s) => ({
|
|
149
|
+
polkadot: s.isPolkadotConnected,
|
|
150
|
+
ethereum: s.isEthereumConnected,
|
|
151
|
+
solana: s.isSolanaConnected
|
|
152
|
+
})),
|
|
153
|
+
distinctUntilChanged(
|
|
154
|
+
(a, b) => a.polkadot === b.polkadot && a.ethereum === b.ethereum && a.solana === b.solana
|
|
155
|
+
),
|
|
156
|
+
tap((connected) => {
|
|
157
|
+
for (const platform of allPlatforms)
|
|
158
|
+
if (prevConnected[platform] && !connected[platform])
|
|
159
|
+
dropAccountsCache(platform);
|
|
160
|
+
prevConnected = connected;
|
|
161
|
+
}),
|
|
162
|
+
map((connected) => {
|
|
163
|
+
const platforms = enabledPlatforms.filter((p) => connected[p]);
|
|
164
|
+
const isConnected = platforms.length > 0;
|
|
379
165
|
const walletInfo = appKit.getWalletInfo();
|
|
380
166
|
return {
|
|
381
|
-
id:
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
appKit,
|
|
385
|
-
// todo maybe we dont want to expose the appKit instance
|
|
167
|
+
id: WALLET_CONNECT_WALLET_ID,
|
|
168
|
+
type: "walletconnect",
|
|
169
|
+
platforms,
|
|
170
|
+
appKit: appKitInstance,
|
|
386
171
|
name: walletInfo?.name ?? "WalletConnect",
|
|
387
172
|
icon: walletInfo?.icon ?? WALLET_CONNECT_ICON,
|
|
173
|
+
// One shared session: connecting opens the modal; the wallet
|
|
174
|
+
// approves namespaces in that single pairing. Disconnect is
|
|
175
|
+
// session-wide; re-pair to change the approved set.
|
|
388
176
|
connect: async () => {
|
|
389
177
|
if (!isConnected) await appKit.open();
|
|
390
178
|
},
|
|
391
|
-
disconnect: () => {
|
|
392
|
-
if (isConnected) appKit.disconnect();
|
|
179
|
+
disconnect: async () => {
|
|
180
|
+
if (isConnected) await appKit.disconnect();
|
|
393
181
|
},
|
|
394
182
|
isConnected
|
|
395
183
|
};
|
|
396
184
|
})
|
|
397
|
-
)
|
|
398
|
-
const ethereumWallet$ = appKit.chainNamespaces.includes("eip155") ? status$.pipe(
|
|
399
|
-
map((s) => s.isEthereumConnected),
|
|
400
|
-
distinctUntilChanged(),
|
|
401
|
-
map((isConnected) => {
|
|
402
|
-
const walletInfo = appKit.getWalletInfo();
|
|
403
|
-
return {
|
|
404
|
-
id: getWalletId("ethereum", "walletconnect"),
|
|
405
|
-
platform: "ethereum",
|
|
406
|
-
type: "appKit",
|
|
407
|
-
appKit,
|
|
408
|
-
name: walletInfo?.name ?? "WalletConnect",
|
|
409
|
-
icon: walletInfo?.icon ?? WALLET_CONNECT_ICON,
|
|
410
|
-
connect: () => appKit.open(),
|
|
411
|
-
disconnect: () => appKit.disconnect(),
|
|
412
|
-
isConnected
|
|
413
|
-
};
|
|
414
|
-
})
|
|
415
|
-
) : of(void 0);
|
|
416
|
-
const sub = combineLatest({
|
|
417
|
-
polkadot: polkadotWallet$,
|
|
418
|
-
ethereum: ethereumWallet$
|
|
419
|
-
}).subscribe(subscriber);
|
|
185
|
+
).subscribe(subscriber);
|
|
420
186
|
return () => {
|
|
421
187
|
sub.unsubscribe();
|
|
422
188
|
unsubProviders();
|
|
423
189
|
};
|
|
424
190
|
});
|
|
425
191
|
}),
|
|
426
|
-
|
|
192
|
+
// refCount:false keeps the AppKit instance alive for the process lifetime
|
|
193
|
+
// once created: createAppKit runs at most once (Reown AppKit cannot be
|
|
194
|
+
// instantiated twice). With refCount:true the producer would re-run
|
|
195
|
+
// createAppKit whenever every subscriber drained and a new one
|
|
196
|
+
// re-subscribed — e.g. a React unmount/remount or StrictMode's
|
|
197
|
+
// mount→unmount→remount — throwing on the duplicate Lit web components and
|
|
198
|
+
// WalletConnect modal singleton. The replayed connector value also keeps
|
|
199
|
+
// the wallet list stable across such teardown/rebuild cycles.
|
|
200
|
+
shareReplay({ refCount: false, bufferSize: 1 })
|
|
427
201
|
);
|
|
202
|
+
setCachedAppKit(cachedAppKit, walletConnect.projectId);
|
|
428
203
|
}
|
|
429
204
|
return cachedAppKit;
|
|
430
205
|
};
|
|
431
206
|
|
|
432
|
-
// src/api/config.ts
|
|
433
|
-
var DEFAULT_STORAGE_KEY = "kheopskit";
|
|
434
|
-
var DEFAULT_CONFIG = {
|
|
435
|
-
autoReconnect: true,
|
|
436
|
-
platforms: ["polkadot"],
|
|
437
|
-
polkadotAccountTypes: ["sr25519", "ed25519", "ecdsa"],
|
|
438
|
-
debug: false,
|
|
439
|
-
storageKey: DEFAULT_STORAGE_KEY,
|
|
440
|
-
hydrationGracePeriod: 500
|
|
441
|
-
};
|
|
442
|
-
var VALID_POLKADOT_ACCOUNT_TYPES = /* @__PURE__ */ new Set([
|
|
443
|
-
"sr25519",
|
|
444
|
-
"ed25519",
|
|
445
|
-
"ecdsa",
|
|
446
|
-
"ethereum"
|
|
447
|
-
]);
|
|
448
|
-
var resolveConfig = (config) => {
|
|
449
|
-
const resolved = Object.assign({}, DEFAULT_CONFIG, config);
|
|
450
|
-
const invalid = resolved.polkadotAccountTypes.filter(
|
|
451
|
-
(t) => !VALID_POLKADOT_ACCOUNT_TYPES.has(t)
|
|
452
|
-
);
|
|
453
|
-
if (invalid.length > 0) {
|
|
454
|
-
console.warn(
|
|
455
|
-
`[kheopskit] Unknown polkadotAccountTypes: ${JSON.stringify(invalid)}. Valid values: "sr25519", "ed25519", "ecdsa", "ethereum".`
|
|
456
|
-
);
|
|
457
|
-
}
|
|
458
|
-
return resolved;
|
|
459
|
-
};
|
|
460
|
-
|
|
461
207
|
// src/api/kheopskit.ts
|
|
462
208
|
import {
|
|
463
|
-
combineLatest as
|
|
209
|
+
combineLatest as combineLatest4,
|
|
464
210
|
debounceTime,
|
|
465
|
-
distinctUntilChanged as
|
|
211
|
+
distinctUntilChanged as distinctUntilChanged2,
|
|
466
212
|
filter as filter3,
|
|
467
|
-
map as
|
|
468
|
-
Observable as
|
|
469
|
-
shareReplay as
|
|
213
|
+
map as map5,
|
|
214
|
+
Observable as Observable5,
|
|
215
|
+
shareReplay as shareReplay5,
|
|
470
216
|
throttleTime
|
|
471
217
|
} from "rxjs";
|
|
472
218
|
|
|
473
219
|
// src/utils/createHydrationBuffer.ts
|
|
474
220
|
import {
|
|
475
221
|
BehaviorSubject as BehaviorSubject2,
|
|
476
|
-
combineLatest
|
|
222
|
+
combineLatest,
|
|
477
223
|
filter,
|
|
478
224
|
map as map2,
|
|
479
225
|
Observable as Observable2,
|
|
@@ -498,7 +244,7 @@ var createBufferCore = (cachedItems, liveItems$, gracePeriodMs, mergeFn, isConve
|
|
|
498
244
|
shareReplay2({ bufferSize: 1, refCount: true })
|
|
499
245
|
);
|
|
500
246
|
subscriptions.add(
|
|
501
|
-
|
|
247
|
+
combineLatest([liveWithInitial$, timerFired$]).pipe(
|
|
502
248
|
filter(([, timerFired]) => timerFired),
|
|
503
249
|
filter(([liveItems]) => isConverged(liveItems, cachedItems)),
|
|
504
250
|
take(1)
|
|
@@ -521,7 +267,7 @@ var createBufferCore = (cachedItems, liveItems$, gracePeriodMs, mergeFn, isConve
|
|
|
521
267
|
);
|
|
522
268
|
}
|
|
523
269
|
subscriptions.add(
|
|
524
|
-
|
|
270
|
+
combineLatest([liveWithInitial$, isHydrating$]).pipe(
|
|
525
271
|
map2(([liveItems, isHydrating]) => {
|
|
526
272
|
if (!isHydrating) {
|
|
527
273
|
return { items: liveItems, isHydrating: false };
|
|
@@ -584,8 +330,8 @@ var createAccountHydrationBuffer = (cachedAccounts, liveAccounts$, gracePeriodMs
|
|
|
584
330
|
};
|
|
585
331
|
|
|
586
332
|
// src/utils/logObservable.ts
|
|
587
|
-
import { tap } from "rxjs";
|
|
588
|
-
var logObservable = (label, opts) =>
|
|
333
|
+
import { tap as tap2 } from "rxjs";
|
|
334
|
+
var logObservable = (label, opts) => tap2((value) => {
|
|
589
335
|
const { printValue = false, enabled = true } = opts || {};
|
|
590
336
|
if (!label || !enabled) return;
|
|
591
337
|
const text = `[kheopskit] observable ${label} emit`;
|
|
@@ -594,925 +340,86 @@ var logObservable = (label, opts) => tap((value) => {
|
|
|
594
340
|
});
|
|
595
341
|
|
|
596
342
|
// src/api/accounts.ts
|
|
597
|
-
import { combineLatest as
|
|
598
|
-
|
|
599
|
-
// src/utils/sortAccounts.ts
|
|
600
|
-
var sortAccounts = (a1, a2) => {
|
|
601
|
-
if (a1.platform === "polkadot") {
|
|
602
|
-
if (a2.platform === "polkadot") {
|
|
603
|
-
if (a1.walletName !== a2.walletName) {
|
|
604
|
-
if (a1.walletName === "talisman") return -1;
|
|
605
|
-
if (a2.walletName === "talisman") return 1;
|
|
606
|
-
return a1.walletName.localeCompare(a2.walletName);
|
|
607
|
-
}
|
|
608
|
-
return a1.name !== a2.name ? (a1.name ?? "").localeCompare(a2.name ?? "") : a1.address.localeCompare(a2.address);
|
|
609
|
-
}
|
|
610
|
-
return -1;
|
|
611
|
-
}
|
|
612
|
-
if (a2.platform === "ethereum") {
|
|
613
|
-
if (a1.walletName !== a2.walletName) {
|
|
614
|
-
if (a1.walletName === "Talisman") return -1;
|
|
615
|
-
if (a2.walletName === "Talisman") return 1;
|
|
616
|
-
return a1.walletName.localeCompare(a2.walletName);
|
|
617
|
-
}
|
|
618
|
-
return a1.id.localeCompare(a2.id);
|
|
619
|
-
}
|
|
620
|
-
return 0;
|
|
621
|
-
};
|
|
622
|
-
|
|
623
|
-
// src/api/ethereum/accounts.ts
|
|
624
|
-
import {
|
|
625
|
-
combineLatest as combineLatest3,
|
|
626
|
-
distinctUntilChanged as distinctUntilChanged2,
|
|
627
|
-
map as map3,
|
|
628
|
-
Observable as Observable3,
|
|
629
|
-
of as of2,
|
|
630
|
-
ReplaySubject,
|
|
631
|
-
shareReplay as shareReplay3,
|
|
632
|
-
switchMap as switchMap2
|
|
633
|
-
} from "rxjs";
|
|
634
|
-
import {
|
|
635
|
-
createWalletClient,
|
|
636
|
-
custom,
|
|
637
|
-
getAddress
|
|
638
|
-
} from "viem";
|
|
639
|
-
|
|
640
|
-
// src/utils/createStore.ts
|
|
641
|
-
import { BehaviorSubject as BehaviorSubject3 } from "rxjs";
|
|
642
|
-
var createStore = (key, defaultValue, storage = safeLocalStorage) => {
|
|
643
|
-
const subject = new BehaviorSubject3(
|
|
644
|
-
getStoredData(key, defaultValue, storage)
|
|
645
|
-
);
|
|
646
|
-
let unsubscribeStorage;
|
|
647
|
-
if (typeof window !== "undefined" && storage.subscribe) {
|
|
648
|
-
unsubscribeStorage = storage.subscribe(key, (newValue) => {
|
|
649
|
-
subject.next(parseData(newValue, defaultValue));
|
|
650
|
-
});
|
|
651
|
-
}
|
|
652
|
-
const update = (val) => {
|
|
653
|
-
setStoredData(key, val, storage);
|
|
654
|
-
subject.next(val);
|
|
655
|
-
};
|
|
656
|
-
return {
|
|
657
|
-
observable: subject.asObservable(),
|
|
658
|
-
set: (val) => update(val),
|
|
659
|
-
mutate: (transform) => update(transform(subject.getValue())),
|
|
660
|
-
get: () => structuredClone(subject.getValue()),
|
|
661
|
-
/**
|
|
662
|
-
* Cleanup subscriptions. Call this when the store is no longer needed.
|
|
663
|
-
*/
|
|
664
|
-
destroy: () => {
|
|
665
|
-
unsubscribeStorage?.();
|
|
666
|
-
subject.complete();
|
|
667
|
-
}
|
|
668
|
-
};
|
|
669
|
-
};
|
|
670
|
-
var parseData = (str, defaultValue) => {
|
|
671
|
-
try {
|
|
672
|
-
if (str) return JSON.parse(str);
|
|
673
|
-
} catch {
|
|
674
|
-
}
|
|
675
|
-
return defaultValue;
|
|
676
|
-
};
|
|
677
|
-
var getStoredData = (key, defaultValue, storage) => {
|
|
678
|
-
const str = storage.getItem(key);
|
|
679
|
-
return parseData(str, defaultValue);
|
|
680
|
-
};
|
|
681
|
-
var setStoredData = (key, val, storage) => {
|
|
682
|
-
const str = JSON.stringify(val);
|
|
683
|
-
storage.setItem(key, str);
|
|
684
|
-
};
|
|
685
|
-
|
|
686
|
-
// src/utils/isEthereumAddress.ts
|
|
687
|
-
import { isAddress } from "viem";
|
|
688
|
-
var isEthereumAddress = (address) => isAddress(address);
|
|
689
|
-
|
|
690
|
-
// src/utils/isSs58Address.ts
|
|
691
|
-
import { AccountId } from "polkadot-api";
|
|
692
|
-
var accountIdEncoder = AccountId().enc;
|
|
693
|
-
var isSs58Address = (address) => {
|
|
694
|
-
try {
|
|
695
|
-
if (!address) return false;
|
|
696
|
-
accountIdEncoder(address);
|
|
697
|
-
return true;
|
|
698
|
-
} catch {
|
|
699
|
-
return false;
|
|
700
|
-
}
|
|
701
|
-
};
|
|
702
|
-
|
|
703
|
-
// src/utils/isValidAddress.ts
|
|
704
|
-
var isValidAddress = (address) => {
|
|
705
|
-
return address.startsWith("0x") ? isEthereumAddress(address) : isSs58Address(address);
|
|
706
|
-
};
|
|
707
|
-
|
|
708
|
-
// src/utils/WalletAccountId.ts
|
|
709
|
-
var getWalletAccountId = (walletId, address) => {
|
|
710
|
-
if (!walletId) throw new Error("Missing walletId");
|
|
711
|
-
if (!isValidAddress(address)) throw new Error("Invalid address");
|
|
712
|
-
return `${walletId}::${address}`;
|
|
713
|
-
};
|
|
714
|
-
|
|
715
|
-
// src/api/ethereum/accounts.ts
|
|
716
|
-
var normalizeEvmChainId = (value) => {
|
|
717
|
-
let raw = value;
|
|
718
|
-
if (typeof raw === "string" && raw.startsWith("eip155:")) {
|
|
719
|
-
raw = raw.slice("eip155:".length);
|
|
720
|
-
}
|
|
721
|
-
if (typeof raw === "bigint") {
|
|
722
|
-
return raw >= 0n ? Number(raw) : void 0;
|
|
723
|
-
}
|
|
724
|
-
if (typeof raw === "number") {
|
|
725
|
-
return Number.isInteger(raw) && raw >= 0 ? raw : void 0;
|
|
726
|
-
}
|
|
727
|
-
if (typeof raw === "string") {
|
|
728
|
-
const normalized = raw.trim().toLowerCase();
|
|
729
|
-
if (!normalized) return void 0;
|
|
730
|
-
const parsed = normalized.startsWith("0x") ? Number.parseInt(normalized, 16) : Number.parseInt(normalized, 10);
|
|
731
|
-
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
732
|
-
}
|
|
733
|
-
return void 0;
|
|
734
|
-
};
|
|
735
|
-
var toCaipNetworkId = (value) => {
|
|
736
|
-
const chainId = normalizeEvmChainId(value);
|
|
737
|
-
return chainId === void 0 ? void 0 : `eip155:${chainId}`;
|
|
738
|
-
};
|
|
739
|
-
var getInjectedWalletAccounts$ = (wallet) => {
|
|
740
|
-
if (!wallet.isConnected) return of2([]);
|
|
741
|
-
return getCachedObservable$(
|
|
742
|
-
`accounts:${wallet.id}`,
|
|
743
|
-
() => new Observable3((subscriber) => {
|
|
744
|
-
const addresses$ = new ReplaySubject(1);
|
|
745
|
-
const chainId$ = new ReplaySubject(1);
|
|
746
|
-
const getAccount = (address, i, chainId) => {
|
|
747
|
-
const client = createWalletClient({
|
|
748
|
-
account: address,
|
|
749
|
-
transport: custom(wallet.provider)
|
|
750
|
-
});
|
|
751
|
-
return {
|
|
752
|
-
id: getWalletAccountId(wallet.id, address),
|
|
753
|
-
platform: "ethereum",
|
|
754
|
-
client,
|
|
755
|
-
address: getAddress(address),
|
|
756
|
-
chainId,
|
|
757
|
-
walletName: wallet.name,
|
|
758
|
-
walletId: wallet.id,
|
|
759
|
-
isWalletDefault: i === 0
|
|
760
|
-
};
|
|
761
|
-
};
|
|
762
|
-
const handleAccountsChanged = (addrs) => {
|
|
763
|
-
addresses$.next(addrs);
|
|
764
|
-
};
|
|
765
|
-
const handleChainChanged = (chainIdHex) => {
|
|
766
|
-
chainId$.next(normalizeEvmChainId(chainIdHex));
|
|
767
|
-
};
|
|
768
|
-
const handleDisconnect = () => {
|
|
769
|
-
chainId$.next(void 0);
|
|
770
|
-
};
|
|
771
|
-
wallet.provider.on("accountsChanged", handleAccountsChanged);
|
|
772
|
-
wallet.provider.on("chainChanged", handleChainChanged);
|
|
773
|
-
wallet.provider.on("disconnect", handleDisconnect);
|
|
774
|
-
wallet.provider.request({ method: "eth_accounts" }).then((addrs) => addresses$.next(addrs)).catch((err) => {
|
|
775
|
-
console.error("Failed to get accounts", err);
|
|
776
|
-
addresses$.next([]);
|
|
777
|
-
});
|
|
778
|
-
wallet.provider.request({ method: "eth_chainId" }).then(handleChainChanged).catch(() => chainId$.next(void 0));
|
|
779
|
-
const sub = combineLatest3([addresses$, chainId$]).pipe(
|
|
780
|
-
map3(
|
|
781
|
-
([addresses, chainId]) => addresses.map((addr, i) => getAccount(addr, i, chainId))
|
|
782
|
-
)
|
|
783
|
-
).subscribe(subscriber);
|
|
784
|
-
return () => {
|
|
785
|
-
wallet.provider.removeListener(
|
|
786
|
-
"accountsChanged",
|
|
787
|
-
handleAccountsChanged
|
|
788
|
-
);
|
|
789
|
-
wallet.provider.removeListener("chainChanged", handleChainChanged);
|
|
790
|
-
wallet.provider.removeListener("disconnect", handleDisconnect);
|
|
791
|
-
sub.unsubscribe();
|
|
792
|
-
};
|
|
793
|
-
}).pipe(shareReplay3({ refCount: true, bufferSize: 1 }))
|
|
794
|
-
);
|
|
795
|
-
};
|
|
796
|
-
var wrapWalletConnectProvider = (provider, sessionTopic, caipNetworkId) => {
|
|
797
|
-
return new Proxy(provider, {
|
|
798
|
-
get(target, prop, receiver) {
|
|
799
|
-
if (prop !== "request") return Reflect.get(target, prop, receiver);
|
|
800
|
-
return (args) => {
|
|
801
|
-
if (args && typeof args === "object" && args.method) {
|
|
802
|
-
if (!args.topic) args.topic = sessionTopic;
|
|
803
|
-
if (!args.chainId) args.chainId = caipNetworkId;
|
|
804
|
-
}
|
|
805
|
-
return target.request(args);
|
|
806
|
-
};
|
|
807
|
-
}
|
|
808
|
-
});
|
|
809
|
-
};
|
|
810
|
-
var getAppKitAccounts$ = (wallet) => {
|
|
811
|
-
const account = wallet.appKit.getAccount("eip155");
|
|
812
|
-
const provider = wallet.appKit.getProvider("eip155");
|
|
813
|
-
if (!wallet.isConnected || !wallet.appKit || !account?.allAccounts.length || !provider?.session)
|
|
814
|
-
return of2([]);
|
|
815
|
-
return getCachedObservable$(
|
|
816
|
-
"accounts:appKit",
|
|
817
|
-
() => new Observable3((subscriber) => {
|
|
818
|
-
const caipNetworkId$ = new ReplaySubject(1);
|
|
819
|
-
const handleChainChanged = (chainId) => {
|
|
820
|
-
const caipNetworkId = toCaipNetworkId(chainId);
|
|
821
|
-
if (caipNetworkId) {
|
|
822
|
-
caipNetworkId$.next(caipNetworkId);
|
|
823
|
-
}
|
|
824
|
-
};
|
|
825
|
-
provider.on("chainChanged", handleChainChanged);
|
|
826
|
-
provider.request({ method: "eth_chainId" }).then(handleChainChanged);
|
|
827
|
-
const sub = caipNetworkId$.pipe(
|
|
828
|
-
distinctUntilChanged2(),
|
|
829
|
-
map3((caipNetworkId) => {
|
|
830
|
-
const chainId = normalizeEvmChainId(caipNetworkId);
|
|
831
|
-
const transport = custom(
|
|
832
|
-
wrapWalletConnectProvider(
|
|
833
|
-
provider,
|
|
834
|
-
// biome-ignore lint/style/noNonNullAssertion: legacy
|
|
835
|
-
provider.session.topic,
|
|
836
|
-
caipNetworkId
|
|
837
|
-
)
|
|
838
|
-
);
|
|
839
|
-
return { transport, chainId };
|
|
840
|
-
}),
|
|
841
|
-
map3(
|
|
842
|
-
({ transport, chainId }) => account.allAccounts.map((acc, i) => {
|
|
843
|
-
const client = createWalletClient({
|
|
844
|
-
account: acc.address,
|
|
845
|
-
transport
|
|
846
|
-
});
|
|
847
|
-
return {
|
|
848
|
-
id: getWalletAccountId(wallet.id, acc.address),
|
|
849
|
-
platform: "ethereum",
|
|
850
|
-
walletName: wallet.name,
|
|
851
|
-
walletId: wallet.id,
|
|
852
|
-
address: acc.address,
|
|
853
|
-
client,
|
|
854
|
-
chainId,
|
|
855
|
-
isWalletDefault: i === 0
|
|
856
|
-
};
|
|
857
|
-
})
|
|
858
|
-
)
|
|
859
|
-
).subscribe(subscriber);
|
|
860
|
-
return () => {
|
|
861
|
-
provider.off("chainChanged", handleChainChanged);
|
|
862
|
-
sub.unsubscribe();
|
|
863
|
-
};
|
|
864
|
-
}).pipe(shareReplay3({ refCount: true, bufferSize: 1 }))
|
|
865
|
-
);
|
|
866
|
-
};
|
|
867
|
-
var getEthereumAccounts$ = (ethereumWallets) => new Observable3((subscriber) => {
|
|
868
|
-
const sub = ethereumWallets.pipe(
|
|
869
|
-
map3((wallets) => wallets.filter((w) => w.isConnected)),
|
|
870
|
-
switchMap2((wallets) => {
|
|
871
|
-
return wallets.length ? combineLatest3([
|
|
872
|
-
...wallets.filter((w) => w.type === "injected").map(getInjectedWalletAccounts$),
|
|
873
|
-
...wallets.filter((w) => w.type === "appKit").map(getAppKitAccounts$)
|
|
874
|
-
// todo appkit
|
|
875
|
-
]) : of2([]);
|
|
876
|
-
}),
|
|
877
|
-
map3((accounts) => accounts.flat()),
|
|
878
|
-
distinctUntilChanged2(isSameAccountsList)
|
|
879
|
-
).subscribe(subscriber);
|
|
880
|
-
return () => {
|
|
881
|
-
sub.unsubscribe();
|
|
882
|
-
};
|
|
883
|
-
}).pipe(
|
|
884
|
-
// logObservable("ethereumAccounts$", true),
|
|
885
|
-
shareReplay3({ refCount: true, bufferSize: 1 })
|
|
886
|
-
);
|
|
887
|
-
var isSameAccountsList = (a, b) => {
|
|
888
|
-
if (a.length !== b.length) return false;
|
|
889
|
-
return a.every(
|
|
890
|
-
(account, i) => account.id === b[i]?.id && account.chainId === b[i]?.chainId
|
|
891
|
-
);
|
|
892
|
-
};
|
|
893
|
-
|
|
894
|
-
// src/api/polkadot/accounts.ts
|
|
895
|
-
import {
|
|
896
|
-
getPolkadotSignerFromPjs
|
|
897
|
-
} from "polkadot-api/pjs-signer";
|
|
898
|
-
import {
|
|
899
|
-
combineLatest as combineLatest4,
|
|
900
|
-
distinctUntilChanged as distinctUntilChanged3,
|
|
901
|
-
map as map4,
|
|
902
|
-
Observable as Observable4,
|
|
903
|
-
of as of3,
|
|
904
|
-
shareReplay as shareReplay4,
|
|
905
|
-
switchMap as switchMap3
|
|
906
|
-
} from "rxjs";
|
|
907
|
-
var getInjectedWalletAccounts$2 = (wallet) => {
|
|
908
|
-
if (!wallet.isConnected) return of3([]);
|
|
909
|
-
return new Observable4((subscriber) => {
|
|
910
|
-
const getAccount = (account) => ({
|
|
911
|
-
id: getWalletAccountId(wallet.id, account.address),
|
|
912
|
-
...account,
|
|
913
|
-
type: account.type ?? "sr25519",
|
|
914
|
-
platform: "polkadot",
|
|
915
|
-
walletName: wallet.name,
|
|
916
|
-
walletId: wallet.id
|
|
917
|
-
});
|
|
918
|
-
const extension = wallet.extension;
|
|
919
|
-
const unsubscribe = extension.subscribe((accounts) => {
|
|
920
|
-
subscriber.next(accounts.map(getAccount));
|
|
921
|
-
});
|
|
922
|
-
subscriber.next(extension.getAccounts().map(getAccount));
|
|
923
|
-
return () => {
|
|
924
|
-
return unsubscribe();
|
|
925
|
-
};
|
|
926
|
-
});
|
|
927
|
-
};
|
|
928
|
-
var getAppKitPolkadotSigner = (appKit, address) => {
|
|
929
|
-
const provider = appKit.getProvider("polkadot");
|
|
930
|
-
if (!provider) throw new Error("No provider found");
|
|
931
|
-
if (!provider.session) throw new Error("No session found");
|
|
932
|
-
return getPolkadotSignerFromPjs(
|
|
933
|
-
address,
|
|
934
|
-
(transactionPayload) => {
|
|
935
|
-
if (!provider.session) throw new Error("No session found");
|
|
936
|
-
return provider.client.request({
|
|
937
|
-
topic: provider.session.topic,
|
|
938
|
-
chainId: `polkadot:${transactionPayload.genesisHash.substring(2, 34)}`,
|
|
939
|
-
request: {
|
|
940
|
-
method: "polkadot_signTransaction",
|
|
941
|
-
params: {
|
|
942
|
-
address,
|
|
943
|
-
transactionPayload
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
});
|
|
947
|
-
},
|
|
948
|
-
async ({ address: address2, data }) => {
|
|
949
|
-
if (!provider.session) throw new Error("No session found");
|
|
950
|
-
const networks = appKit.getCaipNetworks("polkadot");
|
|
951
|
-
const chainId = networks[0]?.caipNetworkId;
|
|
952
|
-
if (!chainId) throw new Error("No chainId found");
|
|
953
|
-
return provider.client.request({
|
|
954
|
-
topic: provider.session.topic,
|
|
955
|
-
chainId,
|
|
956
|
-
request: {
|
|
957
|
-
method: "polkadot_signMessage",
|
|
958
|
-
params: {
|
|
959
|
-
address: address2,
|
|
960
|
-
message: data
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
});
|
|
964
|
-
}
|
|
965
|
-
);
|
|
966
|
-
};
|
|
967
|
-
var getAppKitAccounts$2 = (wallet) => {
|
|
968
|
-
const account = wallet.appKit.getAccount("polkadot");
|
|
969
|
-
const provider = wallet.appKit.getProvider("polkadot");
|
|
970
|
-
if (!wallet.isConnected || !wallet.appKit || !account?.allAccounts.length || !provider?.session)
|
|
971
|
-
return of3([]);
|
|
972
|
-
return of3(
|
|
973
|
-
account.allAccounts.map(
|
|
974
|
-
(acc) => ({
|
|
975
|
-
id: getWalletAccountId(wallet.id, acc.address),
|
|
976
|
-
platform: "polkadot",
|
|
977
|
-
walletName: wallet.name,
|
|
978
|
-
walletId: wallet.id,
|
|
979
|
-
address: acc.address,
|
|
980
|
-
polkadotSigner: getAppKitPolkadotSigner(wallet.appKit, acc.address),
|
|
981
|
-
genesisHash: null,
|
|
982
|
-
name: `${wallet.name} Polkadot`,
|
|
983
|
-
// WalletConnect (Reown AppKit) doesn't expose account key type;
|
|
984
|
-
// default to sr25519, which is the most common Polkadot key type.
|
|
985
|
-
type: "sr25519"
|
|
986
|
-
})
|
|
987
|
-
)
|
|
988
|
-
);
|
|
989
|
-
};
|
|
990
|
-
var getPolkadotAccounts$ = (polkadotWallets$, polkadotAccountTypes) => new Observable4((subscriber) => {
|
|
991
|
-
if (polkadotAccountTypes.length === 0) {
|
|
992
|
-
console.warn(
|
|
993
|
-
"[kheopskit] config.polkadotAccountTypes is empty; all Polkadot accounts will be filtered out."
|
|
994
|
-
);
|
|
995
|
-
}
|
|
996
|
-
const sub = polkadotWallets$.pipe(
|
|
997
|
-
map4((wallets) => wallets.filter((w) => w.isConnected)),
|
|
998
|
-
switchMap3(
|
|
999
|
-
(wallets) => wallets.length ? combineLatest4([
|
|
1000
|
-
...wallets.filter((w) => w.type === "injected").map(getInjectedWalletAccounts$2),
|
|
1001
|
-
...wallets.filter((w) => w.type === "appKit").map(getAppKitAccounts$2)
|
|
1002
|
-
]) : of3([])
|
|
1003
|
-
),
|
|
1004
|
-
map4(
|
|
1005
|
-
(accounts) => accounts.flat().filter((account) => polkadotAccountTypes.includes(account.type))
|
|
1006
|
-
),
|
|
1007
|
-
distinctUntilChanged3(isSameAccountsList2)
|
|
1008
|
-
).subscribe(subscriber);
|
|
1009
|
-
return () => {
|
|
1010
|
-
sub.unsubscribe();
|
|
1011
|
-
};
|
|
1012
|
-
}).pipe(shareReplay4({ refCount: true, bufferSize: 1 }));
|
|
1013
|
-
var isSameAccountsList2 = (a, b) => {
|
|
1014
|
-
if (a.length !== b.length) return false;
|
|
1015
|
-
return a.every((account, i) => account.id === b[i]?.id);
|
|
1016
|
-
};
|
|
1017
|
-
|
|
1018
|
-
// src/api/accounts.ts
|
|
343
|
+
import { combineLatest as combineLatest2, map as map3, Observable as Observable3, of as of2, shareReplay as shareReplay3 } from "rxjs";
|
|
1019
344
|
var getAccounts$ = (config, wallets) => {
|
|
1020
|
-
return new
|
|
345
|
+
return new Observable3((subscriber) => {
|
|
1021
346
|
const sources = config.platforms.map(
|
|
1022
|
-
(
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
case "ethereum":
|
|
1032
|
-
return getEthereumAccounts$(
|
|
1033
|
-
wallets.pipe(
|
|
1034
|
-
map5((w) => w.filter((w2) => w2.platform === "ethereum"))
|
|
1035
|
-
)
|
|
1036
|
-
);
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
347
|
+
(plugin) => plugin.getAccounts$(
|
|
348
|
+
wallets.pipe(
|
|
349
|
+
map3(
|
|
350
|
+
(ws) => ws.filter(
|
|
351
|
+
(w) => isWalletConnectWallet(w) || w.platform === plugin.platform
|
|
352
|
+
)
|
|
353
|
+
)
|
|
354
|
+
)
|
|
355
|
+
)
|
|
1039
356
|
);
|
|
1040
|
-
const accounts$ = sources.length ?
|
|
1041
|
-
|
|
1042
|
-
) :
|
|
357
|
+
const accounts$ = sources.length ? combineLatest2(sources).pipe(
|
|
358
|
+
map3((accounts) => accounts.flat().sort(sortAccounts))
|
|
359
|
+
) : of2([]);
|
|
1043
360
|
const sub = accounts$.subscribe(subscriber);
|
|
1044
361
|
return () => {
|
|
1045
362
|
sub.unsubscribe();
|
|
1046
363
|
};
|
|
1047
|
-
}).pipe(
|
|
1048
|
-
};
|
|
1049
|
-
|
|
1050
|
-
// src/api/store.ts
|
|
1051
|
-
import { uniq } from "lodash-es";
|
|
1052
|
-
var DEFAULT_SETTINGS = {};
|
|
1053
|
-
var toCompactPolkadotAccountType = (type) => {
|
|
1054
|
-
switch (type) {
|
|
1055
|
-
case "sr25519":
|
|
1056
|
-
return 0;
|
|
1057
|
-
case "ed25519":
|
|
1058
|
-
return 1;
|
|
1059
|
-
case "ecdsa":
|
|
1060
|
-
return 2;
|
|
1061
|
-
case "ethereum":
|
|
1062
|
-
return 3;
|
|
1063
|
-
default:
|
|
1064
|
-
return null;
|
|
1065
|
-
}
|
|
1066
|
-
};
|
|
1067
|
-
var fromCompactPolkadotAccountType = (type) => {
|
|
1068
|
-
switch (type) {
|
|
1069
|
-
case 0:
|
|
1070
|
-
return "sr25519";
|
|
1071
|
-
case 1:
|
|
1072
|
-
return "ed25519";
|
|
1073
|
-
case 2:
|
|
1074
|
-
return "ecdsa";
|
|
1075
|
-
case 3:
|
|
1076
|
-
return "ethereum";
|
|
1077
|
-
default:
|
|
1078
|
-
return void 0;
|
|
1079
|
-
}
|
|
1080
|
-
};
|
|
1081
|
-
var createKheopskitStore = (options = {}) => {
|
|
1082
|
-
const { ssrCookies, storageKey = DEFAULT_STORAGE_KEY } = options;
|
|
1083
|
-
const storage = ssrCookies !== void 0 ? createCompactCookieStorage(ssrCookies) : safeLocalStorage;
|
|
1084
|
-
const store2 = createStore(storageKey, DEFAULT_SETTINGS, storage);
|
|
1085
|
-
const addEnabledWalletId = (walletId) => {
|
|
1086
|
-
parseWalletId(walletId);
|
|
1087
|
-
store2.mutate((prev) => ({
|
|
1088
|
-
...prev,
|
|
1089
|
-
autoReconnect: uniq((prev.autoReconnect ?? []).concat(walletId))
|
|
1090
|
-
}));
|
|
1091
|
-
};
|
|
1092
|
-
const removeEnabledWalletId = (walletId) => {
|
|
1093
|
-
store2.mutate((prev) => ({
|
|
1094
|
-
...prev,
|
|
1095
|
-
autoReconnect: uniq(
|
|
1096
|
-
(prev.autoReconnect ?? []).filter((id) => id !== walletId)
|
|
1097
|
-
)
|
|
1098
|
-
}));
|
|
1099
|
-
};
|
|
1100
|
-
const getCachedState = () => {
|
|
1101
|
-
const data = store2.get();
|
|
1102
|
-
return {
|
|
1103
|
-
wallets: data.cachedWallets ?? [],
|
|
1104
|
-
accounts: data.cachedAccounts ?? []
|
|
1105
|
-
};
|
|
1106
|
-
};
|
|
1107
|
-
const setCachedState = (wallets, accounts) => {
|
|
1108
|
-
store2.mutate((prev) => ({
|
|
1109
|
-
...prev,
|
|
1110
|
-
cachedWallets: wallets,
|
|
1111
|
-
cachedAccounts: accounts
|
|
1112
|
-
}));
|
|
1113
|
-
};
|
|
1114
|
-
return {
|
|
1115
|
-
observable: store2.observable,
|
|
1116
|
-
addEnabledWalletId,
|
|
1117
|
-
removeEnabledWalletId,
|
|
1118
|
-
getCachedState,
|
|
1119
|
-
setCachedState
|
|
1120
|
-
};
|
|
1121
|
-
};
|
|
1122
|
-
var _defaultStore = null;
|
|
1123
|
-
var getDefaultStore = () => {
|
|
1124
|
-
if (_defaultStore === null) {
|
|
1125
|
-
_defaultStore = createKheopskitStore();
|
|
1126
|
-
}
|
|
1127
|
-
return _defaultStore;
|
|
1128
|
-
};
|
|
1129
|
-
var store = {
|
|
1130
|
-
get observable() {
|
|
1131
|
-
return getDefaultStore().observable;
|
|
1132
|
-
},
|
|
1133
|
-
addEnabledWalletId: (walletId) => getDefaultStore().addEnabledWalletId(walletId),
|
|
1134
|
-
removeEnabledWalletId: (walletId) => getDefaultStore().removeEnabledWalletId(walletId),
|
|
1135
|
-
getCachedState: () => getDefaultStore().getCachedState(),
|
|
1136
|
-
setCachedState: (wallets, accounts) => getDefaultStore().setCachedState(wallets, accounts)
|
|
1137
|
-
};
|
|
1138
|
-
var isCompactStore = (value) => {
|
|
1139
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
1140
|
-
if ("cachedWallets" in value || "cachedAccounts" in value) return false;
|
|
1141
|
-
return "v" in value || "w" in value || "a" in value || "r" in value;
|
|
1142
|
-
};
|
|
1143
|
-
var toCompactStore = (data) => {
|
|
1144
|
-
const wallets = data.cachedWallets?.map(
|
|
1145
|
-
(wallet) => [
|
|
1146
|
-
wallet.id,
|
|
1147
|
-
wallet.name,
|
|
1148
|
-
wallet.isConnected ? 1 : 0,
|
|
1149
|
-
wallet.type === "appKit" ? 1 : 0
|
|
1150
|
-
]
|
|
1151
|
-
);
|
|
1152
|
-
const accounts = data.cachedAccounts?.map(
|
|
1153
|
-
(account) => [
|
|
1154
|
-
account.walletId,
|
|
1155
|
-
account.address,
|
|
1156
|
-
account.name ?? null,
|
|
1157
|
-
account.chainId ?? null,
|
|
1158
|
-
toCompactPolkadotAccountType(account.polkadotAccountType)
|
|
1159
|
-
]
|
|
1160
|
-
);
|
|
1161
|
-
return {
|
|
1162
|
-
v: 1,
|
|
1163
|
-
r: data.autoReconnect,
|
|
1164
|
-
w: wallets?.length ? wallets : void 0,
|
|
1165
|
-
a: accounts?.length ? accounts : void 0
|
|
1166
|
-
};
|
|
1167
|
-
};
|
|
1168
|
-
var fromCompactStore = (data) => {
|
|
1169
|
-
const walletNameMap = /* @__PURE__ */ new Map();
|
|
1170
|
-
const wallets = (data.w ?? []).map((item) => {
|
|
1171
|
-
const [id, name, isConnected, type] = item;
|
|
1172
|
-
walletNameMap.set(id, name);
|
|
1173
|
-
const { platform } = parseWalletId(id);
|
|
1174
|
-
return {
|
|
1175
|
-
id,
|
|
1176
|
-
platform,
|
|
1177
|
-
type: type === 1 ? "appKit" : "injected",
|
|
1178
|
-
name,
|
|
1179
|
-
isConnected: isConnected === 1
|
|
1180
|
-
};
|
|
1181
|
-
});
|
|
1182
|
-
const accounts = (data.a ?? []).map((item) => {
|
|
1183
|
-
const [walletId, address, name, chainId, polkadotAccountType] = item;
|
|
1184
|
-
const { platform } = parseWalletId(walletId);
|
|
1185
|
-
return {
|
|
1186
|
-
id: getWalletAccountId(walletId, address),
|
|
1187
|
-
platform,
|
|
1188
|
-
address,
|
|
1189
|
-
name: name ?? void 0,
|
|
1190
|
-
chainId: chainId ?? void 0,
|
|
1191
|
-
polkadotAccountType: platform === "polkadot" ? fromCompactPolkadotAccountType(polkadotAccountType) : void 0,
|
|
1192
|
-
walletId,
|
|
1193
|
-
walletName: walletNameMap.get(walletId) ?? walletId
|
|
1194
|
-
};
|
|
1195
|
-
});
|
|
1196
|
-
return {
|
|
1197
|
-
autoReconnect: data.r,
|
|
1198
|
-
cachedWallets: wallets,
|
|
1199
|
-
cachedAccounts: accounts
|
|
1200
|
-
};
|
|
1201
|
-
};
|
|
1202
|
-
var decodeStore = (raw, fallback) => {
|
|
1203
|
-
try {
|
|
1204
|
-
const parsed = JSON.parse(raw);
|
|
1205
|
-
if (isCompactStore(parsed)) return fromCompactStore(parsed);
|
|
1206
|
-
return parsed;
|
|
1207
|
-
} catch {
|
|
1208
|
-
return fallback;
|
|
1209
|
-
}
|
|
1210
|
-
};
|
|
1211
|
-
var encodeStore = (data) => JSON.stringify(toCompactStore(data));
|
|
1212
|
-
var createCompactCookieStorage = (initialCookies) => {
|
|
1213
|
-
const base = cookieStorage(initialCookies);
|
|
1214
|
-
return {
|
|
1215
|
-
getItem: (key) => {
|
|
1216
|
-
const raw = base.getItem(key);
|
|
1217
|
-
if (!raw) return null;
|
|
1218
|
-
const expanded = decodeStore(raw, DEFAULT_SETTINGS);
|
|
1219
|
-
if (typeof document !== "undefined") {
|
|
1220
|
-
try {
|
|
1221
|
-
const parsed = JSON.parse(raw);
|
|
1222
|
-
if (!isCompactStore(parsed)) {
|
|
1223
|
-
base.setItem(key, encodeStore(expanded));
|
|
1224
|
-
}
|
|
1225
|
-
} catch {
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
return JSON.stringify(expanded);
|
|
1229
|
-
},
|
|
1230
|
-
setItem: (key, value) => {
|
|
1231
|
-
const expanded = decodeStore(value, DEFAULT_SETTINGS);
|
|
1232
|
-
base.setItem(key, encodeStore(expanded));
|
|
1233
|
-
},
|
|
1234
|
-
removeItem: base.removeItem,
|
|
1235
|
-
subscribe: (key, callback) => {
|
|
1236
|
-
const unsubscribe = base.subscribe?.(key, (value) => {
|
|
1237
|
-
if (!value) {
|
|
1238
|
-
callback(null);
|
|
1239
|
-
return;
|
|
1240
|
-
}
|
|
1241
|
-
const expanded = decodeStore(value, DEFAULT_SETTINGS);
|
|
1242
|
-
callback(JSON.stringify(expanded));
|
|
1243
|
-
});
|
|
1244
|
-
return () => {
|
|
1245
|
-
unsubscribe?.();
|
|
1246
|
-
};
|
|
1247
|
-
}
|
|
1248
|
-
};
|
|
364
|
+
}).pipe(shareReplay3({ refCount: true, bufferSize: 1 }));
|
|
1249
365
|
};
|
|
1250
366
|
|
|
1251
367
|
// src/api/wallets.ts
|
|
1252
368
|
import {
|
|
1253
|
-
combineLatest as
|
|
1254
|
-
distinct,
|
|
369
|
+
combineLatest as combineLatest3,
|
|
1255
370
|
filter as filter2,
|
|
1256
|
-
map as
|
|
371
|
+
map as map4,
|
|
1257
372
|
mergeMap,
|
|
1258
|
-
Observable as
|
|
1259
|
-
of as
|
|
1260
|
-
shareReplay as
|
|
373
|
+
Observable as Observable4,
|
|
374
|
+
of as of3,
|
|
375
|
+
shareReplay as shareReplay4,
|
|
1261
376
|
take as take2
|
|
1262
377
|
} from "rxjs";
|
|
1263
|
-
|
|
1264
|
-
// src/utils/sortWallets.ts
|
|
1265
|
-
var sortWallets = (w1, w2) => {
|
|
1266
|
-
if (w1.platform !== w2.platform) {
|
|
1267
|
-
return w1.platform === "polkadot" ? -1 : 1;
|
|
1268
|
-
}
|
|
1269
|
-
if (w1.name.toLowerCase() === "talisman") return -1;
|
|
1270
|
-
if (w2.name.toLowerCase() === "talisman") return 1;
|
|
1271
|
-
return w1.name.localeCompare(w2.name);
|
|
1272
|
-
};
|
|
1273
|
-
|
|
1274
|
-
// src/api/ethereum/wallets.ts
|
|
1275
|
-
import {
|
|
1276
|
-
createStore as createMipdStore
|
|
1277
|
-
} from "mipd";
|
|
1278
|
-
import {
|
|
1279
|
-
BehaviorSubject as BehaviorSubject4,
|
|
1280
|
-
combineLatest as combineLatest6,
|
|
1281
|
-
distinctUntilChanged as distinctUntilChanged4,
|
|
1282
|
-
map as map6,
|
|
1283
|
-
Observable as Observable6,
|
|
1284
|
-
shareReplay as shareReplay6
|
|
1285
|
-
} from "rxjs";
|
|
1286
|
-
var providersDetails$ = new Observable6(
|
|
1287
|
-
(subscriber) => {
|
|
1288
|
-
if (typeof window === "undefined") {
|
|
1289
|
-
subscriber.next([]);
|
|
1290
|
-
return () => {
|
|
1291
|
-
};
|
|
1292
|
-
}
|
|
1293
|
-
const mipdStore = createMipdStore();
|
|
1294
|
-
const unsubscribe = mipdStore.subscribe((providerDetails2) => {
|
|
1295
|
-
subscriber.next(providerDetails2);
|
|
1296
|
-
});
|
|
1297
|
-
const providerDetails = mipdStore.getProviders();
|
|
1298
|
-
subscriber.next(providerDetails);
|
|
1299
|
-
return () => {
|
|
1300
|
-
unsubscribe();
|
|
1301
|
-
mipdStore.destroy();
|
|
1302
|
-
};
|
|
1303
|
-
}
|
|
1304
|
-
).pipe(shareReplay6({ refCount: true, bufferSize: 1 }));
|
|
1305
|
-
var createEthereumInjectedWallets$ = (store2) => new Observable6((subscriber) => {
|
|
1306
|
-
const enabledWalletIds$ = new BehaviorSubject4(/* @__PURE__ */ new Set());
|
|
1307
|
-
const connectWallet = async (walletId, provider) => {
|
|
1308
|
-
if (enabledWalletIds$.value.has(walletId))
|
|
1309
|
-
throw new Error(`Extension ${walletId} already connected`);
|
|
1310
|
-
await provider.request({
|
|
1311
|
-
method: "eth_requestAccounts"
|
|
1312
|
-
});
|
|
1313
|
-
const newSet = new Set(enabledWalletIds$.value);
|
|
1314
|
-
newSet.add(walletId);
|
|
1315
|
-
enabledWalletIds$.next(newSet);
|
|
1316
|
-
store2.addEnabledWalletId(walletId);
|
|
1317
|
-
};
|
|
1318
|
-
const disconnectWallet = async (walletId) => {
|
|
1319
|
-
if (!enabledWalletIds$.value.has(walletId))
|
|
1320
|
-
throw new Error(`Extension ${walletId} is not connected`);
|
|
1321
|
-
const newSet = new Set(enabledWalletIds$.value);
|
|
1322
|
-
newSet.delete(walletId);
|
|
1323
|
-
enabledWalletIds$.next(newSet);
|
|
1324
|
-
store2.removeEnabledWalletId(walletId);
|
|
1325
|
-
};
|
|
1326
|
-
const sub = combineLatest6([providersDetails$, enabledWalletIds$]).pipe(
|
|
1327
|
-
map6(([providerDetails, enabledWalletIds]) => {
|
|
1328
|
-
return providerDetails.map((pd) => {
|
|
1329
|
-
const walletId = getWalletId("ethereum", pd.info.rdns);
|
|
1330
|
-
const provider = pd.provider;
|
|
1331
|
-
return {
|
|
1332
|
-
platform: "ethereum",
|
|
1333
|
-
type: "injected",
|
|
1334
|
-
id: walletId,
|
|
1335
|
-
name: pd.info.name,
|
|
1336
|
-
icon: pd.info.icon,
|
|
1337
|
-
provider,
|
|
1338
|
-
isConnected: enabledWalletIds.has(walletId),
|
|
1339
|
-
providerId: pd.info.rdns,
|
|
1340
|
-
connect: () => connectWallet(walletId, provider),
|
|
1341
|
-
disconnect: () => disconnectWallet(walletId)
|
|
1342
|
-
};
|
|
1343
|
-
});
|
|
1344
|
-
}),
|
|
1345
|
-
distinctUntilChanged4(walletsEqual)
|
|
1346
|
-
).subscribe(subscriber);
|
|
1347
|
-
return () => {
|
|
1348
|
-
sub.unsubscribe();
|
|
1349
|
-
};
|
|
1350
|
-
}).pipe(shareReplay6({ refCount: true, bufferSize: 1 }));
|
|
1351
|
-
var getEthereumWallets$ = (config, store2 = store) => {
|
|
1352
|
-
return new Observable6((subscriber) => {
|
|
1353
|
-
const subscription = combineLatest6([
|
|
1354
|
-
createEthereumInjectedWallets$(store2),
|
|
1355
|
-
getAppKitWallets$(config)?.pipe(map6((w) => w.ethereum))
|
|
1356
|
-
]).pipe(
|
|
1357
|
-
map6(
|
|
1358
|
-
([injectedWallets, appKitWallet]) => appKitWallet ? [...injectedWallets, appKitWallet] : injectedWallets
|
|
1359
|
-
)
|
|
1360
|
-
).subscribe(subscriber);
|
|
1361
|
-
return () => {
|
|
1362
|
-
subscription.unsubscribe();
|
|
1363
|
-
};
|
|
1364
|
-
}).pipe(shareReplay6({ refCount: true, bufferSize: 1 }));
|
|
1365
|
-
};
|
|
1366
|
-
var walletsEqual = (a, b) => {
|
|
1367
|
-
if (a.length !== b.length) return false;
|
|
1368
|
-
return a.every(
|
|
1369
|
-
(w, i) => w.id === b[i]?.id && w.isConnected === b[i]?.isConnected && w.name === b[i]?.name
|
|
1370
|
-
);
|
|
1371
|
-
};
|
|
1372
|
-
|
|
1373
|
-
// src/api/polkadot/wallets.ts
|
|
1374
|
-
import { isEqual } from "lodash-es";
|
|
1375
|
-
import {
|
|
1376
|
-
connectInjectedExtension,
|
|
1377
|
-
getInjectedExtensions
|
|
1378
|
-
} from "polkadot-api/pjs-signer";
|
|
1379
|
-
import {
|
|
1380
|
-
BehaviorSubject as BehaviorSubject5,
|
|
1381
|
-
combineLatest as combineLatest7,
|
|
1382
|
-
distinctUntilChanged as distinctUntilChanged5,
|
|
1383
|
-
map as map7,
|
|
1384
|
-
Observable as Observable7,
|
|
1385
|
-
shareReplay as shareReplay7
|
|
1386
|
-
} from "rxjs";
|
|
1387
|
-
var getInjectedWalletsIds = () => typeof window === "undefined" ? [] : getInjectedExtensions().map((name) => getWalletId("polkadot", name));
|
|
1388
|
-
var createWalletIdsPoller$ = () => {
|
|
1389
|
-
return new Observable7((subscriber) => {
|
|
1390
|
-
subscriber.next(getInjectedWalletsIds());
|
|
1391
|
-
const intervals = [100, 200, 300, 500];
|
|
1392
|
-
let index = 0;
|
|
1393
|
-
const poll = () => {
|
|
1394
|
-
subscriber.next(getInjectedWalletsIds());
|
|
1395
|
-
if (index < intervals.length) {
|
|
1396
|
-
const delay = intervals[index++];
|
|
1397
|
-
setTimeout(poll, delay);
|
|
1398
|
-
}
|
|
1399
|
-
};
|
|
1400
|
-
if (intervals.length > 0) {
|
|
1401
|
-
setTimeout(poll, intervals[index++] ?? 100);
|
|
1402
|
-
}
|
|
1403
|
-
return () => {
|
|
1404
|
-
};
|
|
1405
|
-
}).pipe(
|
|
1406
|
-
distinctUntilChanged5(isEqual),
|
|
1407
|
-
shareReplay7({ refCount: true, bufferSize: 1 })
|
|
1408
|
-
);
|
|
1409
|
-
};
|
|
1410
|
-
var createPolkadotInjectedWallets$ = (store2) => new Observable7((subscriber) => {
|
|
1411
|
-
const enabledExtensions$ = new BehaviorSubject5(/* @__PURE__ */ new Map());
|
|
1412
|
-
const connect = async (walletId) => {
|
|
1413
|
-
if (enabledExtensions$.value.has(walletId))
|
|
1414
|
-
throw new Error(`Extension ${walletId} already connected`);
|
|
1415
|
-
const { identifier } = parseWalletId(walletId);
|
|
1416
|
-
const extension = await connectInjectedExtension(identifier);
|
|
1417
|
-
const newMap = new Map(enabledExtensions$.value);
|
|
1418
|
-
newMap.set(walletId, extension);
|
|
1419
|
-
enabledExtensions$.next(newMap);
|
|
1420
|
-
store2.addEnabledWalletId(walletId);
|
|
1421
|
-
};
|
|
1422
|
-
const disconnect = (walletId) => {
|
|
1423
|
-
if (!enabledExtensions$.value.has(walletId))
|
|
1424
|
-
throw new Error(`Extension ${walletId} is not connected`);
|
|
1425
|
-
const newMap = new Map(enabledExtensions$.value);
|
|
1426
|
-
newMap.delete(walletId);
|
|
1427
|
-
enabledExtensions$.next(newMap);
|
|
1428
|
-
store2.removeEnabledWalletId(walletId);
|
|
1429
|
-
};
|
|
1430
|
-
const walletIds$ = createWalletIdsPoller$();
|
|
1431
|
-
const subscription = combineLatest7([walletIds$, enabledExtensions$]).pipe(
|
|
1432
|
-
map7(([walletIds, enabledExtensions]) => {
|
|
1433
|
-
return walletIds.map((id) => {
|
|
1434
|
-
const { identifier } = parseWalletId(id);
|
|
1435
|
-
const extension = enabledExtensions.get(id);
|
|
1436
|
-
const extInfo = POLKADOT_EXTENSIONS[identifier];
|
|
1437
|
-
return {
|
|
1438
|
-
id,
|
|
1439
|
-
type: "injected",
|
|
1440
|
-
platform: "polkadot",
|
|
1441
|
-
name: extInfo?.name ?? identifier,
|
|
1442
|
-
icon: extInfo?.icon ?? "",
|
|
1443
|
-
extensionId: identifier,
|
|
1444
|
-
extension,
|
|
1445
|
-
isConnected: !!extension,
|
|
1446
|
-
connect: () => connect(id),
|
|
1447
|
-
disconnect: () => disconnect(id)
|
|
1448
|
-
};
|
|
1449
|
-
});
|
|
1450
|
-
}),
|
|
1451
|
-
distinctUntilChanged5(walletsEqual2)
|
|
1452
|
-
).subscribe(subscriber);
|
|
1453
|
-
return () => {
|
|
1454
|
-
subscription.unsubscribe();
|
|
1455
|
-
};
|
|
1456
|
-
}).pipe(shareReplay7({ refCount: true, bufferSize: 1 }));
|
|
1457
|
-
var getPolkadotWallets$ = (config, store2 = store) => {
|
|
1458
|
-
return new Observable7((subscriber) => {
|
|
1459
|
-
const subscription = combineLatest7([
|
|
1460
|
-
createPolkadotInjectedWallets$(store2),
|
|
1461
|
-
getAppKitWallets$(config)?.pipe(map7((w) => w.polkadot))
|
|
1462
|
-
]).pipe(
|
|
1463
|
-
map7(
|
|
1464
|
-
([injectedWallets, appKitWallet]) => appKitWallet ? [...injectedWallets, appKitWallet] : injectedWallets
|
|
1465
|
-
)
|
|
1466
|
-
).subscribe(subscriber);
|
|
1467
|
-
return () => {
|
|
1468
|
-
subscription.unsubscribe();
|
|
1469
|
-
};
|
|
1470
|
-
}).pipe(shareReplay7({ refCount: true, bufferSize: 1 }));
|
|
1471
|
-
};
|
|
1472
|
-
var walletsEqual2 = (a, b) => {
|
|
1473
|
-
if (a.length !== b.length) return false;
|
|
1474
|
-
return a.every(
|
|
1475
|
-
(w, i) => w.id === b[i]?.id && w.isConnected === b[i]?.isConnected && w.name === b[i]?.name
|
|
1476
|
-
);
|
|
1477
|
-
};
|
|
1478
|
-
|
|
1479
|
-
// src/api/wallets.ts
|
|
1480
378
|
var getWallets$ = (config, store2 = store) => {
|
|
1481
379
|
const autoReconnectWalletIds$ = store2.observable.pipe(
|
|
1482
|
-
|
|
380
|
+
map4((s) => s.autoReconnect ?? []),
|
|
1483
381
|
take2(1),
|
|
1484
|
-
|
|
382
|
+
shareReplay4({ bufferSize: 1, refCount: true })
|
|
1485
383
|
);
|
|
1486
|
-
return new
|
|
384
|
+
return new Observable4((subscriber) => {
|
|
385
|
+
const ctx = { config, store: store2 };
|
|
1487
386
|
const observables = config.platforms.map(
|
|
1488
|
-
(
|
|
1489
|
-
switch (platform) {
|
|
1490
|
-
case "polkadot":
|
|
1491
|
-
return getPolkadotWallets$(config, store2);
|
|
1492
|
-
case "ethereum":
|
|
1493
|
-
return getEthereumWallets$(config, store2);
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
387
|
+
(plugin) => plugin.getWallets$(ctx)
|
|
1496
388
|
);
|
|
1497
|
-
const
|
|
1498
|
-
|
|
389
|
+
const platformWallets$ = observables.length ? combineLatest3(observables).pipe(map4((wallets) => wallets.flat())) : of3([]);
|
|
390
|
+
const wallets$ = combineLatest3([
|
|
391
|
+
platformWallets$,
|
|
392
|
+
getWalletConnectWallet$(config)
|
|
393
|
+
]).pipe(
|
|
394
|
+
map4(([platformWallets, walletConnect]) => {
|
|
395
|
+
const all = walletConnect ? [...platformWallets, walletConnect] : platformWallets;
|
|
396
|
+
return all.sort(sortWallets);
|
|
397
|
+
})
|
|
1499
398
|
// Note: No startWith([]) here - the hydration buffer handles initial state
|
|
1500
|
-
)
|
|
399
|
+
);
|
|
1501
400
|
const reconnectingWallets = /* @__PURE__ */ new Set();
|
|
1502
|
-
const
|
|
401
|
+
const reconnectedWallets = /* @__PURE__ */ new Set();
|
|
402
|
+
const MAX_RECONNECT_ATTEMPTS = 3;
|
|
403
|
+
const failedAttempts = /* @__PURE__ */ new Map();
|
|
404
|
+
const subAutoReconnect = combineLatest3([wallets$, autoReconnectWalletIds$]).pipe(
|
|
1503
405
|
filter2(([, walletIds]) => config.autoReconnect && !!walletIds?.length),
|
|
1504
406
|
mergeMap(
|
|
1505
407
|
([wallets, walletIds]) => wallets.filter((wallet) => walletIds?.includes(wallet.id))
|
|
1506
|
-
)
|
|
1507
|
-
distinct((w) => w.id)
|
|
408
|
+
)
|
|
1508
409
|
).subscribe(async (wallet) => {
|
|
1509
|
-
if (wallet.isConnected || reconnectingWallets.has(wallet.id)) {
|
|
410
|
+
if (wallet.isConnected || reconnectingWallets.has(wallet.id) || reconnectedWallets.has(wallet.id) || (failedAttempts.get(wallet.id) ?? 0) >= MAX_RECONNECT_ATTEMPTS) {
|
|
1510
411
|
return;
|
|
1511
412
|
}
|
|
1512
413
|
reconnectingWallets.add(wallet.id);
|
|
1513
414
|
try {
|
|
1514
415
|
await wallet.connect();
|
|
416
|
+
reconnectedWallets.add(wallet.id);
|
|
417
|
+
failedAttempts.delete(wallet.id);
|
|
1515
418
|
} catch (err) {
|
|
419
|
+
failedAttempts.set(
|
|
420
|
+
wallet.id,
|
|
421
|
+
(failedAttempts.get(wallet.id) ?? 0) + 1
|
|
422
|
+
);
|
|
1516
423
|
console.error("Failed to reconnect wallet %s", wallet.id, { err });
|
|
1517
424
|
} finally {
|
|
1518
425
|
reconnectingWallets.delete(wallet.id);
|
|
@@ -1523,11 +430,12 @@ var getWallets$ = (config, store2 = store) => {
|
|
|
1523
430
|
subAutoReconnect.unsubscribe();
|
|
1524
431
|
subWallets.unsubscribe();
|
|
1525
432
|
};
|
|
1526
|
-
}).pipe(
|
|
433
|
+
}).pipe(shareReplay4({ refCount: true, bufferSize: 1 }));
|
|
1527
434
|
};
|
|
1528
435
|
|
|
1529
436
|
// src/api/kheopskit.ts
|
|
1530
|
-
var getKheopskit$ = (config,
|
|
437
|
+
var getKheopskit$ = (config, options = {}) => {
|
|
438
|
+
const { ssrCookies, store: existingStore } = options;
|
|
1531
439
|
const kc = resolveConfig(config);
|
|
1532
440
|
const store2 = existingStore ?? createKheopskitStore({ ssrCookies, storageKey: kc.storageKey });
|
|
1533
441
|
if (kc.debug) console.debug("[kheopskit] config", kc);
|
|
@@ -1547,16 +455,14 @@ var getKheopskit$ = (config, ssrCookies, existingStore) => {
|
|
|
1547
455
|
}
|
|
1548
456
|
return wallet;
|
|
1549
457
|
});
|
|
1550
|
-
const cachedAccounts = cachedState.accounts.map(hydrateAccount)
|
|
1551
|
-
(account) => account.platform !== "polkadot" || kc.polkadotAccountTypes.includes(account.type)
|
|
1552
|
-
);
|
|
458
|
+
const cachedAccounts = cachedState.accounts.filter((cached) => acceptsCachedAccount(cached, kc.platforms)).map(hydrateAccount);
|
|
1553
459
|
if (kc.debug && cachedWallets.length > 0) {
|
|
1554
460
|
console.debug("[kheopskit] hydrating from cache:", {
|
|
1555
461
|
wallets: cachedWallets.length,
|
|
1556
462
|
accounts: cachedAccounts.length
|
|
1557
463
|
});
|
|
1558
464
|
}
|
|
1559
|
-
return new
|
|
465
|
+
return new Observable5((subscriber) => {
|
|
1560
466
|
const liveWallets$ = getWallets$(kc, store2);
|
|
1561
467
|
const liveAccounts$ = getAccounts$(kc, liveWallets$);
|
|
1562
468
|
const bufferedWallets$ = createHydrationBuffer(
|
|
@@ -1602,11 +508,17 @@ var getKheopskit$ = (config, ssrCookies, existingStore) => {
|
|
|
1602
508
|
return [...cachedWalletIds].every((id) => liveWalletIds.has(id));
|
|
1603
509
|
}
|
|
1604
510
|
);
|
|
1605
|
-
const
|
|
1606
|
-
|
|
1607
|
-
|
|
511
|
+
const sharedWallets$ = bufferedWallets$.pipe(
|
|
512
|
+
shareReplay5({ bufferSize: 1, refCount: true })
|
|
513
|
+
);
|
|
514
|
+
const sharedAccounts$ = bufferedAccounts$.pipe(
|
|
515
|
+
shareReplay5({ bufferSize: 1, refCount: true })
|
|
516
|
+
);
|
|
517
|
+
const subscription = combineLatest4({
|
|
518
|
+
wallets: sharedWallets$,
|
|
519
|
+
accounts: sharedAccounts$
|
|
1608
520
|
}).pipe(
|
|
1609
|
-
|
|
521
|
+
map5(({ wallets, accounts }) => {
|
|
1610
522
|
if (kc.debug) {
|
|
1611
523
|
console.debug("[kheopskit] hydration state", {
|
|
1612
524
|
walletsHydrating: wallets.isHydrating,
|
|
@@ -1617,15 +529,15 @@ var getKheopskit$ = (config, ssrCookies, existingStore) => {
|
|
|
1617
529
|
}
|
|
1618
530
|
return {
|
|
1619
531
|
config: kc,
|
|
1620
|
-
wallets: wallets.items,
|
|
1621
|
-
accounts: accounts.items,
|
|
532
|
+
wallets: [...wallets.items].sort(sortWallets),
|
|
533
|
+
accounts: [...accounts.items].sort(sortAccounts),
|
|
1622
534
|
isHydrating: wallets.isHydrating || accounts.isHydrating
|
|
1623
535
|
};
|
|
1624
536
|
})
|
|
1625
537
|
).subscribe(subscriber);
|
|
1626
|
-
const persistSub =
|
|
1627
|
-
wallets:
|
|
1628
|
-
accounts:
|
|
538
|
+
const persistSub = combineLatest4({
|
|
539
|
+
wallets: sharedWallets$,
|
|
540
|
+
accounts: sharedAccounts$
|
|
1629
541
|
}).pipe(
|
|
1630
542
|
// Wait for hydration to complete
|
|
1631
543
|
filter3(
|
|
@@ -1633,13 +545,16 @@ var getKheopskit$ = (config, ssrCookies, existingStore) => {
|
|
|
1633
545
|
),
|
|
1634
546
|
// Debounce to avoid excessive writes
|
|
1635
547
|
debounceTime(1e3),
|
|
1636
|
-
// Only persist if
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
const
|
|
1642
|
-
|
|
548
|
+
// Only persist if the serialized snapshot would actually change.
|
|
549
|
+
// Compare the persisted fields (not just ids): an Ethereum chain switch
|
|
550
|
+
// keeps the same account id but changes the cached chainId, so an
|
|
551
|
+
// id-only comparator would skip persisting it.
|
|
552
|
+
distinctUntilChanged2((prev, curr) => {
|
|
553
|
+
const prevWalletKeys = prev.wallets.items.map(walletPersistKey);
|
|
554
|
+
const currWalletKeys = curr.wallets.items.map(walletPersistKey);
|
|
555
|
+
const prevAccountKeys = prev.accounts.items.map(accountChangeKey);
|
|
556
|
+
const currAccountKeys = curr.accounts.items.map(accountChangeKey);
|
|
557
|
+
return arraysEqual(prevWalletKeys, currWalletKeys) && arraysEqual(prevAccountKeys, currAccountKeys);
|
|
1643
558
|
})
|
|
1644
559
|
).subscribe(({ wallets, accounts }) => {
|
|
1645
560
|
const connectedWalletIds = new Set(
|
|
@@ -1671,30 +586,53 @@ var getKheopskit$ = (config, ssrCookies, existingStore) => {
|
|
|
1671
586
|
persistSub.unsubscribe();
|
|
1672
587
|
};
|
|
1673
588
|
}).pipe(
|
|
1674
|
-
|
|
589
|
+
distinctUntilChanged2(statesEqual),
|
|
1675
590
|
throttleTime(16, void 0, { leading: true, trailing: true }),
|
|
1676
591
|
// ~1 frame at 60fps
|
|
1677
592
|
logObservable("kheopskit$", { enabled: kc.debug, printValue: true }),
|
|
1678
|
-
|
|
593
|
+
shareReplay5({ bufferSize: 1, refCount: true })
|
|
594
|
+
// The runtime objects are the concrete per-plugin wallet/account types;
|
|
595
|
+
// recover the precise KheopskitState<P> the caller's plugins imply.
|
|
1679
596
|
);
|
|
1680
597
|
};
|
|
1681
598
|
var arraysEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
|
|
1682
|
-
var
|
|
1683
|
-
(
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
599
|
+
var accountChangeKey = (account) => {
|
|
600
|
+
switch (account.platform) {
|
|
601
|
+
case "ethereum":
|
|
602
|
+
return `${account.id}|${account.chainId ?? ""}`;
|
|
603
|
+
case "polkadot":
|
|
604
|
+
return `${account.id}|${account.type ?? ""}`;
|
|
605
|
+
case "solana":
|
|
606
|
+
return `${account.id}|${(account.chains ?? []).join(",")}`;
|
|
607
|
+
default:
|
|
608
|
+
return account.id;
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
var walletPlatforms = (wallet) => isWalletConnectWallet(wallet) ? wallet.platforms.join(",") : "";
|
|
612
|
+
var walletPersistKey = (wallet) => `${wallet.id}|${wallet.isConnected ? 1 : 0}|${wallet.name}`;
|
|
613
|
+
var walletUiKey = (wallet) => `${walletPersistKey(wallet)}|${wallet.icon}|${walletPlatforms(wallet)}`;
|
|
614
|
+
var statesEqual = (a, b) => a.isHydrating === b.isHydrating && a.wallets.length === b.wallets.length && a.accounts.length === b.accounts.length && a.wallets.every((w, i) => {
|
|
615
|
+
const other = b.wallets[i];
|
|
616
|
+
return !!other && walletUiKey(w) === walletUiKey(other);
|
|
617
|
+
}) && a.accounts.every((acc, i) => {
|
|
618
|
+
const other = b.accounts[i];
|
|
619
|
+
return !!other && accountChangeKey(acc) === accountChangeKey(other);
|
|
620
|
+
});
|
|
1687
621
|
export {
|
|
1688
622
|
DEFAULT_STORAGE_KEY,
|
|
623
|
+
KheopskitError,
|
|
1689
624
|
clearAllCachedObservables,
|
|
1690
|
-
clearCachedObservable,
|
|
1691
625
|
createKheopskitStore,
|
|
1692
|
-
getCachedIcon,
|
|
1693
626
|
getDefaultStore,
|
|
1694
627
|
getKheopskit$,
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
628
|
+
getWalletAccountId,
|
|
629
|
+
getWalletId,
|
|
630
|
+
isInjectedWallet,
|
|
631
|
+
isValidAddress,
|
|
632
|
+
isValidWalletId,
|
|
633
|
+
isWalletConnectWallet,
|
|
634
|
+
parseWalletAccountId,
|
|
635
|
+
parseWalletId,
|
|
1698
636
|
resetAppKitCache,
|
|
1699
637
|
resolveConfig
|
|
1700
638
|
};
|