@ecency/wallets 1.5.55 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,19 +1,11 @@
1
- import { ConfigManager, CONFIG, getAccountFullQueryOptions, getPortfolioQueryOptions, getQueryClient, AssetOperation, useAccountUpdate, getHiveEngineTokensBalancesQueryOptions, getHiveEngineTokensMetadataQueryOptions } from '@ecency/sdk';
1
+ import { ConfigManager, getPortfolioQueryOptions, getQueryClient, getAccountFullQueryOptions, AssetOperation, useAccountUpdate, CONFIG, getHiveEngineTokensBalancesQueryOptions, getHiveEngineTokensMetadataQueryOptions } from '@ecency/sdk';
2
2
  export { AssetOperation, HIVE_ACCOUNT_OPERATION_GROUPS, HIVE_OPERATION_LIST, HIVE_OPERATION_NAME_BY_ID, HIVE_OPERATION_ORDERS, HiveEngineToken, NaiMap, PointTransactionType, Symbol, formattedNumber, getAccountWalletAssetInfoQueryOptions, getAllHiveEngineTokensQueryOptions, getHbdAssetGeneralInfoQueryOptions, getHbdAssetTransactionsQueryOptions, getHiveAssetGeneralInfoQueryOptions, getHiveAssetMetricQueryOptions, getHiveAssetTransactionsQueryOptions, getHiveAssetWithdrawalRoutesQueryOptions, getHiveEngineBalancesWithUsdQueryOptions, getHiveEngineTokenGeneralInfoQueryOptions, getHiveEngineTokenTransactionsQueryOptions, getHiveEngineTokensBalancesQueryOptions, getHiveEngineTokensMarketQueryOptions, getHiveEngineTokensMetadataQueryOptions, getHiveEngineTokensMetricsQueryOptions, getHiveEngineUnclaimedRewardsQueryOptions, getHivePowerAssetGeneralInfoQueryOptions, getHivePowerAssetTransactionsQueryOptions, getHivePowerDelegatesInfiniteQueryOptions, getHivePowerDelegatingsQueryOptions, getLarynxAssetGeneralInfoQueryOptions, getLarynxPowerAssetGeneralInfoQueryOptions, getPointsAssetGeneralInfoQueryOptions, getPointsAssetTransactionsQueryOptions, getPointsQueryOptions, getSpkAssetGeneralInfoQueryOptions, getSpkMarketsQueryOptions, getSpkWalletQueryOptions, isEmptyDate, parseAsset, resolveHiveOperationFilters, rewardSpk, useClaimPoints, useWalletOperation, vestsToHp } from '@ecency/sdk';
3
- import { useQuery, queryOptions, useQueryClient, useMutation } from '@tanstack/react-query';
4
- import bip39, { mnemonicToSeedSync } from 'bip39';
3
+ import { useMutation, useQuery, queryOptions, useQueryClient } from '@tanstack/react-query';
4
+ import * as R from 'remeda';
5
5
  import { LRUCache } from 'lru-cache';
6
- import { BtcWallet, buildPsbt as buildPsbt$1 } from '@okxweb3/coin-bitcoin';
7
- import { EthWallet } from '@okxweb3/coin-ethereum';
8
- import { TrxWallet } from '@okxweb3/coin-tron';
9
- import { TonWallet } from '@okxweb3/coin-ton';
10
- import { SolWallet } from '@okxweb3/coin-solana';
11
- import { AptosWallet } from '@okxweb3/coin-aptos';
12
- import { bip32 } from '@okxweb3/crypto-lib';
6
+ import { mnemonicToSeedSync } from 'bip39';
7
+ import { HDKey } from '@scure/bip32';
13
8
  import { PrivateKey } from '@hiveio/dhive';
14
- import { cryptoUtils } from '@hiveio/dhive/lib/crypto';
15
- import { Memo } from '@hiveio/dhive/lib/memo';
16
- import * as R from 'remeda';
17
9
 
18
10
  var __defProp = Object.defineProperty;
19
11
  var __export = (target, all) => {
@@ -57,9 +49,6 @@ var EcencyWalletCurrency = /* @__PURE__ */ ((EcencyWalletCurrency2) => {
57
49
  EcencyWalletCurrency2["BTC"] = "BTC";
58
50
  EcencyWalletCurrency2["ETH"] = "ETH";
59
51
  EcencyWalletCurrency2["BNB"] = "BNB";
60
- EcencyWalletCurrency2["APT"] = "APT";
61
- EcencyWalletCurrency2["TON"] = "TON";
62
- EcencyWalletCurrency2["TRON"] = "TRX";
63
52
  EcencyWalletCurrency2["SOL"] = "SOL";
64
53
  return EcencyWalletCurrency2;
65
54
  })(EcencyWalletCurrency || {});
@@ -72,14 +61,125 @@ var EcencyWalletBasicTokens = /* @__PURE__ */ ((EcencyWalletBasicTokens2) => {
72
61
  EcencyWalletBasicTokens2["HiveDollar"] = "HBD";
73
62
  return EcencyWalletBasicTokens2;
74
63
  })(EcencyWalletBasicTokens || {});
64
+
65
+ // src/modules/wallets/mutations/private-api/index.ts
66
+ var private_api_exports = {};
67
+ __export(private_api_exports, {
68
+ useCheckWalletExistence: () => useCheckWalletExistence,
69
+ useCreateAccountWithWallets: () => useCreateAccountWithWallets,
70
+ useUpdateAccountWithWallets: () => useUpdateAccountWithWallets
71
+ });
72
+
73
+ // src/modules/wallets/utils/get-bound-fetch.ts
74
+ var cachedFetch;
75
+ function getBoundFetch() {
76
+ if (!cachedFetch) {
77
+ if (typeof globalThis.fetch !== "function") {
78
+ throw new Error("[Ecency][Wallets] - global fetch is not available");
79
+ }
80
+ cachedFetch = globalThis.fetch.bind(globalThis);
81
+ }
82
+ return cachedFetch;
83
+ }
84
+ function useCreateAccountWithWallets(username) {
85
+ const fetchApi = getBoundFetch();
86
+ return useMutation({
87
+ mutationKey: ["ecency-wallets", "create-account-with-wallets", username],
88
+ mutationFn: async ({ currency, address, hiveKeys, walletAddresses }) => {
89
+ const addresses = {};
90
+ if (walletAddresses) {
91
+ for (const [k, v] of Object.entries(walletAddresses)) {
92
+ if (v) addresses[k] = v;
93
+ }
94
+ }
95
+ const response = await fetchApi(`${ConfigManager.getValidatedBaseUrl()}/private-api/wallets-add`, {
96
+ method: "POST",
97
+ headers: {
98
+ "Content-Type": "application/json"
99
+ },
100
+ body: JSON.stringify({
101
+ username,
102
+ token: currency,
103
+ address,
104
+ meta: {
105
+ ...hiveKeys,
106
+ ...addresses,
107
+ [currency]: address
108
+ }
109
+ })
110
+ });
111
+ if (!response.ok) {
112
+ throw new Error(`Account creation failed (${response.status})`);
113
+ }
114
+ return response;
115
+ }
116
+ });
117
+ }
118
+ function useCheckWalletExistence() {
119
+ return useMutation({
120
+ mutationKey: ["ecency-wallets", "check-wallet-existence"],
121
+ mutationFn: async ({ address, currency }) => {
122
+ const response = await fetch(
123
+ `${ConfigManager.getValidatedBaseUrl()}/private-api/wallets-exist`,
124
+ {
125
+ method: "POST",
126
+ headers: {
127
+ "Content-Type": "application/json"
128
+ },
129
+ body: JSON.stringify({
130
+ address,
131
+ token: currency
132
+ })
133
+ }
134
+ );
135
+ const data = await response.json();
136
+ return data.length === 0;
137
+ }
138
+ });
139
+ }
140
+ function useUpdateAccountWithWallets(username, accessToken) {
141
+ const fetchApi = getBoundFetch();
142
+ return useMutation({
143
+ mutationKey: ["ecency-wallets", "update-account-with-wallets", username],
144
+ mutationFn: async ({ tokens, hiveKeys }) => {
145
+ const entries = Object.entries(tokens).filter(([, address]) => Boolean(address));
146
+ if (entries.length === 0) {
147
+ return new Response(null, { status: 204 });
148
+ }
149
+ const [primaryToken, primaryAddress] = entries[0] ?? ["", ""];
150
+ if (!accessToken) {
151
+ throw new Error(
152
+ "[SDK][Wallets][PrivateApi][WalletsAdd] \u2013 access token wasn`t found"
153
+ );
154
+ }
155
+ return fetchApi(`${ConfigManager.getValidatedBaseUrl()}/private-api/wallets-add`, {
156
+ method: "POST",
157
+ headers: {
158
+ "Content-Type": "application/json"
159
+ },
160
+ body: JSON.stringify({
161
+ username,
162
+ code: accessToken,
163
+ token: primaryToken,
164
+ address: primaryAddress,
165
+ status: 3,
166
+ meta: {
167
+ ...Object.fromEntries(entries),
168
+ ownerPublicKey: hiveKeys.ownerPublicKey,
169
+ activePublicKey: hiveKeys.activePublicKey,
170
+ postingPublicKey: hiveKeys.postingPublicKey,
171
+ memoPublicKey: hiveKeys.memoPublicKey
172
+ }
173
+ })
174
+ });
175
+ }
176
+ });
177
+ }
75
178
  var currencyChainMap = {
76
179
  ["BTC" /* BTC */]: "btc",
77
180
  ["ETH" /* ETH */]: "eth",
78
181
  ["BNB" /* BNB */]: "bnb",
79
- ["SOL" /* SOL */]: "sol",
80
- ["TRX" /* TRON */]: "tron",
81
- ["TON" /* TON */]: "ton",
82
- ["APT" /* APT */]: "apt"
182
+ ["SOL" /* SOL */]: "sol"
83
183
  };
84
184
  function normalizeBalance(balance) {
85
185
  if (typeof balance === "number") {
@@ -188,19 +288,6 @@ function useGetExternalWalletBalanceQuery(currency, address) {
188
288
  }
189
289
  });
190
290
  }
191
- function useSeedPhrase(username) {
192
- return useQuery({
193
- queryKey: ["ecency-wallets", "seed", username],
194
- queryFn: async () => bip39.generateMnemonic(128),
195
- // CRITICAL: Prevent seed regeneration - cache forever
196
- // Once generated, the seed must NEVER change to ensure consistency between:
197
- // 1. Displayed seed phrase
198
- // 2. Downloaded seed file
199
- // 3. Keys sent to API for account creation
200
- staleTime: Infinity,
201
- gcTime: Infinity
202
- });
203
- }
204
291
  var options = {
205
292
  max: 500,
206
293
  // how long to live in ms
@@ -221,9 +308,6 @@ var CURRENCY_TO_TOKEN_MAP = {
221
308
  ["BTC" /* BTC */]: "btc",
222
309
  ["ETH" /* ETH */]: "eth",
223
310
  ["SOL" /* SOL */]: "sol",
224
- ["TON" /* TON */]: "ton",
225
- ["TRX" /* TRON */]: "trx",
226
- ["APT" /* APT */]: "apt",
227
311
  ["BNB" /* BNB */]: "bnb",
228
312
  HBD: "hbd",
229
313
  HIVE: "hive"
@@ -278,300 +362,6 @@ function getTokenPriceQueryOptions(currency) {
278
362
  enabled: !!currency
279
363
  });
280
364
  }
281
-
282
- // src/modules/wallets/utils/delay.ts
283
- function delay(ms) {
284
- return new Promise((resolve) => setTimeout(resolve, ms));
285
- }
286
- function getWallet(currency) {
287
- switch (currency) {
288
- case "BTC" /* BTC */:
289
- return new BtcWallet();
290
- case "ETH" /* ETH */:
291
- case "BNB" /* BNB */:
292
- return new EthWallet();
293
- case "TRX" /* TRON */:
294
- return new TrxWallet();
295
- case "TON" /* TON */:
296
- return new TonWallet();
297
- case "SOL" /* SOL */:
298
- return new SolWallet();
299
- case "APT" /* APT */:
300
- return new AptosWallet();
301
- default:
302
- return void 0;
303
- }
304
- }
305
- function mnemonicToSeedBip39(value) {
306
- return mnemonicToSeedSync(value).toString("hex");
307
- }
308
- var ROLE_INDEX = {
309
- owner: 0,
310
- active: 1,
311
- posting: 2,
312
- memo: 3
313
- };
314
- function deriveHiveKey(mnemonic, role, accountIndex = 0) {
315
- const seed = mnemonicToSeedSync(mnemonic);
316
- const master = bip32.fromSeed(seed);
317
- const path = `m/44'/3054'/${accountIndex}'/0'/${ROLE_INDEX[role]}'`;
318
- const child = master.derivePath(path);
319
- if (!child.privateKey) {
320
- throw new Error("[Ecency][Wallets] - hive key derivation failed");
321
- }
322
- const pk = PrivateKey.from(child.privateKey);
323
- return {
324
- privateKey: pk.toString(),
325
- publicKey: pk.createPublic().toString()
326
- };
327
- }
328
- function deriveHiveKeys(mnemonic, accountIndex = 0) {
329
- const owner = deriveHiveKey(mnemonic, "owner", accountIndex);
330
- const active = deriveHiveKey(mnemonic, "active", accountIndex);
331
- const posting = deriveHiveKey(mnemonic, "posting", accountIndex);
332
- const memo = deriveHiveKey(mnemonic, "memo", accountIndex);
333
- return {
334
- owner: owner.privateKey,
335
- active: active.privateKey,
336
- posting: posting.privateKey,
337
- memo: memo.privateKey,
338
- ownerPubkey: owner.publicKey,
339
- activePubkey: active.publicKey,
340
- postingPubkey: posting.publicKey,
341
- memoPubkey: memo.publicKey
342
- };
343
- }
344
- function deriveHiveMasterPasswordKey(username, masterPassword, role) {
345
- const pk = PrivateKey.fromLogin(username, masterPassword, role);
346
- return {
347
- privateKey: pk.toString(),
348
- publicKey: pk.createPublic().toString()
349
- };
350
- }
351
- function deriveHiveMasterPasswordKeys(username, masterPassword) {
352
- const owner = deriveHiveMasterPasswordKey(username, masterPassword, "owner");
353
- const active = deriveHiveMasterPasswordKey(username, masterPassword, "active");
354
- const posting = deriveHiveMasterPasswordKey(
355
- username,
356
- masterPassword,
357
- "posting"
358
- );
359
- const memo = deriveHiveMasterPasswordKey(username, masterPassword, "memo");
360
- return {
361
- owner: owner.privateKey,
362
- active: active.privateKey,
363
- posting: posting.privateKey,
364
- memo: memo.privateKey,
365
- ownerPubkey: owner.publicKey,
366
- activePubkey: active.publicKey,
367
- postingPubkey: posting.publicKey,
368
- memoPubkey: memo.publicKey
369
- };
370
- }
371
- async function detectHiveKeyDerivation(username, seed, type = "active") {
372
- const uname = username.trim().toLowerCase();
373
- const account = await CONFIG.queryClient.fetchQuery(
374
- getAccountFullQueryOptions(uname)
375
- );
376
- const auth = account[type];
377
- const bip44 = deriveHiveKeys(seed);
378
- const bip44Pub = type === "owner" ? bip44.ownerPubkey : bip44.activePubkey;
379
- const matchBip44 = auth.key_auths.some(([pub]) => String(pub) === bip44Pub);
380
- if (matchBip44) return "bip44";
381
- const legacyPub = PrivateKey.fromLogin(uname, seed, type).createPublic().toString();
382
- const matchLegacy = auth.key_auths.some(([pub]) => String(pub) === legacyPub);
383
- if (matchLegacy) return "master-password";
384
- return "unknown";
385
- }
386
- function signDigest(digest, privateKey) {
387
- const key = PrivateKey.fromString(privateKey);
388
- const buf = typeof digest === "string" ? Buffer.from(digest, "hex") : digest;
389
- return key.sign(buf).toString();
390
- }
391
- function signTx(tx, privateKey, chainId) {
392
- const key = PrivateKey.fromString(privateKey);
393
- const chain = chainId ? Buffer.from(chainId, "hex") : void 0;
394
- return cryptoUtils.signTransaction(tx, key, chain);
395
- }
396
- async function signTxAndBroadcast(client, tx, privateKey, chainId) {
397
- const signed = signTx(tx, privateKey, chainId);
398
- return client.broadcast.send(signed);
399
- }
400
- function encryptMemoWithKeys(privateKey, publicKey, memo) {
401
- return Memo.encode(PrivateKey.fromString(privateKey), publicKey, memo);
402
- }
403
- async function encryptMemoWithAccounts(client, fromPrivateKey, toAccount, memo) {
404
- const [account] = await client.database.getAccounts([toAccount]);
405
- if (!account) {
406
- throw new Error("Account not found");
407
- }
408
- return Memo.encode(PrivateKey.fromString(fromPrivateKey), account.memo_key, memo);
409
- }
410
- function decryptMemoWithKeys(privateKey, memo) {
411
- return Memo.decode(PrivateKey.fromString(privateKey), memo);
412
- }
413
- var decryptMemoWithAccounts = decryptMemoWithKeys;
414
- async function signExternalTx(currency, params) {
415
- const wallet = getWallet(currency);
416
- if (!wallet) throw new Error("Unsupported currency");
417
- return wallet.signTransaction(params);
418
- }
419
- async function signExternalTxAndBroadcast(currency, params) {
420
- const signed = await signExternalTx(currency, params);
421
- switch (currency) {
422
- case "BTC" /* BTC */: {
423
- const res = await fetch("https://mempool.space/api/tx", {
424
- method: "POST",
425
- body: signed
426
- });
427
- if (!res.ok) throw new Error("Broadcast failed");
428
- return res.text();
429
- }
430
- case "ETH" /* ETH */:
431
- case "BNB" /* BNB */: {
432
- const rpcUrl = currency === "ETH" /* ETH */ ? "https://rpc.ankr.com/eth" : "https://bsc-dataseed.binance.org";
433
- const res = await fetch(rpcUrl, {
434
- method: "POST",
435
- headers: { "Content-Type": "application/json" },
436
- body: JSON.stringify({
437
- jsonrpc: "2.0",
438
- id: 1,
439
- method: "eth_sendRawTransaction",
440
- params: [signed]
441
- })
442
- });
443
- const json = await res.json();
444
- if (json.error) throw new Error(json.error.message);
445
- return json.result;
446
- }
447
- case "SOL" /* SOL */: {
448
- const res = await fetch(
449
- `https://rpc.helius.xyz/?api-key=${CONFIG.heliusApiKey}`,
450
- {
451
- method: "POST",
452
- headers: { "Content-Type": "application/json" },
453
- body: JSON.stringify({
454
- jsonrpc: "2.0",
455
- id: 1,
456
- method: "sendTransaction",
457
- params: [signed]
458
- })
459
- }
460
- );
461
- const json = await res.json();
462
- if (json.error) throw new Error(json.error.message);
463
- return json.result;
464
- }
465
- case "TRX" /* TRON */: {
466
- const res = await fetch(
467
- "https://api.trongrid.io/wallet/broadcasttransaction",
468
- {
469
- method: "POST",
470
- headers: { "Content-Type": "application/json" },
471
- body: typeof signed === "string" ? signed : JSON.stringify(signed)
472
- }
473
- );
474
- const json = await res.json();
475
- if (json.result === false) throw new Error(json.message);
476
- return json.txid || json.result;
477
- }
478
- case "TON" /* TON */: {
479
- const res = await fetch("https://toncenter.com/api/v2/sendTransaction", {
480
- method: "POST",
481
- headers: { "Content-Type": "application/json" },
482
- body: JSON.stringify({ boc: signed })
483
- });
484
- const json = await res.json();
485
- if (json.error) throw new Error(json.error.message || json.result);
486
- return json.result;
487
- }
488
- case "APT" /* APT */: {
489
- const res = await fetch(
490
- "https://fullnode.mainnet.aptoslabs.com/v1/transactions",
491
- {
492
- method: "POST",
493
- headers: { "Content-Type": "application/json" },
494
- body: typeof signed === "string" ? signed : JSON.stringify(signed)
495
- }
496
- );
497
- if (!res.ok) throw new Error("Broadcast failed");
498
- return res.json();
499
- }
500
- default:
501
- throw new Error("Unsupported currency");
502
- }
503
- }
504
- function buildPsbt(tx, network, maximumFeeRate) {
505
- return buildPsbt$1(tx, network, maximumFeeRate);
506
- }
507
- function buildEthTx(data) {
508
- return data;
509
- }
510
- function buildSolTx(data) {
511
- return data;
512
- }
513
- function buildTronTx(data) {
514
- return data;
515
- }
516
- function buildTonTx(data) {
517
- return data;
518
- }
519
- function buildAptTx(data) {
520
- return data;
521
- }
522
- function buildExternalTx(currency, tx) {
523
- switch (currency) {
524
- case "BTC" /* BTC */:
525
- return buildPsbt(tx);
526
- case "ETH" /* ETH */:
527
- case "BNB" /* BNB */:
528
- return buildEthTx(tx);
529
- case "SOL" /* SOL */:
530
- return buildSolTx(tx);
531
- case "TRX" /* TRON */:
532
- return buildTronTx(tx);
533
- case "TON" /* TON */:
534
- return buildTonTx(tx);
535
- case "APT" /* APT */:
536
- return buildAptTx(tx);
537
- default:
538
- throw new Error("Unsupported currency");
539
- }
540
- }
541
-
542
- // src/modules/wallets/utils/get-bound-fetch.ts
543
- var cachedFetch;
544
- function getBoundFetch() {
545
- if (!cachedFetch) {
546
- if (typeof globalThis.fetch !== "function") {
547
- throw new Error("[Ecency][Wallets] - global fetch is not available");
548
- }
549
- cachedFetch = globalThis.fetch.bind(globalThis);
550
- }
551
- return cachedFetch;
552
- }
553
-
554
- // src/modules/wallets/queries/use-hive-keys-query.ts
555
- function useHiveKeysQuery(username) {
556
- const { data: seed } = useSeedPhrase(username);
557
- return useQuery({
558
- queryKey: ["ecenc\u0443-wallets", "hive-keys", username, seed],
559
- staleTime: Infinity,
560
- queryFn: async () => {
561
- if (!seed) {
562
- throw new Error("[Ecency][Wallets] - no seed to create Hive account");
563
- }
564
- const method = await detectHiveKeyDerivation(username, seed).catch(
565
- () => "bip44"
566
- );
567
- const keys = method === "master-password" ? deriveHiveMasterPasswordKeys(username, seed) : deriveHiveKeys(seed);
568
- return {
569
- username,
570
- ...keys
571
- };
572
- }
573
- });
574
- }
575
365
  function createFallbackTokenMetadata(symbol) {
576
366
  return {
577
367
  issuer: "",
@@ -832,269 +622,8 @@ function getTokenOperationsQueryOptions(token, username, isForOwner = false, cur
832
622
  }
833
623
  });
834
624
  }
835
- function useWalletsCacheQuery(username) {
836
- const queryClient = useQueryClient();
837
- const queryKey = ["ecency-wallets", "wallets", username];
838
- const getCachedWallets = () => queryClient.getQueryData(queryKey);
839
- const createEmptyWalletMap = () => /* @__PURE__ */ new Map();
840
- return useQuery({
841
- queryKey,
842
- enabled: Boolean(username),
843
- initialData: () => getCachedWallets() ?? createEmptyWalletMap(),
844
- queryFn: async () => getCachedWallets() ?? createEmptyWalletMap(),
845
- staleTime: Infinity
846
- });
847
- }
848
- var PATHS = {
849
- ["BTC" /* BTC */]: "m/44'/0'/0'/0/0",
850
- // Bitcoin (BIP44)
851
- ["ETH" /* ETH */]: "m/44'/60'/0'/0/0",
852
- // Ethereum (BIP44)
853
- ["BNB" /* BNB */]: "m/44'/60'/0'/0/0",
854
- // BNB Smart Chain (BIP44)
855
- ["SOL" /* SOL */]: "m/44'/501'/0'/0'",
856
- // Solana (BIP44)
857
- ["TON" /* TON */]: "m/44'/607'/0'",
858
- // TON (BIP44)
859
- ["TRX" /* TRON */]: "m/44'/195'/0'/0/0",
860
- // Tron (BIP44)
861
- ["APT" /* APT */]: "m/44'/637'/0'/0'/0'"
862
- // Aptos (BIP44)
863
- };
864
- function useWalletCreate(username, currency, importedSeed) {
865
- const { data: generatedMnemonic } = useSeedPhrase(username);
866
- const queryClient = useQueryClient();
867
- const createWallet = useMutation({
868
- mutationKey: ["ecency-wallets", "create-wallet", username, currency],
869
- mutationFn: async () => {
870
- const mnemonic = importedSeed || generatedMnemonic;
871
- if (!mnemonic) {
872
- throw new Error("[Ecency][Wallets] - No seed to create a wallet");
873
- }
874
- const wallet = getWallet(currency);
875
- const privateKey = await wallet?.getDerivedPrivateKey({
876
- mnemonic,
877
- hdPath: PATHS[currency]
878
- });
879
- await delay(1e3);
880
- const address = await wallet?.getNewAddress({
881
- privateKey
882
- });
883
- return {
884
- privateKey,
885
- address: address.address,
886
- publicKey: address.publicKey,
887
- username,
888
- currency
889
- };
890
- },
891
- onSuccess: (info) => {
892
- queryClient.setQueryData(
893
- ["ecency-wallets", "wallets", info.username],
894
- (data) => new Map(data ? Array.from(data.entries()) : []).set(
895
- info.currency,
896
- info
897
- )
898
- );
899
- }
900
- });
901
- const importWallet = () => {
902
- };
903
- return {
904
- createWallet,
905
- importWallet
906
- };
907
- }
908
625
 
909
- // src/modules/wallets/mutations/private-api/index.ts
910
- var private_api_exports = {};
911
- __export(private_api_exports, {
912
- useCheckWalletExistence: () => useCheckWalletExistence,
913
- useCreateAccountWithWallets: () => useCreateAccountWithWallets,
914
- useUpdateAccountWithWallets: () => useUpdateAccountWithWallets
915
- });
916
- function useCreateAccountWithWallets(username) {
917
- const { data } = useWalletsCacheQuery(username);
918
- const { data: hiveKeys } = useHiveKeysQuery(username);
919
- const fetchApi = getBoundFetch();
920
- return useMutation({
921
- mutationKey: ["ecency-wallets", "create-account-with-wallets", username],
922
- mutationFn: ({ currency, address }) => fetchApi(`${ConfigManager.getValidatedBaseUrl()}/private-api/wallets-add`, {
923
- method: "POST",
924
- headers: {
925
- "Content-Type": "application/json"
926
- },
927
- body: JSON.stringify({
928
- username,
929
- token: currency,
930
- address,
931
- meta: {
932
- ownerPublicKey: hiveKeys?.ownerPubkey,
933
- activePublicKey: hiveKeys?.activePubkey,
934
- postingPublicKey: hiveKeys?.postingPubkey,
935
- memoPublicKey: hiveKeys?.memoPubkey,
936
- ...Array.from(data?.entries() ?? []).reduce(
937
- (acc, [curr, info]) => ({
938
- ...acc,
939
- [curr]: info.address
940
- }),
941
- {}
942
- )
943
- }
944
- })
945
- })
946
- });
947
- }
948
- function useCheckWalletExistence() {
949
- return useMutation({
950
- mutationKey: ["ecency-wallets", "check-wallet-existence"],
951
- mutationFn: async ({ address, currency }) => {
952
- const response = await fetch(
953
- `${ConfigManager.getValidatedBaseUrl()}/private-api/wallets-exist`,
954
- {
955
- method: "POST",
956
- headers: {
957
- "Content-Type": "application/json"
958
- },
959
- body: JSON.stringify({
960
- address,
961
- token: currency
962
- })
963
- }
964
- );
965
- const data = await response.json();
966
- return data.length === 0;
967
- }
968
- });
969
- }
970
- function useUpdateAccountWithWallets(username, accessToken) {
971
- const fetchApi = getBoundFetch();
972
- return useMutation({
973
- mutationKey: ["ecency-wallets", "update-account-with-wallets", username],
974
- mutationFn: async ({ tokens, hiveKeys }) => {
975
- const entries = Object.entries(tokens).filter(([, address]) => Boolean(address));
976
- if (entries.length === 0) {
977
- return new Response(null, { status: 204 });
978
- }
979
- const [primaryToken, primaryAddress] = entries[0] ?? ["", ""];
980
- if (!accessToken) {
981
- throw new Error(
982
- "[SDK][Wallets][PrivateApi][WalletsAdd] \u2013 access token wasn`t found"
983
- );
984
- }
985
- return fetchApi(`${ConfigManager.getValidatedBaseUrl()}/private-api/wallets-add`, {
986
- method: "POST",
987
- headers: {
988
- "Content-Type": "application/json"
989
- },
990
- body: JSON.stringify({
991
- username,
992
- code: accessToken,
993
- token: primaryToken,
994
- address: primaryAddress,
995
- status: 3,
996
- meta: {
997
- ...Object.fromEntries(entries),
998
- ownerPublicKey: hiveKeys.ownerPublicKey,
999
- activePublicKey: hiveKeys.activePublicKey,
1000
- postingPublicKey: hiveKeys.postingPublicKey,
1001
- memoPublicKey: hiveKeys.memoPublicKey
1002
- }
1003
- })
1004
- });
1005
- }
1006
- });
1007
- }
1008
-
1009
- // src/modules/wallets/functions/get-keys-from-seed.ts
1010
- var HD_PATHS = {
1011
- ["BTC" /* BTC */]: ["m/84'/0'/0'/0/0"],
1012
- ["ETH" /* ETH */]: ["m/84'/60'/0'/0/0"],
1013
- // its not working for Trust, Exodus, todo: check others below
1014
- ["BNB" /* BNB */]: ["m/84'/60'/0'/0/0"],
1015
- ["SOL" /* SOL */]: ["m/84'/501'/0'/0/0"],
1016
- ["TRX" /* TRON */]: ["m/44'/195'/0'/0'/0'"],
1017
- ["APT" /* APT */]: ["m/84'/637'/0'/0/0"],
1018
- ["TON" /* TON */]: ["m/44'/607'/0'"]
1019
- };
1020
- async function getKeysFromSeed(mnemonic, wallet, currency) {
1021
- for (const hdPath of HD_PATHS[currency] || []) {
1022
- try {
1023
- const derivedPrivateKey = await wallet.getDerivedPrivateKey({
1024
- mnemonic,
1025
- hdPath
1026
- });
1027
- const derivedPublicKey = await wallet.getNewAddress({
1028
- privateKey: derivedPrivateKey,
1029
- addressType: currency === "BTC" /* BTC */ ? "segwit_native" : void 0
1030
- });
1031
- return [derivedPrivateKey.toString(), derivedPublicKey.address];
1032
- } catch (error) {
1033
- return [];
1034
- }
1035
- }
1036
- return [];
1037
- }
1038
- function useImportWallet(username, currency) {
1039
- const queryClient = useQueryClient();
1040
- const { mutateAsync: checkWalletExistence } = private_api_exports.useCheckWalletExistence();
1041
- return useMutation({
1042
- mutationKey: ["ecency-wallets", "import-wallet", username, currency],
1043
- mutationFn: async ({ privateKeyOrSeed }) => {
1044
- const wallet = getWallet(currency);
1045
- if (!wallet) {
1046
- throw new Error("Cannot find token for this currency");
1047
- }
1048
- const isSeed = privateKeyOrSeed.split(" ").length === 12;
1049
- let address;
1050
- let privateKey = privateKeyOrSeed;
1051
- if (isSeed) {
1052
- [privateKey, address] = await getKeysFromSeed(
1053
- privateKeyOrSeed,
1054
- wallet,
1055
- currency
1056
- );
1057
- } else {
1058
- address = (await wallet.getNewAddress({
1059
- privateKey: privateKeyOrSeed
1060
- })).address;
1061
- }
1062
- if (!address || !privateKeyOrSeed) {
1063
- throw new Error(
1064
- "Private key/seed phrase isn't matching with public key or token"
1065
- );
1066
- }
1067
- const hasChecked = await checkWalletExistence({
1068
- address,
1069
- currency
1070
- });
1071
- if (!hasChecked) {
1072
- throw new Error(
1073
- "This wallet has already in use by Hive account. Please, try another one"
1074
- );
1075
- }
1076
- return {
1077
- privateKey,
1078
- address,
1079
- publicKey: ""
1080
- };
1081
- },
1082
- onSuccess: ({ privateKey, publicKey, address }) => {
1083
- queryClient.setQueryData(
1084
- ["ecency-wallets", "wallets", username],
1085
- (data) => new Map(data ? Array.from(data.entries()) : []).set(currency, {
1086
- privateKey,
1087
- publicKey,
1088
- address,
1089
- username,
1090
- currency,
1091
- type: "CHAIN",
1092
- custom: true
1093
- })
1094
- );
1095
- }
1096
- });
1097
- }
626
+ // src/modules/wallets/mutations/save-wallet-information-to-metadata.ts
1098
627
  function getGroupedChainTokens(tokens, defaultShow) {
1099
628
  if (!tokens) {
1100
629
  return {};
@@ -1171,9 +700,426 @@ function useSaveWalletInformationToMetadata(username, auth, options2) {
1171
700
  });
1172
701
  }
1173
702
 
703
+ // src/modules/wallets/utils/metamask-evm-transfer.ts
704
+ function getEthereum() {
705
+ if (typeof window === "undefined" || !window.ethereum) {
706
+ throw new Error("MetaMask not found");
707
+ }
708
+ return window.ethereum;
709
+ }
710
+ var WEI_PER_ETH = 1000000000000000000n;
711
+ var EVM_CHAIN_CONFIG = {
712
+ ["ETH" /* ETH */]: {
713
+ chainId: "0x1",
714
+ name: "Ethereum Mainnet",
715
+ rpcUrl: "https://rpc.ankr.com/eth",
716
+ explorerUrl: "https://etherscan.io/tx/"
717
+ },
718
+ ["BNB" /* BNB */]: {
719
+ chainId: "0x38",
720
+ name: "BNB Smart Chain",
721
+ rpcUrl: "https://bsc-dataseed.binance.org",
722
+ explorerUrl: "https://bscscan.com/tx/"
723
+ }
724
+ };
725
+ function getEvmChainConfig(currency) {
726
+ const config = EVM_CHAIN_CONFIG[currency];
727
+ if (!config) throw new Error(`Unsupported EVM currency: ${currency}`);
728
+ return config;
729
+ }
730
+ function getEvmExplorerUrl(currency, txHash) {
731
+ return `${getEvmChainConfig(currency).explorerUrl}${txHash}`;
732
+ }
733
+ async function ensureEvmChain(currency) {
734
+ const ethereum = getEthereum();
735
+ const { chainId, name, rpcUrl } = getEvmChainConfig(currency);
736
+ const currentChainId = await ethereum.request({ method: "eth_chainId" });
737
+ if (currentChainId === chainId) return;
738
+ try {
739
+ await ethereum.request({
740
+ method: "wallet_switchEthereumChain",
741
+ params: [{ chainId }]
742
+ });
743
+ } catch (err) {
744
+ if (typeof err === "object" && err !== null && "code" in err && err.code === 4902) {
745
+ await ethereum.request({
746
+ method: "wallet_addEthereumChain",
747
+ params: [{
748
+ chainId,
749
+ chainName: name,
750
+ rpcUrls: [rpcUrl],
751
+ nativeCurrency: {
752
+ name: currency === "ETH" /* ETH */ ? "Ether" : "BNB",
753
+ symbol: currency === "ETH" /* ETH */ ? "ETH" : "BNB",
754
+ decimals: 18
755
+ }
756
+ }]
757
+ });
758
+ } else {
759
+ throw err;
760
+ }
761
+ }
762
+ }
763
+ async function estimateEvmGas(from, to, valueHex, currency) {
764
+ const ethereum = getEthereum();
765
+ await ensureEvmChain(currency);
766
+ const [gasLimit, gasPrice] = await Promise.all([
767
+ ethereum.request({
768
+ method: "eth_estimateGas",
769
+ params: [{ from, to, value: valueHex }]
770
+ }),
771
+ ethereum.request({ method: "eth_gasPrice" })
772
+ ]);
773
+ const estimatedFeeWei = BigInt(gasLimit) * BigInt(gasPrice);
774
+ return { gasLimit, gasPrice, estimatedFeeWei };
775
+ }
776
+ function formatWei(wei, decimals = 6) {
777
+ const whole = wei / WEI_PER_ETH;
778
+ const rem = wei % WEI_PER_ETH;
779
+ if (rem === 0n) return whole.toString();
780
+ const scale = 10n ** BigInt(decimals);
781
+ const fractional = rem * scale / WEI_PER_ETH;
782
+ const fracStr = fractional.toString().padStart(decimals, "0").replace(/0+$/, "");
783
+ return fracStr ? `${whole}.${fracStr}` : whole.toString();
784
+ }
785
+ var AMOUNT_REGEX = /^\d+(\.\d+)?$/;
786
+ function parseToWei(amount) {
787
+ const trimmed = amount.trim();
788
+ if (!AMOUNT_REGEX.test(trimmed)) {
789
+ throw new Error(`Invalid amount: "${amount}"`);
790
+ }
791
+ const [whole, fraction = ""] = trimmed.split(".");
792
+ if (!/^\d+$/.test(whole) || fraction && !/^\d+$/.test(fraction)) {
793
+ throw new Error(`Invalid amount: "${amount}"`);
794
+ }
795
+ const paddedFraction = fraction.padEnd(18, "0").slice(0, 18);
796
+ const wei = BigInt(whole) * WEI_PER_ETH + BigInt(paddedFraction);
797
+ return "0x" + wei.toString(16);
798
+ }
799
+ async function sendEvmTransfer(to, amountWei, currency) {
800
+ const ethereum = getEthereum();
801
+ await ensureEvmChain(currency);
802
+ const accounts = await ethereum.request({ method: "eth_requestAccounts" });
803
+ const from = accounts[0];
804
+ if (!from) throw new Error("No MetaMask account connected");
805
+ const txHash = await ethereum.request({
806
+ method: "eth_sendTransaction",
807
+ params: [{
808
+ from,
809
+ to,
810
+ value: amountWei
811
+ }]
812
+ });
813
+ return txHash;
814
+ }
815
+ var SOL_EXPLORER_URL = "https://explorer.solana.com/tx/";
816
+ var LAMPORTS_PER_SOL = 1000000000n;
817
+ var AMOUNT_REGEX2 = /^\d+(\.\d+)?$/;
818
+ function getSolExplorerUrl(signature) {
819
+ return `${SOL_EXPLORER_URL}${signature}`;
820
+ }
821
+ function parseToLamports(amount) {
822
+ const trimmed = amount.trim();
823
+ if (!AMOUNT_REGEX2.test(trimmed)) {
824
+ throw new Error(`Invalid amount: "${amount}"`);
825
+ }
826
+ const [whole, fraction = ""] = trimmed.split(".");
827
+ if (!/^\d+$/.test(whole) || fraction && !/^\d+$/.test(fraction)) {
828
+ throw new Error(`Invalid amount: "${amount}"`);
829
+ }
830
+ if (fraction.length > 9 && fraction.slice(9).replace(/0/g, "").length > 0) {
831
+ throw new Error(`Amount has more than 9 decimal places: "${amount}"`);
832
+ }
833
+ const paddedFraction = fraction.padEnd(9, "0").slice(0, 9);
834
+ return BigInt(whole) * LAMPORTS_PER_SOL + BigInt(paddedFraction);
835
+ }
836
+ function formatLamports(lamports, decimals = 6) {
837
+ const whole = lamports / LAMPORTS_PER_SOL;
838
+ const rem = lamports % LAMPORTS_PER_SOL;
839
+ if (rem === 0n) return whole.toString();
840
+ const scale = 10n ** BigInt(decimals);
841
+ const fractional = rem * scale / LAMPORTS_PER_SOL;
842
+ const fracStr = fractional.toString().padStart(decimals, "0").replace(/0+$/, "");
843
+ return fracStr ? `${whole}.${fracStr}` : whole.toString();
844
+ }
845
+ async function solRpc(method, params = []) {
846
+ const baseUrl = ConfigManager.getValidatedBaseUrl();
847
+ const response = await fetch(`${baseUrl}/private-api/rpc/sol`, {
848
+ method: "POST",
849
+ headers: { "Content-Type": "application/json" },
850
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params })
851
+ });
852
+ if (!response.ok) {
853
+ const text = await response.text().catch(() => "");
854
+ throw new Error(`SOL RPC ${method} failed: ${response.status} ${response.statusText}${text ? ` \u2014 ${text}` : ""}`);
855
+ }
856
+ const json = await response.json();
857
+ if (json.error) {
858
+ throw new Error(json.error.message || `SOL RPC ${method} failed`);
859
+ }
860
+ return json.result;
861
+ }
862
+ async function getMetaMaskSolanaWallet() {
863
+ const { getWallets } = await import('@wallet-standard/app');
864
+ const walletsApi = getWallets();
865
+ const wallets = walletsApi.get();
866
+ const mmWallet = wallets.find(
867
+ (w) => w.name.toLowerCase().includes("metamask") && w.features["standard:connect"] && w.features["solana:signAndSendTransaction"]
868
+ );
869
+ if (!mmWallet) {
870
+ throw new Error("MetaMask Solana wallet not found. Enable Solana in MetaMask settings.");
871
+ }
872
+ return mmWallet;
873
+ }
874
+ async function sendSolTransfer(to, amountSol) {
875
+ const mmWallet = await getMetaMaskSolanaWallet();
876
+ const connectFeature = mmWallet.features["standard:connect"];
877
+ await connectFeature.connect();
878
+ const solAccount = mmWallet.accounts?.find(
879
+ (acc) => acc.chains?.some((c) => c.startsWith("solana:"))
880
+ );
881
+ if (!solAccount) {
882
+ throw new Error("No Solana account found in MetaMask.");
883
+ }
884
+ const { PublicKey, SystemProgram, Transaction } = await import('@solana/web3.js');
885
+ const fromPubkey = new PublicKey(solAccount.address);
886
+ const toPubkey = new PublicKey(to);
887
+ const lamports = parseToLamports(amountSol);
888
+ const transaction = new Transaction().add(
889
+ SystemProgram.transfer({
890
+ fromPubkey,
891
+ toPubkey,
892
+ lamports
893
+ })
894
+ );
895
+ const blockhashResult = await solRpc(
896
+ "getLatestBlockhash",
897
+ [{ commitment: "finalized" }]
898
+ );
899
+ transaction.recentBlockhash = blockhashResult.value.blockhash;
900
+ transaction.feePayer = fromPubkey;
901
+ const serializedTx = transaction.serialize({
902
+ requireAllSignatures: false,
903
+ verifySignatures: false
904
+ });
905
+ const signAndSendFeature = mmWallet.features["solana:signAndSendTransaction"];
906
+ if (!signAndSendFeature) {
907
+ throw new Error("MetaMask does not support Solana transaction signing. Please update MetaMask.");
908
+ }
909
+ const [result] = await signAndSendFeature.signAndSendTransaction({
910
+ account: solAccount,
911
+ transaction: serializedTx,
912
+ chain: "solana:mainnet"
913
+ });
914
+ if (typeof result.signature === "string") {
915
+ return result.signature;
916
+ }
917
+ const { base58 } = await import('@scure/base');
918
+ return base58.encode(new Uint8Array(result.signature));
919
+ }
920
+ function useExternalTransfer(currency) {
921
+ const queryClient = useQueryClient();
922
+ return useMutation({
923
+ mutationKey: ["ecency-wallets", "external-transfer", currency],
924
+ mutationFn: async ({ to, amount }) => {
925
+ switch (currency) {
926
+ case "ETH" /* ETH */:
927
+ case "BNB" /* BNB */: {
928
+ const valueHex = parseToWei(amount);
929
+ const txHash = await sendEvmTransfer(to, valueHex, currency);
930
+ return { txHash, currency };
931
+ }
932
+ case "SOL" /* SOL */: {
933
+ const signature = await sendSolTransfer(to, amount);
934
+ return { txHash: signature, currency };
935
+ }
936
+ }
937
+ },
938
+ onSuccess: () => {
939
+ queryClient.invalidateQueries({
940
+ queryKey: ["ecency-wallets", "external-wallet-balance"]
941
+ });
942
+ }
943
+ });
944
+ }
945
+ var ROLE_INDEX = {
946
+ owner: 0,
947
+ active: 1,
948
+ posting: 2,
949
+ memo: 3
950
+ };
951
+ function deriveHiveKey(mnemonic, role, accountIndex = 0) {
952
+ const seed = mnemonicToSeedSync(mnemonic);
953
+ const master = HDKey.fromMasterSeed(seed);
954
+ const path = `m/44'/3054'/${accountIndex}'/0'/${ROLE_INDEX[role]}'`;
955
+ const child = master.derive(path);
956
+ if (!child.privateKey) {
957
+ throw new Error("[Ecency][Wallets] - hive key derivation failed");
958
+ }
959
+ const pk = PrivateKey.from(Buffer.from(child.privateKey));
960
+ return {
961
+ privateKey: pk.toString(),
962
+ publicKey: pk.createPublic().toString()
963
+ };
964
+ }
965
+ function deriveHiveKeys(mnemonic, accountIndex = 0) {
966
+ const owner = deriveHiveKey(mnemonic, "owner", accountIndex);
967
+ const active = deriveHiveKey(mnemonic, "active", accountIndex);
968
+ const posting = deriveHiveKey(mnemonic, "posting", accountIndex);
969
+ const memo = deriveHiveKey(mnemonic, "memo", accountIndex);
970
+ return {
971
+ owner: owner.privateKey,
972
+ active: active.privateKey,
973
+ posting: posting.privateKey,
974
+ memo: memo.privateKey,
975
+ ownerPubkey: owner.publicKey,
976
+ activePubkey: active.publicKey,
977
+ postingPubkey: posting.publicKey,
978
+ memoPubkey: memo.publicKey
979
+ };
980
+ }
981
+ function deriveHiveMasterPasswordKey(username, masterPassword, role) {
982
+ const pk = PrivateKey.fromLogin(username, masterPassword, role);
983
+ return {
984
+ privateKey: pk.toString(),
985
+ publicKey: pk.createPublic().toString()
986
+ };
987
+ }
988
+ function deriveHiveMasterPasswordKeys(username, masterPassword) {
989
+ const owner = deriveHiveMasterPasswordKey(username, masterPassword, "owner");
990
+ const active = deriveHiveMasterPasswordKey(username, masterPassword, "active");
991
+ const posting = deriveHiveMasterPasswordKey(
992
+ username,
993
+ masterPassword,
994
+ "posting"
995
+ );
996
+ const memo = deriveHiveMasterPasswordKey(username, masterPassword, "memo");
997
+ return {
998
+ owner: owner.privateKey,
999
+ active: active.privateKey,
1000
+ posting: posting.privateKey,
1001
+ memo: memo.privateKey,
1002
+ ownerPubkey: owner.publicKey,
1003
+ activePubkey: active.publicKey,
1004
+ postingPubkey: posting.publicKey,
1005
+ memoPubkey: memo.publicKey
1006
+ };
1007
+ }
1008
+ async function detectHiveKeyDerivation(username, seed, type = "active") {
1009
+ const uname = username.trim().toLowerCase();
1010
+ const account = await CONFIG.queryClient.fetchQuery(
1011
+ getAccountFullQueryOptions(uname)
1012
+ );
1013
+ const auth = account[type];
1014
+ const bip44 = deriveHiveKeys(seed);
1015
+ const bip44Pub = type === "owner" ? bip44.ownerPubkey : bip44.activePubkey;
1016
+ const matchBip44 = auth.key_auths.some(([pub]) => String(pub) === bip44Pub);
1017
+ if (matchBip44) return "bip44";
1018
+ const legacyPub = PrivateKey.fromLogin(uname, seed, type).createPublic().toString();
1019
+ const matchLegacy = auth.key_auths.some(([pub]) => String(pub) === legacyPub);
1020
+ if (matchLegacy) return "master-password";
1021
+ return "unknown";
1022
+ }
1023
+
1024
+ // src/modules/wallets/utils/metamask-discovery.ts
1025
+ var CHAIN_PREFIX_MAP = {
1026
+ "solana:": "SOL" /* SOL */,
1027
+ "bip122:": "BTC" /* BTC */
1028
+ };
1029
+ var HIVE_SNAP_ID = "npm:@hiveio/metamask-snap";
1030
+ async function fetchMultichainAddresses() {
1031
+ const addresses = {};
1032
+ try {
1033
+ const { getWallets } = await import('@wallet-standard/app');
1034
+ const walletsApi = getWallets();
1035
+ const wallets = walletsApi.get();
1036
+ const mmWallets = wallets.filter(
1037
+ (w) => w.name.toLowerCase().includes("metamask") && w.features["standard:connect"]
1038
+ );
1039
+ for (const mmWallet of mmWallets) {
1040
+ try {
1041
+ const connectFeature = mmWallet.features["standard:connect"];
1042
+ await connectFeature.connect();
1043
+ } catch (connectErr) {
1044
+ if (false) ;
1045
+ continue;
1046
+ }
1047
+ for (const account of mmWallet.accounts ?? []) {
1048
+ if (!account.address || !Array.isArray(account.chains)) continue;
1049
+ for (const [prefix, currency] of Object.entries(CHAIN_PREFIX_MAP)) {
1050
+ if (addresses[currency]) continue;
1051
+ if (account.chains.some((c) => c.startsWith(prefix))) {
1052
+ addresses[currency] = account.address;
1053
+ }
1054
+ }
1055
+ }
1056
+ }
1057
+ } catch (e) {
1058
+ }
1059
+ return addresses;
1060
+ }
1061
+ async function fetchEvmAddress() {
1062
+ if (typeof window === "undefined" || !window.ethereum?.isMetaMask) return void 0;
1063
+ try {
1064
+ const accounts = await window.ethereum.request({
1065
+ method: "eth_requestAccounts"
1066
+ });
1067
+ return accounts?.[0] ?? void 0;
1068
+ } catch {
1069
+ return void 0;
1070
+ }
1071
+ }
1072
+ async function discoverMetaMaskWallets() {
1073
+ const addresses = {};
1074
+ const evmAddress = await fetchEvmAddress();
1075
+ if (evmAddress) {
1076
+ addresses["ETH" /* ETH */] = evmAddress;
1077
+ addresses["BNB" /* BNB */] = evmAddress;
1078
+ }
1079
+ const multichainAddresses = await fetchMultichainAddresses();
1080
+ Object.assign(addresses, multichainAddresses);
1081
+ return addresses;
1082
+ }
1083
+ async function installHiveSnap() {
1084
+ if (typeof window === "undefined" || !window.ethereum) {
1085
+ throw new Error("MetaMask is not available");
1086
+ }
1087
+ await window.ethereum.request({
1088
+ method: "wallet_requestSnaps",
1089
+ params: { [HIVE_SNAP_ID]: {} }
1090
+ });
1091
+ }
1092
+ async function getHivePublicKeys() {
1093
+ if (typeof window === "undefined" || !window.ethereum) {
1094
+ throw new Error("MetaMask is not available");
1095
+ }
1096
+ const result = await window.ethereum.request({
1097
+ method: "wallet_invokeSnap",
1098
+ params: {
1099
+ snapId: HIVE_SNAP_ID,
1100
+ request: {
1101
+ method: "hive_getPublicKeys",
1102
+ params: {
1103
+ keys: [
1104
+ { role: "owner", accountIndex: 0 },
1105
+ { role: "active", accountIndex: 0 },
1106
+ { role: "posting", accountIndex: 0 },
1107
+ { role: "memo", accountIndex: 0 }
1108
+ ]
1109
+ }
1110
+ }
1111
+ }
1112
+ });
1113
+ const keys = result?.publicKeys;
1114
+ if (!Array.isArray(keys)) {
1115
+ throw new Error("Hive Snap returned invalid response \u2014 expected publicKeys array");
1116
+ }
1117
+ return keys;
1118
+ }
1119
+
1174
1120
  // src/index.ts
1175
1121
  rememberScryptBsvVersion();
1176
1122
 
1177
- export { EcencyWalletBasicTokens, EcencyWalletCurrency, private_api_exports as EcencyWalletsPrivateApi, buildAptTx, buildEthTx, buildExternalTx, buildPsbt, buildSolTx, buildTonTx, buildTronTx, decryptMemoWithAccounts, decryptMemoWithKeys, delay, deriveHiveKey, deriveHiveKeys, deriveHiveMasterPasswordKey, deriveHiveMasterPasswordKeys, detectHiveKeyDerivation, encryptMemoWithAccounts, encryptMemoWithKeys, getAccountWalletListQueryOptions, getAllTokensListQueryOptions, getBoundFetch, getTokenOperationsQueryOptions, getTokenPriceQueryOptions, getWallet, mnemonicToSeedBip39, signDigest, signExternalTx, signExternalTxAndBroadcast, signTx, signTxAndBroadcast, useGetExternalWalletBalanceQuery, useHiveKeysQuery, useImportWallet, useSaveWalletInformationToMetadata, useSeedPhrase, useWalletCreate, useWalletsCacheQuery };
1123
+ export { EcencyWalletBasicTokens, EcencyWalletCurrency, private_api_exports as EcencyWalletsPrivateApi, deriveHiveKey, deriveHiveKeys, deriveHiveMasterPasswordKey, deriveHiveMasterPasswordKeys, detectHiveKeyDerivation, discoverMetaMaskWallets, ensureEvmChain, estimateEvmGas, fetchEvmAddress, fetchMultichainAddresses, formatLamports, formatWei, getAccountWalletListQueryOptions, getAllTokensListQueryOptions, getEvmChainConfig, getEvmExplorerUrl, getHivePublicKeys, getSolExplorerUrl, getTokenOperationsQueryOptions, getTokenPriceQueryOptions, installHiveSnap, parseToLamports, parseToWei, sendEvmTransfer, sendSolTransfer, useExternalTransfer, useGetExternalWalletBalanceQuery, useSaveWalletInformationToMetadata };
1178
1124
  //# sourceMappingURL=index.js.map
1179
1125
  //# sourceMappingURL=index.js.map