@trustware/sdk-staging 1.1.8-staging.2 → 1.1.8-staging.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +27 -0
  2. package/dist/blockchain-BONedEsU.d.cts +110 -0
  3. package/dist/blockchain-BONedEsU.d.ts +110 -0
  4. package/dist/constants.cjs +1 -1
  5. package/dist/constants.mjs +1 -1
  6. package/dist/{core-u95iahDO.d.cts → core-B9PJ0mUX.d.cts} +3 -2
  7. package/dist/{core-CVbN3gJy.d.ts → core-DrWK6PT3.d.ts} +3 -2
  8. package/dist/core.cjs +2290 -2247
  9. package/dist/core.cjs.map +1 -1
  10. package/dist/core.d.cts +4 -3
  11. package/dist/core.d.ts +4 -3
  12. package/dist/core.mjs +2277 -2244
  13. package/dist/core.mjs.map +1 -1
  14. package/dist/{detect-6MRR4B7g.d.ts → detect-BLE9aPwJ.d.ts} +2 -2
  15. package/dist/{detect-DVIWcXpl.d.cts → detect-Dn7A-Svt.d.cts} +2 -2
  16. package/dist/index.cjs +22356 -3553
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +28 -10
  19. package/dist/index.d.ts +28 -10
  20. package/dist/index.mjs +28302 -9499
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/{manager-CXSw1h5e.d.cts → manager-C85ARoxD.d.cts} +65 -121
  23. package/dist/{manager-CXSw1h5e.d.ts → manager-PBjHXKjh.d.ts} +65 -121
  24. package/dist/smart-account.cjs +14707 -0
  25. package/dist/smart-account.cjs.map +1 -0
  26. package/dist/smart-account.d.cts +3962 -0
  27. package/dist/smart-account.d.ts +3962 -0
  28. package/dist/smart-account.mjs +14686 -0
  29. package/dist/smart-account.mjs.map +1 -0
  30. package/dist/types-B3nKHW6H.d.cts +32 -0
  31. package/dist/types-MtdjJgwT.d.ts +32 -0
  32. package/dist/wallet.cjs +29 -9
  33. package/dist/wallet.cjs.map +1 -1
  34. package/dist/wallet.d.cts +4 -3
  35. package/dist/wallet.d.ts +4 -3
  36. package/dist/wallet.mjs +16 -6
  37. package/dist/wallet.mjs.map +1 -1
  38. package/dist/widget.cjs +33042 -14248
  39. package/dist/widget.cjs.map +1 -1
  40. package/dist/widget.d.cts +5 -4
  41. package/dist/widget.d.ts +5 -4
  42. package/dist/widget.mjs +32978 -14180
  43. package/dist/widget.mjs.map +1 -1
  44. package/package.json +17 -4
  45. package/dist/types-BrVfNxND.d.cts +0 -14
  46. package/dist/types-BrVfNxND.d.ts +0 -14
package/dist/core.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
9
  var __esm = (fn, res) => function __init() {
@@ -19,6 +21,14 @@ var __copyProps = (to, from, except, desc) => {
19
21
  }
20
22
  return to;
21
23
  };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
+ // If the importer is in node compatibility mode or this is not an ESM
26
+ // file that has been converted to a CommonJS file using a Babel-
27
+ // compatible transform (i.e. "__esModule" has not been set), then set
28
+ // "default" to the CommonJS "module.exports" for node compatibility.
29
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
+ mod
31
+ ));
22
32
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
23
33
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
24
34
 
@@ -58,7 +68,11 @@ var init_config = __esm({
58
68
  DEFAULT_FEATURE_FLAGS = {
59
69
  tokensPagination: true,
60
70
  balanceStreaming: false,
61
- shouldAllowGA4: true
71
+ shouldAllowGA4: true,
72
+ swapMode: false,
73
+ swapDefaultDestToken: null,
74
+ swapLockDestToken: false,
75
+ swapAllowedDestTokens: null
62
76
  };
63
77
  }
64
78
  });
@@ -69,7 +83,7 @@ var init_constants = __esm({
69
83
  "src/constants.ts"() {
70
84
  "use strict";
71
85
  SDK_NAME = "@trustware/sdk";
72
- SDK_VERSION = "1.1.8-staging.2";
86
+ SDK_VERSION = "1.1.8-staging.4";
73
87
  API_ROOT = "https://bv-staging-api.trustware.io";
74
88
  API_PREFIX = "/api";
75
89
  WALLETCONNECT_PROJECT_ID = "72ea74c400f5111d43aea638d7d83a24";
@@ -224,373 +238,432 @@ var init_http = __esm({
224
238
  }
225
239
  });
226
240
 
227
- // src/wallets/bridges.ts
228
- var init_bridges = __esm({
229
- "src/wallets/bridges.ts"() {
230
- "use strict";
241
+ // src/utils/chains.ts
242
+ function inferChainTypeFromValue(normalized) {
243
+ if (!normalized) return void 0;
244
+ const aliased = CHAIN_TYPE_ALIASES[normalized];
245
+ if (aliased) return aliased;
246
+ if (normalized === "evm" || normalized === "solana" || normalized === "cosmos" || normalized === "bitcoin") {
247
+ return normalized;
231
248
  }
232
- });
233
-
234
- // src/wallets/eipWallets.ts
235
- async function addThenSwitch(eth, chainId) {
236
- const p = CHAIN_PARAMS[chainId];
237
- if (!p) throw new Error(`Unknown chain ${chainId} (no params to add)`);
238
- await eth.request({ method: "wallet_addEthereumChain", params: [p] });
239
- await eth.request({
240
- method: "wallet_switchEthereumChain",
241
- params: [{ chainId: p.chainIdHex }]
242
- });
243
- }
244
- function useEIP1193(eth) {
245
- if (!eth?.request) throw new Error("useEIP1193: invalid provider");
246
- let switching = false;
247
- return {
248
- ecosystem: "evm",
249
- type: "eip1193",
250
- async getAddress() {
251
- const [a] = await eth.request({
252
- method: "eth_requestAccounts"
253
- });
254
- if (!a) throw new Error("No connected address");
255
- return a;
256
- },
257
- async getChainId() {
258
- const hex = await eth.request({ method: "eth_chainId" });
259
- return parseInt(String(hex), 16);
260
- },
261
- async switchChain(chainId) {
262
- if (switching) return;
263
- switching = true;
264
- const hex = CHAIN_PARAMS[chainId]?.chainIdHex ?? `0x${chainId.toString(16)}`;
265
- try {
266
- await eth.request({
267
- method: "wallet_switchEthereumChain",
268
- params: [{ chainId: hex }]
269
- });
270
- } catch (e2) {
271
- if (e2?.code === 4902) {
272
- await addThenSwitch(eth, chainId);
273
- } else if (e2?.code === 4001) {
274
- } else {
275
- throw e2;
276
- }
277
- } finally {
278
- switching = false;
279
- }
280
- },
281
- request: (args) => eth.request(args)
282
- };
283
- }
284
- var CHAIN_PARAMS;
285
- var init_eipWallets = __esm({
286
- "src/wallets/eipWallets.ts"() {
287
- "use strict";
288
- CHAIN_PARAMS = {
289
- 8453: {
290
- chainIdHex: "0x2105",
291
- chainName: "Base",
292
- rpcUrls: ["https://mainnet.base.org"],
293
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
294
- blockExplorerUrls: ["https://basescan.org"]
295
- },
296
- 42161: {
297
- chainIdHex: "0xa4b1",
298
- chainName: "Arbitrum One",
299
- rpcUrls: ["https://arb1.arbitrum.io/rpc"],
300
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
301
- blockExplorerUrls: ["https://arbiscan.io"]
302
- },
303
- 43114: {
304
- chainIdHex: "0xa86a",
305
- chainName: "Avalanche C-Chain",
306
- rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"],
307
- nativeCurrency: { name: "Avalanche", symbol: "AVAX", decimals: 18 },
308
- blockExplorerUrls: ["https://snowtrace.io"]
309
- }
310
- };
249
+ if (/^eip155:\d+$/.test(normalized) || /^\d+$/.test(normalized)) {
250
+ return "evm";
311
251
  }
312
- });
313
-
314
- // src/core/sdkRpc.ts
315
- async function requestSDKRPC(path, init = {}) {
316
- const response = await rateLimitedFetch(`${apiBase()}/v1/sdk/rpc${path}`, {
317
- ...init,
318
- headers: jsonHeaders()
319
- });
320
- let payload = null;
321
- try {
322
- payload = await response.json();
323
- } catch {
324
- payload = null;
252
+ if (normalized.startsWith("solana:") || normalized.includes("solana")) {
253
+ return "solana";
325
254
  }
326
- if (response.ok && payload?.success && payload.data !== void 0) {
327
- return payload.data;
255
+ if (normalized.startsWith("cosmos:") || normalized.startsWith("sei:") || normalized === "sei-evm") {
256
+ return "cosmos";
328
257
  }
329
- throw new SDKRPCError(
330
- payload?.error?.message || `HTTP ${response.status}: ${response.statusText || "SDK RPC request failed"}`,
331
- {
332
- code: payload?.error?.code,
333
- context: payload?.error?.context,
334
- status: response.status
335
- }
336
- );
258
+ return void 0;
337
259
  }
338
- async function sendSolanaSerialized(body) {
339
- return requestSDKRPC(
340
- "/solana/send-serialized",
341
- {
342
- method: "POST",
343
- body: JSON.stringify(body)
260
+ function normalizeChainKey(value) {
261
+ if (value === void 0 || value === null) return "";
262
+ return String(value).trim().toLowerCase();
263
+ }
264
+ function normalizeChainType(chain) {
265
+ if (!chain) return void 0;
266
+ const raw = typeof chain === "string" ? chain : chain.type ?? chain.chainType ?? chain.networkIdentifier ?? chain.chainId ?? chain.id ?? chain.networkName ?? chain.axelarChainName;
267
+ if (!raw) return void 0;
268
+ const normalized = String(raw).trim().toLowerCase();
269
+ return inferChainTypeFromValue(normalized) ?? normalized;
270
+ }
271
+ function getNativeTokenAddress(chainType) {
272
+ return normalizeChainType(chainType) === "solana" ? NATIVE_SOLANA : NATIVE_EVM;
273
+ }
274
+ function isSolanaNativeTokenAlias(address) {
275
+ if (!address) return false;
276
+ const trimmed = address.trim();
277
+ if (!trimmed) return false;
278
+ return trimmed === NATIVE_SOLANA || trimmed.toLowerCase() === NATIVE_EVM;
279
+ }
280
+ function normalizeAddress(address, chainType) {
281
+ const trimmed = address.trim();
282
+ if (normalizeChainType(chainType) === "solana") {
283
+ if (isSolanaNativeTokenAlias(trimmed)) {
284
+ return NATIVE_SOLANA;
344
285
  }
345
- );
286
+ return trimmed;
287
+ }
288
+ return trimmed.toLowerCase();
346
289
  }
347
- async function getSolanaTxStatus(params) {
348
- const search = new URLSearchParams(params);
349
- return requestSDKRPC(
350
- `/solana/tx-status?${search.toString()}`,
351
- { method: "GET" }
352
- );
290
+ function isZeroAddressLike(address, chainType) {
291
+ if (!address) return true;
292
+ const normalized = normalizeAddress(address, chainType);
293
+ return normalized === normalizeAddress(getNativeTokenAddress(chainType), chainType) || normalized === "0x0000000000000000000000000000000000000000";
353
294
  }
354
- var SDKRPCError;
355
- var init_sdkRpc = __esm({
356
- "src/core/sdkRpc.ts"() {
295
+ var NATIVE_EVM, NATIVE_SOLANA, CHAIN_TYPE_ALIASES;
296
+ var init_chains = __esm({
297
+ "src/utils/chains.ts"() {
357
298
  "use strict";
358
- init_http();
359
- SDKRPCError = class extends Error {
360
- constructor(message, options) {
361
- super(message);
362
- this.name = "SDKRPCError";
363
- this.code = options?.code;
364
- this.context = options?.context;
365
- this.status = options?.status;
366
- }
299
+ NATIVE_EVM = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
300
+ NATIVE_SOLANA = "So11111111111111111111111111111111111111111";
301
+ CHAIN_TYPE_ALIASES = {
302
+ btc: "bitcoin",
303
+ bitcoin: "bitcoin",
304
+ sei: "cosmos",
305
+ "pacific-1": "cosmos"
367
306
  };
368
307
  }
369
308
  });
370
309
 
371
- // src/wallets/solana.ts
372
- function getPublicKeyString(provider) {
373
- const publicKey = provider?.publicKey;
374
- if (!publicKey) return null;
375
- const text = publicKey.toString().trim();
376
- return text || null;
310
+ // src/registry.ts
311
+ var registry_exports = {};
312
+ __export(registry_exports, {
313
+ NATIVE: () => NATIVE,
314
+ Registry: () => Registry
315
+ });
316
+ function getChainAliases(chain) {
317
+ const values = [
318
+ chain.chainId,
319
+ chain.id,
320
+ chain.networkIdentifier,
321
+ chain.axelarChainName,
322
+ chain.networkName
323
+ ];
324
+ return values.map((value) => normalizeChainKey(value)).filter(Boolean);
377
325
  }
378
- function decodeBase64(serializedTransaction) {
379
- const trimmed = serializedTransaction.trim();
380
- if (typeof Buffer !== "undefined") {
381
- return Uint8Array.from(Buffer.from(trimmed, "base64"));
382
- }
383
- const binary = globalThis.atob(trimmed);
384
- return Uint8Array.from(binary, (char) => char.charCodeAt(0));
326
+ function tokenKey(token) {
327
+ return `${normalizeChainKey(token.chainId)}:${token.address.toLowerCase()}`;
385
328
  }
386
- function decodeBase64Transaction(serializedTransaction) {
387
- const bytes = decodeBase64(serializedTransaction);
388
- try {
389
- return import_web3.VersionedTransaction.deserialize(bytes);
390
- } catch {
391
- return import_web3.Transaction.from(bytes);
329
+ function parseTokenPage(payload) {
330
+ if (Array.isArray(payload)) {
331
+ return {
332
+ data: payload,
333
+ pageInfo: { hasNextPage: false }
334
+ };
392
335
  }
336
+ const parsed = payload ?? {};
337
+ const data = parsed.data ?? parsed.results ?? parsed.tokens ?? [];
338
+ const info = parsed.pageInfo ?? parsed.pagination;
339
+ return {
340
+ data: Array.isArray(data) ? data : [],
341
+ pageInfo: {
342
+ hasNextPage: info?.hasNextPage ?? parsed.hasNextPage ?? Boolean(info?.nextCursor),
343
+ nextCursor: info?.nextCursor ?? parsed.nextCursor
344
+ }
345
+ };
393
346
  }
394
- function encodeBase64(bytes) {
395
- if (typeof Buffer !== "undefined") {
396
- return Buffer.from(bytes).toString("base64");
397
- }
398
- let binary = "";
399
- for (const byte of bytes) {
400
- binary += String.fromCharCode(byte);
401
- }
402
- return globalThis.btoa(binary);
347
+ function normalizeToken(token) {
348
+ return {
349
+ ...token,
350
+ chainId: token.chainId
351
+ };
403
352
  }
404
- async function waitForSolanaConfirmation(chainId, signature) {
405
- const started = Date.now();
406
- const timeoutMs = 12e4;
407
- const intervalMs = 2e3;
408
- while (Date.now() - started < timeoutMs) {
409
- const status = await getSolanaTxStatus({ chainId, signature });
410
- if (status.status === "success") return signature;
411
- if (status.status === "failed") {
412
- throw new Error("Solana transaction failed");
413
- }
414
- await new Promise((resolve) => setTimeout(resolve, intervalMs));
415
- }
416
- throw new Error("Timed out waiting for Solana transaction confirmation");
417
- }
418
- function bindSolanaProviderEvents(provider, handlers) {
419
- const onConnect = () => handlers.onConnect?.();
420
- const onAccountChanged = () => handlers.onAccountChanged?.();
421
- const onDisconnect = () => handlers.onDisconnect?.();
422
- provider.on?.("connect", onConnect);
423
- provider.on?.("accountChanged", onAccountChanged);
424
- provider.on?.("disconnect", onDisconnect);
425
- return () => {
426
- provider.off?.("connect", onConnect);
427
- provider.off?.("accountChanged", onAccountChanged);
428
- provider.off?.("disconnect", onDisconnect);
429
- provider.removeListener?.("connect", onConnect);
430
- provider.removeListener?.("accountChanged", onAccountChanged);
431
- provider.removeListener?.("disconnect", onDisconnect);
432
- };
433
- }
434
- function toSolanaWalletInterface(provider) {
435
- return {
436
- ecosystem: "solana",
437
- type: "solana",
438
- async getAddress() {
439
- const current = getPublicKeyString(provider);
440
- if (current) return current;
441
- if (!provider.connect) {
442
- throw new Error("Selected Solana wallet cannot connect");
353
+ var NATIVE, PAGE_CACHE_TTL_MS, PAGE_CACHE_LIMIT, Registry;
354
+ var init_registry = __esm({
355
+ "src/registry.ts"() {
356
+ "use strict";
357
+ init_store();
358
+ init_chains();
359
+ NATIVE = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
360
+ PAGE_CACHE_TTL_MS = 5 * 60 * 1e3;
361
+ PAGE_CACHE_LIMIT = 100;
362
+ Registry = class {
363
+ constructor(baseURL) {
364
+ this.baseURL = baseURL;
365
+ this._chainsById = /* @__PURE__ */ new Map();
366
+ this._chainAliases = /* @__PURE__ */ new Map();
367
+ this._tokensByChain = /* @__PURE__ */ new Map();
368
+ this._tokensByChainKey = /* @__PURE__ */ new Map();
369
+ this._pageCache = /* @__PURE__ */ new Map();
370
+ this._loaded = false;
371
+ this._chainsLoaded = false;
372
+ this._loadingPromise = null;
373
+ this._chainsLoadingPromise = null;
443
374
  }
444
- await provider.connect();
445
- const next = getPublicKeyString(provider);
446
- if (!next) throw new Error("No connected Solana address");
447
- return next;
448
- },
449
- async disconnect() {
450
- await provider.disconnect?.();
451
- },
452
- async getChainKey() {
453
- return "solana-mainnet-beta";
454
- },
455
- async sendSerializedTransaction(serializedTransactionBase64, chainId) {
456
- const transaction = decodeBase64Transaction(serializedTransactionBase64);
457
- if (provider.signAndSendTransaction) {
458
- const result = await provider.signAndSendTransaction(transaction, {
459
- preflightCommitment: "confirmed"
375
+ async ensureLoaded() {
376
+ if (this._loaded) return;
377
+ if (this._loadingPromise) {
378
+ await this._loadingPromise;
379
+ return;
380
+ }
381
+ this._loadingPromise = this.loadAllTokens();
382
+ try {
383
+ await this._loadingPromise;
384
+ } finally {
385
+ this._loadingPromise = null;
386
+ }
387
+ }
388
+ async ensureChainsLoaded() {
389
+ if (this._chainsLoaded) return;
390
+ if (this._chainsLoadingPromise) {
391
+ await this._chainsLoadingPromise;
392
+ return;
393
+ }
394
+ this._chainsLoadingPromise = this.loadChains();
395
+ try {
396
+ await this._chainsLoadingPromise;
397
+ } finally {
398
+ this._chainsLoadingPromise = null;
399
+ }
400
+ }
401
+ get config() {
402
+ return TrustwareConfigStore.get();
403
+ }
404
+ emitPageLoaded(chainRef, query, result, cursor) {
405
+ this.config.onEvent?.({
406
+ type: "token_page_loaded",
407
+ chainRef: String(chainRef),
408
+ query,
409
+ count: result.data.length,
410
+ hasNextPage: result.pageInfo.hasNextPage,
411
+ cursor
460
412
  });
461
- if (typeof result === "string") return result;
462
- if (result?.signature) return result.signature;
463
413
  }
464
- if (!provider.signTransaction) {
465
- throw new Error("Connected Solana wallet cannot sign transactions");
414
+ emitPageError(chainRef, query, cursor, error) {
415
+ const message = error instanceof Error ? error.message : String(error);
416
+ this.config.onEvent?.({
417
+ type: "token_page_error",
418
+ chainRef: String(chainRef),
419
+ query,
420
+ cursor,
421
+ message
422
+ });
466
423
  }
467
- const signed = await provider.signTransaction(transaction);
468
- const resolvedChainId = chainId?.trim() || "solana-mainnet";
469
- const serializedSigned = encodeBase64(signed.serialize());
470
- const { signature } = await sendSolanaSerialized({
471
- chainId: resolvedChainId,
472
- serializedTransaction: serializedSigned
473
- });
474
- await waitForSolanaConfirmation(resolvedChainId, signature);
475
- return signature;
476
- }
477
- };
478
- }
479
- var import_web3;
480
- var init_solana = __esm({
481
- "src/wallets/solana.ts"() {
482
- "use strict";
483
- import_web3 = require("@solana/web3.js");
484
- init_sdkRpc();
485
- }
486
- });
487
-
488
- // src/wallets/adapters.ts
489
- function toWalletInterfaceFromDetected(dw) {
490
- if (!dw?.provider) throw new Error("No provider on detected wallet");
491
- if (dw.via === "solana-window" || dw.meta.ecosystem === "solana") {
492
- return toSolanaWalletInterface(dw.provider);
493
- }
494
- const eth = dw.provider;
495
- return useEIP1193(eth);
496
- }
497
- var init_adapters = __esm({
498
- "src/wallets/adapters.ts"() {
499
- "use strict";
500
- init_eipWallets();
501
- init_solana();
502
- }
503
- });
504
-
505
- // src/wallets/connect.ts
506
- function pickWagmiConnector(wagmi, metaName, metaId, metaCategory) {
507
- const lower = metaName.toLowerCase();
508
- const cons = wagmi.connectors();
509
- return cons.find((c) => c.name.toLowerCase().includes(lower)) || metaId === "coinbase" && cons.find((c) => c.name.toLowerCase().includes("coinbase")) || metaId === "walletconnect" && cons.find((c) => (c.type ?? "").toLowerCase() === "walletconnect") || metaCategory === "injected" && cons.find((c) => (c.type ?? "").toLowerCase() === "injected") || null;
510
- }
511
- async function connectDetectedWallet(dw, opts) {
512
- const { wagmi, touchAddress = true } = opts ?? {};
513
- if (dw.meta.id === "walletconnect" || dw.via === "walletconnect") {
514
- if (wagmi) {
515
- const conn = pickWagmiConnector(
516
- wagmi,
517
- dw.meta.name,
518
- dw.meta.id,
519
- dw.meta.category
520
- );
521
- if (conn) {
522
- await wagmi.connect(conn);
523
- return { via: "wagmi", api: null };
424
+ storeChain(chain) {
425
+ const canonical = chain?.chainId ?? chain?.id;
426
+ if (canonical == null) return;
427
+ const normalized = {
428
+ ...chain,
429
+ id: chain.id ?? canonical,
430
+ chainId: chain.chainId ?? canonical
431
+ };
432
+ const canonicalKey = normalizeChainKey(canonical);
433
+ this._chainsById.set(canonicalKey, normalized);
434
+ for (const alias of getChainAliases(normalized)) {
435
+ this._chainAliases.set(alias, canonicalKey);
436
+ }
524
437
  }
525
- }
526
- throw new Error("WalletConnect connection failed. Please try again.");
527
- }
528
- if (dw.via === "solana-window" || dw.meta.ecosystem === "solana") {
529
- try {
530
- const provider = dw.provider;
531
- await provider.connect();
532
- return {
533
- via: "eip1193",
534
- api: toWalletInterfaceFromDetected(dw),
535
- error: null
536
- };
537
- } catch (err) {
538
- const errorMsg = err instanceof Error ? err.message : String(err);
539
- return { via: "eip1193", api: null, error: errorMsg };
540
- }
541
- }
542
- if (wagmi) {
543
- const conn = pickWagmiConnector(
544
- wagmi,
545
- dw.meta.name,
546
- dw.meta.id,
547
- dw.meta.category
548
- );
549
- if (conn) {
550
- await wagmi.connect(conn);
551
- return { via: "wagmi", api: null, error: null };
552
- }
553
- }
554
- const api = toWalletInterfaceFromDetected(dw);
555
- if (touchAddress) await api.getAddress();
556
- return { via: "eip1193", api, error: null };
557
- }
558
- var init_connect = __esm({
559
- "src/wallets/connect.ts"() {
560
- "use strict";
561
- init_adapters();
562
- }
563
- });
564
-
565
- // node_modules/@solana/errors/dist/index.node.mjs
566
- function encodeValue(value) {
567
- if (Array.isArray(value)) {
568
- const commaSeparatedValues = value.map(encodeValue).join(
569
- "%2C%20"
570
- /* ", " */
571
- );
572
- return "%5B" + commaSeparatedValues + /* "]" */
573
- "%5D";
574
- } else if (typeof value === "bigint") {
575
- return `${value}n`;
576
- } else {
577
- return encodeURIComponent(
578
- String(
579
- value != null && Object.getPrototypeOf(value) === null ? (
580
- // Plain objects with no prototype don't have a `toString` method.
581
- // Convert them before stringifying them.
582
- { ...value }
583
- ) : value
584
- )
585
- );
586
- }
587
- }
588
- function encodeObjectContextEntry([key, value]) {
589
- return `${key}=${encodeValue(value)}`;
590
- }
591
- function encodeContextObject(context) {
592
- const searchParamsString = Object.entries(context).map(encodeObjectContextEntry).join("&");
593
- return Buffer.from(searchParamsString, "utf8").toString("base64");
438
+ storeTokenForAlias(chainKey, token) {
439
+ const key = tokenKey(token);
440
+ const existingByKey = this._tokensByChainKey.get(chainKey) ?? /* @__PURE__ */ new Map();
441
+ existingByKey.set(key, token);
442
+ this._tokensByChainKey.set(chainKey, existingByKey);
443
+ this._tokensByChain.set(chainKey, Array.from(existingByKey.values()));
444
+ }
445
+ storeToken(token) {
446
+ const chainRef = token?.chainId;
447
+ if (chainRef == null) return;
448
+ const normalized = normalizeToken(token);
449
+ const resolvedChain = this.chain(chainRef);
450
+ const aliases = resolvedChain ? getChainAliases(resolvedChain) : [normalizeChainKey(chainRef)];
451
+ for (const alias of aliases) {
452
+ this.storeTokenForAlias(alias, normalized);
453
+ }
454
+ }
455
+ async loadChains() {
456
+ const chainsRes = await fetch(`${this.baseURL}/v1/routes/chains`, {
457
+ headers: { Accept: "application/json", "X-API-Key": this.config.apiKey }
458
+ });
459
+ if (!chainsRes.ok) throw new Error(`chains: HTTP ${chainsRes.status}`);
460
+ const chains = await chainsRes.json();
461
+ const chainsArr = Array.isArray(chains) ? chains : chains.data ?? [];
462
+ for (const chain of chainsArr) {
463
+ this.storeChain(chain);
464
+ }
465
+ this._chainsLoaded = true;
466
+ }
467
+ async loadAllTokens() {
468
+ await this.ensureChainsLoaded();
469
+ const tokensRes = await fetch(`${this.baseURL}/v1/routes/tokens`, {
470
+ headers: { Accept: "application/json", "X-API-Key": this.config.apiKey }
471
+ });
472
+ if (!tokensRes.ok) throw new Error(`tokens: HTTP ${tokensRes.status}`);
473
+ const tokens = await tokensRes.json();
474
+ const tokensArr = Array.isArray(tokens) ? tokens : tokens.data ?? [];
475
+ for (const token of tokensArr) {
476
+ this.storeToken(token);
477
+ }
478
+ this._loaded = true;
479
+ }
480
+ prunePageCache() {
481
+ const now = Date.now();
482
+ for (const [key, value] of this._pageCache.entries()) {
483
+ if (now - value.storedAt > PAGE_CACHE_TTL_MS) {
484
+ this._pageCache.delete(key);
485
+ }
486
+ }
487
+ while (this._pageCache.size > PAGE_CACHE_LIMIT) {
488
+ const oldestKey = this._pageCache.keys().next().value;
489
+ if (!oldestKey) {
490
+ break;
491
+ }
492
+ this._pageCache.delete(oldestKey);
493
+ }
494
+ }
495
+ pageCacheKey(chainRef, opts = {}) {
496
+ const chain = this.chain(chainRef);
497
+ const canonical = normalizeChainKey(chain?.chainId ?? chainRef);
498
+ return `${canonical}::${opts.q ?? ""}::${opts.limit ?? ""}::${opts.cursor ?? ""}`;
499
+ }
500
+ filterTokens(tokens, chainRef, query) {
501
+ const normalizedChain = normalizeChainKey(chainRef);
502
+ const normalizedQuery = query?.trim().toLowerCase();
503
+ return tokens.filter((token) => {
504
+ if (normalizeChainKey(token.chainId) !== normalizedChain) {
505
+ return false;
506
+ }
507
+ if (!normalizedQuery) {
508
+ return true;
509
+ }
510
+ return token.symbol?.toLowerCase().includes(normalizedQuery) || token.name?.toLowerCase().includes(normalizedQuery) || token.address?.toLowerCase().includes(normalizedQuery);
511
+ });
512
+ }
513
+ chains() {
514
+ return Array.from(this._chainsById.values());
515
+ }
516
+ chain(chainRef) {
517
+ const normalized = normalizeChainKey(chainRef);
518
+ const canonicalKey = this._chainAliases.get(normalized) ?? normalized;
519
+ return this._chainsById.get(canonicalKey);
520
+ }
521
+ allTokens() {
522
+ const unique = /* @__PURE__ */ new Map();
523
+ for (const list of this._tokensByChain.values()) {
524
+ for (const token of list) {
525
+ unique.set(tokenKey(token), token);
526
+ }
527
+ }
528
+ return Array.from(unique.values());
529
+ }
530
+ tokens(chainRef) {
531
+ return this._tokensByChain.get(normalizeChainKey(chainRef)) ?? [];
532
+ }
533
+ async tokensPage(chainRef, opts = {}) {
534
+ await this.ensureChainsLoaded();
535
+ if (!this.config.features.tokensPagination) {
536
+ await this.ensureLoaded();
537
+ const all = this.filterTokens(this.allTokens(), chainRef, opts.q);
538
+ const start = opts.cursor ? Number(opts.cursor) || 0 : 0;
539
+ const limit = opts.limit ?? all.length;
540
+ const data = all.slice(start, start + limit);
541
+ return {
542
+ data,
543
+ pageInfo: {
544
+ hasNextPage: start + limit < all.length,
545
+ nextCursor: start + limit < all.length ? String(start + limit) : void 0
546
+ }
547
+ };
548
+ }
549
+ const cacheKey = this.pageCacheKey(chainRef, opts);
550
+ const cached = this._pageCache.get(cacheKey);
551
+ if (cached && Date.now() - cached.storedAt <= PAGE_CACHE_TTL_MS) {
552
+ return { data: cached.data, pageInfo: cached.pageInfo };
553
+ }
554
+ const chain = this.chain(chainRef);
555
+ const chainKey = normalizeChainKey(chain?.chainId ?? chainRef);
556
+ const url = new URL(`${this.baseURL}/v1/routes/tokens`);
557
+ url.searchParams.set("chainId", chainKey);
558
+ if (opts.cursor) url.searchParams.set("cursor", opts.cursor);
559
+ if (opts.limit != null) url.searchParams.set("limit", String(opts.limit));
560
+ if (opts.q) url.searchParams.set("q", opts.q);
561
+ try {
562
+ const res = await fetch(url.toString(), {
563
+ headers: {
564
+ Accept: "application/json",
565
+ "X-API-Key": this.config.apiKey
566
+ }
567
+ });
568
+ if (!res.ok) {
569
+ throw new Error(`tokens page: HTTP ${res.status}`);
570
+ }
571
+ const parsed = parseTokenPage(await res.json());
572
+ const deduped = /* @__PURE__ */ new Map();
573
+ for (const token of parsed.data) {
574
+ const normalized = normalizeToken(token);
575
+ this.storeToken(normalized);
576
+ deduped.set(tokenKey(normalized), normalized);
577
+ }
578
+ const result = {
579
+ data: Array.from(deduped.values()),
580
+ pageInfo: parsed.pageInfo
581
+ };
582
+ this._pageCache.set(cacheKey, { ...result, storedAt: Date.now() });
583
+ this.prunePageCache();
584
+ this.emitPageLoaded(chainRef, opts.q, result, opts.cursor);
585
+ return result;
586
+ } catch (error) {
587
+ this.emitPageError(chainRef, opts.q, opts.cursor, error);
588
+ await this.ensureLoaded();
589
+ const fallback = this.filterTokens(this.allTokens(), chainRef, opts.q);
590
+ return {
591
+ data: fallback,
592
+ pageInfo: { hasNextPage: false }
593
+ };
594
+ }
595
+ }
596
+ async *iterateTokens(chainRef, opts = {}) {
597
+ let cursor;
598
+ do {
599
+ const page = await this.tokensPage(chainRef, { ...opts, cursor });
600
+ yield page;
601
+ cursor = page.pageInfo.nextCursor;
602
+ if (!page.pageInfo.hasNextPage) {
603
+ break;
604
+ }
605
+ } while (cursor);
606
+ }
607
+ findToken(chainRef, address) {
608
+ const chain = this.chain(chainRef);
609
+ const chainType = normalizeChainType(chain);
610
+ const normalizedAddress = normalizeAddress(address, chainType);
611
+ return this.tokens(chainRef).find((token) => {
612
+ return normalizeAddress(token.address, chainType) === normalizedAddress;
613
+ });
614
+ }
615
+ resolveToken(chainRef, input) {
616
+ if (!input) return void 0;
617
+ const s = String(input).trim();
618
+ const chain = this.chain(chainRef);
619
+ const chainType = normalizeChainType(chain);
620
+ if (/^0x[0-9a-fA-F]{40}$/.test(s)) return s;
621
+ if (chainType === "solana" && s.length > 20) return s;
622
+ const nativeAddress = getNativeTokenAddress(chainType);
623
+ const nativeSymbol = chain?.nativeCurrency?.symbol?.toUpperCase?.();
624
+ if (nativeSymbol && s.toUpperCase() === nativeSymbol || ["ETH", "MATIC", "AVAX", "BNB", "SOL", "NATIVE"].includes(s.toUpperCase())) {
625
+ return chainType === "solana" ? nativeAddress : NATIVE;
626
+ }
627
+ const hit = this.tokens(chainRef).find((token) => {
628
+ if (!token.symbol) return false;
629
+ return token.symbol.toUpperCase() === s.toUpperCase();
630
+ });
631
+ if (hit) return hit.address;
632
+ return s;
633
+ }
634
+ };
635
+ }
636
+ });
637
+
638
+ // node_modules/@solana/errors/dist/index.node.mjs
639
+ function encodeValue(value) {
640
+ if (Array.isArray(value)) {
641
+ const commaSeparatedValues = value.map(encodeValue).join(
642
+ "%2C%20"
643
+ /* ", " */
644
+ );
645
+ return "%5B" + commaSeparatedValues + /* "]" */
646
+ "%5D";
647
+ } else if (typeof value === "bigint") {
648
+ return `${value}n`;
649
+ } else {
650
+ return encodeURIComponent(
651
+ String(
652
+ value != null && Object.getPrototypeOf(value) === null ? (
653
+ // Plain objects with no prototype don't have a `toString` method.
654
+ // Convert them before stringifying them.
655
+ { ...value }
656
+ ) : value
657
+ )
658
+ );
659
+ }
660
+ }
661
+ function encodeObjectContextEntry([key, value]) {
662
+ return `${key}=${encodeValue(value)}`;
663
+ }
664
+ function encodeContextObject(context) {
665
+ const searchParamsString = Object.entries(context).map(encodeObjectContextEntry).join("&");
666
+ return Buffer.from(searchParamsString, "utf8").toString("base64");
594
667
  }
595
668
  function getHumanReadableErrorMessage(code, context = {}) {
596
669
  const messageFormatString = SolanaErrorMessages[code];
@@ -1376,86 +1449,17 @@ var init_index_node4 = __esm({
1376
1449
  }
1377
1450
  });
1378
1451
 
1379
- // src/utils/chains.ts
1380
- function inferChainTypeFromValue(normalized) {
1381
- if (!normalized) return void 0;
1382
- const aliased = CHAIN_TYPE_ALIASES[normalized];
1383
- if (aliased) return aliased;
1384
- if (normalized === "evm" || normalized === "solana" || normalized === "cosmos" || normalized === "bitcoin") {
1385
- return normalized;
1386
- }
1387
- if (/^eip155:\d+$/.test(normalized) || /^\d+$/.test(normalized)) {
1388
- return "evm";
1389
- }
1390
- if (normalized.startsWith("solana:") || normalized.includes("solana")) {
1391
- return "solana";
1452
+ // src/validation/address.ts
1453
+ function hasMixedCase(value) {
1454
+ return value !== value.toLowerCase() && value !== value.toUpperCase();
1455
+ }
1456
+ function validateBech32LikeAddress(address, prefix) {
1457
+ const trimmed = address.trim();
1458
+ if (!trimmed) {
1459
+ return { isValid: false, error: "Address is required." };
1392
1460
  }
1393
- if (normalized.startsWith("cosmos:") || normalized.startsWith("sei:") || normalized === "sei-evm") {
1394
- return "cosmos";
1395
- }
1396
- return void 0;
1397
- }
1398
- function normalizeChainKey(value) {
1399
- if (value === void 0 || value === null) return "";
1400
- return String(value).trim().toLowerCase();
1401
- }
1402
- function normalizeChainType(chain) {
1403
- if (!chain) return void 0;
1404
- const raw = typeof chain === "string" ? chain : chain.type ?? chain.chainType ?? chain.networkIdentifier ?? chain.chainId ?? chain.id ?? chain.networkName ?? chain.axelarChainName;
1405
- if (!raw) return void 0;
1406
- const normalized = String(raw).trim().toLowerCase();
1407
- return inferChainTypeFromValue(normalized) ?? normalized;
1408
- }
1409
- function getNativeTokenAddress(chainType) {
1410
- return normalizeChainType(chainType) === "solana" ? NATIVE_SOLANA : NATIVE_EVM;
1411
- }
1412
- function isSolanaNativeTokenAlias(address) {
1413
- if (!address) return false;
1414
- const trimmed = address.trim();
1415
- if (!trimmed) return false;
1416
- return trimmed === NATIVE_SOLANA || trimmed.toLowerCase() === NATIVE_EVM;
1417
- }
1418
- function normalizeAddress(address, chainType) {
1419
- const trimmed = address.trim();
1420
- if (normalizeChainType(chainType) === "solana") {
1421
- if (isSolanaNativeTokenAlias(trimmed)) {
1422
- return NATIVE_SOLANA;
1423
- }
1424
- return trimmed;
1425
- }
1426
- return trimmed.toLowerCase();
1427
- }
1428
- function isZeroAddressLike(address, chainType) {
1429
- if (!address) return true;
1430
- const normalized = normalizeAddress(address, chainType);
1431
- return normalized === normalizeAddress(getNativeTokenAddress(chainType), chainType) || normalized === "0x0000000000000000000000000000000000000000";
1432
- }
1433
- var NATIVE_EVM, NATIVE_SOLANA, CHAIN_TYPE_ALIASES;
1434
- var init_chains = __esm({
1435
- "src/utils/chains.ts"() {
1436
- "use strict";
1437
- NATIVE_EVM = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
1438
- NATIVE_SOLANA = "So11111111111111111111111111111111111111111";
1439
- CHAIN_TYPE_ALIASES = {
1440
- btc: "bitcoin",
1441
- bitcoin: "bitcoin",
1442
- sei: "cosmos",
1443
- "pacific-1": "cosmos"
1444
- };
1445
- }
1446
- });
1447
-
1448
- // src/validation/address.ts
1449
- function hasMixedCase(value) {
1450
- return value !== value.toLowerCase() && value !== value.toUpperCase();
1451
- }
1452
- function validateBech32LikeAddress(address, prefix) {
1453
- const trimmed = address.trim();
1454
- if (!trimmed) {
1455
- return { isValid: false, error: "Address is required." };
1456
- }
1457
- if (hasMixedCase(trimmed)) {
1458
- return { isValid: false, error: "Bech32 addresses cannot mix case." };
1461
+ if (hasMixedCase(trimmed)) {
1462
+ return { isValid: false, error: "Bech32 addresses cannot mix case." };
1459
1463
  }
1460
1464
  const lower = trimmed.toLowerCase();
1461
1465
  const expectedPrefix = `${prefix.toLowerCase()}1`;
@@ -1640,2088 +1644,2108 @@ var init_address = __esm({
1640
1644
  }
1641
1645
  });
1642
1646
 
1643
- // src/identity/index.ts
1644
- function normalizeIdentityChainId(chain) {
1645
- if (!chain || typeof chain === "string") return void 0;
1646
- const raw = chain.chainId ?? chain.id;
1647
- if (raw === void 0 || raw === null) return void 0;
1648
- const normalized = String(raw).trim();
1649
- return normalized || void 0;
1647
+ // src/core/balances.ts
1648
+ function toStringOrUndefined(value) {
1649
+ if (typeof value !== "string") return void 0;
1650
+ const trimmed = value.trim();
1651
+ return trimmed || void 0;
1650
1652
  }
1651
- function identityEntryMatchesChain(entry, chainType, chainKey, chainId) {
1652
- if (chainKey && entry.chainKey && entry.chainKey === chainKey) return true;
1653
- if (chainId && entry.chainId && entry.chainId === chainId) return true;
1654
- if (chainType && entry.chainType === chainType) return true;
1655
- return false;
1653
+ function toNumberOrUndefined(value) {
1654
+ if (typeof value === "number") {
1655
+ return Number.isFinite(value) ? value : void 0;
1656
+ }
1657
+ if (typeof value === "string") {
1658
+ const parsed = Number(value.trim());
1659
+ return Number.isFinite(parsed) ? parsed : void 0;
1660
+ }
1661
+ return void 0;
1656
1662
  }
1657
- function createWalletIdentity(addresses = []) {
1658
- return { addresses };
1663
+ function fallbackTokenSymbol(address, chainType) {
1664
+ if (chainType?.toLowerCase() === "solana") {
1665
+ return "SPL";
1666
+ }
1667
+ return `TOKEN-${address.slice(0, 6)}`;
1659
1668
  }
1660
- function upsertWalletIdentityAddress(identity, next) {
1661
- const normalizedAddress = next.address.trim();
1662
- const normalizedChainKey = next.chainKey ? normalizeChainKey(next.chainKey) : void 0;
1663
- const normalizedChainId = next.chainId?.trim() || void 0;
1664
- const addresses = identity.addresses.filter((entry) => {
1665
- if (entry.chainType !== next.chainType) return true;
1666
- if (normalizedChainKey && entry.chainKey === normalizedChainKey)
1667
- return false;
1668
- if (normalizedChainId && entry.chainId === normalizedChainId) return false;
1669
- if (!normalizedChainKey && !normalizedChainId) return false;
1670
- return true;
1669
+ function emitBalanceStreamChunk(address, chunkSize) {
1670
+ TrustwareConfigStore.get().onEvent?.({
1671
+ type: "balance_stream_chunk",
1672
+ address,
1673
+ chunkSize
1671
1674
  });
1672
- if (!normalizedAddress) return createWalletIdentity(addresses);
1673
- return createWalletIdentity([
1674
- ...addresses,
1675
- {
1676
- ...next,
1677
- address: normalizedAddress,
1678
- chainKey: normalizedChainKey,
1679
- chainId: normalizedChainId
1680
- }
1681
- ]);
1682
1675
  }
1683
- function resolveWalletAddressForChain(identity, chain) {
1676
+ function emitBalanceStreamFallback(address, error) {
1677
+ const message = error instanceof Error ? error.message : String(error);
1678
+ TrustwareConfigStore.get().onEvent?.({
1679
+ type: "balance_stream_fallback",
1680
+ address,
1681
+ message
1682
+ });
1683
+ }
1684
+ function normalizeRows(rows, chain, address, registry) {
1685
+ const chainKey = chain.networkIdentifier ?? String(chain.chainId ?? chain.id);
1684
1686
  const chainType = normalizeChainType(chain);
1685
- const chainDef = typeof chain === "object" && chain ? chain : void 0;
1686
- const chainKey = chainDef ? normalizeChainKey(
1687
- chainDef.networkIdentifier ?? chainDef.chainId ?? chainDef.id
1688
- ) : typeof chain === "string" ? normalizeChainKey(chain) : void 0;
1689
- const chainId = normalizeIdentityChainId(chain);
1690
- if (!chainType) {
1691
- return {
1692
- status: "missing",
1693
- reason: "unknown_chain_type",
1694
- chainKey,
1695
- chainId
1696
- };
1697
- }
1698
- const match = identity.addresses.find(
1699
- (entry) => identityEntryMatchesChain(entry, chainType, chainKey, chainId)
1700
- );
1701
- if (!match) {
1702
- return {
1703
- status: "missing",
1704
- reason: "missing_chain_address",
1705
- chainType,
1706
- chainKey,
1707
- chainId
1708
- };
1687
+ const nativeAddress = getNativeTokenAddress(chainType);
1688
+ const map = /* @__PURE__ */ new Map();
1689
+ for (const item of rows) {
1690
+ const category = toStringOrUndefined(item.category)?.toLowerCase();
1691
+ const addressRaw = item.contract ?? item.token_address ?? item.address ?? item.addr;
1692
+ const tokenAddress = typeof addressRaw === "string" ? addressRaw.trim() : void 0;
1693
+ const symbol = toStringOrUndefined(item.symbol ?? item.sym);
1694
+ const name = toStringOrUndefined(item.name ?? item.token_name ?? item.token) ?? symbol;
1695
+ const decimals = toNumberOrUndefined(item.decimals ?? item.dec);
1696
+ const balance = String(item.balance ?? item.bal ?? "0");
1697
+ const explicitNative = Boolean(item.native ?? item.is_native);
1698
+ const nativeFlag = explicitNative || category === "native" || isZeroAddressLike(tokenAddress, chainType);
1699
+ if (nativeFlag) {
1700
+ const nativeRow = {
1701
+ chain_key: chainKey,
1702
+ category: "native",
1703
+ contract: nativeAddress,
1704
+ address: nativeAddress,
1705
+ symbol: symbol ?? chain.nativeCurrency?.symbol ?? "NATIVE",
1706
+ name: name ?? chain.nativeCurrency?.name ?? symbol,
1707
+ decimals: decimals ?? chain.nativeCurrency?.decimals ?? 18,
1708
+ balance
1709
+ };
1710
+ map.set(`${chainKey}:${nativeAddress}`, nativeRow);
1711
+ continue;
1712
+ }
1713
+ if (!tokenAddress || decimals === void 0) continue;
1714
+ const metadata = registry.findToken(chain.chainId, tokenAddress);
1715
+ const displaySymbol = symbol ?? metadata?.symbol ?? fallbackTokenSymbol(tokenAddress, chainType);
1716
+ const displayName = name ?? metadata?.name ?? displaySymbol;
1717
+ const normalizedAddress = metadata?.address ?? tokenAddress;
1718
+ map.set(`${chainKey}:${normalizedAddress}`, {
1719
+ chain_key: chainKey,
1720
+ category: category ?? (chainType === "solana" ? "spl" : "erc20"),
1721
+ contract: normalizedAddress,
1722
+ address: normalizedAddress,
1723
+ symbol: displaySymbol,
1724
+ name: displayName,
1725
+ decimals: metadata?.decimals ?? decimals,
1726
+ balance,
1727
+ logoURI: metadata?.logoURI,
1728
+ usdPrice: metadata?.usdPrice
1729
+ });
1709
1730
  }
1710
- const validation = validateAddressForChain(
1711
- match.address,
1712
- chainDef ?? chainType
1713
- );
1714
- if (!validation.isValid) {
1715
- return {
1716
- status: "invalid",
1717
- reason: validation.error ?? "invalid_chain_address",
1718
- address: match.address,
1719
- source: match.source,
1720
- chainType,
1721
- chainKey,
1722
- chainId
1723
- };
1731
+ if (!Array.from(map.values()).some((row) => row.category === "native")) {
1732
+ map.set(`${chainKey}:${nativeAddress}`, {
1733
+ chain_key: chainKey,
1734
+ category: "native",
1735
+ contract: nativeAddress,
1736
+ address: nativeAddress,
1737
+ symbol: chain.nativeCurrency?.symbol ?? "NATIVE",
1738
+ name: chain.nativeCurrency?.name ?? chain.nativeCurrency?.symbol,
1739
+ decimals: chain.nativeCurrency?.decimals ?? 18,
1740
+ balance: "0"
1741
+ });
1724
1742
  }
1725
- return {
1726
- status: "resolved",
1727
- address: match.address.trim(),
1728
- source: match.source,
1729
- chainType,
1730
- chainKey,
1731
- chainId
1732
- };
1743
+ return Array.from(map.values()).sort((a, b) => {
1744
+ try {
1745
+ return Number(BigInt(b.balance) - BigInt(a.balance));
1746
+ } catch {
1747
+ return 0;
1748
+ }
1749
+ });
1733
1750
  }
1734
- function buildWalletIdentityAddress(params) {
1735
- const chainType = normalizeChainType(params.chain);
1736
- if (!chainType) return null;
1737
- const address = params.address.trim();
1738
- const chainId = normalizeIdentityChainId(params.chain);
1739
- const chainDef = typeof params.chain === "object" && params.chain ? params.chain : void 0;
1740
- const chainKey = chainDef ? normalizeChainKey(
1741
- chainDef.networkIdentifier ?? chainDef.chainId ?? chainDef.id
1742
- ) : void 0;
1743
- return {
1744
- address,
1745
- chainType,
1746
- chainId,
1747
- chainKey,
1748
- providerId: params.providerId,
1749
- source: params.source
1750
- };
1751
+ function normalizeStreamChunk(chunk) {
1752
+ return Array.isArray(chunk) ? chunk : [chunk];
1751
1753
  }
1752
- var IdentityStore;
1753
- var init_identity = __esm({
1754
- "src/identity/index.ts"() {
1755
- "use strict";
1756
- init_address();
1757
- init_chains();
1758
- IdentityStore = class {
1759
- constructor() {
1760
- this._identity = createWalletIdentity();
1761
- }
1762
- get snapshot() {
1763
- return this._identity;
1764
- }
1765
- reset() {
1766
- this._identity = createWalletIdentity();
1767
- }
1768
- upsert(next) {
1769
- this._identity = upsertWalletIdentityAddress(this._identity, next);
1770
- return this._identity;
1754
+ function mergeBalanceWrappers(current, incoming) {
1755
+ const merged = /* @__PURE__ */ new Map();
1756
+ for (const item of current) {
1757
+ merged.set(item.chain_id, item);
1758
+ }
1759
+ for (const item of incoming) {
1760
+ const existing = merged.get(item.chain_id);
1761
+ if (!existing) {
1762
+ merged.set(item.chain_id, item);
1763
+ continue;
1764
+ }
1765
+ const balancesByKey = /* @__PURE__ */ new Map();
1766
+ for (const row of existing.balances ?? []) {
1767
+ balancesByKey.set(`${row.contract ?? row.address ?? row.symbol}`, row);
1768
+ }
1769
+ for (const row of item.balances ?? []) {
1770
+ balancesByKey.set(`${row.contract ?? row.address ?? row.symbol}`, row);
1771
+ }
1772
+ merged.set(item.chain_id, {
1773
+ ...existing,
1774
+ ...item,
1775
+ balances: Array.from(balancesByKey.values()),
1776
+ count: item.count ?? existing.count
1777
+ });
1778
+ }
1779
+ return Array.from(merged.values());
1780
+ }
1781
+ async function parseStreamingBalances(response, address, options = {}) {
1782
+ if (!response.body) {
1783
+ throw new Error("balances stream: empty response body");
1784
+ }
1785
+ const decoder = new TextDecoder();
1786
+ const reader = response.body.getReader();
1787
+ async function* stream() {
1788
+ let buffer = "";
1789
+ try {
1790
+ while (true) {
1791
+ const { value, done } = await reader.read();
1792
+ if (done) break;
1793
+ buffer += decoder.decode(value, { stream: true });
1794
+ const frames = buffer.split(/\r?\n/);
1795
+ buffer = frames.pop() ?? "";
1796
+ for (const frame of frames) {
1797
+ const trimmed = frame.trim();
1798
+ if (!trimmed) continue;
1799
+ try {
1800
+ const parsed = JSON.parse(trimmed);
1801
+ if (!parsed.chain_id) continue;
1802
+ const chunk = normalizeStreamChunk(parsed);
1803
+ emitBalanceStreamChunk(address, chunk.length);
1804
+ yield chunk;
1805
+ } catch (error) {
1806
+ if (options.strict) {
1807
+ throw error;
1808
+ }
1809
+ }
1810
+ }
1771
1811
  }
1772
- resolve(chain) {
1773
- return resolveWalletAddressForChain(this._identity, chain);
1812
+ const tail = buffer.trim();
1813
+ if (tail) {
1814
+ try {
1815
+ const parsed = JSON.parse(tail);
1816
+ if (parsed.chain_id) {
1817
+ const chunk = normalizeStreamChunk(parsed);
1818
+ emitBalanceStreamChunk(address, chunk.length);
1819
+ yield chunk;
1820
+ }
1821
+ } catch (error) {
1822
+ if (options.strict) {
1823
+ throw error;
1824
+ }
1825
+ }
1774
1826
  }
1775
- };
1827
+ } finally {
1828
+ reader.releaseLock();
1829
+ }
1776
1830
  }
1777
- });
1778
-
1779
- // src/config/walletconnect.ts
1780
- function resolvedMetadata() {
1781
- const cfg = TrustwareConfigStore.peek();
1782
- const walletConnect = cfg ? cfg?.walletConnect : void 0;
1783
- const configured = walletConnect?.metadata;
1784
- const pageUrl = typeof window !== "undefined" && window.location?.origin ? window.location.origin : configured?.url;
1785
- if (!pageUrl) {
1786
- console.warn(
1787
- "[Trustware SDK] WalletConnect metadata.url could not be determined from window.location or config. Falling back to 'https://trustware.io'. Pass metadata.url explicitly in your WalletConnectConfig to avoid domain verification failures in production."
1788
- );
1831
+ return stream();
1832
+ }
1833
+ async function getBalances(chainRef, address) {
1834
+ const reg = await ensureRegistry();
1835
+ const chain = reg.chain(chainRef);
1836
+ if (!chain) return [];
1837
+ const trimmedAddress = address.trim();
1838
+ const validation = validateAddressForChain(trimmedAddress, chain);
1839
+ if (!validation.isValid) return [];
1840
+ const chainKey = chain.networkIdentifier ?? String(chain.chainId ?? chain.id);
1841
+ const cacheKey = [
1842
+ chainKey,
1843
+ trimmedAddress,
1844
+ chain.nativeCurrency?.symbol ?? "",
1845
+ chain.nativeCurrency?.decimals ?? "",
1846
+ normalizeChainType(chain) ?? ""
1847
+ ].join(":");
1848
+ const cached = balanceCache.get(cacheKey);
1849
+ if (cached) return cached;
1850
+ const url = `${apiBase()}/v1/data/wallets/${encodeURIComponent(chainKey)}/${trimmedAddress}/balances`;
1851
+ const response = await fetch(url, {
1852
+ method: "GET",
1853
+ credentials: "omit",
1854
+ headers: jsonHeaders()
1855
+ });
1856
+ if (!response.ok) throw new Error(`balances: HTTP ${response.status}`);
1857
+ const json = await response.json();
1858
+ const rows = Array.isArray(json) ? json : json.data ?? [];
1859
+ const normalized = normalizeRows(rows, chain, trimmedAddress, reg);
1860
+ balanceCache.set(cacheKey, normalized);
1861
+ return normalized;
1862
+ }
1863
+ async function getBalancesByAddress(address, opts) {
1864
+ if (opts?.stream && TrustwareConfigStore.get().features.balanceStreaming) {
1865
+ const merged = [];
1866
+ for await (const chunk of getBalancesByAddressStream(address, opts)) {
1867
+ const next = mergeBalanceWrappers(merged, chunk);
1868
+ merged.splice(0, merged.length, ...next);
1869
+ }
1870
+ return merged;
1789
1871
  }
1790
- return {
1791
- name: configured?.name ?? "Trustware",
1792
- description: configured?.description ?? "Cross-chain bridge & top-up",
1793
- url: pageUrl ?? "https://trustware.io",
1794
- icons: configured?.icons?.length ? configured.icons : ["https://app.trustware.io/icon.png"]
1795
- };
1872
+ const url = `${apiBase()}/data/balances/${address}`;
1873
+ const r = await rateLimitedFetch(url, {
1874
+ method: "GET",
1875
+ credentials: "omit",
1876
+ headers: jsonHeaders()
1877
+ });
1878
+ if (!r.ok) throw new Error(`balances: HTTP ${r.status}`);
1879
+ const j = await r.json();
1880
+ return Array.isArray(j) ? j : j.results ?? [];
1796
1881
  }
1797
- async function getUniversalConnector(walletCfg) {
1798
- const projectId = walletCfg?.projectId ?? WALLETCONNECT_PROJECT_ID;
1799
- if (universalConnectorPromise && initializedProjectId !== projectId) {
1800
- console.warn(
1801
- "[Trustware SDK] projectId changed since last init \u2014 reinitializing WalletConnect connector."
1802
- );
1803
- universalConnectorPromise = null;
1804
- initializedProjectId = null;
1882
+ async function* getBalancesByAddressStream(address, opts = {}) {
1883
+ if (!TrustwareConfigStore.get().features.balanceStreaming) {
1884
+ yield await getBalancesByAddress(address);
1885
+ return;
1805
1886
  }
1806
- if (!universalConnectorPromise) {
1807
- initializedProjectId = projectId;
1808
- universalConnectorPromise = import_appkit_universal_connector.UniversalConnector.init({
1809
- projectId,
1810
- metadata: resolvedMetadata(),
1811
- networks: namespaceConfig
1812
- }).catch((error) => {
1813
- universalConnectorPromise = null;
1814
- initializedProjectId = null;
1815
- console.error(
1816
- "[Trustware SDK] Failed to initialize WalletConnect:",
1817
- error
1818
- );
1819
- throw error;
1887
+ const url = `${apiBase()}/data/balances/${address}?stream=1`;
1888
+ try {
1889
+ const response = await rateLimitedFetch(url, {
1890
+ method: "GET",
1891
+ credentials: "omit",
1892
+ headers: jsonHeaders({
1893
+ Accept: "application/x-ndjson, application/json"
1894
+ }),
1895
+ signal: opts.signal
1820
1896
  });
1897
+ if (!response.ok) {
1898
+ throw new Error(`balances stream: HTTP ${response.status}`);
1899
+ }
1900
+ const contentType = response.headers.get("content-type") ?? "";
1901
+ if (contentType.includes("application/json")) {
1902
+ const payload = await response.json();
1903
+ yield Array.isArray(payload) ? payload : payload.results ?? [];
1904
+ return;
1905
+ }
1906
+ const stream = await parseStreamingBalances(response, address, opts);
1907
+ for await (const chunk of stream) {
1908
+ yield chunk;
1909
+ }
1910
+ } catch (error) {
1911
+ emitBalanceStreamFallback(address, error);
1912
+ yield await getBalancesByAddress(address);
1821
1913
  }
1822
- return universalConnectorPromise;
1823
1914
  }
1824
- function resetUniversalConnector() {
1825
- universalConnectorPromise = null;
1826
- initializedProjectId = null;
1915
+ async function ensureRegistry() {
1916
+ if (!_registry) {
1917
+ _registry = new Registry(apiBase());
1918
+ }
1919
+ await _registry.ensureLoaded();
1920
+ return _registry;
1827
1921
  }
1828
- var import_appkit_universal_connector, solanaMainnet, bitcoinMainnet, seiCosmosMainnet, ethereumMainnet, optimismMainnet, flareMainnet, cronosMainnet, rootstockMainnet, telosMainnet, xdcMainnet, bscMainnet, victionMainnet, gnosisMainnet, fuseMainnet, unichainMainnet, polygonMainnet, monadMainnet, sonicMainnet, opBnbMainnet, lensMainnet, fantomMainnet, fraxtalMainnet, bobaMainnet, hederaMainnet, filecoinMainnet, zkSyncMainnet, worldchainMainnet, flowMainnet, stableMainnet, hyperEvmMainnet, metisMainnet, liskMainnet, moonbeamMainnet, seiMainnet, hyperliquidMainnet, vanaMainnet, gravityMainnet, pharosMainnet, soneiumMainnet, swellchainMainnet, roninMainnet, kavaEvmMainnet, abstractMainnet, morphMainnet, peaqMainnet, tempoMainnet, megaEthMainnet, mantleMainnet, somniaMainnet, kaiaMainnet, baseMainnet, plasmaMainnet, immutableZkEvmMainnet, apechainMainnet, modeMainnet, arbitrumMainnet, arbitrumNovaMainnet, celoMainnet, etherlinkMainnet, hemiMainnet, avalancheMainnet, sophonMainnet, superpositionMainnet, inkMainnet, lineaMainnet, bobMainnet, berachainMainnet, blastMainnet, plumeMainnet, taikoMainnet, scrollMainnet, katanaMainnet, cornMainnet, evmChains, solanaChains, bitcoinChains, cosmosChains, networks, namespaceConfig, universalConnectorPromise, initializedProjectId;
1829
- var init_walletconnect = __esm({
1830
- "src/config/walletconnect.ts"() {
1922
+ var balanceCache, _registry;
1923
+ var init_balances = __esm({
1924
+ "src/core/balances.ts"() {
1831
1925
  "use strict";
1832
- import_appkit_universal_connector = require("@reown/appkit-universal-connector");
1926
+ init_http();
1927
+ init_registry();
1833
1928
  init_store();
1834
- init_constants();
1835
- solanaMainnet = {
1836
- id: 900,
1837
- chainNamespace: "solana",
1838
- caipNetworkId: "solana:5eykt4UsFv8P8NJdTREpY1vzqAQ3H1FQ",
1839
- name: "Solana Mainnet",
1840
- nativeCurrency: {
1841
- name: "Solana",
1842
- symbol: "SOL",
1843
- decimals: 9
1844
- },
1845
- rpcUrls: {
1846
- default: {
1847
- http: ["https://api.mainnet-beta.solana.com"]
1848
- }
1849
- }
1850
- };
1851
- bitcoinMainnet = {
1852
- id: 8333,
1853
- chainNamespace: "bip122",
1854
- caipNetworkId: "bip122:000000000019d6689c085ae165831e93",
1855
- name: "Bitcoin Mainnet",
1856
- nativeCurrency: {
1857
- name: "Bitcoin",
1858
- symbol: "BTC",
1859
- decimals: 8
1860
- },
1861
- rpcUrls: {
1862
- default: {
1863
- http: ["https://api.blockcypher.com/v1/btc/main"]
1929
+ init_chains();
1930
+ init_address();
1931
+ balanceCache = /* @__PURE__ */ new Map();
1932
+ }
1933
+ });
1934
+
1935
+ // src/wallets/eipWallets.ts
1936
+ async function addThenSwitch(eth, chainId) {
1937
+ const p = CHAIN_PARAMS[chainId];
1938
+ if (!p) throw new Error(`Unknown chain ${chainId} (no params to add)`);
1939
+ await eth.request({ method: "wallet_addEthereumChain", params: [p] });
1940
+ await eth.request({
1941
+ method: "wallet_switchEthereumChain",
1942
+ params: [{ chainId: p.chainIdHex }]
1943
+ });
1944
+ }
1945
+ function useEIP1193(eth) {
1946
+ if (!eth?.request) throw new Error("useEIP1193: invalid provider");
1947
+ let switching = false;
1948
+ return {
1949
+ ecosystem: "evm",
1950
+ type: "eip1193",
1951
+ async getAddress() {
1952
+ const [a] = await eth.request({
1953
+ method: "eth_requestAccounts"
1954
+ });
1955
+ if (!a) throw new Error("No connected address");
1956
+ return a;
1957
+ },
1958
+ async getChainId() {
1959
+ const hex = await eth.request({ method: "eth_chainId" });
1960
+ return parseInt(String(hex), 16);
1961
+ },
1962
+ async switchChain(chainId) {
1963
+ if (switching) return;
1964
+ switching = true;
1965
+ const hex = CHAIN_PARAMS[chainId]?.chainIdHex ?? `0x${chainId.toString(16)}`;
1966
+ try {
1967
+ await eth.request({
1968
+ method: "wallet_switchEthereumChain",
1969
+ params: [{ chainId: hex }]
1970
+ });
1971
+ } catch (e2) {
1972
+ if (e2?.code === 4902) {
1973
+ await addThenSwitch(eth, chainId);
1974
+ } else if (e2?.code === 4001) {
1975
+ } else {
1976
+ throw e2;
1864
1977
  }
1978
+ } finally {
1979
+ switching = false;
1865
1980
  }
1866
- };
1867
- seiCosmosMainnet = {
1868
- id: 9001,
1869
- chainNamespace: "cosmos",
1870
- caipNetworkId: "cosmos:pacific-1",
1871
- name: "Sei Cosmos",
1872
- nativeCurrency: { name: "Sei", symbol: "SEI", decimals: 6 },
1873
- rpcUrls: {
1874
- default: { http: ["https://rpc.sei-apis.com"] }
1875
- }
1876
- };
1877
- ethereumMainnet = {
1878
- id: 1,
1879
- chainNamespace: "eip155",
1880
- caipNetworkId: "eip155:1",
1881
- name: "Ethereum Mainnet",
1882
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
1883
- rpcUrls: {
1884
- default: { http: ["https://rpc.ankr.com/eth"] }
1885
- }
1886
- };
1887
- optimismMainnet = {
1888
- id: 10,
1889
- chainNamespace: "eip155",
1890
- caipNetworkId: "eip155:10",
1891
- name: "Optimism Mainnet",
1892
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
1893
- rpcUrls: {
1894
- default: { http: ["https://rpc.ankr.com/optimism"] }
1895
- }
1896
- };
1897
- flareMainnet = {
1898
- id: 14,
1899
- chainNamespace: "eip155",
1900
- caipNetworkId: "eip155:14",
1901
- name: "Flare",
1902
- nativeCurrency: { name: "Flare", symbol: "FLR", decimals: 18 },
1903
- rpcUrls: {
1904
- default: { http: ["https://flare-api.flare.network/ext/C/rpc"] }
1905
- }
1906
- };
1907
- cronosMainnet = {
1908
- id: 25,
1909
- chainNamespace: "eip155",
1910
- caipNetworkId: "eip155:25",
1911
- name: "Cronos",
1912
- nativeCurrency: { name: "Cronos", symbol: "CRO", decimals: 18 },
1913
- rpcUrls: {
1914
- default: { http: ["https://evm.cronos.org"] }
1915
- }
1916
- };
1917
- rootstockMainnet = {
1918
- id: 30,
1919
- chainNamespace: "eip155",
1920
- caipNetworkId: "eip155:30",
1921
- name: "Rootstock",
1922
- nativeCurrency: {
1923
- name: "Rootstock Smart Bitcoin",
1924
- symbol: "RBTC",
1925
- decimals: 18
1981
+ },
1982
+ request: (args) => eth.request(args)
1983
+ };
1984
+ }
1985
+ var CHAIN_PARAMS;
1986
+ var init_eipWallets = __esm({
1987
+ "src/wallets/eipWallets.ts"() {
1988
+ "use strict";
1989
+ CHAIN_PARAMS = {
1990
+ 8453: {
1991
+ chainIdHex: "0x2105",
1992
+ chainName: "Base",
1993
+ rpcUrls: ["https://mainnet.base.org"],
1994
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
1995
+ blockExplorerUrls: ["https://basescan.org"]
1926
1996
  },
1927
- rpcUrls: {
1928
- default: { http: ["https://public-node.rsk.co"] }
1929
- }
1930
- };
1931
- telosMainnet = {
1932
- id: 40,
1933
- chainNamespace: "eip155",
1934
- caipNetworkId: "eip155:40",
1935
- name: "Telos",
1936
- nativeCurrency: { name: "Telos", symbol: "TLOS", decimals: 18 },
1937
- rpcUrls: {
1938
- default: { http: ["https://rpc.telos.net"] }
1939
- }
1940
- };
1941
- xdcMainnet = {
1942
- id: 50,
1943
- chainNamespace: "eip155",
1944
- caipNetworkId: "eip155:50",
1945
- name: "XDC",
1946
- nativeCurrency: { name: "XDC", symbol: "XDC", decimals: 18 },
1947
- rpcUrls: {
1948
- default: { http: ["https://rpc.xdcrpc.com"] }
1949
- }
1950
- };
1951
- bscMainnet = {
1952
- id: 56,
1953
- chainNamespace: "eip155",
1954
- caipNetworkId: "eip155:56",
1955
- name: "BNB Smart Chain",
1956
- nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 },
1957
- rpcUrls: {
1958
- default: { http: ["https://rpc.ankr.com/bsc"] }
1959
- }
1960
- };
1961
- victionMainnet = {
1962
- id: 88,
1963
- chainNamespace: "eip155",
1964
- caipNetworkId: "eip155:88",
1965
- name: "Viction",
1966
- nativeCurrency: { name: "Viction", symbol: "VIC", decimals: 18 },
1967
- rpcUrls: {
1968
- default: { http: ["https://rpc.viction.xyz"] }
1969
- }
1970
- };
1971
- gnosisMainnet = {
1972
- id: 100,
1973
- chainNamespace: "eip155",
1974
- caipNetworkId: "eip155:100",
1975
- name: "Gnosis Chain",
1976
- nativeCurrency: { name: "xDAI", symbol: "XDAI", decimals: 18 },
1977
- rpcUrls: {
1978
- default: { http: ["https://rpc.ankr.com/gnosis"] }
1997
+ 42161: {
1998
+ chainIdHex: "0xa4b1",
1999
+ chainName: "Arbitrum One",
2000
+ rpcUrls: ["https://arb1.arbitrum.io/rpc"],
2001
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2002
+ blockExplorerUrls: ["https://arbiscan.io"]
2003
+ },
2004
+ 43114: {
2005
+ chainIdHex: "0xa86a",
2006
+ chainName: "Avalanche C-Chain",
2007
+ rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"],
2008
+ nativeCurrency: { name: "Avalanche", symbol: "AVAX", decimals: 18 },
2009
+ blockExplorerUrls: ["https://snowtrace.io"]
1979
2010
  }
1980
2011
  };
1981
- fuseMainnet = {
1982
- id: 122,
1983
- chainNamespace: "eip155",
1984
- caipNetworkId: "eip155:122",
1985
- name: "FUSE",
1986
- nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 },
1987
- rpcUrls: {
1988
- default: { http: ["https://rpc.fuse.io"] }
2012
+ }
2013
+ });
2014
+
2015
+ // src/core/sdkRpc.ts
2016
+ async function requestSDKRPC(path, init = {}) {
2017
+ const response = await rateLimitedFetch(`${apiBase()}/v1/sdk/rpc${path}`, {
2018
+ ...init,
2019
+ headers: jsonHeaders()
2020
+ });
2021
+ let payload = null;
2022
+ try {
2023
+ payload = await response.json();
2024
+ } catch {
2025
+ payload = null;
2026
+ }
2027
+ if (response.ok && payload?.success && payload.data !== void 0) {
2028
+ return payload.data;
2029
+ }
2030
+ throw new SDKRPCError(
2031
+ payload?.error?.message || `HTTP ${response.status}: ${response.statusText || "SDK RPC request failed"}`,
2032
+ {
2033
+ code: payload?.error?.code,
2034
+ context: payload?.error?.context,
2035
+ status: response.status
2036
+ }
2037
+ );
2038
+ }
2039
+ async function sendSolanaSerialized(body) {
2040
+ return requestSDKRPC(
2041
+ "/solana/send-serialized",
2042
+ {
2043
+ method: "POST",
2044
+ body: JSON.stringify(body)
2045
+ }
2046
+ );
2047
+ }
2048
+ async function getSolanaTxStatus(params) {
2049
+ const search = new URLSearchParams(params);
2050
+ return requestSDKRPC(
2051
+ `/solana/tx-status?${search.toString()}`,
2052
+ { method: "GET" }
2053
+ );
2054
+ }
2055
+ var SDKRPCError;
2056
+ var init_sdkRpc = __esm({
2057
+ "src/core/sdkRpc.ts"() {
2058
+ "use strict";
2059
+ init_http();
2060
+ SDKRPCError = class extends Error {
2061
+ constructor(message, options) {
2062
+ super(message);
2063
+ this.name = "SDKRPCError";
2064
+ this.code = options?.code;
2065
+ this.context = options?.context;
2066
+ this.status = options?.status;
1989
2067
  }
1990
2068
  };
1991
- unichainMainnet = {
1992
- id: 130,
1993
- chainNamespace: "eip155",
1994
- caipNetworkId: "eip155:130",
1995
- name: "Unichain",
1996
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
1997
- rpcUrls: {
1998
- default: { http: ["https://mainnet.unichain.org"] }
1999
- }
2000
- };
2001
- polygonMainnet = {
2002
- id: 137,
2003
- chainNamespace: "eip155",
2004
- caipNetworkId: "eip155:137",
2005
- name: "Polygon Mainnet",
2006
- nativeCurrency: { name: "POL", symbol: "POL", decimals: 18 },
2007
- rpcUrls: {
2008
- default: { http: ["https://rpc.ankr.com/polygon"] }
2009
- }
2010
- };
2011
- monadMainnet = {
2012
- id: 143,
2013
- chainNamespace: "eip155",
2014
- caipNetworkId: "eip155:143",
2015
- name: "MONAD",
2016
- nativeCurrency: { name: "Mon", symbol: "MON", decimals: 18 },
2017
- rpcUrls: {
2018
- default: { http: ["https://rpc.monad.xyz/"] }
2019
- }
2020
- };
2021
- sonicMainnet = {
2022
- id: 146,
2023
- chainNamespace: "eip155",
2024
- caipNetworkId: "eip155:146",
2025
- name: "Sonic",
2026
- nativeCurrency: { name: "Sonic", symbol: "S", decimals: 18 },
2027
- rpcUrls: {
2028
- default: { http: ["https://rpc.soniclabs.com"] }
2029
- }
2030
- };
2031
- opBnbMainnet = {
2032
- id: 204,
2033
- chainNamespace: "eip155",
2034
- caipNetworkId: "eip155:204",
2035
- name: "opBNB",
2036
- nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 },
2037
- rpcUrls: {
2038
- default: { http: ["https://opbnb-mainnet-rpc.bnbchain.org"] }
2039
- }
2040
- };
2041
- lensMainnet = {
2042
- id: 232,
2043
- chainNamespace: "eip155",
2044
- caipNetworkId: "eip155:232",
2045
- name: "Lens",
2046
- nativeCurrency: { name: "GHO", symbol: "GHO", decimals: 18 },
2047
- rpcUrls: {
2048
- default: { http: ["https://api.lens.matterhosted.dev"] }
2049
- }
2050
- };
2051
- fantomMainnet = {
2052
- id: 250,
2053
- chainNamespace: "eip155",
2054
- caipNetworkId: "eip155:250",
2055
- name: "Fantom Opera",
2056
- nativeCurrency: { name: "Fantom", symbol: "FTM", decimals: 18 },
2057
- rpcUrls: {
2058
- default: { http: ["https://rpc.ankr.com/fantom"] }
2059
- }
2060
- };
2061
- fraxtalMainnet = {
2062
- id: 252,
2063
- chainNamespace: "eip155",
2064
- caipNetworkId: "eip155:252",
2065
- name: "Fraxtal",
2066
- nativeCurrency: { name: "FRAX", symbol: "FRAX", decimals: 18 },
2067
- rpcUrls: {
2068
- default: { http: ["https://rpc.frax.com"] }
2069
+ }
2070
+ });
2071
+
2072
+ // src/wallets/solana.ts
2073
+ function getPublicKeyString(provider) {
2074
+ const publicKey = provider?.publicKey;
2075
+ if (!publicKey) return null;
2076
+ const text = publicKey.toString().trim();
2077
+ return text || null;
2078
+ }
2079
+ function decodeBase64(serializedTransaction) {
2080
+ const trimmed = serializedTransaction.trim();
2081
+ if (typeof Buffer !== "undefined") {
2082
+ return Uint8Array.from(Buffer.from(trimmed, "base64"));
2083
+ }
2084
+ const binary = globalThis.atob(trimmed);
2085
+ return Uint8Array.from(binary, (char) => char.charCodeAt(0));
2086
+ }
2087
+ async function decodeBase64Transaction(serializedTransaction) {
2088
+ const bytes = decodeBase64(serializedTransaction);
2089
+ const { Transaction, VersionedTransaction } = await import("@solana/web3.js");
2090
+ try {
2091
+ return VersionedTransaction.deserialize(bytes);
2092
+ } catch {
2093
+ return Transaction.from(bytes);
2094
+ }
2095
+ }
2096
+ function encodeBase64(bytes) {
2097
+ if (typeof Buffer !== "undefined") {
2098
+ return Buffer.from(bytes).toString("base64");
2099
+ }
2100
+ let binary = "";
2101
+ for (const byte of bytes) {
2102
+ binary += String.fromCharCode(byte);
2103
+ }
2104
+ return globalThis.btoa(binary);
2105
+ }
2106
+ async function waitForSolanaConfirmation(chainId, signature) {
2107
+ const started = Date.now();
2108
+ const timeoutMs = 12e4;
2109
+ const intervalMs = 2e3;
2110
+ while (Date.now() - started < timeoutMs) {
2111
+ const status = await getSolanaTxStatus({ chainId, signature });
2112
+ if (status.status === "success") return signature;
2113
+ if (status.status === "failed") {
2114
+ throw new Error("Solana transaction failed");
2115
+ }
2116
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
2117
+ }
2118
+ throw new Error("Timed out waiting for Solana transaction confirmation");
2119
+ }
2120
+ function bindSolanaProviderEvents(provider, handlers) {
2121
+ const onConnect = () => handlers.onConnect?.();
2122
+ const onAccountChanged = () => handlers.onAccountChanged?.();
2123
+ const onDisconnect = () => handlers.onDisconnect?.();
2124
+ provider.on?.("connect", onConnect);
2125
+ provider.on?.("accountChanged", onAccountChanged);
2126
+ provider.on?.("disconnect", onDisconnect);
2127
+ return () => {
2128
+ provider.off?.("connect", onConnect);
2129
+ provider.off?.("accountChanged", onAccountChanged);
2130
+ provider.off?.("disconnect", onDisconnect);
2131
+ provider.removeListener?.("connect", onConnect);
2132
+ provider.removeListener?.("accountChanged", onAccountChanged);
2133
+ provider.removeListener?.("disconnect", onDisconnect);
2134
+ };
2135
+ }
2136
+ function toSolanaWalletInterface(provider) {
2137
+ return {
2138
+ ecosystem: "solana",
2139
+ type: "solana",
2140
+ async getAddress() {
2141
+ const current = getPublicKeyString(provider);
2142
+ if (current) return current;
2143
+ if (!provider.connect) {
2144
+ throw new Error("Selected Solana wallet cannot connect");
2069
2145
  }
2070
- };
2071
- bobaMainnet = {
2072
- id: 288,
2073
- chainNamespace: "eip155",
2074
- caipNetworkId: "eip155:288",
2075
- name: "Boba",
2076
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2077
- rpcUrls: {
2078
- default: { http: ["https://mainnet.boba.network"] }
2146
+ await provider.connect();
2147
+ const next = getPublicKeyString(provider);
2148
+ if (!next) throw new Error("No connected Solana address");
2149
+ return next;
2150
+ },
2151
+ async disconnect() {
2152
+ await provider.disconnect?.();
2153
+ },
2154
+ async getChainKey() {
2155
+ return "solana-mainnet-beta";
2156
+ },
2157
+ async sendSerializedTransaction(serializedTransactionBase64, chainId) {
2158
+ const transaction = await decodeBase64Transaction(
2159
+ serializedTransactionBase64
2160
+ );
2161
+ if (provider.signAndSendTransaction) {
2162
+ const result = await provider.signAndSendTransaction(transaction, {
2163
+ preflightCommitment: "confirmed"
2164
+ });
2165
+ if (typeof result === "string") return result;
2166
+ if (result?.signature) return result.signature;
2079
2167
  }
2080
- };
2081
- hederaMainnet = {
2082
- id: 295,
2083
- chainNamespace: "eip155",
2084
- caipNetworkId: "eip155:295",
2085
- name: "HEDERA",
2086
- nativeCurrency: { name: "Hbar", symbol: "HBAR", decimals: 18 },
2087
- rpcUrls: {
2088
- default: { http: ["https://mainnet.hashio.io/api"] }
2168
+ if (!provider.signTransaction) {
2169
+ throw new Error("Connected Solana wallet cannot sign transactions");
2089
2170
  }
2090
- };
2091
- filecoinMainnet = {
2092
- id: 314,
2093
- chainNamespace: "eip155",
2094
- caipNetworkId: "eip155:314",
2095
- name: "Filecoin",
2096
- nativeCurrency: { name: "Filecoin", symbol: "FIL", decimals: 18 },
2097
- rpcUrls: {
2098
- default: { http: ["https://api.node.glif.io"] }
2099
- }
2100
- };
2101
- zkSyncMainnet = {
2102
- id: 324,
2103
- chainNamespace: "eip155",
2104
- caipNetworkId: "eip155:324",
2105
- name: "zkSync Era Mainnet",
2106
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2107
- rpcUrls: {
2108
- default: { http: ["https://mainnet.era.zksync.io"] }
2109
- }
2110
- };
2111
- worldchainMainnet = {
2112
- id: 480,
2113
- chainNamespace: "eip155",
2114
- caipNetworkId: "eip155:480",
2115
- name: "World Chain",
2116
- nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2117
- rpcUrls: {
2118
- default: {
2119
- http: ["https://worldchain-mainnet.g.alchemy.com/public"]
2120
- }
2121
- }
2122
- };
2123
- flowMainnet = {
2124
- id: 747,
2125
- chainNamespace: "eip155",
2126
- caipNetworkId: "eip155:747",
2127
- name: "Flow",
2128
- nativeCurrency: { name: "FLOW", symbol: "FLOW", decimals: 18 },
2129
- rpcUrls: {
2130
- default: { http: ["https://mainnet.evm.nodes.onflow.org"] }
2171
+ const signed = await provider.signTransaction(transaction);
2172
+ const resolvedChainId = chainId?.trim() || "solana-mainnet";
2173
+ const serializedSigned = encodeBase64(signed.serialize());
2174
+ const { signature } = await sendSolanaSerialized({
2175
+ chainId: resolvedChainId,
2176
+ serializedTransaction: serializedSigned
2177
+ });
2178
+ await waitForSolanaConfirmation(resolvedChainId, signature);
2179
+ return signature;
2180
+ }
2181
+ };
2182
+ }
2183
+ var init_solana = __esm({
2184
+ "src/wallets/solana.ts"() {
2185
+ "use strict";
2186
+ init_sdkRpc();
2187
+ }
2188
+ });
2189
+
2190
+ // src/wallets/adapters.ts
2191
+ function toWalletInterfaceFromDetected(dw) {
2192
+ if (!dw?.provider) throw new Error("No provider on detected wallet");
2193
+ if (dw.via === "solana-window" || dw.meta.ecosystem === "solana") {
2194
+ return toSolanaWalletInterface(dw.provider);
2195
+ }
2196
+ const eth = dw.provider;
2197
+ return useEIP1193(eth);
2198
+ }
2199
+ var init_adapters = __esm({
2200
+ "src/wallets/adapters.ts"() {
2201
+ "use strict";
2202
+ init_eipWallets();
2203
+ init_solana();
2204
+ }
2205
+ });
2206
+
2207
+ // src/wallets/connect.ts
2208
+ function pickWagmiConnector(wagmi, metaName, metaId, metaCategory) {
2209
+ const lower = metaName.toLowerCase();
2210
+ const cons = wagmi.connectors();
2211
+ return cons.find((c) => c.name.toLowerCase().includes(lower)) || metaId === "coinbase" && cons.find((c) => c.name.toLowerCase().includes("coinbase")) || metaId === "walletconnect" && cons.find((c) => (c.type ?? "").toLowerCase() === "walletconnect") || metaCategory === "injected" && cons.find((c) => (c.type ?? "").toLowerCase() === "injected") || null;
2212
+ }
2213
+ async function connectDetectedWallet(dw, opts) {
2214
+ const { wagmi, touchAddress = true } = opts ?? {};
2215
+ if (dw.meta.id === "walletconnect" || dw.via === "walletconnect") {
2216
+ if (wagmi) {
2217
+ const conn = pickWagmiConnector(
2218
+ wagmi,
2219
+ dw.meta.name,
2220
+ dw.meta.id,
2221
+ dw.meta.category
2222
+ );
2223
+ if (conn) {
2224
+ await wagmi.connect(conn);
2225
+ return { via: "wagmi", api: null };
2131
2226
  }
2227
+ }
2228
+ throw new Error("WalletConnect connection failed. Please try again.");
2229
+ }
2230
+ if (dw.via === "solana-window" || dw.meta.ecosystem === "solana") {
2231
+ try {
2232
+ const provider = dw.provider;
2233
+ await provider.connect();
2234
+ return {
2235
+ via: "eip1193",
2236
+ api: toWalletInterfaceFromDetected(dw),
2237
+ error: null
2238
+ };
2239
+ } catch (err) {
2240
+ const errorMsg = err instanceof Error ? err.message : String(err);
2241
+ return { via: "eip1193", api: null, error: errorMsg };
2242
+ }
2243
+ }
2244
+ if (wagmi) {
2245
+ const conn = pickWagmiConnector(
2246
+ wagmi,
2247
+ dw.meta.name,
2248
+ dw.meta.id,
2249
+ dw.meta.category
2250
+ );
2251
+ if (conn) {
2252
+ await wagmi.connect(conn);
2253
+ return { via: "wagmi", api: null, error: null };
2254
+ }
2255
+ }
2256
+ const api = toWalletInterfaceFromDetected(dw);
2257
+ if (touchAddress) await api.getAddress();
2258
+ return { via: "eip1193", api, error: null };
2259
+ }
2260
+ var init_connect = __esm({
2261
+ "src/wallets/connect.ts"() {
2262
+ "use strict";
2263
+ init_adapters();
2264
+ }
2265
+ });
2266
+
2267
+ // src/identity/index.ts
2268
+ function normalizeIdentityChainId(chain) {
2269
+ if (!chain || typeof chain === "string") return void 0;
2270
+ const raw = chain.chainId ?? chain.id;
2271
+ if (raw === void 0 || raw === null) return void 0;
2272
+ const normalized = String(raw).trim();
2273
+ return normalized || void 0;
2274
+ }
2275
+ function identityEntryMatchesChain(entry, chainType, chainKey, chainId) {
2276
+ if (chainKey && entry.chainKey && entry.chainKey === chainKey) return true;
2277
+ if (chainId && entry.chainId && entry.chainId === chainId) return true;
2278
+ if (chainType && entry.chainType === chainType) return true;
2279
+ return false;
2280
+ }
2281
+ function createWalletIdentity(addresses = []) {
2282
+ return { addresses };
2283
+ }
2284
+ function upsertWalletIdentityAddress(identity, next) {
2285
+ const normalizedAddress = next.address.trim();
2286
+ const normalizedChainKey = next.chainKey ? normalizeChainKey(next.chainKey) : void 0;
2287
+ const normalizedChainId = next.chainId?.trim() || void 0;
2288
+ const addresses = identity.addresses.filter((entry) => {
2289
+ if (entry.chainType !== next.chainType) return true;
2290
+ if (normalizedChainKey && entry.chainKey === normalizedChainKey)
2291
+ return false;
2292
+ if (normalizedChainId && entry.chainId === normalizedChainId) return false;
2293
+ if (!normalizedChainKey && !normalizedChainId) return false;
2294
+ return true;
2295
+ });
2296
+ if (!normalizedAddress) return createWalletIdentity(addresses);
2297
+ return createWalletIdentity([
2298
+ ...addresses,
2299
+ {
2300
+ ...next,
2301
+ address: normalizedAddress,
2302
+ chainKey: normalizedChainKey,
2303
+ chainId: normalizedChainId
2304
+ }
2305
+ ]);
2306
+ }
2307
+ function resolveWalletAddressForChain(identity, chain) {
2308
+ const chainType = normalizeChainType(chain);
2309
+ const chainDef = typeof chain === "object" && chain ? chain : void 0;
2310
+ const chainKey = chainDef ? normalizeChainKey(
2311
+ chainDef.networkIdentifier ?? chainDef.chainId ?? chainDef.id
2312
+ ) : typeof chain === "string" ? normalizeChainKey(chain) : void 0;
2313
+ const chainId = normalizeIdentityChainId(chain);
2314
+ if (!chainType) {
2315
+ return {
2316
+ status: "missing",
2317
+ reason: "unknown_chain_type",
2318
+ chainKey,
2319
+ chainId
2132
2320
  };
2133
- stableMainnet = {
2134
- id: 988,
2135
- chainNamespace: "eip155",
2136
- caipNetworkId: "eip155:988",
2137
- name: "Stable",
2138
- nativeCurrency: { name: "USDT0", symbol: "USDT0", decimals: 6 },
2139
- rpcUrls: {
2140
- default: { http: ["https://rpc.stable.xyz"] }
2141
- }
2321
+ }
2322
+ const match = identity.addresses.find(
2323
+ (entry) => identityEntryMatchesChain(entry, chainType, chainKey, chainId)
2324
+ );
2325
+ if (!match) {
2326
+ return {
2327
+ status: "missing",
2328
+ reason: "missing_chain_address",
2329
+ chainType,
2330
+ chainKey,
2331
+ chainId
2142
2332
  };
2143
- hyperEvmMainnet = {
2144
- id: 999,
2145
- chainNamespace: "eip155",
2146
- caipNetworkId: "eip155:999",
2147
- name: "HyperEVM",
2148
- nativeCurrency: { name: "Hyperliquid", symbol: "HYPE", decimals: 18 },
2149
- rpcUrls: {
2150
- default: { http: ["https://rpc.hyperliquid.xyz/evm"] }
2151
- }
2333
+ }
2334
+ const validation = validateAddressForChain(
2335
+ match.address,
2336
+ chainDef ?? chainType
2337
+ );
2338
+ if (!validation.isValid) {
2339
+ return {
2340
+ status: "invalid",
2341
+ reason: validation.error ?? "invalid_chain_address",
2342
+ address: match.address,
2343
+ source: match.source,
2344
+ chainType,
2345
+ chainKey,
2346
+ chainId
2152
2347
  };
2153
- metisMainnet = {
2154
- id: 1088,
2155
- chainNamespace: "eip155",
2156
- caipNetworkId: "eip155:1088",
2157
- name: "Metis",
2158
- nativeCurrency: { name: "METIS", symbol: "METIS", decimals: 18 },
2159
- rpcUrls: {
2160
- default: { http: ["https://metis-public.nodies.app"] }
2348
+ }
2349
+ return {
2350
+ status: "resolved",
2351
+ address: match.address.trim(),
2352
+ source: match.source,
2353
+ chainType,
2354
+ chainKey,
2355
+ chainId
2356
+ };
2357
+ }
2358
+ function buildWalletIdentityAddress(params) {
2359
+ const chainType = normalizeChainType(params.chain);
2360
+ if (!chainType) return null;
2361
+ const address = params.address.trim();
2362
+ const chainId = normalizeIdentityChainId(params.chain);
2363
+ const chainDef = typeof params.chain === "object" && params.chain ? params.chain : void 0;
2364
+ const chainKey = chainDef ? normalizeChainKey(
2365
+ chainDef.networkIdentifier ?? chainDef.chainId ?? chainDef.id
2366
+ ) : void 0;
2367
+ return {
2368
+ address,
2369
+ chainType,
2370
+ chainId,
2371
+ chainKey,
2372
+ providerId: params.providerId,
2373
+ source: params.source
2374
+ };
2375
+ }
2376
+ var IdentityStore;
2377
+ var init_identity = __esm({
2378
+ "src/identity/index.ts"() {
2379
+ "use strict";
2380
+ init_address();
2381
+ init_chains();
2382
+ IdentityStore = class {
2383
+ constructor() {
2384
+ this._identity = createWalletIdentity();
2161
2385
  }
2162
- };
2163
- liskMainnet = {
2164
- id: 1135,
2165
- chainNamespace: "eip155",
2166
- caipNetworkId: "eip155:1135",
2167
- name: "Lisk",
2168
- nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2169
- rpcUrls: {
2170
- default: { http: ["https://rpc.api.lisk.com"] }
2386
+ get snapshot() {
2387
+ return this._identity;
2171
2388
  }
2172
- };
2173
- moonbeamMainnet = {
2174
- id: 1284,
2175
- chainNamespace: "eip155",
2176
- caipNetworkId: "eip155:1284",
2177
- name: "Moonbeam",
2178
- nativeCurrency: { name: "Moonbeam", symbol: "GLMR", decimals: 18 },
2179
- rpcUrls: {
2180
- default: { http: ["https://rpc.api.moonbeam.network"] }
2389
+ reset() {
2390
+ this._identity = createWalletIdentity();
2181
2391
  }
2182
- };
2183
- seiMainnet = {
2184
- id: 1329,
2185
- chainNamespace: "eip155",
2186
- caipNetworkId: "eip155:1329",
2187
- name: "Sei Mainnet",
2188
- nativeCurrency: { name: "Sei", symbol: "SEI", decimals: 18 },
2189
- rpcUrls: {
2190
- default: { http: ["https://evm-rpc.sei-apis.com"] }
2392
+ upsert(next) {
2393
+ this._identity = upsertWalletIdentityAddress(this._identity, next);
2394
+ return this._identity;
2191
2395
  }
2192
- };
2193
- hyperliquidMainnet = {
2194
- id: 1337,
2195
- chainNamespace: "eip155",
2196
- caipNetworkId: "eip155:1337",
2197
- name: "Hyperliquid",
2198
- nativeCurrency: { name: "USDC", symbol: "USDC", decimals: 6 },
2199
- rpcUrls: {
2200
- default: { http: ["https://li.quest/v1/rpc/1337"] }
2396
+ resolve(chain) {
2397
+ return resolveWalletAddressForChain(this._identity, chain);
2201
2398
  }
2202
2399
  };
2203
- vanaMainnet = {
2204
- id: 1480,
2205
- chainNamespace: "eip155",
2206
- caipNetworkId: "eip155:1480",
2207
- name: "Vana",
2208
- nativeCurrency: { name: "VAN", symbol: "VAN", decimals: 18 },
2400
+ }
2401
+ });
2402
+
2403
+ // src/config/walletconnect.ts
2404
+ function resolvedMetadata() {
2405
+ const cfg = TrustwareConfigStore.peek();
2406
+ const walletConnect = cfg ? cfg?.walletConnect : void 0;
2407
+ const configured = walletConnect?.metadata;
2408
+ const pageUrl = typeof window !== "undefined" && window.location?.origin ? window.location.origin : configured?.url;
2409
+ if (!pageUrl) {
2410
+ console.warn(
2411
+ "[Trustware SDK] WalletConnect metadata.url could not be determined from window.location or config. Falling back to 'https://trustware.io'. Pass metadata.url explicitly in your WalletConnectConfig to avoid domain verification failures in production."
2412
+ );
2413
+ }
2414
+ return {
2415
+ name: configured?.name ?? "Trustware",
2416
+ description: configured?.description ?? "Cross-chain bridge & top-up",
2417
+ url: pageUrl ?? "https://trustware.io",
2418
+ icons: configured?.icons?.length ? configured.icons : ["https://app.trustware.io/icon.png"]
2419
+ };
2420
+ }
2421
+ async function getUniversalConnector(walletCfg) {
2422
+ const projectId = walletCfg?.projectId ?? WALLETCONNECT_PROJECT_ID;
2423
+ if (universalConnectorPromise && initializedProjectId !== projectId) {
2424
+ console.warn(
2425
+ "[Trustware SDK] projectId changed since last init \u2014 reinitializing WalletConnect connector."
2426
+ );
2427
+ universalConnectorPromise = null;
2428
+ initializedProjectId = null;
2429
+ }
2430
+ if (!universalConnectorPromise) {
2431
+ initializedProjectId = projectId;
2432
+ universalConnectorPromise = import_appkit_universal_connector.UniversalConnector.init({
2433
+ projectId,
2434
+ metadata: resolvedMetadata(),
2435
+ networks: namespaceConfig
2436
+ }).catch((error) => {
2437
+ universalConnectorPromise = null;
2438
+ initializedProjectId = null;
2439
+ console.error(
2440
+ "[Trustware SDK] Failed to initialize WalletConnect:",
2441
+ error
2442
+ );
2443
+ throw error;
2444
+ });
2445
+ }
2446
+ return universalConnectorPromise;
2447
+ }
2448
+ function resetUniversalConnector() {
2449
+ universalConnectorPromise = null;
2450
+ initializedProjectId = null;
2451
+ }
2452
+ var import_appkit_universal_connector, solanaMainnet, bitcoinMainnet, seiCosmosMainnet, ethereumMainnet, optimismMainnet, flareMainnet, cronosMainnet, rootstockMainnet, telosMainnet, xdcMainnet, bscMainnet, victionMainnet, gnosisMainnet, fuseMainnet, unichainMainnet, polygonMainnet, monadMainnet, sonicMainnet, opBnbMainnet, lensMainnet, fantomMainnet, fraxtalMainnet, bobaMainnet, hederaMainnet, filecoinMainnet, zkSyncMainnet, worldchainMainnet, flowMainnet, stableMainnet, hyperEvmMainnet, metisMainnet, liskMainnet, moonbeamMainnet, seiMainnet, hyperliquidMainnet, vanaMainnet, gravityMainnet, pharosMainnet, soneiumMainnet, swellchainMainnet, roninMainnet, kavaEvmMainnet, abstractMainnet, morphMainnet, peaqMainnet, tempoMainnet, megaEthMainnet, mantleMainnet, somniaMainnet, kaiaMainnet, baseMainnet, plasmaMainnet, immutableZkEvmMainnet, apechainMainnet, modeMainnet, arbitrumMainnet, arbitrumNovaMainnet, celoMainnet, etherlinkMainnet, hemiMainnet, avalancheMainnet, sophonMainnet, superpositionMainnet, inkMainnet, lineaMainnet, bobMainnet, berachainMainnet, blastMainnet, plumeMainnet, taikoMainnet, scrollMainnet, katanaMainnet, cornMainnet, evmChains, solanaChains, bitcoinChains, cosmosChains, networks, namespaceConfig, universalConnectorPromise, initializedProjectId;
2453
+ var init_walletconnect = __esm({
2454
+ "src/config/walletconnect.ts"() {
2455
+ "use strict";
2456
+ import_appkit_universal_connector = require("@reown/appkit-universal-connector");
2457
+ init_store();
2458
+ init_constants();
2459
+ solanaMainnet = {
2460
+ id: 900,
2461
+ chainNamespace: "solana",
2462
+ caipNetworkId: "solana:5eykt4UsFv8P8NJdTREpY1vzqAQ3H1FQ",
2463
+ name: "Solana Mainnet",
2464
+ nativeCurrency: {
2465
+ name: "Solana",
2466
+ symbol: "SOL",
2467
+ decimals: 9
2468
+ },
2209
2469
  rpcUrls: {
2210
- default: { http: ["https://rpc.vana.org"] }
2470
+ default: {
2471
+ http: ["https://api.mainnet-beta.solana.com"]
2472
+ }
2211
2473
  }
2212
2474
  };
2213
- gravityMainnet = {
2214
- id: 1625,
2215
- chainNamespace: "eip155",
2216
- caipNetworkId: "eip155:1625",
2217
- name: "Gravity",
2218
- nativeCurrency: { name: "G", symbol: "G", decimals: 18 },
2475
+ bitcoinMainnet = {
2476
+ id: 8333,
2477
+ chainNamespace: "bip122",
2478
+ caipNetworkId: "bip122:000000000019d6689c085ae165831e93",
2479
+ name: "Bitcoin Mainnet",
2480
+ nativeCurrency: {
2481
+ name: "Bitcoin",
2482
+ symbol: "BTC",
2483
+ decimals: 8
2484
+ },
2219
2485
  rpcUrls: {
2220
- default: { http: ["https://rpc.gravity.xyz/"] }
2486
+ default: {
2487
+ http: ["https://api.blockcypher.com/v1/btc/main"]
2488
+ }
2221
2489
  }
2222
2490
  };
2223
- pharosMainnet = {
2224
- id: 1672,
2225
- chainNamespace: "eip155",
2226
- caipNetworkId: "eip155:1672",
2227
- name: "Pharos Mainnet",
2228
- nativeCurrency: { name: "Pharos", symbol: "PROS", decimals: 18 },
2491
+ seiCosmosMainnet = {
2492
+ id: 9001,
2493
+ chainNamespace: "cosmos",
2494
+ caipNetworkId: "cosmos:pacific-1",
2495
+ name: "Sei Cosmos",
2496
+ nativeCurrency: { name: "Sei", symbol: "SEI", decimals: 6 },
2229
2497
  rpcUrls: {
2230
- default: { http: ["https://rpc.pharos.xyz"] }
2498
+ default: { http: ["https://rpc.sei-apis.com"] }
2231
2499
  }
2232
2500
  };
2233
- soneiumMainnet = {
2234
- id: 1868,
2501
+ ethereumMainnet = {
2502
+ id: 1,
2235
2503
  chainNamespace: "eip155",
2236
- caipNetworkId: "eip155:1868",
2237
- name: "Soneium",
2238
- nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2504
+ caipNetworkId: "eip155:1",
2505
+ name: "Ethereum Mainnet",
2506
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2239
2507
  rpcUrls: {
2240
- default: { http: ["https://rpc.soneium.org/"] }
2508
+ default: { http: ["https://rpc.ankr.com/eth"] }
2241
2509
  }
2242
2510
  };
2243
- swellchainMainnet = {
2244
- id: 1923,
2511
+ optimismMainnet = {
2512
+ id: 10,
2245
2513
  chainNamespace: "eip155",
2246
- caipNetworkId: "eip155:1923",
2247
- name: "Swellchain",
2514
+ caipNetworkId: "eip155:10",
2515
+ name: "Optimism Mainnet",
2248
2516
  nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2249
2517
  rpcUrls: {
2250
- default: { http: ["https://swell-mainnet.alt.technology"] }
2518
+ default: { http: ["https://rpc.ankr.com/optimism"] }
2251
2519
  }
2252
2520
  };
2253
- roninMainnet = {
2254
- id: 2020,
2521
+ flareMainnet = {
2522
+ id: 14,
2255
2523
  chainNamespace: "eip155",
2256
- caipNetworkId: "eip155:2020",
2257
- name: "Ronin",
2258
- nativeCurrency: { name: "RON", symbol: "RON", decimals: 18 },
2524
+ caipNetworkId: "eip155:14",
2525
+ name: "Flare",
2526
+ nativeCurrency: { name: "Flare", symbol: "FLR", decimals: 18 },
2259
2527
  rpcUrls: {
2260
- default: { http: ["https://api.roninchain.com/rpc"] }
2528
+ default: { http: ["https://flare-api.flare.network/ext/C/rpc"] }
2261
2529
  }
2262
2530
  };
2263
- kavaEvmMainnet = {
2264
- id: 2222,
2531
+ cronosMainnet = {
2532
+ id: 25,
2265
2533
  chainNamespace: "eip155",
2266
- caipNetworkId: "eip155:2222",
2267
- name: "Kava EVM",
2268
- nativeCurrency: { name: "Kava", symbol: "KAVA", decimals: 18 },
2534
+ caipNetworkId: "eip155:25",
2535
+ name: "Cronos",
2536
+ nativeCurrency: { name: "Cronos", symbol: "CRO", decimals: 18 },
2269
2537
  rpcUrls: {
2270
- default: { http: ["https://evm2.kava.io"] }
2538
+ default: { http: ["https://evm.cronos.org"] }
2271
2539
  }
2272
2540
  };
2273
- abstractMainnet = {
2274
- id: 2741,
2541
+ rootstockMainnet = {
2542
+ id: 30,
2275
2543
  chainNamespace: "eip155",
2276
- caipNetworkId: "eip155:2741",
2277
- name: "Abstract",
2278
- nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2544
+ caipNetworkId: "eip155:30",
2545
+ name: "Rootstock",
2546
+ nativeCurrency: {
2547
+ name: "Rootstock Smart Bitcoin",
2548
+ symbol: "RBTC",
2549
+ decimals: 18
2550
+ },
2279
2551
  rpcUrls: {
2280
- default: { http: ["https://api.mainnet.abs.xyz"] }
2552
+ default: { http: ["https://public-node.rsk.co"] }
2281
2553
  }
2282
2554
  };
2283
- morphMainnet = {
2284
- id: 2818,
2555
+ telosMainnet = {
2556
+ id: 40,
2285
2557
  chainNamespace: "eip155",
2286
- caipNetworkId: "eip155:2818",
2287
- name: "Morph",
2288
- nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2558
+ caipNetworkId: "eip155:40",
2559
+ name: "Telos",
2560
+ nativeCurrency: { name: "Telos", symbol: "TLOS", decimals: 18 },
2289
2561
  rpcUrls: {
2290
- default: { http: ["https://rpc.morph.network"] }
2562
+ default: { http: ["https://rpc.telos.net"] }
2291
2563
  }
2292
2564
  };
2293
- peaqMainnet = {
2294
- id: 3338,
2565
+ xdcMainnet = {
2566
+ id: 50,
2295
2567
  chainNamespace: "eip155",
2296
- caipNetworkId: "eip155:3338",
2297
- name: "Peaq",
2298
- nativeCurrency: { name: "Peaq", symbol: "PEAQ", decimals: 18 },
2568
+ caipNetworkId: "eip155:50",
2569
+ name: "XDC",
2570
+ nativeCurrency: { name: "XDC", symbol: "XDC", decimals: 18 },
2299
2571
  rpcUrls: {
2300
- default: { http: ["https://quicknode1.peaq.xyz"] }
2572
+ default: { http: ["https://rpc.xdcrpc.com"] }
2301
2573
  }
2302
2574
  };
2303
- tempoMainnet = {
2304
- id: 4217,
2575
+ bscMainnet = {
2576
+ id: 56,
2305
2577
  chainNamespace: "eip155",
2306
- caipNetworkId: "eip155:4217",
2307
- name: "Tempo",
2308
- nativeCurrency: { name: "PathUSD", symbol: "PathUSD", decimals: 6 },
2578
+ caipNetworkId: "eip155:56",
2579
+ name: "BNB Smart Chain",
2580
+ nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 },
2309
2581
  rpcUrls: {
2310
- default: { http: ["https://rpc.tempo.xyz"] }
2582
+ default: { http: ["https://rpc.ankr.com/bsc"] }
2311
2583
  }
2312
2584
  };
2313
- megaEthMainnet = {
2314
- id: 4326,
2585
+ victionMainnet = {
2586
+ id: 88,
2315
2587
  chainNamespace: "eip155",
2316
- caipNetworkId: "eip155:4326",
2317
- name: "MegaETH",
2318
- nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2588
+ caipNetworkId: "eip155:88",
2589
+ name: "Viction",
2590
+ nativeCurrency: { name: "Viction", symbol: "VIC", decimals: 18 },
2319
2591
  rpcUrls: {
2320
- default: { http: ["https://mainnet.megaeth.com/rpc"] }
2592
+ default: { http: ["https://rpc.viction.xyz"] }
2321
2593
  }
2322
2594
  };
2323
- mantleMainnet = {
2324
- id: 5e3,
2595
+ gnosisMainnet = {
2596
+ id: 100,
2325
2597
  chainNamespace: "eip155",
2326
- caipNetworkId: "eip155:5000",
2327
- name: "Mantle Mainnet",
2328
- nativeCurrency: { name: "Mantle", symbol: "MNT", decimals: 18 },
2598
+ caipNetworkId: "eip155:100",
2599
+ name: "Gnosis Chain",
2600
+ nativeCurrency: { name: "xDAI", symbol: "XDAI", decimals: 18 },
2329
2601
  rpcUrls: {
2330
- default: { http: ["https://rpc.mantle.xyz"] }
2602
+ default: { http: ["https://rpc.ankr.com/gnosis"] }
2331
2603
  }
2332
2604
  };
2333
- somniaMainnet = {
2334
- id: 5031,
2605
+ fuseMainnet = {
2606
+ id: 122,
2335
2607
  chainNamespace: "eip155",
2336
- caipNetworkId: "eip155:5031",
2337
- name: "Somnia",
2338
- nativeCurrency: { name: "Somnia", symbol: "SOMI", decimals: 18 },
2608
+ caipNetworkId: "eip155:122",
2609
+ name: "FUSE",
2610
+ nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 },
2339
2611
  rpcUrls: {
2340
- default: { http: ["https://api.infra.mainnet.somnia.network/"] }
2612
+ default: { http: ["https://rpc.fuse.io"] }
2341
2613
  }
2342
2614
  };
2343
- kaiaMainnet = {
2344
- id: 8217,
2615
+ unichainMainnet = {
2616
+ id: 130,
2345
2617
  chainNamespace: "eip155",
2346
- caipNetworkId: "eip155:8217",
2347
- name: "Kaia",
2348
- nativeCurrency: { name: "KAIA", symbol: "KAIA", decimals: 18 },
2618
+ caipNetworkId: "eip155:130",
2619
+ name: "Unichain",
2620
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2349
2621
  rpcUrls: {
2350
- default: { http: ["https://public-en.node.kaia.io"] }
2622
+ default: { http: ["https://mainnet.unichain.org"] }
2351
2623
  }
2352
2624
  };
2353
- baseMainnet = {
2354
- id: 8453,
2625
+ polygonMainnet = {
2626
+ id: 137,
2355
2627
  chainNamespace: "eip155",
2356
- caipNetworkId: "eip155:8453",
2357
- name: "Base Mainnet",
2358
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2628
+ caipNetworkId: "eip155:137",
2629
+ name: "Polygon Mainnet",
2630
+ nativeCurrency: { name: "POL", symbol: "POL", decimals: 18 },
2359
2631
  rpcUrls: {
2360
- default: { http: ["https://mainnet.base.org"] }
2632
+ default: { http: ["https://rpc.ankr.com/polygon"] }
2361
2633
  }
2362
2634
  };
2363
- plasmaMainnet = {
2364
- id: 9745,
2635
+ monadMainnet = {
2636
+ id: 143,
2365
2637
  chainNamespace: "eip155",
2366
- caipNetworkId: "eip155:9745",
2367
- name: "Plasma",
2368
- nativeCurrency: { name: "XPL", symbol: "XPL", decimals: 18 },
2638
+ caipNetworkId: "eip155:143",
2639
+ name: "MONAD",
2640
+ nativeCurrency: { name: "Mon", symbol: "MON", decimals: 18 },
2369
2641
  rpcUrls: {
2370
- default: { http: ["https://rpc.plasma.to"] }
2642
+ default: { http: ["https://rpc.monad.xyz/"] }
2371
2643
  }
2372
2644
  };
2373
- immutableZkEvmMainnet = {
2374
- id: 13371,
2645
+ sonicMainnet = {
2646
+ id: 146,
2375
2647
  chainNamespace: "eip155",
2376
- caipNetworkId: "eip155:13371",
2377
- name: "Immutable zkEVM",
2378
- nativeCurrency: { name: "IMX", symbol: "IMX", decimals: 18 },
2648
+ caipNetworkId: "eip155:146",
2649
+ name: "Sonic",
2650
+ nativeCurrency: { name: "Sonic", symbol: "S", decimals: 18 },
2379
2651
  rpcUrls: {
2380
- default: { http: ["https://rpc.immutable.com"] }
2652
+ default: { http: ["https://rpc.soniclabs.com"] }
2381
2653
  }
2382
2654
  };
2383
- apechainMainnet = {
2384
- id: 33139,
2655
+ opBnbMainnet = {
2656
+ id: 204,
2385
2657
  chainNamespace: "eip155",
2386
- caipNetworkId: "eip155:33139",
2387
- name: "Apechain",
2388
- nativeCurrency: { name: "ApeCoin", symbol: "APE", decimals: 18 },
2658
+ caipNetworkId: "eip155:204",
2659
+ name: "opBNB",
2660
+ nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 },
2389
2661
  rpcUrls: {
2390
- default: { http: ["https://rpc.apechain.com"] }
2662
+ default: { http: ["https://opbnb-mainnet-rpc.bnbchain.org"] }
2391
2663
  }
2392
2664
  };
2393
- modeMainnet = {
2394
- id: 34443,
2665
+ lensMainnet = {
2666
+ id: 232,
2395
2667
  chainNamespace: "eip155",
2396
- caipNetworkId: "eip155:34443",
2397
- name: "Mode",
2398
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2668
+ caipNetworkId: "eip155:232",
2669
+ name: "Lens",
2670
+ nativeCurrency: { name: "GHO", symbol: "GHO", decimals: 18 },
2399
2671
  rpcUrls: {
2400
- default: { http: ["https://mainnet.mode.network"] }
2672
+ default: { http: ["https://api.lens.matterhosted.dev"] }
2401
2673
  }
2402
2674
  };
2403
- arbitrumMainnet = {
2404
- id: 42161,
2675
+ fantomMainnet = {
2676
+ id: 250,
2405
2677
  chainNamespace: "eip155",
2406
- caipNetworkId: "eip155:42161",
2407
- name: "Arbitrum One",
2408
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2678
+ caipNetworkId: "eip155:250",
2679
+ name: "Fantom Opera",
2680
+ nativeCurrency: { name: "Fantom", symbol: "FTM", decimals: 18 },
2409
2681
  rpcUrls: {
2410
- default: { http: ["https://rpc.ankr.com/arbitrum"] }
2682
+ default: { http: ["https://rpc.ankr.com/fantom"] }
2411
2683
  }
2412
2684
  };
2413
- arbitrumNovaMainnet = {
2414
- id: 42170,
2685
+ fraxtalMainnet = {
2686
+ id: 252,
2415
2687
  chainNamespace: "eip155",
2416
- caipNetworkId: "eip155:42170",
2417
- name: "Arbitrum Nova",
2418
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2688
+ caipNetworkId: "eip155:252",
2689
+ name: "Fraxtal",
2690
+ nativeCurrency: { name: "FRAX", symbol: "FRAX", decimals: 18 },
2419
2691
  rpcUrls: {
2420
- default: { http: ["https://arbitrum-nova-rpc.publicnode.com"] }
2692
+ default: { http: ["https://rpc.frax.com"] }
2421
2693
  }
2422
2694
  };
2423
- celoMainnet = {
2424
- id: 42220,
2695
+ bobaMainnet = {
2696
+ id: 288,
2425
2697
  chainNamespace: "eip155",
2426
- caipNetworkId: "eip155:42220",
2427
- name: "Celo Mainnet",
2428
- nativeCurrency: { name: "Celo", symbol: "CELO", decimals: 18 },
2698
+ caipNetworkId: "eip155:288",
2699
+ name: "Boba",
2700
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2429
2701
  rpcUrls: {
2430
- default: { http: ["https://rpc.ankr.com/celo"] }
2702
+ default: { http: ["https://mainnet.boba.network"] }
2431
2703
  }
2432
2704
  };
2433
- etherlinkMainnet = {
2434
- id: 42793,
2705
+ hederaMainnet = {
2706
+ id: 295,
2435
2707
  chainNamespace: "eip155",
2436
- caipNetworkId: "eip155:42793",
2437
- name: "Etherlink",
2438
- nativeCurrency: { name: "Tezos", symbol: "XTZ", decimals: 18 },
2708
+ caipNetworkId: "eip155:295",
2709
+ name: "HEDERA",
2710
+ nativeCurrency: { name: "Hbar", symbol: "HBAR", decimals: 18 },
2439
2711
  rpcUrls: {
2440
- default: { http: ["https://node.mainnet.etherlink.com"] }
2712
+ default: { http: ["https://mainnet.hashio.io/api"] }
2441
2713
  }
2442
2714
  };
2443
- hemiMainnet = {
2444
- id: 43111,
2715
+ filecoinMainnet = {
2716
+ id: 314,
2445
2717
  chainNamespace: "eip155",
2446
- caipNetworkId: "eip155:43111",
2447
- name: "Hemi",
2448
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2718
+ caipNetworkId: "eip155:314",
2719
+ name: "Filecoin",
2720
+ nativeCurrency: { name: "Filecoin", symbol: "FIL", decimals: 18 },
2449
2721
  rpcUrls: {
2450
- default: { http: ["https://rpc.hemi.network/rpc"] }
2722
+ default: { http: ["https://api.node.glif.io"] }
2451
2723
  }
2452
2724
  };
2453
- avalancheMainnet = {
2454
- id: 43114,
2725
+ zkSyncMainnet = {
2726
+ id: 324,
2455
2727
  chainNamespace: "eip155",
2456
- caipNetworkId: "eip155:43114",
2457
- name: "Avalanche C-Chain",
2458
- nativeCurrency: { name: "Avalanche", symbol: "AVAX", decimals: 18 },
2728
+ caipNetworkId: "eip155:324",
2729
+ name: "zkSync Era Mainnet",
2730
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2459
2731
  rpcUrls: {
2460
- default: { http: ["https://rpc.ankr.com/avalanche"] }
2732
+ default: { http: ["https://mainnet.era.zksync.io"] }
2461
2733
  }
2462
2734
  };
2463
- sophonMainnet = {
2464
- id: 50104,
2735
+ worldchainMainnet = {
2736
+ id: 480,
2465
2737
  chainNamespace: "eip155",
2466
- caipNetworkId: "eip155:50104",
2467
- name: "Sophon",
2468
- nativeCurrency: { name: "SOPH", symbol: "SOPH", decimals: 18 },
2738
+ caipNetworkId: "eip155:480",
2739
+ name: "World Chain",
2740
+ nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2469
2741
  rpcUrls: {
2470
- default: { http: ["https://rpc.sophon.xyz"] }
2742
+ default: {
2743
+ http: ["https://worldchain-mainnet.g.alchemy.com/public"]
2744
+ }
2471
2745
  }
2472
2746
  };
2473
- superpositionMainnet = {
2474
- id: 55244,
2747
+ flowMainnet = {
2748
+ id: 747,
2475
2749
  chainNamespace: "eip155",
2476
- caipNetworkId: "eip155:55244",
2477
- name: "Superposition",
2478
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2750
+ caipNetworkId: "eip155:747",
2751
+ name: "Flow",
2752
+ nativeCurrency: { name: "FLOW", symbol: "FLOW", decimals: 18 },
2479
2753
  rpcUrls: {
2480
- default: { http: ["https://rpc.superposition.so"] }
2754
+ default: { http: ["https://mainnet.evm.nodes.onflow.org"] }
2481
2755
  }
2482
2756
  };
2483
- inkMainnet = {
2484
- id: 57073,
2757
+ stableMainnet = {
2758
+ id: 988,
2485
2759
  chainNamespace: "eip155",
2486
- caipNetworkId: "eip155:57073",
2487
- name: "Ink",
2488
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2760
+ caipNetworkId: "eip155:988",
2761
+ name: "Stable",
2762
+ nativeCurrency: { name: "USDT0", symbol: "USDT0", decimals: 6 },
2489
2763
  rpcUrls: {
2490
- default: { http: ["https://rpc-gel.inkonchain.com"] }
2764
+ default: { http: ["https://rpc.stable.xyz"] }
2491
2765
  }
2492
2766
  };
2493
- lineaMainnet = {
2494
- id: 59144,
2767
+ hyperEvmMainnet = {
2768
+ id: 999,
2495
2769
  chainNamespace: "eip155",
2496
- caipNetworkId: "eip155:59144",
2497
- name: "Linea Mainnet",
2498
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2770
+ caipNetworkId: "eip155:999",
2771
+ name: "HyperEVM",
2772
+ nativeCurrency: { name: "Hyperliquid", symbol: "HYPE", decimals: 18 },
2499
2773
  rpcUrls: {
2500
- default: { http: ["https://rpc.linea.build"] }
2774
+ default: { http: ["https://rpc.hyperliquid.xyz/evm"] }
2501
2775
  }
2502
2776
  };
2503
- bobMainnet = {
2504
- id: 60808,
2777
+ metisMainnet = {
2778
+ id: 1088,
2505
2779
  chainNamespace: "eip155",
2506
- caipNetworkId: "eip155:60808",
2507
- name: "BOB",
2508
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2780
+ caipNetworkId: "eip155:1088",
2781
+ name: "Metis",
2782
+ nativeCurrency: { name: "METIS", symbol: "METIS", decimals: 18 },
2509
2783
  rpcUrls: {
2510
- default: { http: ["https://rpc.gobob.xyz"] }
2784
+ default: { http: ["https://metis-public.nodies.app"] }
2511
2785
  }
2512
2786
  };
2513
- berachainMainnet = {
2514
- id: 80094,
2787
+ liskMainnet = {
2788
+ id: 1135,
2515
2789
  chainNamespace: "eip155",
2516
- caipNetworkId: "eip155:80094",
2517
- name: "Berachain",
2518
- nativeCurrency: { name: "BERA", symbol: "BERA", decimals: 18 },
2790
+ caipNetworkId: "eip155:1135",
2791
+ name: "Lisk",
2792
+ nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2519
2793
  rpcUrls: {
2520
- default: { http: ["https://rpc.berachain.com/"] }
2794
+ default: { http: ["https://rpc.api.lisk.com"] }
2521
2795
  }
2522
2796
  };
2523
- blastMainnet = {
2524
- id: 81457,
2797
+ moonbeamMainnet = {
2798
+ id: 1284,
2525
2799
  chainNamespace: "eip155",
2526
- caipNetworkId: "eip155:81457",
2527
- name: "Blast Mainnet",
2528
- nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2800
+ caipNetworkId: "eip155:1284",
2801
+ name: "Moonbeam",
2802
+ nativeCurrency: { name: "Moonbeam", symbol: "GLMR", decimals: 18 },
2529
2803
  rpcUrls: {
2530
- default: { http: ["https://rpc.blast.io"] }
2804
+ default: { http: ["https://rpc.api.moonbeam.network"] }
2531
2805
  }
2532
2806
  };
2533
- plumeMainnet = {
2534
- id: 98866,
2807
+ seiMainnet = {
2808
+ id: 1329,
2535
2809
  chainNamespace: "eip155",
2536
- caipNetworkId: "eip155:98866",
2537
- name: "Plume",
2538
- nativeCurrency: { name: "PLUME", symbol: "PLUME", decimals: 18 },
2810
+ caipNetworkId: "eip155:1329",
2811
+ name: "Sei Mainnet",
2812
+ nativeCurrency: { name: "Sei", symbol: "SEI", decimals: 18 },
2539
2813
  rpcUrls: {
2540
- default: { http: ["https://rpc.plume.org"] }
2814
+ default: { http: ["https://evm-rpc.sei-apis.com"] }
2541
2815
  }
2542
2816
  };
2543
- taikoMainnet = {
2544
- id: 167e3,
2817
+ hyperliquidMainnet = {
2818
+ id: 1337,
2545
2819
  chainNamespace: "eip155",
2546
- caipNetworkId: "eip155:167000",
2547
- name: "Taiko",
2548
- nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2820
+ caipNetworkId: "eip155:1337",
2821
+ name: "Hyperliquid",
2822
+ nativeCurrency: { name: "USDC", symbol: "USDC", decimals: 6 },
2549
2823
  rpcUrls: {
2550
- default: { http: ["https://rpc.mainnet.taiko.xyz"] }
2824
+ default: { http: ["https://li.quest/v1/rpc/1337"] }
2551
2825
  }
2552
2826
  };
2553
- scrollMainnet = {
2554
- id: 534352,
2827
+ vanaMainnet = {
2828
+ id: 1480,
2555
2829
  chainNamespace: "eip155",
2556
- caipNetworkId: "eip155:534352",
2557
- name: "Scroll",
2558
- nativeCurrency: { name: "Scroll", symbol: "ETH", decimals: 18 },
2830
+ caipNetworkId: "eip155:1480",
2831
+ name: "Vana",
2832
+ nativeCurrency: { name: "VAN", symbol: "VAN", decimals: 18 },
2559
2833
  rpcUrls: {
2560
- default: { http: ["https://rpc.scroll.io"] }
2834
+ default: { http: ["https://rpc.vana.org"] }
2561
2835
  }
2562
2836
  };
2563
- katanaMainnet = {
2564
- id: 747474,
2837
+ gravityMainnet = {
2838
+ id: 1625,
2565
2839
  chainNamespace: "eip155",
2566
- caipNetworkId: "eip155:747474",
2567
- name: "Katana",
2840
+ caipNetworkId: "eip155:1625",
2841
+ name: "Gravity",
2842
+ nativeCurrency: { name: "G", symbol: "G", decimals: 18 },
2843
+ rpcUrls: {
2844
+ default: { http: ["https://rpc.gravity.xyz/"] }
2845
+ }
2846
+ };
2847
+ pharosMainnet = {
2848
+ id: 1672,
2849
+ chainNamespace: "eip155",
2850
+ caipNetworkId: "eip155:1672",
2851
+ name: "Pharos Mainnet",
2852
+ nativeCurrency: { name: "Pharos", symbol: "PROS", decimals: 18 },
2853
+ rpcUrls: {
2854
+ default: { http: ["https://rpc.pharos.xyz"] }
2855
+ }
2856
+ };
2857
+ soneiumMainnet = {
2858
+ id: 1868,
2859
+ chainNamespace: "eip155",
2860
+ caipNetworkId: "eip155:1868",
2861
+ name: "Soneium",
2862
+ nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2863
+ rpcUrls: {
2864
+ default: { http: ["https://rpc.soneium.org/"] }
2865
+ }
2866
+ };
2867
+ swellchainMainnet = {
2868
+ id: 1923,
2869
+ chainNamespace: "eip155",
2870
+ caipNetworkId: "eip155:1923",
2871
+ name: "Swellchain",
2568
2872
  nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2569
2873
  rpcUrls: {
2570
- default: { http: ["https://rpc.katana.network"] }
2874
+ default: { http: ["https://swell-mainnet.alt.technology"] }
2571
2875
  }
2572
2876
  };
2573
- cornMainnet = {
2574
- id: 21e6,
2877
+ roninMainnet = {
2878
+ id: 2020,
2575
2879
  chainNamespace: "eip155",
2576
- caipNetworkId: "eip155:21000000",
2577
- name: "Corn",
2578
- nativeCurrency: { name: "Bitcorn", symbol: "BTCN", decimals: 18 },
2880
+ caipNetworkId: "eip155:2020",
2881
+ name: "Ronin",
2882
+ nativeCurrency: { name: "RON", symbol: "RON", decimals: 18 },
2579
2883
  rpcUrls: {
2580
- default: { http: ["https://mainnet.corn-rpc.com"] }
2884
+ default: { http: ["https://api.roninchain.com/rpc"] }
2581
2885
  }
2582
2886
  };
2583
- evmChains = [
2584
- // Major L1s
2585
- ethereumMainnet,
2586
- bscMainnet,
2587
- avalancheMainnet,
2588
- polygonMainnet,
2589
- // L2s / rollups
2590
- arbitrumMainnet,
2591
- arbitrumNovaMainnet,
2592
- optimismMainnet,
2593
- baseMainnet,
2594
- zkSyncMainnet,
2595
- lineaMainnet,
2596
- mantleMainnet,
2597
- blastMainnet,
2598
- scrollMainnet,
2599
- taikoMainnet,
2600
- modeMainnet,
2601
- inkMainnet,
2602
- unichainMainnet,
2603
- worldchainMainnet,
2604
- swellchainMainnet,
2605
- soneiumMainnet,
2606
- liskMainnet,
2607
- morphMainnet,
2608
- abstractMainnet,
2609
- megaEthMainnet,
2610
- superpositionMainnet,
2611
- fraxtalMainnet,
2612
- // EVM-compatible L1s & app-chains
2613
- gnosisMainnet,
2614
- fantomMainnet,
2615
- celoMainnet,
2616
- sonicMainnet,
2617
- berachainMainnet,
2618
- moonbeamMainnet,
2619
- metisMainnet,
2620
- bobaMainnet,
2621
- roninMainnet,
2622
- kavaEvmMainnet,
2623
- cronosMainnet,
2624
- kaiaMainnet,
2625
- flareMainnet,
2626
- telosMainnet,
2627
- xdcMainnet,
2628
- fuseMainnet,
2629
- victionMainnet,
2630
- rootstockMainnet,
2631
- hederaMainnet,
2632
- filecoinMainnet,
2633
- flowMainnet,
2634
- opBnbMainnet,
2635
- lensMainnet,
2636
- apechainMainnet,
2637
- etherlinkMainnet,
2638
- hemiMainnet,
2639
- immutableZkEvmMainnet,
2640
- peaqMainnet,
2641
- sophonMainnet,
2642
- gravityMainnet,
2643
- vanaMainnet,
2644
- hyperliquidMainnet,
2645
- hyperEvmMainnet,
2646
- stableMainnet,
2647
- tempoMainnet,
2648
- plasmaMainnet,
2649
- somniaMainnet,
2650
- monadMainnet,
2651
- pharosMainnet,
2652
- bobMainnet,
2653
- plumeMainnet,
2654
- katanaMainnet,
2655
- cornMainnet,
2656
- // Sei EVM
2657
- seiMainnet
2658
- ];
2659
- solanaChains = [solanaMainnet];
2660
- bitcoinChains = [bitcoinMainnet];
2661
- cosmosChains = [seiCosmosMainnet];
2662
- networks = [
2663
- // ...solanaChains,
2664
- // ...bitcoinChains,
2665
- ...evmChains
2666
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
2667
- ];
2668
- namespaceConfig = [
2669
- {
2670
- namespace: "solana",
2671
- chains: solanaChains,
2672
- methods: ["solana_signMessage", "solana_signTransaction"],
2673
- events: []
2674
- },
2675
- {
2676
- namespace: "eip155",
2677
- chains: evmChains,
2678
- methods: [
2679
- "eth_sendTransaction",
2680
- "eth_signTransaction",
2681
- "eth_sign",
2682
- "personal_sign",
2683
- "eth_signTypedData_v4"
2684
- ],
2685
- events: ["accountsChanged", "chainChanged"]
2686
- },
2687
- {
2688
- namespace: "bip122",
2689
- chains: bitcoinChains,
2690
- methods: ["signMessage", "sendTransfer"],
2691
- events: []
2692
- },
2693
- {
2694
- namespace: "cosmos",
2695
- chains: cosmosChains,
2696
- methods: ["cosmos_signDirect", "cosmos_signAmino", "cosmos_getAccounts"],
2697
- events: []
2887
+ kavaEvmMainnet = {
2888
+ id: 2222,
2889
+ chainNamespace: "eip155",
2890
+ caipNetworkId: "eip155:2222",
2891
+ name: "Kava EVM",
2892
+ nativeCurrency: { name: "Kava", symbol: "KAVA", decimals: 18 },
2893
+ rpcUrls: {
2894
+ default: { http: ["https://evm2.kava.io"] }
2698
2895
  }
2699
- ];
2700
- universalConnectorPromise = null;
2701
- initializedProjectId = null;
2702
- }
2703
- });
2704
-
2705
- // src/wallets/manager.ts
2706
- function getChainMeta(chainId) {
2707
- const chain = evmChains.find((c) => c.id === chainId);
2708
- if (!chain) throw new Error(`Chain ${chainId} not configured`);
2709
- return {
2710
- chainId: `0x${chainId.toString(16)}`,
2711
- chainName: chain.name,
2712
- nativeCurrency: chain.nativeCurrency,
2713
- rpcUrls: chain.rpcUrls.default.http
2714
- };
2715
- }
2716
- async function buildWalletConnectAPI(walletCfg) {
2717
- const connector = await getUniversalConnector(walletCfg);
2718
- const provider = connector.provider;
2719
- const api = {
2720
- ecosystem: "evm",
2721
- type: "eip1193",
2722
- async getAddress() {
2723
- const accounts = await provider.request({
2724
- method: "eth_accounts"
2725
- });
2726
- if (!accounts?.[0])
2727
- throw new Error("No account connected via WalletConnect");
2728
- return accounts[0];
2729
- },
2730
- async getChainId() {
2731
- const hex = await provider.request({ method: "eth_chainId" });
2732
- return parseInt(hex, 16);
2733
- },
2734
- async switchChain(chainId) {
2735
- const hexChainId = `0x${chainId.toString(16)}`;
2736
- try {
2737
- await provider.request({
2738
- method: "wallet_switchEthereumChain",
2739
- params: [{ chainId: hexChainId }]
2740
- });
2741
- } catch (err) {
2742
- const code = err?.code;
2743
- if (code === 4902) {
2744
- const chainMeta = getChainMeta(chainId);
2745
- await provider.request({
2746
- method: "wallet_addEthereumChain",
2747
- params: [chainMeta]
2748
- });
2749
- } else {
2750
- throw err;
2751
- }
2896
+ };
2897
+ abstractMainnet = {
2898
+ id: 2741,
2899
+ chainNamespace: "eip155",
2900
+ caipNetworkId: "eip155:2741",
2901
+ name: "Abstract",
2902
+ nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2903
+ rpcUrls: {
2904
+ default: { http: ["https://api.mainnet.abs.xyz"] }
2752
2905
  }
2753
- },
2754
- async request(args) {
2755
- return provider.request(args);
2756
- },
2757
- async disconnect() {
2758
- await connector.disconnect().catch(() => {
2759
- });
2760
- }
2761
- };
2762
- return api;
2763
- }
2764
- function bindWalletConnectEvents(provider, callbacks) {
2765
- const onAccountsChanged = (accounts) => {
2766
- const list = Array.isArray(accounts) ? accounts : [];
2767
- callbacks.onAccountsChanged(list);
2768
- };
2769
- const onChainChanged = (chainId) => {
2770
- callbacks.onChainChanged(String(chainId));
2771
- };
2772
- const onDisconnect = () => {
2773
- callbacks.onDisconnect();
2774
- };
2775
- provider.on?.("accountsChanged", onAccountsChanged);
2776
- provider.on?.("chainChanged", onChainChanged);
2777
- provider.on?.("disconnect", onDisconnect);
2778
- return () => {
2779
- provider.removeListener?.("accountsChanged", onAccountsChanged);
2780
- provider.removeListener?.("chainChanged", onChainChanged);
2781
- provider.removeListener?.("disconnect", onDisconnect);
2782
- };
2783
- }
2784
- var import_react, WalletManager, walletManager;
2785
- var init_manager = __esm({
2786
- "src/wallets/manager.ts"() {
2787
- "use strict";
2788
- init_connect();
2789
- init_identity();
2790
- init_solana();
2791
- init_walletconnect();
2792
- import_react = require("react");
2793
- WalletManager = class {
2794
- constructor() {
2795
- this._status = "idle";
2796
- this._connectedVia = null;
2797
- this._wallet = null;
2798
- this._detected = [];
2799
- this._listeners = /* @__PURE__ */ new Set();
2800
- this._error = null;
2801
- this._identity = new IdentityStore();
2802
- this._providerCleanup = null;
2803
- this._connectedWalletId = null;
2804
- this._address = null;
2805
- this._onExternalDisconnectCallback = null;
2806
- this._snapshot = null;
2906
+ };
2907
+ morphMainnet = {
2908
+ id: 2818,
2909
+ chainNamespace: "eip155",
2910
+ caipNetworkId: "eip155:2818",
2911
+ name: "Morph",
2912
+ nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2913
+ rpcUrls: {
2914
+ default: { http: ["https://rpc.morph.network"] }
2807
2915
  }
2808
- get status() {
2809
- return this._status;
2916
+ };
2917
+ peaqMainnet = {
2918
+ id: 3338,
2919
+ chainNamespace: "eip155",
2920
+ caipNetworkId: "eip155:3338",
2921
+ name: "Peaq",
2922
+ nativeCurrency: { name: "Peaq", symbol: "PEAQ", decimals: 18 },
2923
+ rpcUrls: {
2924
+ default: { http: ["https://quicknode1.peaq.xyz"] }
2810
2925
  }
2811
- get error() {
2812
- return this._error;
2926
+ };
2927
+ tempoMainnet = {
2928
+ id: 4217,
2929
+ chainNamespace: "eip155",
2930
+ caipNetworkId: "eip155:4217",
2931
+ name: "Tempo",
2932
+ nativeCurrency: { name: "PathUSD", symbol: "PathUSD", decimals: 6 },
2933
+ rpcUrls: {
2934
+ default: { http: ["https://rpc.tempo.xyz"] }
2813
2935
  }
2814
- get detected() {
2815
- return this._detected;
2936
+ };
2937
+ megaEthMainnet = {
2938
+ id: 4326,
2939
+ chainNamespace: "eip155",
2940
+ caipNetworkId: "eip155:4326",
2941
+ name: "MegaETH",
2942
+ nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
2943
+ rpcUrls: {
2944
+ default: { http: ["https://mainnet.megaeth.com/rpc"] }
2816
2945
  }
2817
- get wallet() {
2818
- return this._wallet;
2946
+ };
2947
+ mantleMainnet = {
2948
+ id: 5e3,
2949
+ chainNamespace: "eip155",
2950
+ caipNetworkId: "eip155:5000",
2951
+ name: "Mantle Mainnet",
2952
+ nativeCurrency: { name: "Mantle", symbol: "MNT", decimals: 18 },
2953
+ rpcUrls: {
2954
+ default: { http: ["https://rpc.mantle.xyz"] }
2819
2955
  }
2820
- get connectedVia() {
2821
- return this._connectedVia;
2956
+ };
2957
+ somniaMainnet = {
2958
+ id: 5031,
2959
+ chainNamespace: "eip155",
2960
+ caipNetworkId: "eip155:5031",
2961
+ name: "Somnia",
2962
+ nativeCurrency: { name: "Somnia", symbol: "SOMI", decimals: 18 },
2963
+ rpcUrls: {
2964
+ default: { http: ["https://api.infra.mainnet.somnia.network/"] }
2822
2965
  }
2823
- get connectedWalletId() {
2824
- return this._connectedWalletId;
2966
+ };
2967
+ kaiaMainnet = {
2968
+ id: 8217,
2969
+ chainNamespace: "eip155",
2970
+ caipNetworkId: "eip155:8217",
2971
+ name: "Kaia",
2972
+ nativeCurrency: { name: "KAIA", symbol: "KAIA", decimals: 18 },
2973
+ rpcUrls: {
2974
+ default: { http: ["https://public-en.node.kaia.io"] }
2825
2975
  }
2826
- get address() {
2827
- return this._address;
2976
+ };
2977
+ baseMainnet = {
2978
+ id: 8453,
2979
+ chainNamespace: "eip155",
2980
+ caipNetworkId: "eip155:8453",
2981
+ name: "Base Mainnet",
2982
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
2983
+ rpcUrls: {
2984
+ default: { http: ["https://mainnet.base.org"] }
2828
2985
  }
2829
- get isConnected() {
2830
- return this._status === "connected";
2986
+ };
2987
+ plasmaMainnet = {
2988
+ id: 9745,
2989
+ chainNamespace: "eip155",
2990
+ caipNetworkId: "eip155:9745",
2991
+ name: "Plasma",
2992
+ nativeCurrency: { name: "XPL", symbol: "XPL", decimals: 18 },
2993
+ rpcUrls: {
2994
+ default: { http: ["https://rpc.plasma.to"] }
2831
2995
  }
2832
- get walletType() {
2833
- return this._connectedVia === "walletconnect" ? "walletconnect" : "other";
2996
+ };
2997
+ immutableZkEvmMainnet = {
2998
+ id: 13371,
2999
+ chainNamespace: "eip155",
3000
+ caipNetworkId: "eip155:13371",
3001
+ name: "Immutable zkEVM",
3002
+ nativeCurrency: { name: "IMX", symbol: "IMX", decimals: 18 },
3003
+ rpcUrls: {
3004
+ default: { http: ["https://rpc.immutable.com"] }
2834
3005
  }
2835
- get simple() {
2836
- if (!this._wallet) return null;
2837
- const { getAddress, disconnect } = this._wallet;
2838
- return { getAddress, disconnect };
3006
+ };
3007
+ apechainMainnet = {
3008
+ id: 33139,
3009
+ chainNamespace: "eip155",
3010
+ caipNetworkId: "eip155:33139",
3011
+ name: "Apechain",
3012
+ nativeCurrency: { name: "ApeCoin", symbol: "APE", decimals: 18 },
3013
+ rpcUrls: {
3014
+ default: { http: ["https://rpc.apechain.com"] }
2839
3015
  }
2840
- get identity() {
2841
- return this._identity.snapshot;
3016
+ };
3017
+ modeMainnet = {
3018
+ id: 34443,
3019
+ chainNamespace: "eip155",
3020
+ caipNetworkId: "eip155:34443",
3021
+ name: "Mode",
3022
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
3023
+ rpcUrls: {
3024
+ default: { http: ["https://mainnet.mode.network"] }
2842
3025
  }
2843
- get snapshot() {
2844
- if (!this._snapshot) {
2845
- this._snapshot = this.buildSnapshot();
2846
- }
2847
- return this._snapshot;
3026
+ };
3027
+ arbitrumMainnet = {
3028
+ id: 42161,
3029
+ chainNamespace: "eip155",
3030
+ caipNetworkId: "eip155:42161",
3031
+ name: "Arbitrum One",
3032
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
3033
+ rpcUrls: {
3034
+ default: { http: ["https://rpc.ankr.com/arbitrum"] }
2848
3035
  }
2849
- buildSnapshot() {
2850
- return {
2851
- status: this._status,
2852
- connectedVia: this._connectedVia,
2853
- walletType: this.walletType,
2854
- error: this._error,
2855
- detected: this._detected,
2856
- wallet: this._wallet,
2857
- simple: this.simple,
2858
- identity: this.identity,
2859
- connectedWalletId: this._connectedWalletId,
2860
- address: this._address,
2861
- isConnected: this.isConnected
2862
- };
3036
+ };
3037
+ arbitrumNovaMainnet = {
3038
+ id: 42170,
3039
+ chainNamespace: "eip155",
3040
+ caipNetworkId: "eip155:42170",
3041
+ name: "Arbitrum Nova",
3042
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
3043
+ rpcUrls: {
3044
+ default: { http: ["https://arbitrum-nova-rpc.publicnode.com"] }
2863
3045
  }
2864
- onChange(fn) {
2865
- this._listeners.add(fn);
2866
- return () => this._listeners.delete(fn);
3046
+ };
3047
+ celoMainnet = {
3048
+ id: 42220,
3049
+ chainNamespace: "eip155",
3050
+ caipNetworkId: "eip155:42220",
3051
+ name: "Celo Mainnet",
3052
+ nativeCurrency: { name: "Celo", symbol: "CELO", decimals: 18 },
3053
+ rpcUrls: {
3054
+ default: { http: ["https://rpc.ankr.com/celo"] }
2867
3055
  }
2868
- emit() {
2869
- this._snapshot = null;
2870
- for (const fn of this._listeners) fn(this._status);
3056
+ };
3057
+ etherlinkMainnet = {
3058
+ id: 42793,
3059
+ chainNamespace: "eip155",
3060
+ caipNetworkId: "eip155:42793",
3061
+ name: "Etherlink",
3062
+ nativeCurrency: { name: "Tezos", symbol: "XTZ", decimals: 18 },
3063
+ rpcUrls: {
3064
+ default: { http: ["https://node.mainnet.etherlink.com"] }
2871
3065
  }
2872
- onExternalDisconnect(cb) {
2873
- this._onExternalDisconnectCallback = cb;
2874
- return () => {
2875
- if (this._onExternalDisconnectCallback === cb) {
2876
- this._onExternalDisconnectCallback = null;
2877
- }
2878
- };
3066
+ };
3067
+ hemiMainnet = {
3068
+ id: 43111,
3069
+ chainNamespace: "eip155",
3070
+ caipNetworkId: "eip155:43111",
3071
+ name: "Hemi",
3072
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
3073
+ rpcUrls: {
3074
+ default: { http: ["https://rpc.hemi.network/rpc"] }
2879
3075
  }
2880
- triggerExternalDisconnect() {
2881
- this._onExternalDisconnectCallback?.();
3076
+ };
3077
+ avalancheMainnet = {
3078
+ id: 43114,
3079
+ chainNamespace: "eip155",
3080
+ caipNetworkId: "eip155:43114",
3081
+ name: "Avalanche C-Chain",
3082
+ nativeCurrency: { name: "Avalanche", symbol: "AVAX", decimals: 18 },
3083
+ rpcUrls: {
3084
+ default: { http: ["https://rpc.ankr.com/avalanche"] }
2882
3085
  }
2883
- setDetected(list) {
2884
- this._detected = list;
3086
+ };
3087
+ sophonMainnet = {
3088
+ id: 50104,
3089
+ chainNamespace: "eip155",
3090
+ caipNetworkId: "eip155:50104",
3091
+ name: "Sophon",
3092
+ nativeCurrency: { name: "SOPH", symbol: "SOPH", decimals: 18 },
3093
+ rpcUrls: {
3094
+ default: { http: ["https://rpc.sophon.xyz"] }
2885
3095
  }
2886
- async autoAttach(opts) {
2887
- if (!this._detected.length) return;
2888
- const target = (opts?.pick ?? ((l) => l[0]))(this._detected);
2889
- if (!target) return;
2890
- await this.connectDetected(target, opts);
3096
+ };
3097
+ superpositionMainnet = {
3098
+ id: 55244,
3099
+ chainNamespace: "eip155",
3100
+ caipNetworkId: "eip155:55244",
3101
+ name: "Superposition",
3102
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
3103
+ rpcUrls: {
3104
+ default: { http: ["https://rpc.superposition.so"] }
2891
3105
  }
2892
- async connectDetected(target, opts) {
2893
- if (this._status === "connected" && this._connectedVia === "extension" && this._connectedWalletId === target.meta.id && this._wallet) {
2894
- this.emit();
2895
- return;
2896
- }
2897
- this._status = "connecting";
2898
- this.clearConnectedState();
2899
- this.emit();
2900
- try {
2901
- const { api, error } = await connectDetectedWallet(target, {
2902
- wagmi: opts?.wagmi
2903
- });
2904
- if (api && !error) {
2905
- this._wallet = api;
2906
- this._connectedVia = "extension";
2907
- this._connectedWalletId = target.meta.id;
2908
- this.bindExtensionProviderEvents(target);
2909
- await this.syncIdentityFromWallet(target.meta.id);
2910
- this._status = "connected";
2911
- this._error = null;
2912
- return { error: null, api };
2913
- }
2914
- if (error) {
2915
- this._status = "error";
2916
- this._error = error;
2917
- return { error, api };
2918
- }
2919
- } catch (e2) {
2920
- this._error = e2 instanceof Error ? e2.message : String(e2);
2921
- this._status = "error";
2922
- this.clearConnectedState();
2923
- } finally {
2924
- this.emit();
2925
- }
3106
+ };
3107
+ inkMainnet = {
3108
+ id: 57073,
3109
+ chainNamespace: "eip155",
3110
+ caipNetworkId: "eip155:57073",
3111
+ name: "Ink",
3112
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
3113
+ rpcUrls: {
3114
+ default: { http: ["https://rpc-gel.inkonchain.com"] }
2926
3115
  }
2927
- async connectWalletConnect(walletCfg) {
2928
- if (this._status === "connected" && this._connectedVia === "walletconnect" && this._wallet) {
2929
- this.emit();
2930
- return { error: null, api: this._wallet };
2931
- }
2932
- this._status = "connecting";
2933
- this.clearConnectedState();
2934
- this.emit();
2935
- try {
2936
- const connector = await getUniversalConnector(walletCfg);
2937
- await connector.connect();
2938
- const api = await buildWalletConnectAPI(walletCfg);
2939
- this._wallet = api;
2940
- this._connectedVia = "walletconnect";
2941
- this._connectedWalletId = "walletconnect";
2942
- const provider = connector.provider;
2943
- this._providerCleanup = bindWalletConnectEvents(provider, {
2944
- onAccountsChanged: (accounts) => {
2945
- if (accounts.length === 0) {
2946
- this.fullReset();
2947
- this.triggerExternalDisconnect();
2948
- this.emit();
2949
- return;
2950
- }
2951
- void this.syncIdentityFromWallet("walletconnect");
2952
- this.emit();
2953
- },
2954
- onChainChanged: () => {
2955
- void this.syncIdentityFromWallet("walletconnect");
2956
- this.emit();
2957
- },
2958
- onDisconnect: () => {
2959
- this.fullReset();
2960
- resetUniversalConnector();
2961
- this.triggerExternalDisconnect();
2962
- this.emit();
2963
- }
2964
- });
2965
- await this.syncIdentityFromWallet("walletconnect");
2966
- this._status = "connected";
2967
- this._error = null;
2968
- this.emit();
2969
- return { error: null, api };
2970
- } catch (e2) {
2971
- const message = e2 instanceof Error ? e2.message : String(e2);
2972
- this._error = message;
2973
- this._status = "error";
2974
- this.clearConnectedState();
2975
- this.emit();
2976
- return { error: message, api: null };
2977
- }
3116
+ };
3117
+ lineaMainnet = {
3118
+ id: 59144,
3119
+ chainNamespace: "eip155",
3120
+ caipNetworkId: "eip155:59144",
3121
+ name: "Linea Mainnet",
3122
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
3123
+ rpcUrls: {
3124
+ default: { http: ["https://rpc.linea.build"] }
2978
3125
  }
2979
- async disconnect(wagmi) {
2980
- if (wagmi && this._connectedVia === "extension") {
2981
- await wagmi.disconnect().catch(() => {
2982
- });
2983
- }
2984
- if (this._wallet?.disconnect) {
2985
- await this._wallet.disconnect().catch(() => {
2986
- });
2987
- }
2988
- if (this._connectedVia === "walletconnect") {
2989
- resetUniversalConnector();
2990
- }
2991
- this.fullReset();
2992
- this.emit();
3126
+ };
3127
+ bobMainnet = {
3128
+ id: 60808,
3129
+ chainNamespace: "eip155",
3130
+ caipNetworkId: "eip155:60808",
3131
+ name: "BOB",
3132
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
3133
+ rpcUrls: {
3134
+ default: { http: ["https://rpc.gobob.xyz"] }
2993
3135
  }
2994
- attachWallet(api) {
2995
- this.clearConnectedState();
2996
- this._wallet = api;
2997
- this._connectedVia = "direct";
2998
- this._connectedWalletId = null;
2999
- this._status = "connected";
3000
- void this.syncIdentityFromWallet();
3001
- this.emit();
3136
+ };
3137
+ berachainMainnet = {
3138
+ id: 80094,
3139
+ chainNamespace: "eip155",
3140
+ caipNetworkId: "eip155:80094",
3141
+ name: "Berachain",
3142
+ nativeCurrency: { name: "BERA", symbol: "BERA", decimals: 18 },
3143
+ rpcUrls: {
3144
+ default: { http: ["https://rpc.berachain.com/"] }
3002
3145
  }
3003
- setStatus(s) {
3004
- this._status = s;
3005
- this.emit();
3146
+ };
3147
+ blastMainnet = {
3148
+ id: 81457,
3149
+ chainNamespace: "eip155",
3150
+ caipNetworkId: "eip155:81457",
3151
+ name: "Blast Mainnet",
3152
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
3153
+ rpcUrls: {
3154
+ default: { http: ["https://rpc.blast.io"] }
3006
3155
  }
3007
- addIdentityAddress(address) {
3008
- this._identity.upsert(address);
3156
+ };
3157
+ plumeMainnet = {
3158
+ id: 98866,
3159
+ chainNamespace: "eip155",
3160
+ caipNetworkId: "eip155:98866",
3161
+ name: "Plume",
3162
+ nativeCurrency: { name: "PLUME", symbol: "PLUME", decimals: 18 },
3163
+ rpcUrls: {
3164
+ default: { http: ["https://rpc.plume.org"] }
3009
3165
  }
3010
- resolveAddressForChain(chain) {
3011
- return this._identity.resolve(chain);
3166
+ };
3167
+ taikoMainnet = {
3168
+ id: 167e3,
3169
+ chainNamespace: "eip155",
3170
+ caipNetworkId: "eip155:167000",
3171
+ name: "Taiko",
3172
+ nativeCurrency: { name: "Ethereum", symbol: "ETH", decimals: 18 },
3173
+ rpcUrls: {
3174
+ default: { http: ["https://rpc.mainnet.taiko.xyz"] }
3012
3175
  }
3013
- clearProviderCleanup() {
3014
- this._providerCleanup?.();
3015
- this._providerCleanup = null;
3176
+ };
3177
+ scrollMainnet = {
3178
+ id: 534352,
3179
+ chainNamespace: "eip155",
3180
+ caipNetworkId: "eip155:534352",
3181
+ name: "Scroll",
3182
+ nativeCurrency: { name: "Scroll", symbol: "ETH", decimals: 18 },
3183
+ rpcUrls: {
3184
+ default: { http: ["https://rpc.scroll.io"] }
3016
3185
  }
3017
- clearConnectedState() {
3018
- this.clearProviderCleanup();
3019
- this._wallet = null;
3020
- this._connectedVia = null;
3021
- this._connectedWalletId = null;
3186
+ };
3187
+ katanaMainnet = {
3188
+ id: 747474,
3189
+ chainNamespace: "eip155",
3190
+ caipNetworkId: "eip155:747474",
3191
+ name: "Katana",
3192
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
3193
+ rpcUrls: {
3194
+ default: { http: ["https://rpc.katana.network"] }
3022
3195
  }
3023
- fullReset() {
3024
- this.clearConnectedState();
3025
- this._address = null;
3026
- this._identity = new IdentityStore();
3027
- this._status = "idle";
3028
- this._error = null;
3029
- }
3030
- bindExtensionProviderEvents(target) {
3031
- if (!target.provider) return;
3032
- if (target.via === "solana-window") {
3033
- this._providerCleanup = bindSolanaProviderEvents(target.provider, {
3034
- onConnect: () => {
3035
- this._status = "connected";
3036
- void this.syncIdentityFromWallet(target.meta.id);
3037
- this.emit();
3038
- },
3039
- onAccountChanged: () => {
3040
- void this.syncIdentityFromWallet(target.meta.id);
3041
- this.emit();
3042
- },
3043
- onDisconnect: () => {
3044
- this.fullReset();
3045
- this.triggerExternalDisconnect();
3046
- this.emit();
3047
- }
3048
- });
3049
- return;
3050
- }
3051
- const provider = target.provider;
3052
- const onAccountsChanged = (accounts) => {
3053
- const nextAccounts = Array.isArray(accounts) ? accounts : [];
3054
- if (nextAccounts.length === 0) {
3055
- this.fullReset();
3056
- this.triggerExternalDisconnect();
3057
- this.emit();
3058
- return;
3059
- }
3060
- this._status = "connected";
3061
- void this.syncIdentityFromWallet(target.meta.id);
3062
- this.emit();
3063
- };
3064
- const onDisconnect = () => {
3065
- this.fullReset();
3066
- this.triggerExternalDisconnect();
3067
- this.emit();
3068
- };
3069
- provider.on?.("accountsChanged", onAccountsChanged);
3070
- provider.on?.("disconnect", onDisconnect);
3071
- this._providerCleanup = () => {
3072
- provider.off?.("accountsChanged", onAccountsChanged);
3073
- provider.off?.("disconnect", onDisconnect);
3074
- provider.removeListener?.("accountsChanged", onAccountsChanged);
3075
- provider.removeListener?.("disconnect", onDisconnect);
3076
- };
3077
- }
3078
- async syncIdentityFromWallet(providerId) {
3079
- if (!this._wallet) return;
3080
- try {
3081
- const address = await this._wallet.getAddress();
3082
- this._address = address;
3083
- const chain = this._wallet.ecosystem === "evm" ? { chainId: String(await this._wallet.getChainId()), type: "evm" } : this._wallet.ecosystem === "solana" ? {
3084
- chainId: "solana-mainnet-beta",
3085
- networkIdentifier: "solana-mainnet-beta",
3086
- type: "solana"
3087
- } : {
3088
- chainId: "bip122:000000000019d6689c085ae165831e93",
3089
- networkIdentifier: "bitcoin-mainnet",
3090
- type: "bitcoin"
3091
- };
3092
- const identityAddress = buildWalletIdentityAddress({
3093
- address,
3094
- chain,
3095
- source: "provider",
3096
- providerId
3097
- });
3098
- if (identityAddress) {
3099
- this._identity.upsert(identityAddress);
3100
- }
3101
- } catch {
3102
- }
3196
+ };
3197
+ cornMainnet = {
3198
+ id: 21e6,
3199
+ chainNamespace: "eip155",
3200
+ caipNetworkId: "eip155:21000000",
3201
+ name: "Corn",
3202
+ nativeCurrency: { name: "Bitcorn", symbol: "BTCN", decimals: 18 },
3203
+ rpcUrls: {
3204
+ default: { http: ["https://mainnet.corn-rpc.com"] }
3103
3205
  }
3104
3206
  };
3105
- walletManager = new WalletManager();
3106
- }
3107
- });
3108
-
3109
- // src/wallets/index.ts
3110
- var init_wallets = __esm({
3111
- "src/wallets/index.ts"() {
3112
- "use strict";
3113
- init_bridges();
3114
- init_connect();
3115
- init_manager();
3116
- init_adapters();
3117
- init_solana();
3207
+ evmChains = [
3208
+ // Major L1s
3209
+ ethereumMainnet,
3210
+ bscMainnet,
3211
+ avalancheMainnet,
3212
+ polygonMainnet,
3213
+ // L2s / rollups
3214
+ arbitrumMainnet,
3215
+ arbitrumNovaMainnet,
3216
+ optimismMainnet,
3217
+ baseMainnet,
3218
+ zkSyncMainnet,
3219
+ lineaMainnet,
3220
+ mantleMainnet,
3221
+ blastMainnet,
3222
+ scrollMainnet,
3223
+ taikoMainnet,
3224
+ modeMainnet,
3225
+ inkMainnet,
3226
+ unichainMainnet,
3227
+ worldchainMainnet,
3228
+ swellchainMainnet,
3229
+ soneiumMainnet,
3230
+ liskMainnet,
3231
+ morphMainnet,
3232
+ abstractMainnet,
3233
+ megaEthMainnet,
3234
+ superpositionMainnet,
3235
+ fraxtalMainnet,
3236
+ // EVM-compatible L1s & app-chains
3237
+ gnosisMainnet,
3238
+ fantomMainnet,
3239
+ celoMainnet,
3240
+ sonicMainnet,
3241
+ berachainMainnet,
3242
+ moonbeamMainnet,
3243
+ metisMainnet,
3244
+ bobaMainnet,
3245
+ roninMainnet,
3246
+ kavaEvmMainnet,
3247
+ cronosMainnet,
3248
+ kaiaMainnet,
3249
+ flareMainnet,
3250
+ telosMainnet,
3251
+ xdcMainnet,
3252
+ fuseMainnet,
3253
+ victionMainnet,
3254
+ rootstockMainnet,
3255
+ hederaMainnet,
3256
+ filecoinMainnet,
3257
+ flowMainnet,
3258
+ opBnbMainnet,
3259
+ lensMainnet,
3260
+ apechainMainnet,
3261
+ etherlinkMainnet,
3262
+ hemiMainnet,
3263
+ immutableZkEvmMainnet,
3264
+ peaqMainnet,
3265
+ sophonMainnet,
3266
+ gravityMainnet,
3267
+ vanaMainnet,
3268
+ hyperliquidMainnet,
3269
+ hyperEvmMainnet,
3270
+ stableMainnet,
3271
+ tempoMainnet,
3272
+ plasmaMainnet,
3273
+ somniaMainnet,
3274
+ monadMainnet,
3275
+ pharosMainnet,
3276
+ bobMainnet,
3277
+ plumeMainnet,
3278
+ katanaMainnet,
3279
+ cornMainnet,
3280
+ // Sei EVM
3281
+ seiMainnet
3282
+ ];
3283
+ solanaChains = [solanaMainnet];
3284
+ bitcoinChains = [bitcoinMainnet];
3285
+ cosmosChains = [seiCosmosMainnet];
3286
+ networks = [
3287
+ // ...solanaChains,
3288
+ // ...bitcoinChains,
3289
+ ...evmChains
3290
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3291
+ ];
3292
+ namespaceConfig = [
3293
+ {
3294
+ namespace: "solana",
3295
+ chains: solanaChains,
3296
+ methods: ["solana_signMessage", "solana_signTransaction"],
3297
+ events: []
3298
+ },
3299
+ {
3300
+ namespace: "eip155",
3301
+ chains: evmChains,
3302
+ methods: [
3303
+ "eth_sendTransaction",
3304
+ "eth_signTransaction",
3305
+ "eth_sign",
3306
+ "personal_sign",
3307
+ "eth_signTypedData_v4"
3308
+ ],
3309
+ events: ["accountsChanged", "chainChanged"]
3310
+ },
3311
+ {
3312
+ namespace: "bip122",
3313
+ chains: bitcoinChains,
3314
+ methods: ["signMessage", "sendTransfer"],
3315
+ events: []
3316
+ },
3317
+ {
3318
+ namespace: "cosmos",
3319
+ chains: cosmosChains,
3320
+ methods: ["cosmos_signDirect", "cosmos_signAmino", "cosmos_getAccounts"],
3321
+ events: []
3322
+ }
3323
+ ];
3324
+ universalConnectorPromise = null;
3325
+ initializedProjectId = null;
3118
3326
  }
3119
3327
  });
3120
3328
 
3121
- // src/registry.ts
3122
- var registry_exports = {};
3123
- __export(registry_exports, {
3124
- NATIVE: () => NATIVE,
3125
- Registry: () => Registry
3126
- });
3127
- function getChainAliases(chain) {
3128
- const values = [
3129
- chain.chainId,
3130
- chain.id,
3131
- chain.networkIdentifier,
3132
- chain.axelarChainName,
3133
- chain.networkName
3134
- ];
3135
- return values.map((value) => normalizeChainKey(value)).filter(Boolean);
3136
- }
3137
- function tokenKey(token) {
3138
- return `${normalizeChainKey(token.chainId)}:${token.address.toLowerCase()}`;
3139
- }
3140
- function parseTokenPage(payload) {
3141
- if (Array.isArray(payload)) {
3142
- return {
3143
- data: payload,
3144
- pageInfo: { hasNextPage: false }
3145
- };
3146
- }
3147
- const parsed = payload ?? {};
3148
- const data = parsed.data ?? parsed.results ?? parsed.tokens ?? [];
3149
- const info = parsed.pageInfo ?? parsed.pagination;
3150
- return {
3151
- data: Array.isArray(data) ? data : [],
3152
- pageInfo: {
3153
- hasNextPage: info?.hasNextPage ?? parsed.hasNextPage ?? Boolean(info?.nextCursor),
3154
- nextCursor: info?.nextCursor ?? parsed.nextCursor
3155
- }
3156
- };
3157
- }
3158
- function normalizeToken(token) {
3329
+ // src/wallets/manager.ts
3330
+ function getChainMeta(chainId) {
3331
+ const chain = evmChains.find((c) => c.id === chainId);
3332
+ if (!chain) throw new Error(`Chain ${chainId} not configured`);
3159
3333
  return {
3160
- ...token,
3161
- chainId: token.chainId
3334
+ chainId: `0x${chainId.toString(16)}`,
3335
+ chainName: chain.name,
3336
+ nativeCurrency: chain.nativeCurrency,
3337
+ rpcUrls: chain.rpcUrls.default.http
3162
3338
  };
3163
3339
  }
3164
- var NATIVE, PAGE_CACHE_TTL_MS, PAGE_CACHE_LIMIT, Registry;
3165
- var init_registry = __esm({
3166
- "src/registry.ts"() {
3167
- "use strict";
3168
- init_store();
3169
- init_chains();
3170
- NATIVE = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
3171
- PAGE_CACHE_TTL_MS = 5 * 60 * 1e3;
3172
- PAGE_CACHE_LIMIT = 100;
3173
- Registry = class {
3174
- constructor(baseURL) {
3175
- this.baseURL = baseURL;
3176
- this._chainsById = /* @__PURE__ */ new Map();
3177
- this._chainAliases = /* @__PURE__ */ new Map();
3178
- this._tokensByChain = /* @__PURE__ */ new Map();
3179
- this._tokensByChainKey = /* @__PURE__ */ new Map();
3180
- this._pageCache = /* @__PURE__ */ new Map();
3181
- this._loaded = false;
3182
- this._chainsLoaded = false;
3183
- this._loadingPromise = null;
3184
- this._chainsLoadingPromise = null;
3185
- }
3186
- async ensureLoaded() {
3187
- if (this._loaded) return;
3188
- if (this._loadingPromise) {
3189
- await this._loadingPromise;
3190
- return;
3191
- }
3192
- this._loadingPromise = this.loadAllTokens();
3193
- try {
3194
- await this._loadingPromise;
3195
- } finally {
3196
- this._loadingPromise = null;
3197
- }
3198
- }
3199
- async ensureChainsLoaded() {
3200
- if (this._chainsLoaded) return;
3201
- if (this._chainsLoadingPromise) {
3202
- await this._chainsLoadingPromise;
3203
- return;
3204
- }
3205
- this._chainsLoadingPromise = this.loadChains();
3206
- try {
3207
- await this._chainsLoadingPromise;
3208
- } finally {
3209
- this._chainsLoadingPromise = null;
3340
+ async function buildWalletConnectAPI(walletCfg) {
3341
+ const connector = await getUniversalConnector(walletCfg);
3342
+ const provider = connector.provider;
3343
+ const api = {
3344
+ ecosystem: "evm",
3345
+ type: "eip1193",
3346
+ async getAddress() {
3347
+ const accounts = await provider.request({
3348
+ method: "eth_accounts"
3349
+ });
3350
+ if (!accounts?.[0])
3351
+ throw new Error("No account connected via WalletConnect");
3352
+ return accounts[0];
3353
+ },
3354
+ async getChainId() {
3355
+ const hex = await provider.request({ method: "eth_chainId" });
3356
+ return parseInt(hex, 16);
3357
+ },
3358
+ async switchChain(chainId) {
3359
+ const hexChainId = `0x${chainId.toString(16)}`;
3360
+ try {
3361
+ await provider.request({
3362
+ method: "wallet_switchEthereumChain",
3363
+ params: [{ chainId: hexChainId }]
3364
+ });
3365
+ } catch (err) {
3366
+ const code = err?.code;
3367
+ if (code === 4902) {
3368
+ const chainMeta = getChainMeta(chainId);
3369
+ await provider.request({
3370
+ method: "wallet_addEthereumChain",
3371
+ params: [chainMeta]
3372
+ });
3373
+ } else {
3374
+ throw err;
3210
3375
  }
3211
3376
  }
3212
- get config() {
3213
- return TrustwareConfigStore.get();
3377
+ },
3378
+ async request(args) {
3379
+ return provider.request(args);
3380
+ },
3381
+ async disconnect() {
3382
+ await connector.disconnect().catch(() => {
3383
+ });
3384
+ }
3385
+ };
3386
+ return api;
3387
+ }
3388
+ function bindWalletConnectEvents(provider, callbacks) {
3389
+ const onAccountsChanged = (accounts) => {
3390
+ const list = Array.isArray(accounts) ? accounts : [];
3391
+ callbacks.onAccountsChanged(list);
3392
+ };
3393
+ const onChainChanged = (chainId) => {
3394
+ callbacks.onChainChanged(String(chainId));
3395
+ };
3396
+ const onDisconnect = () => {
3397
+ callbacks.onDisconnect();
3398
+ };
3399
+ provider.on?.("accountsChanged", onAccountsChanged);
3400
+ provider.on?.("chainChanged", onChainChanged);
3401
+ provider.on?.("disconnect", onDisconnect);
3402
+ return () => {
3403
+ provider.removeListener?.("accountsChanged", onAccountsChanged);
3404
+ provider.removeListener?.("chainChanged", onChainChanged);
3405
+ provider.removeListener?.("disconnect", onDisconnect);
3406
+ };
3407
+ }
3408
+ var import_react, WalletManager, walletManager;
3409
+ var init_manager = __esm({
3410
+ "src/wallets/manager.ts"() {
3411
+ "use strict";
3412
+ init_connect();
3413
+ init_identity();
3414
+ init_solana();
3415
+ init_walletconnect();
3416
+ import_react = require("react");
3417
+ WalletManager = class {
3418
+ constructor() {
3419
+ this._status = "idle";
3420
+ this._connectedVia = null;
3421
+ this._wallet = null;
3422
+ this._detected = [];
3423
+ this._listeners = /* @__PURE__ */ new Set();
3424
+ this._error = null;
3425
+ this._identity = new IdentityStore();
3426
+ this._providerCleanup = null;
3427
+ this._connectedWalletId = null;
3428
+ this._address = null;
3429
+ this._onExternalDisconnectCallback = null;
3430
+ this._snapshot = null;
3214
3431
  }
3215
- emitPageLoaded(chainRef, query, result, cursor) {
3216
- this.config.onEvent?.({
3217
- type: "token_page_loaded",
3218
- chainRef: String(chainRef),
3219
- query,
3220
- count: result.data.length,
3221
- hasNextPage: result.pageInfo.hasNextPage,
3222
- cursor
3223
- });
3432
+ get status() {
3433
+ return this._status;
3224
3434
  }
3225
- emitPageError(chainRef, query, cursor, error) {
3226
- const message = error instanceof Error ? error.message : String(error);
3227
- this.config.onEvent?.({
3228
- type: "token_page_error",
3229
- chainRef: String(chainRef),
3230
- query,
3231
- cursor,
3232
- message
3233
- });
3435
+ get error() {
3436
+ return this._error;
3234
3437
  }
3235
- storeChain(chain) {
3236
- const canonical = chain?.chainId ?? chain?.id;
3237
- if (canonical == null) return;
3238
- const normalized = {
3239
- ...chain,
3240
- id: chain.id ?? canonical,
3241
- chainId: chain.chainId ?? canonical
3242
- };
3243
- const canonicalKey = normalizeChainKey(canonical);
3244
- this._chainsById.set(canonicalKey, normalized);
3245
- for (const alias of getChainAliases(normalized)) {
3246
- this._chainAliases.set(alias, canonicalKey);
3247
- }
3438
+ get detected() {
3439
+ return this._detected;
3248
3440
  }
3249
- storeTokenForAlias(chainKey, token) {
3250
- const key = tokenKey(token);
3251
- const existingByKey = this._tokensByChainKey.get(chainKey) ?? /* @__PURE__ */ new Map();
3252
- existingByKey.set(key, token);
3253
- this._tokensByChainKey.set(chainKey, existingByKey);
3254
- this._tokensByChain.set(chainKey, Array.from(existingByKey.values()));
3441
+ get wallet() {
3442
+ return this._wallet;
3255
3443
  }
3256
- storeToken(token) {
3257
- const chainRef = token?.chainId;
3258
- if (chainRef == null) return;
3259
- const normalized = normalizeToken(token);
3260
- const resolvedChain = this.chain(chainRef);
3261
- const aliases = resolvedChain ? getChainAliases(resolvedChain) : [normalizeChainKey(chainRef)];
3262
- for (const alias of aliases) {
3263
- this.storeTokenForAlias(alias, normalized);
3264
- }
3444
+ get connectedVia() {
3445
+ return this._connectedVia;
3265
3446
  }
3266
- async loadChains() {
3267
- const chainsRes = await fetch(`${this.baseURL}/v1/routes/chains`, {
3268
- headers: { Accept: "application/json", "X-API-Key": this.config.apiKey }
3269
- });
3270
- if (!chainsRes.ok) throw new Error(`chains: HTTP ${chainsRes.status}`);
3271
- const chains = await chainsRes.json();
3272
- const chainsArr = Array.isArray(chains) ? chains : chains.data ?? [];
3273
- for (const chain of chainsArr) {
3274
- this.storeChain(chain);
3275
- }
3276
- this._chainsLoaded = true;
3447
+ get connectedWalletId() {
3448
+ return this._connectedWalletId;
3277
3449
  }
3278
- async loadAllTokens() {
3279
- await this.ensureChainsLoaded();
3280
- const tokensRes = await fetch(`${this.baseURL}/v1/routes/tokens`, {
3281
- headers: { Accept: "application/json", "X-API-Key": this.config.apiKey }
3282
- });
3283
- if (!tokensRes.ok) throw new Error(`tokens: HTTP ${tokensRes.status}`);
3284
- const tokens = await tokensRes.json();
3285
- const tokensArr = Array.isArray(tokens) ? tokens : tokens.data ?? [];
3286
- for (const token of tokensArr) {
3287
- this.storeToken(token);
3288
- }
3289
- this._loaded = true;
3450
+ get address() {
3451
+ return this._address;
3290
3452
  }
3291
- prunePageCache() {
3292
- const now = Date.now();
3293
- for (const [key, value] of this._pageCache.entries()) {
3294
- if (now - value.storedAt > PAGE_CACHE_TTL_MS) {
3295
- this._pageCache.delete(key);
3296
- }
3297
- }
3298
- while (this._pageCache.size > PAGE_CACHE_LIMIT) {
3299
- const oldestKey = this._pageCache.keys().next().value;
3300
- if (!oldestKey) {
3301
- break;
3302
- }
3303
- this._pageCache.delete(oldestKey);
3304
- }
3453
+ get isConnected() {
3454
+ return this._status === "connected";
3305
3455
  }
3306
- pageCacheKey(chainRef, opts = {}) {
3307
- const chain = this.chain(chainRef);
3308
- const canonical = normalizeChainKey(chain?.chainId ?? chainRef);
3309
- return `${canonical}::${opts.q ?? ""}::${opts.limit ?? ""}::${opts.cursor ?? ""}`;
3456
+ get walletType() {
3457
+ return this._connectedVia === "walletconnect" ? "walletconnect" : "other";
3310
3458
  }
3311
- filterTokens(tokens, chainRef, query) {
3312
- const normalizedChain = normalizeChainKey(chainRef);
3313
- const normalizedQuery = query?.trim().toLowerCase();
3314
- return tokens.filter((token) => {
3315
- if (normalizeChainKey(token.chainId) !== normalizedChain) {
3316
- return false;
3317
- }
3318
- if (!normalizedQuery) {
3319
- return true;
3320
- }
3321
- return token.symbol?.toLowerCase().includes(normalizedQuery) || token.name?.toLowerCase().includes(normalizedQuery) || token.address?.toLowerCase().includes(normalizedQuery);
3322
- });
3459
+ get simple() {
3460
+ if (!this._wallet) return null;
3461
+ const { getAddress, disconnect } = this._wallet;
3462
+ return { getAddress, disconnect };
3323
3463
  }
3324
- chains() {
3325
- return Array.from(this._chainsById.values());
3464
+ get identity() {
3465
+ return this._identity.snapshot;
3326
3466
  }
3327
- chain(chainRef) {
3328
- const normalized = normalizeChainKey(chainRef);
3329
- const canonicalKey = this._chainAliases.get(normalized) ?? normalized;
3330
- return this._chainsById.get(canonicalKey);
3467
+ get snapshot() {
3468
+ if (!this._snapshot) {
3469
+ this._snapshot = this.buildSnapshot();
3470
+ }
3471
+ return this._snapshot;
3331
3472
  }
3332
- allTokens() {
3333
- const unique = /* @__PURE__ */ new Map();
3334
- for (const list of this._tokensByChain.values()) {
3335
- for (const token of list) {
3336
- unique.set(tokenKey(token), token);
3473
+ buildSnapshot() {
3474
+ return {
3475
+ status: this._status,
3476
+ connectedVia: this._connectedVia,
3477
+ walletType: this.walletType,
3478
+ error: this._error,
3479
+ detected: this._detected,
3480
+ wallet: this._wallet,
3481
+ simple: this.simple,
3482
+ identity: this.identity,
3483
+ connectedWalletId: this._connectedWalletId,
3484
+ address: this._address,
3485
+ isConnected: this.isConnected
3486
+ };
3487
+ }
3488
+ onChange(fn) {
3489
+ this._listeners.add(fn);
3490
+ return () => this._listeners.delete(fn);
3491
+ }
3492
+ emit() {
3493
+ this._snapshot = null;
3494
+ for (const fn of this._listeners) fn(this._status);
3495
+ }
3496
+ onExternalDisconnect(cb) {
3497
+ this._onExternalDisconnectCallback = cb;
3498
+ return () => {
3499
+ if (this._onExternalDisconnectCallback === cb) {
3500
+ this._onExternalDisconnectCallback = null;
3337
3501
  }
3338
- }
3339
- return Array.from(unique.values());
3502
+ };
3340
3503
  }
3341
- tokens(chainRef) {
3342
- return this._tokensByChain.get(normalizeChainKey(chainRef)) ?? [];
3504
+ triggerExternalDisconnect() {
3505
+ this._onExternalDisconnectCallback?.();
3343
3506
  }
3344
- async tokensPage(chainRef, opts = {}) {
3345
- await this.ensureChainsLoaded();
3346
- if (!this.config.features.tokensPagination) {
3347
- await this.ensureLoaded();
3348
- const all = this.filterTokens(this.allTokens(), chainRef, opts.q);
3349
- const start = opts.cursor ? Number(opts.cursor) || 0 : 0;
3350
- const limit = opts.limit ?? all.length;
3351
- const data = all.slice(start, start + limit);
3352
- return {
3353
- data,
3354
- pageInfo: {
3355
- hasNextPage: start + limit < all.length,
3356
- nextCursor: start + limit < all.length ? String(start + limit) : void 0
3357
- }
3358
- };
3359
- }
3360
- const cacheKey = this.pageCacheKey(chainRef, opts);
3361
- const cached = this._pageCache.get(cacheKey);
3362
- if (cached && Date.now() - cached.storedAt <= PAGE_CACHE_TTL_MS) {
3363
- return { data: cached.data, pageInfo: cached.pageInfo };
3507
+ setDetected(list) {
3508
+ this._detected = list;
3509
+ }
3510
+ async autoAttach(opts) {
3511
+ if (!this._detected.length) return;
3512
+ const target = (opts?.pick ?? ((l) => l[0]))(this._detected);
3513
+ if (!target) return;
3514
+ await this.connectDetected(target, opts);
3515
+ }
3516
+ async connectDetected(target, opts) {
3517
+ if (this._status === "connected" && this._connectedVia === "extension" && this._connectedWalletId === target.meta.id && this._wallet) {
3518
+ this.emit();
3519
+ return;
3364
3520
  }
3365
- const chain = this.chain(chainRef);
3366
- const chainKey = normalizeChainKey(chain?.chainId ?? chainRef);
3367
- const url = new URL(`${this.baseURL}/v1/routes/tokens`);
3368
- url.searchParams.set("chainId", chainKey);
3369
- if (opts.cursor) url.searchParams.set("cursor", opts.cursor);
3370
- if (opts.limit != null) url.searchParams.set("limit", String(opts.limit));
3371
- if (opts.q) url.searchParams.set("q", opts.q);
3521
+ this._status = "connecting";
3522
+ this.clearConnectedState();
3523
+ this.emit();
3372
3524
  try {
3373
- const res = await fetch(url.toString(), {
3374
- headers: {
3375
- Accept: "application/json",
3376
- "X-API-Key": this.config.apiKey
3377
- }
3525
+ const { api, error } = await connectDetectedWallet(target, {
3526
+ wagmi: opts?.wagmi
3378
3527
  });
3379
- if (!res.ok) {
3380
- throw new Error(`tokens page: HTTP ${res.status}`);
3528
+ if (api && !error) {
3529
+ this._wallet = api;
3530
+ this._connectedVia = "extension";
3531
+ this._connectedWalletId = target.meta.id;
3532
+ this.bindExtensionProviderEvents(target);
3533
+ await this.syncIdentityFromWallet(target.meta.id);
3534
+ this._status = "connected";
3535
+ this._error = null;
3536
+ return { error: null, api };
3381
3537
  }
3382
- const parsed = parseTokenPage(await res.json());
3383
- const deduped = /* @__PURE__ */ new Map();
3384
- for (const token of parsed.data) {
3385
- const normalized = normalizeToken(token);
3386
- this.storeToken(normalized);
3387
- deduped.set(tokenKey(normalized), normalized);
3538
+ if (error) {
3539
+ this._status = "error";
3540
+ this._error = error;
3541
+ return { error, api };
3388
3542
  }
3389
- const result = {
3390
- data: Array.from(deduped.values()),
3391
- pageInfo: parsed.pageInfo
3392
- };
3393
- this._pageCache.set(cacheKey, { ...result, storedAt: Date.now() });
3394
- this.prunePageCache();
3395
- this.emitPageLoaded(chainRef, opts.q, result, opts.cursor);
3396
- return result;
3397
- } catch (error) {
3398
- this.emitPageError(chainRef, opts.q, opts.cursor, error);
3399
- await this.ensureLoaded();
3400
- const fallback = this.filterTokens(this.allTokens(), chainRef, opts.q);
3401
- return {
3402
- data: fallback,
3403
- pageInfo: { hasNextPage: false }
3404
- };
3543
+ } catch (e2) {
3544
+ this._error = e2 instanceof Error ? e2.message : String(e2);
3545
+ this._status = "error";
3546
+ this.clearConnectedState();
3547
+ } finally {
3548
+ this.emit();
3405
3549
  }
3406
3550
  }
3407
- async *iterateTokens(chainRef, opts = {}) {
3408
- let cursor;
3409
- do {
3410
- const page = await this.tokensPage(chainRef, { ...opts, cursor });
3411
- yield page;
3412
- cursor = page.pageInfo.nextCursor;
3413
- if (!page.pageInfo.hasNextPage) {
3414
- break;
3415
- }
3416
- } while (cursor);
3417
- }
3418
- findToken(chainRef, address) {
3419
- const chain = this.chain(chainRef);
3420
- const chainType = normalizeChainType(chain);
3421
- const normalizedAddress = normalizeAddress(address, chainType);
3422
- return this.tokens(chainRef).find((token) => {
3423
- return normalizeAddress(token.address, chainType) === normalizedAddress;
3424
- });
3425
- }
3426
- resolveToken(chainRef, input) {
3427
- if (!input) return void 0;
3428
- const s = String(input).trim();
3429
- const chain = this.chain(chainRef);
3430
- const chainType = normalizeChainType(chain);
3431
- if (/^0x[0-9a-fA-F]{40}$/.test(s)) return s;
3432
- if (chainType === "solana" && s.length > 20) return s;
3433
- const nativeAddress = getNativeTokenAddress(chainType);
3434
- const nativeSymbol = chain?.nativeCurrency?.symbol?.toUpperCase?.();
3435
- if (nativeSymbol && s.toUpperCase() === nativeSymbol || ["ETH", "MATIC", "AVAX", "BNB", "SOL", "NATIVE"].includes(s.toUpperCase())) {
3436
- return chainType === "solana" ? nativeAddress : NATIVE;
3551
+ async connectWalletConnect(walletCfg) {
3552
+ if (this._status === "connected" && this._connectedVia === "walletconnect" && this._wallet) {
3553
+ this.emit();
3554
+ return { error: null, api: this._wallet };
3437
3555
  }
3438
- const hit = this.tokens(chainRef).find((token) => {
3439
- if (!token.symbol) return false;
3440
- return token.symbol.toUpperCase() === s.toUpperCase();
3441
- });
3442
- if (hit) return hit.address;
3443
- return s;
3444
- }
3445
- };
3446
- }
3447
- });
3448
-
3449
- // src/core/balances.ts
3450
- function toStringOrUndefined(value) {
3451
- if (typeof value !== "string") return void 0;
3452
- const trimmed = value.trim();
3453
- return trimmed || void 0;
3454
- }
3455
- function toNumberOrUndefined(value) {
3456
- if (typeof value === "number") {
3457
- return Number.isFinite(value) ? value : void 0;
3458
- }
3459
- if (typeof value === "string") {
3460
- const parsed = Number(value.trim());
3461
- return Number.isFinite(parsed) ? parsed : void 0;
3462
- }
3463
- return void 0;
3464
- }
3465
- function fallbackTokenSymbol(address, chainType) {
3466
- if (chainType?.toLowerCase() === "solana") {
3467
- return "SPL";
3468
- }
3469
- return `TOKEN-${address.slice(0, 6)}`;
3470
- }
3471
- function emitBalanceStreamChunk(address, chunkSize) {
3472
- TrustwareConfigStore.get().onEvent?.({
3473
- type: "balance_stream_chunk",
3474
- address,
3475
- chunkSize
3476
- });
3477
- }
3478
- function emitBalanceStreamFallback(address, error) {
3479
- const message = error instanceof Error ? error.message : String(error);
3480
- TrustwareConfigStore.get().onEvent?.({
3481
- type: "balance_stream_fallback",
3482
- address,
3483
- message
3484
- });
3485
- }
3486
- function normalizeRows(rows, chain, address, registry) {
3487
- const chainKey = chain.networkIdentifier ?? String(chain.chainId ?? chain.id);
3488
- const chainType = normalizeChainType(chain);
3489
- const nativeAddress = getNativeTokenAddress(chainType);
3490
- const map = /* @__PURE__ */ new Map();
3491
- for (const item of rows) {
3492
- const category = toStringOrUndefined(item.category)?.toLowerCase();
3493
- const addressRaw = item.contract ?? item.token_address ?? item.address ?? item.addr;
3494
- const tokenAddress = typeof addressRaw === "string" ? addressRaw.trim() : void 0;
3495
- const symbol = toStringOrUndefined(item.symbol ?? item.sym);
3496
- const name = toStringOrUndefined(item.name ?? item.token_name ?? item.token) ?? symbol;
3497
- const decimals = toNumberOrUndefined(item.decimals ?? item.dec);
3498
- const balance = String(item.balance ?? item.bal ?? "0");
3499
- const explicitNative = Boolean(item.native ?? item.is_native);
3500
- const nativeFlag = explicitNative || category === "native" || isZeroAddressLike(tokenAddress, chainType);
3501
- if (nativeFlag) {
3502
- const nativeRow = {
3503
- chain_key: chainKey,
3504
- category: "native",
3505
- contract: nativeAddress,
3506
- address: nativeAddress,
3507
- symbol: symbol ?? chain.nativeCurrency?.symbol ?? "NATIVE",
3508
- name: name ?? chain.nativeCurrency?.name ?? symbol,
3509
- decimals: decimals ?? chain.nativeCurrency?.decimals ?? 18,
3510
- balance
3511
- };
3512
- map.set(`${chainKey}:${nativeAddress}`, nativeRow);
3513
- continue;
3514
- }
3515
- if (!tokenAddress || decimals === void 0) continue;
3516
- const metadata = registry.findToken(chain.chainId, tokenAddress);
3517
- const displaySymbol = symbol ?? metadata?.symbol ?? fallbackTokenSymbol(tokenAddress, chainType);
3518
- const displayName = name ?? metadata?.name ?? displaySymbol;
3519
- const normalizedAddress = metadata?.address ?? tokenAddress;
3520
- map.set(`${chainKey}:${normalizedAddress}`, {
3521
- chain_key: chainKey,
3522
- category: category ?? (chainType === "solana" ? "spl" : "erc20"),
3523
- contract: normalizedAddress,
3524
- address: normalizedAddress,
3525
- symbol: displaySymbol,
3526
- name: displayName,
3527
- decimals: metadata?.decimals ?? decimals,
3528
- balance,
3529
- logoURI: metadata?.logoURI,
3530
- usdPrice: metadata?.usdPrice
3531
- });
3532
- }
3533
- if (!Array.from(map.values()).some((row) => row.category === "native")) {
3534
- map.set(`${chainKey}:${nativeAddress}`, {
3535
- chain_key: chainKey,
3536
- category: "native",
3537
- contract: nativeAddress,
3538
- address: nativeAddress,
3539
- symbol: chain.nativeCurrency?.symbol ?? "NATIVE",
3540
- name: chain.nativeCurrency?.name ?? chain.nativeCurrency?.symbol,
3541
- decimals: chain.nativeCurrency?.decimals ?? 18,
3542
- balance: "0"
3543
- });
3544
- }
3545
- return Array.from(map.values()).sort((a, b) => {
3546
- try {
3547
- return Number(BigInt(b.balance) - BigInt(a.balance));
3548
- } catch {
3549
- return 0;
3550
- }
3551
- });
3552
- }
3553
- function normalizeStreamChunk(chunk) {
3554
- return Array.isArray(chunk) ? chunk : [chunk];
3555
- }
3556
- function mergeBalanceWrappers(current, incoming) {
3557
- const merged = /* @__PURE__ */ new Map();
3558
- for (const item of current) {
3559
- merged.set(item.chain_id, item);
3560
- }
3561
- for (const item of incoming) {
3562
- const existing = merged.get(item.chain_id);
3563
- if (!existing) {
3564
- merged.set(item.chain_id, item);
3565
- continue;
3566
- }
3567
- const balancesByKey = /* @__PURE__ */ new Map();
3568
- for (const row of existing.balances ?? []) {
3569
- balancesByKey.set(`${row.contract ?? row.address ?? row.symbol}`, row);
3570
- }
3571
- for (const row of item.balances ?? []) {
3572
- balancesByKey.set(`${row.contract ?? row.address ?? row.symbol}`, row);
3573
- }
3574
- merged.set(item.chain_id, {
3575
- ...existing,
3576
- ...item,
3577
- balances: Array.from(balancesByKey.values()),
3578
- count: item.count ?? existing.count
3579
- });
3580
- }
3581
- return Array.from(merged.values());
3582
- }
3583
- async function parseStreamingBalances(response, address, options = {}) {
3584
- if (!response.body) {
3585
- throw new Error("balances stream: empty response body");
3586
- }
3587
- const decoder = new TextDecoder();
3588
- const reader = response.body.getReader();
3589
- async function* stream() {
3590
- let buffer = "";
3591
- try {
3592
- while (true) {
3593
- const { value, done } = await reader.read();
3594
- if (done) break;
3595
- buffer += decoder.decode(value, { stream: true });
3596
- const frames = buffer.split(/\r?\n/);
3597
- buffer = frames.pop() ?? "";
3598
- for (const frame of frames) {
3599
- const trimmed = frame.trim();
3600
- if (!trimmed) continue;
3601
- try {
3602
- const chunk = normalizeStreamChunk(
3603
- JSON.parse(trimmed)
3604
- );
3605
- emitBalanceStreamChunk(address, chunk.length);
3606
- yield chunk;
3607
- } catch (error) {
3608
- if (options.strict) {
3609
- throw error;
3556
+ this._status = "connecting";
3557
+ this.clearConnectedState();
3558
+ this.emit();
3559
+ try {
3560
+ const connector = await getUniversalConnector(walletCfg);
3561
+ await connector.connect();
3562
+ const api = await buildWalletConnectAPI(walletCfg);
3563
+ this._wallet = api;
3564
+ this._connectedVia = "walletconnect";
3565
+ this._connectedWalletId = "walletconnect";
3566
+ const provider = connector.provider;
3567
+ this._providerCleanup = bindWalletConnectEvents(provider, {
3568
+ onAccountsChanged: (accounts) => {
3569
+ if (accounts.length === 0) {
3570
+ this.fullReset();
3571
+ this.triggerExternalDisconnect();
3572
+ this.emit();
3573
+ return;
3574
+ }
3575
+ void this.syncIdentityFromWallet("walletconnect");
3576
+ this.emit();
3577
+ },
3578
+ onChainChanged: () => {
3579
+ void this.syncIdentityFromWallet("walletconnect");
3580
+ this.emit();
3581
+ },
3582
+ onDisconnect: () => {
3583
+ this.fullReset();
3584
+ resetUniversalConnector();
3585
+ this.triggerExternalDisconnect();
3586
+ this.emit();
3587
+ }
3588
+ });
3589
+ await this.syncIdentityFromWallet("walletconnect");
3590
+ this._status = "connected";
3591
+ this._error = null;
3592
+ this.emit();
3593
+ return { error: null, api };
3594
+ } catch (e2) {
3595
+ const message = e2 instanceof Error ? e2.message : String(e2);
3596
+ this._error = message;
3597
+ this._status = "error";
3598
+ this.clearConnectedState();
3599
+ this.emit();
3600
+ return { error: message, api: null };
3601
+ }
3602
+ }
3603
+ async disconnect(wagmi) {
3604
+ if (wagmi && this._connectedVia === "extension") {
3605
+ await wagmi.disconnect().catch(() => {
3606
+ });
3607
+ }
3608
+ if (this._wallet?.disconnect) {
3609
+ await this._wallet.disconnect().catch(() => {
3610
+ });
3611
+ }
3612
+ if (this._connectedVia === "walletconnect") {
3613
+ resetUniversalConnector();
3614
+ }
3615
+ this.fullReset();
3616
+ this.emit();
3617
+ }
3618
+ attachWallet(api) {
3619
+ this.clearConnectedState();
3620
+ this._wallet = api;
3621
+ this._connectedVia = "direct";
3622
+ this._connectedWalletId = null;
3623
+ this._status = "connected";
3624
+ void this.syncIdentityFromWallet();
3625
+ this.emit();
3626
+ }
3627
+ setStatus(s) {
3628
+ this._status = s;
3629
+ this.emit();
3630
+ }
3631
+ addIdentityAddress(address) {
3632
+ this._identity.upsert(address);
3633
+ }
3634
+ resolveAddressForChain(chain) {
3635
+ return this._identity.resolve(chain);
3636
+ }
3637
+ clearProviderCleanup() {
3638
+ this._providerCleanup?.();
3639
+ this._providerCleanup = null;
3640
+ }
3641
+ clearConnectedState() {
3642
+ this.clearProviderCleanup();
3643
+ this._wallet = null;
3644
+ this._connectedVia = null;
3645
+ this._connectedWalletId = null;
3646
+ }
3647
+ fullReset() {
3648
+ this.clearConnectedState();
3649
+ this._address = null;
3650
+ this._identity = new IdentityStore();
3651
+ this._status = "idle";
3652
+ this._error = null;
3653
+ }
3654
+ bindExtensionProviderEvents(target) {
3655
+ if (!target.provider) return;
3656
+ if (target.via === "solana-window") {
3657
+ this._providerCleanup = bindSolanaProviderEvents(target.provider, {
3658
+ onConnect: () => {
3659
+ this._status = "connected";
3660
+ void this.syncIdentityFromWallet(target.meta.id);
3661
+ this.emit();
3662
+ },
3663
+ onAccountChanged: () => {
3664
+ void this.syncIdentityFromWallet(target.meta.id);
3665
+ this.emit();
3666
+ },
3667
+ onDisconnect: () => {
3668
+ this.fullReset();
3669
+ this.triggerExternalDisconnect();
3670
+ this.emit();
3610
3671
  }
3611
- }
3672
+ });
3673
+ return;
3612
3674
  }
3675
+ const provider = target.provider;
3676
+ const onAccountsChanged = (accounts) => {
3677
+ const nextAccounts = Array.isArray(accounts) ? accounts : [];
3678
+ if (nextAccounts.length === 0) {
3679
+ this.fullReset();
3680
+ this.triggerExternalDisconnect();
3681
+ this.emit();
3682
+ return;
3683
+ }
3684
+ this._status = "connected";
3685
+ void this.syncIdentityFromWallet(target.meta.id);
3686
+ this.emit();
3687
+ };
3688
+ const onDisconnect = () => {
3689
+ this.fullReset();
3690
+ this.triggerExternalDisconnect();
3691
+ this.emit();
3692
+ };
3693
+ provider.on?.("accountsChanged", onAccountsChanged);
3694
+ provider.on?.("disconnect", onDisconnect);
3695
+ this._providerCleanup = () => {
3696
+ provider.off?.("accountsChanged", onAccountsChanged);
3697
+ provider.off?.("disconnect", onDisconnect);
3698
+ provider.removeListener?.("accountsChanged", onAccountsChanged);
3699
+ provider.removeListener?.("disconnect", onDisconnect);
3700
+ };
3613
3701
  }
3614
- const tail = buffer.trim();
3615
- if (tail) {
3616
- const chunk = normalizeStreamChunk(JSON.parse(tail));
3617
- emitBalanceStreamChunk(address, chunk.length);
3618
- yield chunk;
3702
+ async syncIdentityFromWallet(providerId) {
3703
+ if (!this._wallet) return;
3704
+ try {
3705
+ const address = await this._wallet.getAddress();
3706
+ this._address = address;
3707
+ const chain = this._wallet.ecosystem === "evm" ? { chainId: String(await this._wallet.getChainId()), type: "evm" } : this._wallet.ecosystem === "solana" ? {
3708
+ chainId: "solana-mainnet-beta",
3709
+ networkIdentifier: "solana-mainnet-beta",
3710
+ type: "solana"
3711
+ } : {
3712
+ chainId: "bip122:000000000019d6689c085ae165831e93",
3713
+ networkIdentifier: "bitcoin-mainnet",
3714
+ type: "bitcoin"
3715
+ };
3716
+ const identityAddress = buildWalletIdentityAddress({
3717
+ address,
3718
+ chain,
3719
+ source: "provider",
3720
+ providerId
3721
+ });
3722
+ if (identityAddress) {
3723
+ this._identity.upsert(identityAddress);
3724
+ }
3725
+ } catch {
3726
+ }
3619
3727
  }
3620
- } finally {
3621
- reader.releaseLock();
3622
- }
3623
- }
3624
- return stream();
3625
- }
3626
- async function getBalances(chainRef, address) {
3627
- const reg = await ensureRegistry();
3628
- const chain = reg.chain(chainRef);
3629
- if (!chain) return [];
3630
- const trimmedAddress = address.trim();
3631
- const validation = validateAddressForChain(trimmedAddress, chain);
3632
- if (!validation.isValid) return [];
3633
- const chainKey = chain.networkIdentifier ?? String(chain.chainId ?? chain.id);
3634
- const cacheKey = [
3635
- chainKey,
3636
- trimmedAddress,
3637
- chain.nativeCurrency?.symbol ?? "",
3638
- chain.nativeCurrency?.decimals ?? "",
3639
- normalizeChainType(chain) ?? ""
3640
- ].join(":");
3641
- const cached = balanceCache.get(cacheKey);
3642
- if (cached) return cached;
3643
- const url = `${apiBase()}/v1/data/wallets/${encodeURIComponent(chainKey)}/${trimmedAddress}/balances`;
3644
- const response = await fetch(url, {
3645
- method: "GET",
3646
- credentials: "omit",
3647
- headers: jsonHeaders()
3648
- });
3649
- if (!response.ok) throw new Error(`balances: HTTP ${response.status}`);
3650
- const json = await response.json();
3651
- const rows = Array.isArray(json) ? json : json.data ?? [];
3652
- const normalized = normalizeRows(rows, chain, trimmedAddress, reg);
3653
- balanceCache.set(cacheKey, normalized);
3654
- return normalized;
3655
- }
3656
- async function getBalancesByAddress(address, opts) {
3657
- if (opts?.stream && TrustwareConfigStore.get().features.balanceStreaming) {
3658
- const merged = [];
3659
- for await (const chunk of getBalancesByAddressStream(address, opts)) {
3660
- const next = mergeBalanceWrappers(merged, chunk);
3661
- merged.splice(0, merged.length, ...next);
3662
- }
3663
- return merged;
3664
- }
3665
- const url = `${apiBase()}/data/balances/${address}`;
3666
- const r = await rateLimitedFetch(url, {
3667
- method: "GET",
3668
- credentials: "omit",
3669
- headers: jsonHeaders()
3670
- });
3671
- if (!r.ok) throw new Error(`balances: HTTP ${r.status}`);
3672
- const j = await r.json();
3673
- return Array.isArray(j) ? j : j.results ?? [];
3674
- }
3675
- async function* getBalancesByAddressStream(address, opts = {}) {
3676
- if (!TrustwareConfigStore.get().features.balanceStreaming) {
3677
- yield await getBalancesByAddress(address);
3678
- return;
3679
- }
3680
- const url = `${apiBase()}/data/balances/${address}?stream=1`;
3681
- try {
3682
- const response = await rateLimitedFetch(url, {
3683
- method: "GET",
3684
- credentials: "omit",
3685
- headers: jsonHeaders({
3686
- Accept: "application/x-ndjson, application/json"
3687
- }),
3688
- signal: opts.signal
3689
- });
3690
- if (!response.ok) {
3691
- throw new Error(`balances stream: HTTP ${response.status}`);
3692
- }
3693
- const contentType = response.headers.get("content-type") ?? "";
3694
- if (contentType.includes("application/json")) {
3695
- const payload = await response.json();
3696
- yield Array.isArray(payload) ? payload : payload.results ?? [];
3697
- return;
3698
- }
3699
- const stream = await parseStreamingBalances(response, address, opts);
3700
- for await (const chunk of stream) {
3701
- yield chunk;
3702
- }
3703
- } catch (error) {
3704
- emitBalanceStreamFallback(address, error);
3705
- yield await getBalancesByAddress(address);
3728
+ };
3729
+ walletManager = new WalletManager();
3706
3730
  }
3707
- }
3708
- async function ensureRegistry() {
3709
- if (!_registry) {
3710
- _registry = new Registry(apiBase());
3731
+ });
3732
+
3733
+ // src/wallets/bridges.ts
3734
+ var init_bridges = __esm({
3735
+ "src/wallets/bridges.ts"() {
3736
+ "use strict";
3711
3737
  }
3712
- await _registry.ensureLoaded();
3713
- return _registry;
3714
- }
3715
- var balanceCache, _registry;
3716
- var init_balances = __esm({
3717
- "src/core/balances.ts"() {
3738
+ });
3739
+
3740
+ // src/wallets/index.ts
3741
+ var init_wallets = __esm({
3742
+ "src/wallets/index.ts"() {
3718
3743
  "use strict";
3719
- init_http();
3720
- init_registry();
3721
- init_store();
3722
- init_chains();
3723
- init_address();
3724
- balanceCache = /* @__PURE__ */ new Map();
3744
+ init_bridges();
3745
+ init_connect();
3746
+ init_manager();
3747
+ init_adapters();
3748
+ init_solana();
3725
3749
  }
3726
3750
  });
3727
3751
 
@@ -3771,6 +3795,7 @@ async function buildRoute(body, signal) {
3771
3795
  const txReq = route?.execution?.transaction;
3772
3796
  const actions = Array.isArray(route?.steps) ? route.steps : [];
3773
3797
  const estimate = route?.estimate ?? {};
3798
+ const sponsorship = json?.data?.sponsorship ?? json?.sponsorship ?? void 0;
3774
3799
  const finalExchangeRate = {
3775
3800
  fromAmountUSD: estimate.fromAmountUsd,
3776
3801
  toAmountMinUSD: estimate?.toAmountMinUsd ?? estimate?.toAmountUsd
@@ -3778,7 +3803,7 @@ async function buildRoute(body, signal) {
3778
3803
  if (!txReq?.data) {
3779
3804
  throw new Error("Invalid route: missing transaction data");
3780
3805
  }
3781
- return { intentId, txReq, actions, finalExchangeRate, route };
3806
+ return { intentId, txReq, actions, finalExchangeRate, route, sponsorship };
3782
3807
  }
3783
3808
  async function buildDepositAddress(body, signal) {
3784
3809
  const cfg = TrustwareConfigStore.get();
@@ -3822,13 +3847,16 @@ async function buildDepositAddress(body, signal) {
3822
3847
  route
3823
3848
  };
3824
3849
  }
3825
- async function submitReceipt(intentId, txHash) {
3850
+ async function submitReceipt(intentId, txHash, sponsorshipRequestId) {
3826
3851
  const r = await rateLimitedFetch(
3827
3852
  `${apiBase()}/v1/route-intent/${intentId}/receipt`,
3828
3853
  {
3829
3854
  method: "POST",
3830
3855
  headers: jsonHeaders({ "Idempotency-Key": txHash }),
3831
- body: JSON.stringify({ txHash })
3856
+ body: JSON.stringify({
3857
+ txHash,
3858
+ ...sponsorshipRequestId ? { sponsorshipRequestId } : {}
3859
+ })
3832
3860
  }
3833
3861
  );
3834
3862
  await assertOK(r);
@@ -4584,7 +4612,11 @@ function resolveConfig(input) {
4584
4612
  const features = {
4585
4613
  tokensPagination: input.features?.tokensPagination ?? DEFAULT_FEATURE_FLAGS.tokensPagination,
4586
4614
  balanceStreaming: input.features?.balanceStreaming ?? DEFAULT_FEATURE_FLAGS.balanceStreaming,
4587
- shouldAllowGA4: input.features?.shouldAllowGA4 ?? DEFAULT_FEATURE_FLAGS.shouldAllowGA4
4615
+ shouldAllowGA4: input.features?.shouldAllowGA4 ?? DEFAULT_FEATURE_FLAGS.shouldAllowGA4,
4616
+ swapMode: input.features?.swapMode ?? DEFAULT_FEATURE_FLAGS.swapMode,
4617
+ swapDefaultDestToken: input.features?.swapDefaultDestToken ?? DEFAULT_FEATURE_FLAGS.swapDefaultDestToken,
4618
+ swapLockDestToken: input.features?.swapLockDestToken ?? DEFAULT_FEATURE_FLAGS.swapLockDestToken,
4619
+ swapAllowedDestTokens: input.features?.swapAllowedDestTokens ?? DEFAULT_FEATURE_FLAGS.swapAllowedDestTokens
4588
4620
  };
4589
4621
  return {
4590
4622
  apiKey: input.apiKey,
@@ -4715,6 +4747,12 @@ async function sendRouteTransaction(b, fallbackChainId) {
4715
4747
  const data = txReq.data;
4716
4748
  const value = txReq.value ? BigInt(txReq.value) : 0n;
4717
4749
  const target = Number(txReq.chainId ?? fallbackChainId);
4750
+ let validatedSponsorship;
4751
+ if (b.sponsorship) {
4752
+ if ((0, import_viem2.keccak256)(data) === b.sponsorship.callDataHash) {
4753
+ validatedSponsorship = b.sponsorship;
4754
+ }
4755
+ }
4718
4756
  if (Number.isFinite(target)) {
4719
4757
  const current = await w.getChainId();
4720
4758
  if (current !== target) {
@@ -4746,7 +4784,10 @@ async function sendRouteTransaction(b, fallbackChainId) {
4746
4784
  to,
4747
4785
  data,
4748
4786
  value,
4749
- chainId: Number.isFinite(target) ? target : void 0
4787
+ chainId: Number.isFinite(target) ? target : void 0,
4788
+ ...validatedSponsorship ? {
4789
+ paymasterAndData: validatedSponsorship.paymasterAndData
4790
+ } : {}
4750
4791
  });
4751
4792
  return response.hash;
4752
4793
  }
@@ -4819,11 +4860,13 @@ async function runTopUp(params) {
4819
4860
  }
4820
4861
  }
4821
4862
  }
4863
+ var import_viem2;
4822
4864
  var init_tx = __esm({
4823
4865
  "src/core/tx.ts"() {
4824
4866
  "use strict";
4825
4867
  init_wallets();
4826
4868
  init_routes();
4869
+ import_viem2 = require("viem");
4827
4870
  }
4828
4871
  });
4829
4872