@bze/bze-ui-kit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,4663 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
32
+
33
+ // src/constants/chain.ts
34
+ import { chains as testnetChains } from "chain-registry/testnet";
35
+ import { getAssetLists as ibcAssetsList } from "@chain-registry/utils";
36
+
37
+ // src/constants/assets.ts
38
+ var ASSET_TYPE_FACTORY = "Factory";
39
+ var ASSET_TYPE_IBC = "IBC";
40
+ var ASSET_TYPE_NATIVE = "Native";
41
+ var ASSET_TYPE_LP = "LP";
42
+ var VERIFIED_ASSETS = {
43
+ "factory/testbz1w9vva0muctcrmd9xgret9x4wasw2rrflsdkwfs/faneatiku2": true,
44
+ "factory/testbz1z3mkcr2jz424w6m49frgjmy9uhlrx69p4cvrgf/vidulum": true,
45
+ "factory/testbz1z3mkcr2jz424w6m49frgjmy9uhlrx69p4cvrgf/bitcoinz": true,
46
+ "ubze": true,
47
+ "utbz": true,
48
+ "factory/bze13gzq40che93tgfm9kzmkpjamah5nj0j73pyhqk/uvdl": true,
49
+ "factory/bze15pqjgk4la0mfphwddce00d05n3th3u66n3ptcv/2MARS": true,
50
+ "factory/bze12gyp30f29zg26nuqrwdhl26ej4q066pt572fhm/GGE": true
51
+ };
52
+ var EXCLUDED_ASSETS = {
53
+ "factory/testbz1w9vva0muctcrmd9xgret9x4wasw2rrflsdkwfs/faneatiku1": false,
54
+ "factory/bze1972aqfzdg29ugjln74edx0xvcg4ehvysjptk77/1000000000": true,
55
+ "ibc/689DD6F80E4DBCE14877462B182504037FAEAD0699D5804A7F5CB328D33ED24B": true,
56
+ "factory/bze1f0qgels0eu96ev6a67znu70q7rquy9eragn8nw/ucorey": true
57
+ };
58
+ var STABLE_COINS = {
59
+ "factory/testbz1z3mkcr2jz424w6m49frgjmy9uhlrx69p4cvrgf/uusdt": true,
60
+ "factory/bze1z3mkcr2jz424w6m49frgjmy9uhlrx69phqwg3l/testusd": true,
61
+ "ibc/6490A7EAB61059BFC1CDDEB05917DD70BDF3A611654162A1A47DB930D40D8AF4": true
62
+ };
63
+ var getChainNativeAssetDenom = () => {
64
+ return process.env.NEXT_PUBLIC_CHAIN_NATIVE_ASSET_DENOM || "ubze";
65
+ };
66
+ var getUSDCDenom = () => {
67
+ return process.env.NEXT_PUBLIC_USDC_IBC_DENOM || "";
68
+ };
69
+
70
+ // src/constants/testnet.ts
71
+ var BZE_TESTNET_2_SUGGEST_CHAIN = {
72
+ chainId: "bzetestnet-3",
73
+ chainType: "cosmos",
74
+ chainName: "BeeZee Testnet 3",
75
+ prettyName: "BeeZee Testnet 3",
76
+ networkType: "mainnet",
77
+ bech32Prefix: "bze",
78
+ status: "live",
79
+ slip44: 118,
80
+ logoURIs: {
81
+ svg: "https://raw.githubusercontent.com/cosmos/chain-registry/master/beezee/images/bze.svg"
82
+ },
83
+ fees: {
84
+ feeTokens: [
85
+ {
86
+ denom: getChainNativeAssetDenom(),
87
+ fixedMinGasPrice: 0.01,
88
+ lowGasPrice: 0.01,
89
+ averageGasPrice: 0.025,
90
+ highGasPrice: 0.04
91
+ }
92
+ ]
93
+ },
94
+ keyAlgos: [
95
+ "secp256k1"
96
+ ],
97
+ staking: {
98
+ stakingTokens: [
99
+ {
100
+ denom: getChainNativeAssetDenom()
101
+ }
102
+ ]
103
+ },
104
+ explorers: [
105
+ {
106
+ "kind": "ping.pub",
107
+ "url": "https://testnet.explorer.thesilverfox.pro/beezee",
108
+ "tx_page": "https://testnet.explorer.thesilverfox.pro/beezee/tx/${txHash}"
109
+ }
110
+ ],
111
+ codebase: {
112
+ "git_repo": "https://github.com/bze-alphateam/bze",
113
+ "recommended_version": "v5.1.2",
114
+ "compatible_versions": [
115
+ "v5.1.2"
116
+ ],
117
+ "binaries": {
118
+ "darwin/amd64": "https://github.com/bze-alphateam/bze/releases/download/v5.1.2/bze-5.1.2-darwin-amd64.tar.gz",
119
+ "darwin/arm64": "https://github.com/bze-alphateam/bze/releases/download/v5.1.2/bze-5.1.2-darwin-arm64.tar.gz",
120
+ "linux/amd64": "https://github.com/bze-alphateam/bze/releases/download/v5.1.2/bze-5.1.2-linux-amd64.tar.gz",
121
+ "linux/arm64": "https://github.com/bze-alphateam/bze/releases/download/v5.1.2/bze-5.1.2-linux-arm64.tar.gz",
122
+ "windows/amd64": "https://github.com/bze-alphateam/bze/releases/download/v5.1.2/bze-5.1.2-win64.zip"
123
+ },
124
+ "genesis": {
125
+ "genesis_url": "https://raw.githubusercontent.com/bze-alphateam/bze/main/genesis.json"
126
+ }
127
+ },
128
+ apis: {
129
+ "rpc": [
130
+ {
131
+ "address": "https://testnet-rpc.getbze.com",
132
+ "provider": "AlphaTeam"
133
+ }
134
+ ],
135
+ "rest": [
136
+ {
137
+ "address": "https://testnet.getbze.com",
138
+ "provider": "AlphaTeam"
139
+ }
140
+ ],
141
+ "grpc": [
142
+ {
143
+ "address": "grpc.getbze.com:9999",
144
+ "provider": "AlphaTeam"
145
+ }
146
+ ]
147
+ }
148
+ };
149
+ var BZE_TESTNET_NETWORK = {
150
+ base: {
151
+ explorerBaseUrl: "https://explorer.getbze.com/bze%20testnet",
152
+ rpcUrl: "https://testnet-rpc.getbze.com",
153
+ restUrl: "https://testnet.getbze.com",
154
+ chainName: BZE_TESTNET_2_SUGGEST_CHAIN.chainName
155
+ },
156
+ chain: [BZE_TESTNET_2_SUGGEST_CHAIN],
157
+ assets: [
158
+ {
159
+ chainName: BZE_TESTNET_2_SUGGEST_CHAIN.chainName,
160
+ assets: [
161
+ {
162
+ "description": "BeeZee native blockchain",
163
+ "typeAsset": "sdk.coin",
164
+ "denomUnits": [
165
+ {
166
+ "denom": getChainNativeAssetDenom(),
167
+ "exponent": 0
168
+ },
169
+ {
170
+ "denom": "TBZE",
171
+ "exponent": 6
172
+ }
173
+ ],
174
+ "base": getChainNativeAssetDenom(),
175
+ "name": "BeeZee",
176
+ "display": "TBZE",
177
+ "symbol": "TBZE",
178
+ "logoURIs": {
179
+ "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/beezee/images/bze.svg",
180
+ "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/beezee/images/bze.png"
181
+ },
182
+ "coingeckoId": "bzedge"
183
+ },
184
+ {
185
+ "description": "Lumen",
186
+ "typeAsset": "sdk.coin",
187
+ "denomUnits": [
188
+ {
189
+ "denom": "ibc/9DA252F9F9C86132CC282EA431DFB7DE7729501F6DC9A3E0F50EC8C6EE380CC7",
190
+ "exponent": 0,
191
+ "aliases": []
192
+ },
193
+ {
194
+ "denom": "LMN",
195
+ "exponent": 6,
196
+ "aliases": []
197
+ }
198
+ ],
199
+ "base": "ibc/9DA252F9F9C86132CC282EA431DFB7DE7729501F6DC9A3E0F50EC8C6EE380CC7",
200
+ "display": "LMN",
201
+ "name": "Lumen",
202
+ "symbol": "LMN",
203
+ "logoURIs": {
204
+ "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/lumen/images/lmn.png"
205
+ }
206
+ },
207
+ {
208
+ "description": "Vidulum app token",
209
+ "typeAsset": "sdk.coin",
210
+ "denomUnits": [
211
+ {
212
+ "denom": "factory/bze1z3mkcr2jz424w6m49frgjmy9uhlrx69phqwg3l/vidulum",
213
+ "exponent": 0,
214
+ "aliases": []
215
+ },
216
+ {
217
+ "denom": "VDL",
218
+ "exponent": 6,
219
+ "aliases": []
220
+ }
221
+ ],
222
+ "base": "factory/bze1z3mkcr2jz424w6m49frgjmy9uhlrx69phqwg3l/vidulum",
223
+ "display": "VDL",
224
+ "name": "Vidulum",
225
+ "symbol": "VDL",
226
+ "logoURIs": {
227
+ "png": "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/beezee/factory/bze13gzq40che93tgfm9kzmkpjamah5nj0j73pyhqk/uvdl.png"
228
+ }
229
+ }
230
+ ]
231
+ }
232
+ ]
233
+ };
234
+
235
+ // src/constants/chain.ts
236
+ import { assetLists, chains, ibcData } from "@chain-registry/v2";
237
+ var getChainId = () => {
238
+ return process.env.NEXT_PUBLIC_CHAIN_ID || "beezee-1";
239
+ };
240
+ var getChainName = () => {
241
+ return process.env.NEXT_PUBLIC_CHAIN_NAME || "beezee";
242
+ };
243
+ var isTestnetChain = () => {
244
+ const isTestnet = process.env.NEXT_PUBLIC_CHAIN_IS_TESTNET;
245
+ return isTestnet === "true" || isTestnet === "1";
246
+ };
247
+ var getChains = () => {
248
+ let localChains = chains;
249
+ if (isTestnetChain()) {
250
+ localChains = [...testnetChains, BZE_TESTNET_2_SUGGEST_CHAIN];
251
+ }
252
+ return localChains;
253
+ };
254
+ var getChainByChainId = (chainId) => {
255
+ let localChains = chains;
256
+ if (isTestnetChain()) {
257
+ localChains = [...testnetChains, BZE_TESTNET_2_SUGGEST_CHAIN];
258
+ }
259
+ return localChains.find((c) => {
260
+ var _a2;
261
+ return ((_a2 = c.chainId) == null ? void 0 : _a2.toLowerCase()) === chainId.toLowerCase();
262
+ });
263
+ };
264
+ var getChainByName = (name) => {
265
+ let localChains = chains;
266
+ if (isTestnetChain()) {
267
+ localChains = [...testnetChains, BZE_TESTNET_2_SUGGEST_CHAIN];
268
+ }
269
+ return localChains.find((c) => c.chainName.toLowerCase() === name.toLowerCase());
270
+ };
271
+ var getWalletChainsNames = () => {
272
+ const localChains = getChains();
273
+ const envChainsNames = process.env.NEXT_PUBLIC_WALLET_CHAINS_NAMES;
274
+ if (!envChainsNames) {
275
+ return localChains.filter((c) => c.chainId === getChainId());
276
+ }
277
+ const split = envChainsNames.split(",");
278
+ return appChainFirst(localChains.filter((c) => split.includes(c.chainName)));
279
+ };
280
+ var appChainFirst = (chains2) => {
281
+ return chains2.sort((a, b) => a.chainId === getChainId() ? -1 : b.chainId === getChainId() ? 1 : 0);
282
+ };
283
+ var getAssetLists = () => {
284
+ let localAssetLists = assetLists;
285
+ if (isTestnetChain()) {
286
+ localAssetLists = BZE_TESTNET_NETWORK.assets;
287
+ }
288
+ return localAssetLists;
289
+ };
290
+ var getIBCAssetList = () => {
291
+ const all = ibcAssetsList(getChainName(), ibcData, getAssetLists());
292
+ return all.length > 0 ? all[0].assets : [];
293
+ };
294
+ var getChainAddressPrefix = () => {
295
+ return process.env.NEXT_PUBLIC_CHAIN_ADDRESS_PREFIX || "bze";
296
+ };
297
+ var getChainExplorerURL = (chainName) => {
298
+ if (process.env.NEXT_PUBLIC_EXPLORER_URL) {
299
+ return `${process.env.NEXT_PUBLIC_EXPLORER_URL}/${chainName}`;
300
+ }
301
+ return `https://explorer.chaintools.tech/${chainName}`;
302
+ };
303
+ var getLockerAddress = () => {
304
+ return process.env.NEXT_PUBLIC_LOCKER_ADDRESS || "bze1pc5zjcvhx3e8l305zjl72grytfa30r5mdypmw4";
305
+ };
306
+
307
+ // src/storage/storage.ts
308
+ var TTL_NO_EXPIRY = 0;
309
+ var _storageKeyVersion = "1";
310
+ var setStorageKeyVersion = (version) => {
311
+ _storageKeyVersion = version;
312
+ };
313
+ var getFromLocalStorage = (key) => {
314
+ if (typeof window === "undefined") return null;
315
+ try {
316
+ const cachedItem = localStorage.getItem(prefixedKey(key));
317
+ if (cachedItem) {
318
+ const item = JSON.parse(cachedItem);
319
+ const now = (/* @__PURE__ */ new Date()).getTime();
320
+ if (item.expiry === TTL_NO_EXPIRY || now < item.expiry) {
321
+ return item.data;
322
+ }
323
+ localStorage.removeItem(prefixedKey(key));
324
+ }
325
+ } catch (error) {
326
+ console.error("Failed to get data from localStorage:", error);
327
+ }
328
+ return null;
329
+ };
330
+ var setInLocalStorage = (key, data, ttl) => {
331
+ if (typeof window === "undefined") return false;
332
+ try {
333
+ if (ttl < 0) ttl = 0;
334
+ const item = {
335
+ data,
336
+ expiry: TTL_NO_EXPIRY
337
+ };
338
+ if (ttl > 0) {
339
+ const now = (/* @__PURE__ */ new Date()).getTime();
340
+ item.expiry = now + ttl * 1e3;
341
+ }
342
+ localStorage.setItem(prefixedKey(key), JSON.stringify(item));
343
+ return true;
344
+ } catch (error) {
345
+ console.error("Failed to set data in localStorage:", error);
346
+ }
347
+ return false;
348
+ };
349
+ var removeFromLocalStorage = (key) => {
350
+ if (typeof window === "undefined") return;
351
+ try {
352
+ localStorage.removeItem(prefixedKey(key));
353
+ } catch (error) {
354
+ console.error("Failed to remove data from localStorage:", error);
355
+ }
356
+ };
357
+ var getKeyExpiry = (key) => {
358
+ if (typeof window === "undefined") return null;
359
+ try {
360
+ const cachedItem = localStorage.getItem(prefixedKey(key));
361
+ if (cachedItem) {
362
+ const item = JSON.parse(cachedItem);
363
+ if (item.expiry > TTL_NO_EXPIRY) {
364
+ return new Date(item.expiry);
365
+ }
366
+ }
367
+ } catch (error) {
368
+ console.error("Failed to get data from localStorage:", error);
369
+ }
370
+ return null;
371
+ };
372
+ var setKeyExpiry = (key, expiry) => {
373
+ if (typeof window === "undefined") return false;
374
+ try {
375
+ const cachedItem = localStorage.getItem(prefixedKey(key));
376
+ if (cachedItem) {
377
+ const item = JSON.parse(cachedItem);
378
+ if (item) {
379
+ item.expiry = expiry.getTime();
380
+ localStorage.setItem(prefixedKey(key), JSON.stringify(item));
381
+ return true;
382
+ }
383
+ }
384
+ } catch (error) {
385
+ console.error("Failed to set data in localStorage:", error);
386
+ }
387
+ return false;
388
+ };
389
+ var prefixedKey = (key) => {
390
+ return `${_storageKeyVersion}-${getChainId()}:${key}`;
391
+ };
392
+
393
+ // src/constants/placeholders.ts
394
+ var TOKEN_LOGO_PLACEHOLDER = "/images/token.svg";
395
+ var BZE_CIRCLE_LOGO = "/images/bze_alternative_512x512.png";
396
+ var _defaultTxMemo = "getbze.com";
397
+ var DEFAULT_TX_MEMO = _defaultTxMemo;
398
+ var setDefaultTxMemo = (memo) => {
399
+ _defaultTxMemo = memo;
400
+ };
401
+ var getDefaultTxMemo = () => {
402
+ return _defaultTxMemo;
403
+ };
404
+
405
+ // src/types/asset.ts
406
+ var LP_ASSETS_DECIMALS = 12;
407
+
408
+ // src/types/market.ts
409
+ var ORDER_TYPE_BUY = "buy";
410
+ var ORDER_TYPE_SELL = "sell";
411
+
412
+ // src/types/settings.ts
413
+ var CONNECTION_TYPE_WS = 2;
414
+ var CONNECTION_TYPE_POLLING = 1;
415
+ var CONNECTION_TYPE_NONE = 0;
416
+
417
+ // src/types/events.ts
418
+ var CURRENT_WALLET_BALANCE_EVENT = "current_wallet_balance";
419
+ var ORDER_EXECUTED_EVENT = "order_executed";
420
+ var ORDER_BOOK_CHANGED_EVENT = "order_book_changed";
421
+ var SUPPLY_CHANGED_EVENT = "supply_changed";
422
+ var SWAP_EXECUTED_EVENT = "swap_executed";
423
+ var NEXT_BURN_CHANGED_EVENT = "next_burn_changed";
424
+ var RAFFLE_CHANGED_EVENT = "raffle_changed";
425
+ var LOCK_CHANGED_EVENT = "lock_changed";
426
+ var EPOCH_START_EVENT = "epoch_start";
427
+
428
+ // src/utils/amount.ts
429
+ import BigNumber from "bignumber.js";
430
+ var MAX_PRICE_DECIMALS = 14;
431
+ function toBigNumber(amount) {
432
+ if (amount instanceof BigNumber) {
433
+ return amount;
434
+ }
435
+ return new BigNumber(amount);
436
+ }
437
+ function uAmountToAmount(amount, noOfDecimals) {
438
+ return uAmountToBigNumberAmount(amount, noOfDecimals).toString();
439
+ }
440
+ function uAmountToBigNumberAmount(amount, noOfDecimals) {
441
+ return toBigNumber(amount || 0).shiftedBy(-1 * noOfDecimals).decimalPlaces(noOfDecimals || 6);
442
+ }
443
+ function amountToBigNumberUAmount(amount, noOfDecimals) {
444
+ return toBigNumber(amount).shiftedBy(noOfDecimals).decimalPlaces(noOfDecimals || 6);
445
+ }
446
+ function amountToUAmount(amount, noOfDecimals) {
447
+ return amountToBigNumberUAmount(amount, noOfDecimals).toString();
448
+ }
449
+ function prettyAmount(amount) {
450
+ const num = toBigNumber(amount);
451
+ if (num.isNaN()) {
452
+ return "0";
453
+ }
454
+ if (num.lt(1) && num.gt(0)) {
455
+ return num.toFixed(6);
456
+ }
457
+ return Intl.NumberFormat("en", { notation: "standard" }).format(num.toNumber());
458
+ }
459
+ var priceToUPrice = (price, quoteExponent, baseExponent) => {
460
+ return priceToBigNumberUPrice(price, quoteExponent, baseExponent).toFixed(MAX_PRICE_DECIMALS).toString();
461
+ };
462
+ var priceToBigNumberUPrice = (price, quoteExponent, baseExponent) => {
463
+ price = toBigNumber(price);
464
+ return price.multipliedBy(Math.pow(10, quoteExponent - baseExponent));
465
+ };
466
+ var uPriceToPrice = (price, quoteExponent, baseExponent) => {
467
+ return uPriceToBigNumberPrice(toBigNumber(price), quoteExponent, baseExponent).toString();
468
+ };
469
+ var uPriceToBigNumberPrice = (price, quoteExponent, baseExponent) => {
470
+ const converted = toBigNumber(price);
471
+ return converted.multipliedBy(Math.pow(10, baseExponent - quoteExponent));
472
+ };
473
+
474
+ // src/utils/address.ts
475
+ import { fromBech32 } from "@interchainjs/encoding";
476
+
477
+ // src/utils/strings.ts
478
+ function stringTruncateFromCenter(str, maxLength) {
479
+ const midChar = "\u2026";
480
+ if (str.length <= maxLength) return str;
481
+ const left = Math.ceil(maxLength / 2);
482
+ const right = str.length - Math.floor(maxLength / 2) + 1;
483
+ return str.substring(0, left) + midChar + str.substring(right);
484
+ }
485
+ function removeLeadingZeros(str) {
486
+ return str.replace(/^0+/, "") || "0";
487
+ }
488
+
489
+ // src/utils/address.ts
490
+ var truncateAddress = (address) => {
491
+ return stringTruncateFromCenter(address, 12);
492
+ };
493
+ var validateBech32Address = (address, prefix) => {
494
+ const result = {
495
+ isValid: false,
496
+ message: ""
497
+ };
498
+ try {
499
+ const { prefix: addressPrefix } = fromBech32(address);
500
+ if (addressPrefix === prefix) {
501
+ result.isValid = true;
502
+ return result;
503
+ }
504
+ result.message = `This address is from another network (${addressPrefix}). Please use an address from the destination network (${prefix}).`;
505
+ } catch (e) {
506
+ console.error("invalid address ", e);
507
+ result.message = "Invalid address";
508
+ }
509
+ return result;
510
+ };
511
+ var validateBZEBech32Address = (address) => validateBech32Address(address, getChainAddressPrefix());
512
+
513
+ // src/utils/charts.ts
514
+ var CHART_4H = "4H";
515
+ var CHART_1D = "1D";
516
+ var CHART_7D = "7D";
517
+ var CHART_30D = "30D";
518
+ var CHART_1Y = "1Y";
519
+ function getNoOfIntervalsNeeded(chart) {
520
+ switch (chart) {
521
+ case CHART_4H:
522
+ return 12 * 4;
523
+ case CHART_1D:
524
+ return 4 * 24;
525
+ case CHART_7D:
526
+ return 24 * 7;
527
+ case CHART_30D:
528
+ return 6 * 30;
529
+ case CHART_1Y:
530
+ return 365;
531
+ default:
532
+ return 0;
533
+ }
534
+ }
535
+ function getChartIntervalsLimit(chart) {
536
+ switch (chart) {
537
+ case CHART_4H:
538
+ return 12 * 24 * 7;
539
+ case CHART_1D:
540
+ return 4 * 24 * 30;
541
+ case CHART_7D:
542
+ return 24 * 90;
543
+ case CHART_30D:
544
+ return 6 * 365;
545
+ case CHART_1Y:
546
+ return 365 * 3;
547
+ default:
548
+ return 12;
549
+ }
550
+ }
551
+ function getChartMinutes(chart) {
552
+ switch (chart) {
553
+ case CHART_4H:
554
+ return 5;
555
+ case CHART_1D:
556
+ return 15;
557
+ case CHART_7D:
558
+ return 60;
559
+ case CHART_30D:
560
+ return 240;
561
+ case CHART_1Y:
562
+ return 1440;
563
+ default:
564
+ return 5;
565
+ }
566
+ }
567
+
568
+ // src/utils/debounce.ts
569
+ var debounces = /* @__PURE__ */ new Map();
570
+ async function addMultipleDebounce(name, delay, callback, times) {
571
+ for (let index = 1; index <= times; index++) {
572
+ addDebounce(`${name}-${index}`, delay * index, callback);
573
+ }
574
+ }
575
+ async function addDebounce(name, delay, callback) {
576
+ cancelDebounce(name);
577
+ const newTimer = setTimeout(() => {
578
+ callback();
579
+ }, delay);
580
+ debounces.set(name, newTimer);
581
+ }
582
+ async function cancelDebounce(name) {
583
+ const timer = debounces.get(name);
584
+ if (timer) {
585
+ clearTimeout(timer);
586
+ debounces.delete(name);
587
+ }
588
+ }
589
+
590
+ // src/utils/denom.ts
591
+ var MAX_DENOM_LEN = 8;
592
+ var isFactoryDenom = (denom) => denom.startsWith("factory/");
593
+ var isIbcDenom = (denom) => denom.startsWith("ibc/");
594
+ var isLpDenom = (denom) => denom.startsWith("ulp_");
595
+ var isNativeDenom = (denom) => getChainNativeAssetDenom() === denom;
596
+ var getDenomType = (denom) => isFactoryDenom(denom) ? ASSET_TYPE_FACTORY : isIbcDenom(denom) ? ASSET_TYPE_IBC : isLpDenom(denom) ? ASSET_TYPE_LP : ASSET_TYPE_NATIVE;
597
+ function truncateDenom(denom) {
598
+ return stringTruncateFromCenter(denom, MAX_DENOM_LEN);
599
+ }
600
+ var isIbcAsset = (asset) => asset.type === ASSET_TYPE_IBC;
601
+
602
+ // src/utils/events.ts
603
+ var getMarketOrderBookChangedEvent = (marketId) => getMarketEventKey(ORDER_BOOK_CHANGED_EVENT, marketId);
604
+ var getMarketEventKey = (eventType, marketId) => `${eventType}:${marketId}`;
605
+ var mapEventAttributes = (attributes) => {
606
+ return attributes.reduce((acc, attr) => __spreadProps(__spreadValues({}, acc), { [attr.key]: attr.value.replace('"', "").replace('"', "") }), {});
607
+ };
608
+
609
+ // src/utils/formatter.ts
610
+ import BigNumber2 from "bignumber.js";
611
+ var formatUsdAmount = (priceNum) => {
612
+ const price = priceNum.toString();
613
+ const decimalIndex = price.indexOf(".");
614
+ if (decimalIndex === -1) {
615
+ return price;
616
+ }
617
+ const decimalPart = price.substring(decimalIndex + 1);
618
+ let significantDigitCount = 0;
619
+ let decimalsFound = 0;
620
+ for (let i = 0; i < decimalPart.length; i++) {
621
+ const digit = decimalPart[i];
622
+ decimalsFound++;
623
+ if (digit !== "0" || significantDigitCount > 0) {
624
+ significantDigitCount++;
625
+ }
626
+ if (significantDigitCount >= 6) {
627
+ break;
628
+ }
629
+ }
630
+ return priceNum.toFixed(decimalsFound).toString();
631
+ };
632
+ function shortNumberFormat(amount) {
633
+ if (amount.isNaN() || amount.isZero()) {
634
+ return "0";
635
+ }
636
+ if (amount.lt(1e-3)) {
637
+ return "0";
638
+ }
639
+ const units = [
640
+ { value: new BigNumber2("1e15"), suffix: "Q" },
641
+ { value: new BigNumber2("1e12"), suffix: "T" },
642
+ { value: new BigNumber2("1e9"), suffix: "B" },
643
+ { value: new BigNumber2("1e6"), suffix: "M" },
644
+ { value: new BigNumber2("1e3"), suffix: "K" }
645
+ ];
646
+ for (const unit of units) {
647
+ if (amount.gte(unit.value)) {
648
+ const formatted = amount.div(unit.value);
649
+ const result = formatted.toFixed(3).replace(/\.?0+$/, "");
650
+ return `${result}${unit.suffix}`;
651
+ }
652
+ }
653
+ return amount.toFixed(3).replace(/\.?0+$/, "");
654
+ }
655
+ var intlDateFormat = new Intl.DateTimeFormat("en-US", {
656
+ year: "2-digit",
657
+ month: "2-digit",
658
+ day: "2-digit",
659
+ hour: "numeric",
660
+ minute: "2-digit",
661
+ hour12: false
662
+ });
663
+ var formatDate = (date) => {
664
+ return intlDateFormat.format(date);
665
+ };
666
+ var formatTimeRemaining = (targetDate) => {
667
+ const now = /* @__PURE__ */ new Date();
668
+ const diff = targetDate.getTime() - now.getTime();
669
+ if (diff <= 0) {
670
+ return "Now";
671
+ }
672
+ const days = Math.floor(diff / (1e3 * 60 * 60 * 24));
673
+ const hours = Math.floor(diff % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60));
674
+ const minutes = Math.floor(diff % (1e3 * 60 * 60) / (1e3 * 60));
675
+ const parts = [];
676
+ if (days > 0) parts.push(`${days}d`);
677
+ if (hours > 0) parts.push(`${hours}h`);
678
+ if (minutes > 0) parts.push(`${minutes}m`);
679
+ return parts.join(" ") || "Now";
680
+ };
681
+ var formatTimeRemainingFromEpochs = (epochs) => {
682
+ if (epochs.lte(0)) {
683
+ return "Now";
684
+ }
685
+ const totalSeconds = epochs.multipliedBy(60).toNumber();
686
+ const days = Math.floor(totalSeconds / (60 * 60 * 24));
687
+ const hours = Math.floor(totalSeconds % (60 * 60 * 24) / (60 * 60));
688
+ const minutes = Math.floor(totalSeconds % (60 * 60) / 60);
689
+ const parts = [];
690
+ if (days > 0) parts.push(`${days}d`);
691
+ if (hours > 0) parts.push(`${hours}h`);
692
+ if (minutes > 0) parts.push(`${minutes}m`);
693
+ return parts.join(" ") || "Now";
694
+ };
695
+
696
+ // src/utils/functions.ts
697
+ async function sleep(ms) {
698
+ return new Promise((resolve) => setTimeout(resolve, ms));
699
+ }
700
+ var openExternalLink = (url) => {
701
+ if (!window) return;
702
+ window.open(url, "_blank", "noopener,noreferrer");
703
+ };
704
+
705
+ // src/utils/ibc.ts
706
+ import BigNumber3 from "bignumber.js";
707
+ var canDepositFromIBC = (ibcData2) => {
708
+ return ibcData2.counterparty.baseDenom !== "" && ibcData2.counterparty.channelId !== "" && ibcData2.counterparty.chainName != "";
709
+ };
710
+ var canSendToIBC = (ibcData2) => {
711
+ return ibcData2.chain.channelId !== "" && ibcData2.counterparty.chainName != "";
712
+ };
713
+ async function denomOnFirstHopChainFromTrace(trace) {
714
+ try {
715
+ if (!(trace == null ? void 0 : trace.base_denom)) return void 0;
716
+ const parts = trace.path.split("/").filter(Boolean);
717
+ if (parts.length < 2) {
718
+ return trace.base_denom || void 0;
719
+ }
720
+ const remaining = parts.slice(2);
721
+ if (remaining.length === 0) {
722
+ return trace.base_denom;
723
+ }
724
+ const remainingPath = remaining.join("/");
725
+ const full = `${remainingPath}/${trace.base_denom}`;
726
+ const enc = new TextEncoder();
727
+ const buf = enc.encode(full);
728
+ const digest = await crypto.subtle.digest("SHA-256", buf);
729
+ const hashBytes = new Uint8Array(digest);
730
+ let hex = "";
731
+ for (let i = 0; i < hashBytes.length; i++) {
732
+ const b = hashBytes[i].toString(16).padStart(2, "0");
733
+ hex += b;
734
+ }
735
+ return `ibc/${hex.toUpperCase()}`;
736
+ } catch (e) {
737
+ console.error("[denomOnFirstHopChainFromTrace] error:", e);
738
+ return void 0;
739
+ }
740
+ }
741
+ var getIbcTransferTimeout = () => {
742
+ return new BigNumber3(Date.now() + 6e5).multipliedBy(1e6);
743
+ };
744
+
745
+ // src/utils/liquidity_pool.ts
746
+ var calculateUserPoolData = (balance, lpAsset, poolData) => {
747
+ const zeroBN = toBigNumber(0);
748
+ if (!balance || balance.amount.isZero()) {
749
+ return { userLiquidityUsd: zeroBN, userSharesPercentage: 0 };
750
+ }
751
+ if (!lpAsset) {
752
+ return { userLiquidityUsd: zeroBN, userSharesPercentage: 0 };
753
+ }
754
+ const userShares = toBigNumber(balance.amount);
755
+ const totalShares = toBigNumber(lpAsset.supply);
756
+ if (totalShares.isZero()) {
757
+ return { userLiquidityUsd: zeroBN, userSharesPercentage: 0 };
758
+ }
759
+ const userSharesPercentage = userShares.dividedBy(totalShares).multipliedBy(100).toNumber();
760
+ let userLiquidityUsd = zeroBN;
761
+ if (poolData && poolData.usdValue) {
762
+ userLiquidityUsd = userShares.dividedBy(totalShares).multipliedBy(poolData.usdValue);
763
+ }
764
+ return { userLiquidityUsd, userSharesPercentage };
765
+ };
766
+ var calculatePoolOppositeAmount = (pool, amount, isBase) => {
767
+ const amountBN = toBigNumber(amount);
768
+ if (amountBN.isZero() || amountBN.isNaN()) {
769
+ return toBigNumber(0);
770
+ }
771
+ const reserveBase = toBigNumber(pool.reserve_base);
772
+ const reserveQuote = toBigNumber(pool.reserve_quote);
773
+ if (reserveBase.isZero() || reserveQuote.isZero()) {
774
+ return toBigNumber(0);
775
+ }
776
+ if (isBase) {
777
+ return amountBN.multipliedBy(reserveQuote).dividedBy(reserveBase);
778
+ } else {
779
+ return amountBN.multipliedBy(reserveBase).dividedBy(reserveQuote);
780
+ }
781
+ };
782
+ var calculatePoolPrice = (denom, pool) => {
783
+ if (!pool || !denom) return null;
784
+ const reserveBase = toBigNumber(pool.reserve_base);
785
+ const reserveQuote = toBigNumber(pool.reserve_quote);
786
+ if (reserveBase.lte(0) || reserveQuote.lte(0)) {
787
+ return null;
788
+ }
789
+ if (denom === pool.base) {
790
+ return reserveQuote.dividedBy(reserveBase);
791
+ }
792
+ if (denom === pool.quote) {
793
+ return reserveBase.dividedBy(reserveQuote);
794
+ }
795
+ return null;
796
+ };
797
+ var createPoolId = (base, quote) => {
798
+ if (base > quote) return `${quote}_${base}`;
799
+ return `${base}_${quote}`;
800
+ };
801
+ var poolIdFromPoolDenom = (poolDenom) => poolDenom.replace("ulp_", "");
802
+
803
+ // src/utils/market.ts
804
+ import BigNumber4 from "bignumber.js";
805
+ var createMarketId = (base, quote) => `${base}/${quote}`;
806
+ var calculateTotalAmount = (price, amount, decimals) => {
807
+ const priceNum = toBigNumber(price);
808
+ const amountNum = toBigNumber(amount);
809
+ if (priceNum.isNaN() || amountNum.isNaN() || priceNum.isZero() || amountNum.isZero()) return "";
810
+ const total = priceNum.multipliedBy(amountNum);
811
+ return total.decimalPlaces(decimals).toString();
812
+ };
813
+ var calculatePricePerUnit = (amount, totalPrice, decimals) => {
814
+ const amountNum = toBigNumber(amount);
815
+ const total = toBigNumber(totalPrice);
816
+ if (amountNum.isNaN() || total.isNaN() || amountNum.isZero() || total.isZero()) return "";
817
+ return total.dividedBy(amountNum).decimalPlaces(decimals).toString();
818
+ };
819
+ var calculateAmountFromPrice = (price, totalPrice, decimals) => {
820
+ const total = toBigNumber(totalPrice);
821
+ const priceNum = toBigNumber(price);
822
+ if (total.isNaN() || priceNum.isNaN() || total.isZero() || priceNum.isZero()) return "";
823
+ return total.div(priceNum).decimalPlaces(decimals).toString();
824
+ };
825
+ var getMinAmount = (uPrice, noOfDecimals) => {
826
+ const uPriceDec = toBigNumber(uPrice);
827
+ if (uPriceDec.lte(0)) {
828
+ return new BigNumber4(0);
829
+ }
830
+ const oneDec = new BigNumber4(1);
831
+ const amtDec = oneDec.dividedBy(uPriceDec).decimalPlaces(0, BigNumber4.ROUND_CEIL).multipliedBy(2);
832
+ return amtDec.shiftedBy(-1 * noOfDecimals).decimalPlaces(noOfDecimals || 6).multipliedBy(2);
833
+ };
834
+
835
+ // src/utils/number.ts
836
+ var sanitizeNumberInput = (input) => {
837
+ let sanitized = input.replace(/[^0-9.,]/g, "");
838
+ sanitized = sanitized.replace(",", ".");
839
+ const parts = sanitized.split(".");
840
+ if (parts.length > 2) {
841
+ sanitized = parts[0] + "." + parts.slice(1).join("");
842
+ }
843
+ return sanitized;
844
+ };
845
+ var sanitizeIntegerInput = (input) => {
846
+ if (input.length === 0) {
847
+ return "";
848
+ }
849
+ const sanitized = input.replace(/[^0-9]/g, "");
850
+ const parsed = parseInt(sanitized, 10);
851
+ if (!parsed) {
852
+ return "1";
853
+ }
854
+ return `${parsed}`;
855
+ };
856
+ var toPercentage = (dec) => toBigNumber(dec).multipliedBy(100).decimalPlaces(2).toString();
857
+
858
+ // src/utils/staking.ts
859
+ import BigNumber5 from "bignumber.js";
860
+ var DAY_TO_SECONDS = 24 * 60 * 60;
861
+ var calcNativeStakingApr = (pool, communityTax, annualProvisions) => {
862
+ const totalSupply = new BigNumber5((pool == null ? void 0 : pool.bonded_tokens) || 0).plus(
863
+ (pool == null ? void 0 : pool.not_bonded_tokens) || 0
864
+ );
865
+ if (totalSupply.isZero() || annualProvisions.isZero()) {
866
+ return "0.00";
867
+ }
868
+ const bondedTokens = new BigNumber5((pool == null ? void 0 : pool.bonded_tokens) || 0);
869
+ if (bondedTokens.isZero()) {
870
+ return "0.00";
871
+ }
872
+ const bondedTokensRatio = bondedTokens.div(totalSupply);
873
+ const inflation = annualProvisions.div(totalSupply);
874
+ const communityTaxRate = new BigNumber5(communityTax || 0);
875
+ const apr = inflation.multipliedBy(new BigNumber5(1).minus(communityTaxRate)).div(bondedTokensRatio).multipliedBy(100).decimalPlaces(2, BigNumber5.ROUND_DOWN);
876
+ return apr.toString();
877
+ };
878
+ var parseUnbondingDays = (unbondingTime) => {
879
+ const split = unbondingTime.split("s");
880
+ return new BigNumber5(split[0] || 0).div(DAY_TO_SECONDS).decimalPlaces(0).toString();
881
+ };
882
+ var calculateRewardsStakingApr = (dailyAmount, staked) => {
883
+ const stakedNum = new BigNumber5(staked);
884
+ let computedApr = new BigNumber5(dailyAmount).dividedBy(stakedNum).multipliedBy(365).multipliedBy(100);
885
+ if (computedApr.lt(1)) {
886
+ computedApr = computedApr.decimalPlaces(6);
887
+ } else {
888
+ computedApr = computedApr.decimalPlaces(2);
889
+ }
890
+ return computedApr;
891
+ };
892
+ var calculateRewardsStakingPendingRewards = (stakingReward, userStake) => {
893
+ const distr = new BigNumber5((stakingReward == null ? void 0 : stakingReward.distributed_stake) || 0);
894
+ const joinedAt = new BigNumber5((userStake == null ? void 0 : userStake.joined_at) || 0);
895
+ if (distr.isEqualTo(joinedAt)) {
896
+ return new BigNumber5(0);
897
+ }
898
+ const deposited = new BigNumber5((userStake == null ? void 0 : userStake.amount) || 0);
899
+ return deposited.multipliedBy(distr.minus(joinedAt)).decimalPlaces(0);
900
+ };
901
+
902
+ // src/utils/user_errors.ts
903
+ var errorsMap = {
904
+ "failed to execute message; message index: 0: amount is smaller than staking reward min stake": "Amount is smaller than minimum required stake",
905
+ "the resulted amount is too low": "Swap minimum amount could not be met. Increase the slippage and try again.",
906
+ "amount is too low to be traded": "Amount is too low to be traded",
907
+ "can not buy more than 50 tickets": "You can only contribute up to 50 times per transaction."
908
+ };
909
+ var prettyError = (err) => {
910
+ if (!err) return void 0;
911
+ if (errorsMap[err]) {
912
+ return errorsMap[err];
913
+ }
914
+ for (const [key, value] of Object.entries(errorsMap)) {
915
+ if (err.includes(key)) {
916
+ return value;
917
+ }
918
+ }
919
+ return err;
920
+ };
921
+
922
+ // src/constants/settings.ts
923
+ var SETTINGS_STORAGE_KEY = "bze_app_settings";
924
+ var _a, _b;
925
+ var DEFAULT_SETTINGS = {
926
+ endpoints: {
927
+ restEndpoint: (_a = process.env.NEXT_PUBLIC_REST_ENDPOINT) != null ? _a : "",
928
+ rpcEndpoint: (_b = process.env.NEXT_PUBLIC_RPC_ENDPOINT) != null ? _b : ""
929
+ },
930
+ preferredFeeDenom: getChainNativeAssetDenom()
931
+ };
932
+ var VALIDATION_ERRORS = {
933
+ EMPTY_ENDPOINT: "Endpoint cannot be empty",
934
+ INVALID_URL: "Invalid URL format",
935
+ INVALID_REST_PROTOCOL: "REST endpoint must use HTTP or HTTPS protocol",
936
+ INVALID_RPC_PROTOCOL: "RPC endpoint must use WS or WSS protocol for WebSocket connection",
937
+ CORS_ERROR: "Endpoint validation failed - unable to connect or CORS not enabled",
938
+ WEBSOCKET_ERROR: "WebSocket connection failed - unable to connect to RPC endpoint",
939
+ NETWORK_ERROR: "Network error - unable to validate endpoint"
940
+ };
941
+ var getAppName = () => {
942
+ var _a2;
943
+ return (_a2 = process.env.NEXT_PUBLIC_APP_NAME) != null ? _a2 : "BZE";
944
+ };
945
+
946
+ // src/storage/settings.ts
947
+ var getSettings = () => {
948
+ const saved = getFromLocalStorage(SETTINGS_STORAGE_KEY);
949
+ if (saved) {
950
+ const parsed = JSON.parse(saved);
951
+ return __spreadValues(__spreadValues({}, DEFAULT_SETTINGS), parsed);
952
+ }
953
+ return DEFAULT_SETTINGS;
954
+ };
955
+ var setSettings = (newSettings) => {
956
+ return setInLocalStorage(SETTINGS_STORAGE_KEY, JSON.stringify(newSettings), TTL_NO_EXPIRY);
957
+ };
958
+
959
+ // src/query/client.ts
960
+ import { bze } from "@bze/bzejs";
961
+ import { PageRequest } from "@bze/bzejs/cosmos/base/query/v1beta1/pagination";
962
+ var getRestClient = () => {
963
+ const settings = getSettings();
964
+ return createRestClient(settings.endpoints.restEndpoint);
965
+ };
966
+ var createRestClient = async (endpoint) => {
967
+ return bze.ClientFactory.createLCDClient({ restEndpoint: endpoint });
968
+ };
969
+ var getPageRequestWithLimit = (limit) => {
970
+ return PageRequest.fromPartial({
971
+ limit: BigInt(limit)
972
+ });
973
+ };
974
+
975
+ // src/query/burner.ts
976
+ import { bze as bze2 } from "@bze/bzejs";
977
+ import { PageRequest as PageRequest2 } from "@bze/bzejs/cosmos/base/query/v1beta1/pagination";
978
+ var BURNED_KEY = "burner:all_burned_coins";
979
+ var LOCAL_CACHE_TTL = 60 * 60 * 4;
980
+ var { fromPartial: QueryAllBurnedCoinsRequestFromPartial } = bze2.burner.QueryAllBurnedCoinsRequest;
981
+ var getBurnerParams = async () => {
982
+ try {
983
+ const client = await getRestClient();
984
+ return getBurnerParamsWithClient(client);
985
+ } catch (error) {
986
+ console.error("failed to get burner params: ", error);
987
+ }
988
+ return void 0;
989
+ };
990
+ var getBurnerParamsWithClient = async (client) => {
991
+ try {
992
+ const response = await client.bze.burner.params();
993
+ return response.params;
994
+ } catch (error) {
995
+ console.error("failed to get burner params: ", error);
996
+ }
997
+ return void 0;
998
+ };
999
+ async function getAllBurnedCoins() {
1000
+ try {
1001
+ const localData = getFromLocalStorage(BURNED_KEY);
1002
+ if (null !== localData) {
1003
+ const parsed = JSON.parse(localData);
1004
+ if (parsed) {
1005
+ return parsed;
1006
+ }
1007
+ }
1008
+ const client = await getRestClient();
1009
+ const response = await client.bze.burner.allBurnedCoins(
1010
+ QueryAllBurnedCoinsRequestFromPartial({
1011
+ pagination: PageRequest2.fromPartial({ reverse: true })
1012
+ })
1013
+ );
1014
+ setInLocalStorage(BURNED_KEY, JSON.stringify(response), LOCAL_CACHE_TTL);
1015
+ return response;
1016
+ } catch (e) {
1017
+ console.error(e);
1018
+ return {
1019
+ burnedCoins: []
1020
+ };
1021
+ }
1022
+ }
1023
+
1024
+ // src/utils/validation.ts
1025
+ function isValidUrl(urlString) {
1026
+ try {
1027
+ const url = new URL(urlString);
1028
+ return url.protocol === "http:" || url.protocol === "https:" || url.protocol === "ws:" || url.protocol === "wss:";
1029
+ } catch (e) {
1030
+ return false;
1031
+ }
1032
+ }
1033
+ async function validateRestEndpoint(endpoint) {
1034
+ if (!endpoint.trim()) {
1035
+ return { isValid: false, error: VALIDATION_ERRORS.EMPTY_ENDPOINT };
1036
+ }
1037
+ if (!isValidUrl(endpoint)) {
1038
+ return { isValid: false, error: VALIDATION_ERRORS.INVALID_URL };
1039
+ }
1040
+ const url = new URL(endpoint);
1041
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
1042
+ return { isValid: false, error: VALIDATION_ERRORS.INVALID_REST_PROTOCOL };
1043
+ }
1044
+ try {
1045
+ const client = await createRestClient(endpoint);
1046
+ const params = await getBurnerParamsWithClient(client);
1047
+ if (params) {
1048
+ return { isValid: true };
1049
+ }
1050
+ return { isValid: false, error: VALIDATION_ERRORS.CORS_ERROR };
1051
+ } catch (error) {
1052
+ console.error(error);
1053
+ return { isValid: false, error: VALIDATION_ERRORS.NETWORK_ERROR };
1054
+ }
1055
+ }
1056
+ async function validateRpcEndpoint(endpoint) {
1057
+ if (!endpoint.trim()) {
1058
+ return { isValid: false, error: VALIDATION_ERRORS.EMPTY_ENDPOINT };
1059
+ }
1060
+ if (!isValidUrl(endpoint)) {
1061
+ return { isValid: false, error: VALIDATION_ERRORS.INVALID_URL };
1062
+ }
1063
+ const wsEndpoint = convertToWebSocketUrl(endpoint);
1064
+ const url = new URL(wsEndpoint);
1065
+ if (url.protocol !== "ws:" && url.protocol !== "wss:") {
1066
+ return { isValid: false, error: VALIDATION_ERRORS.INVALID_RPC_PROTOCOL };
1067
+ }
1068
+ try {
1069
+ const isConnectable = await testWebSocketConnection(wsEndpoint);
1070
+ if (isConnectable) {
1071
+ return { isValid: true };
1072
+ } else {
1073
+ return { isValid: false, error: VALIDATION_ERRORS.WEBSOCKET_ERROR };
1074
+ }
1075
+ } catch (error) {
1076
+ console.error("WebSocket validation error:", error);
1077
+ return { isValid: false, error: VALIDATION_ERRORS.NETWORK_ERROR };
1078
+ }
1079
+ }
1080
+ function testWebSocketConnection(endpoint) {
1081
+ return new Promise((resolve) => {
1082
+ const ws = new WebSocket(`${endpoint}/websocket`);
1083
+ const timeout = setTimeout(() => {
1084
+ ws.close();
1085
+ resolve(false);
1086
+ }, 5e3);
1087
+ ws.onopen = () => {
1088
+ clearTimeout(timeout);
1089
+ ws.close();
1090
+ resolve(true);
1091
+ };
1092
+ ws.onerror = () => {
1093
+ clearTimeout(timeout);
1094
+ resolve(false);
1095
+ };
1096
+ ws.onclose = (event) => {
1097
+ clearTimeout(timeout);
1098
+ if (event.wasClean) {
1099
+ resolve(true);
1100
+ }
1101
+ };
1102
+ });
1103
+ }
1104
+ async function validateEndpoints(restEndpoint, rpcEndpoint) {
1105
+ const [restResult, rpcResult] = await Promise.all([
1106
+ validateRestEndpoint(restEndpoint),
1107
+ validateRpcEndpoint(rpcEndpoint)
1108
+ ]);
1109
+ return {
1110
+ rest: restResult,
1111
+ rpc: rpcResult,
1112
+ isValid: restResult.isValid && rpcResult.isValid
1113
+ };
1114
+ }
1115
+ function convertToWebSocketUrl(url) {
1116
+ try {
1117
+ const parsedUrl = new URL(url);
1118
+ if (parsedUrl.protocol === "http:") {
1119
+ parsedUrl.protocol = "ws:";
1120
+ } else if (parsedUrl.protocol === "https:") {
1121
+ parsedUrl.protocol = "wss:";
1122
+ }
1123
+ return parsedUrl.toString();
1124
+ } catch (error) {
1125
+ console.warn("Failed to parse URL for WebSocket conversion:", error);
1126
+ return url;
1127
+ }
1128
+ }
1129
+
1130
+ // src/utils/validator.ts
1131
+ var getValidatorSupportedDenoms = () => {
1132
+ const denoms = process.env.NEXT_PUBLIC_ATONE_VALIDATOR_SUPPORTED_DENOMS || "";
1133
+ return denoms.split(",").map((d) => d.trim()).filter((d) => d.length > 0);
1134
+ };
1135
+ var getValidatorPageUrl = () => {
1136
+ return process.env.NEXT_PUBLIC_ATONE_VALIDATOR_PAGE_URL || "";
1137
+ };
1138
+ var isPoolSupportedByValidator = (baseDenom, quoteDenom) => {
1139
+ const supportedDenoms = getValidatorSupportedDenoms();
1140
+ return supportedDenoms.includes(baseDenom) || supportedDenoms.includes(quoteDenom);
1141
+ };
1142
+
1143
+ // src/constants/endpoints.ts
1144
+ function getRestURL() {
1145
+ return process.env.NEXT_PUBLIC_REST_URL || "";
1146
+ }
1147
+ function getRpcURL() {
1148
+ return process.env.NEXT_PUBLIC_RPC_URL || "";
1149
+ }
1150
+ function getArchwayRpcURL() {
1151
+ return process.env.NEXT_PUBLIC_RPC_URL_ARCHWAY || "";
1152
+ }
1153
+ function getOsmosisRpcUrl() {
1154
+ return process.env.NEXT_PUBLIC_RPC_URL_OSMOSIS || "";
1155
+ }
1156
+ function getNobleRpcUrl() {
1157
+ return process.env.NEXT_PUBLIC_RPC_URL_NOBLE || "";
1158
+ }
1159
+ function getJackalRpcUrl() {
1160
+ return process.env.NEXT_PUBLIC_RPC_URL_JACKAL || "";
1161
+ }
1162
+ function getOmniFlixRpcUrl() {
1163
+ return process.env.NEXT_PUBLIC_RPC_URL_FLIX || "";
1164
+ }
1165
+ function getAtomOneRpcUrl() {
1166
+ return process.env.NEXT_PUBLIC_RPC_URL_ATOMONE || "";
1167
+ }
1168
+ function getArchwayRestURL() {
1169
+ return process.env.NEXT_PUBLIC_REST_URL_ARCHWAY || "";
1170
+ }
1171
+ function getOsmosisRestURL() {
1172
+ return process.env.NEXT_PUBLIC_REST_URL_OSMOSIS || "";
1173
+ }
1174
+ function getNobleRestURL() {
1175
+ return process.env.NEXT_PUBLIC_REST_URL_NOBLE || "";
1176
+ }
1177
+ function getJackalRestURL() {
1178
+ return process.env.NEXT_PUBLIC_REST_URL_JACKAL || "";
1179
+ }
1180
+ function getOmniFlixRestURL() {
1181
+ return process.env.NEXT_PUBLIC_REST_URL_FLIX || "";
1182
+ }
1183
+ function getAtomOneRestURL() {
1184
+ return process.env.NEXT_PUBLIC_REST_URL_ATOMONE || "";
1185
+ }
1186
+ var getAggregatorHost = () => {
1187
+ var _a2;
1188
+ return (_a2 = process.env.NEXT_PUBLIC_AGG_API_HOST) != null ? _a2 : "https://getbze.com";
1189
+ };
1190
+
1191
+ // src/constants/market.ts
1192
+ var EXCLUDED_MARKETS = {
1193
+ "factory/bze1f0qgels0eu96ev6a67znu70q7rquy9eragn8nw/ucorey/factory/bze13gzq40che93tgfm9kzmkpjamah5nj0j73pyhqk/uvdl": true,
1194
+ "factory/bze1f0qgels0eu96ev6a67znu70q7rquy9eragn8nw/ucorey/ubze": true
1195
+ };
1196
+
1197
+ // src/constants/ecosystem.ts
1198
+ import { LuGlobe, LuCoins, LuChartColumn, LuFlame, LuFactory } from "react-icons/lu";
1199
+ var ECOSYSTEM_MENU_LABEL = "Other";
1200
+ var ALL_APPS = [
1201
+ { name: "Website", href: "https://getbze.com", disabled: false, icon: LuGlobe },
1202
+ { name: "Staking", href: "https://staking.getbze.com", disabled: false, icon: LuCoins },
1203
+ { name: "DEX", href: "https://dex.getbze.com", disabled: false, icon: LuChartColumn },
1204
+ { name: "Burner", href: "https://burner.getbze.com", disabled: false, icon: LuFlame },
1205
+ { name: "Factory", href: "#", disabled: true, icon: LuFactory }
1206
+ ];
1207
+ var getEcosystemApps = () => {
1208
+ const currentHost = process.env.NEXT_PUBLIC_SITE_URL || "";
1209
+ if (!currentHost) {
1210
+ return ALL_APPS;
1211
+ }
1212
+ return ALL_APPS.filter((app) => app.href !== currentHost);
1213
+ };
1214
+
1215
+ // src/constants/keplr.ts
1216
+ var MAINNET_CHAIN_INFO_FALLBACK = {
1217
+ "chainId": "beezee-1",
1218
+ "chainName": "BeeZee",
1219
+ "chainSymbolImageUrl": "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/beezee/chain.png",
1220
+ "rpc": "https://rpc.getbze.com",
1221
+ "rest": "https://rest.getbze.com",
1222
+ "nodeProvider": {
1223
+ "name": "BZE Alpha Team",
1224
+ "email": "alphateam@getbze.com",
1225
+ "website": "https://getbze.com"
1226
+ },
1227
+ "stakeCurrency": {
1228
+ "coinDenom": "BZE",
1229
+ "coinMinimalDenom": "ubze",
1230
+ "coinDecimals": 6,
1231
+ "coinGeckoId": "bzedge",
1232
+ "coinImageUrl": "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/beezee/chain.png"
1233
+ },
1234
+ "bip44": {
1235
+ "coinType": 118
1236
+ },
1237
+ "bech32Config": {
1238
+ "bech32PrefixAccAddr": "bze",
1239
+ "bech32PrefixAccPub": "bzepub",
1240
+ "bech32PrefixValAddr": "bzevaloper",
1241
+ "bech32PrefixValPub": "bzevaloperpub",
1242
+ "bech32PrefixConsAddr": "bzevalcons",
1243
+ "bech32PrefixConsPub": "bzevalconspub"
1244
+ },
1245
+ "currencies": [
1246
+ {
1247
+ "coinDenom": "BZE",
1248
+ "coinMinimalDenom": "ubze",
1249
+ "coinDecimals": 6,
1250
+ "coinGeckoId": "bzedge",
1251
+ "coinImageUrl": "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/beezee/chain.png"
1252
+ },
1253
+ {
1254
+ "coinDenom": "VDL",
1255
+ "coinMinimalDenom": "factory/bze13gzq40che93tgfm9kzmkpjamah5nj0j73pyhqk/uvdl",
1256
+ "coinDecimals": 6,
1257
+ "coinGeckoId": "vidulum",
1258
+ "coinImageUrl": "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/beezee/factory/bze13gzq40che93tgfm9kzmkpjamah5nj0j73pyhqk/uvdl.png"
1259
+ }
1260
+ ],
1261
+ "feeCurrencies": [{
1262
+ "coinDenom": "BZE",
1263
+ "coinMinimalDenom": "ubze",
1264
+ "coinDecimals": 6,
1265
+ "coinGeckoId": "bzedge",
1266
+ "gasPriceStep": {
1267
+ "low": 1e-3,
1268
+ "average": 0.01,
1269
+ "high": 0.1
1270
+ },
1271
+ "coinImageUrl": "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/beezee/chain.png"
1272
+ }],
1273
+ "features": []
1274
+ };
1275
+ var TESTNET_CHAIN_INFO_FALLBACK = {
1276
+ "chainId": "bzetestnet-3",
1277
+ "chainName": "BeeZee Testnet 3",
1278
+ "chainSymbolImageUrl": "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/bzetestnet/chain.png",
1279
+ "rpc": "https://testnet-rpc.getbze.com",
1280
+ "rest": "https://testnet.getbze.com",
1281
+ "nodeProvider": {
1282
+ "name": "BZE Alpha Team",
1283
+ "email": "alphateam@getbze.com",
1284
+ "website": "https://getbze.com"
1285
+ },
1286
+ "stakeCurrency": {
1287
+ "coinDenom": "TBZE",
1288
+ "coinMinimalDenom": "ubze",
1289
+ "coinDecimals": 6,
1290
+ "coinGeckoId": "bzedge",
1291
+ "coinImageUrl": "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/bzetestnet/chain.png"
1292
+ },
1293
+ "bip44": {
1294
+ "coinType": 118
1295
+ },
1296
+ "bech32Config": {
1297
+ "bech32PrefixAccAddr": "bze",
1298
+ "bech32PrefixAccPub": "bzepub",
1299
+ "bech32PrefixValAddr": "bzevaloper",
1300
+ "bech32PrefixValPub": "bzevaloperpub",
1301
+ "bech32PrefixConsAddr": "bzevalcons",
1302
+ "bech32PrefixConsPub": "bzevalconspub"
1303
+ },
1304
+ "currencies": [
1305
+ {
1306
+ "coinDenom": "TBZE",
1307
+ "coinMinimalDenom": "ubze",
1308
+ "coinDecimals": 6,
1309
+ "coinGeckoId": "bzedge",
1310
+ "coinImageUrl": "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/bzetestnet/chain.png"
1311
+ },
1312
+ {
1313
+ "coinDenom": "TVDL",
1314
+ "coinMinimalDenom": "factory/bze1z3mkcr2jz424w6m49frgjmy9uhlrx69phqwg3l/vidulum",
1315
+ "coinDecimals": 6,
1316
+ "coinGeckoId": "vidulum",
1317
+ "coinImageUrl": "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/bzetestnet/factory/testbz1z3mkcr2jz424w6m49frgjmy9uhlrx69p4cvrgf/vidulum.png"
1318
+ }
1319
+ ],
1320
+ "feeCurrencies": [{
1321
+ "coinDenom": "TBZE",
1322
+ "coinMinimalDenom": "ubze",
1323
+ "coinDecimals": 6,
1324
+ "coinGeckoId": "bzedge",
1325
+ "gasPriceStep": {
1326
+ "low": 1e-3,
1327
+ "average": 0.01,
1328
+ "high": 0.1
1329
+ },
1330
+ "coinImageUrl": "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/bzetestnet/chain.png"
1331
+ }],
1332
+ "features": []
1333
+ };
1334
+
1335
+ // src/service/amm_router.ts
1336
+ var AmmRouter = class _AmmRouter {
1337
+ constructor() {
1338
+ this.routeCache = /* @__PURE__ */ new Map();
1339
+ this.routeMap = /* @__PURE__ */ new Map();
1340
+ }
1341
+ static getInstance() {
1342
+ if (!_AmmRouter.instance) {
1343
+ _AmmRouter.instance = new _AmmRouter();
1344
+ }
1345
+ return _AmmRouter.instance;
1346
+ }
1347
+ updatePools(pools) {
1348
+ this.routeMap = this.mapLiquidityPoolRoutes(pools);
1349
+ this.clearCache();
1350
+ }
1351
+ mapLiquidityPoolRoutes(pools) {
1352
+ const routeMap = /* @__PURE__ */ new Map();
1353
+ for (const pool of pools) {
1354
+ if (!routeMap.has(pool.base)) {
1355
+ routeMap.set(pool.base, /* @__PURE__ */ new Map());
1356
+ }
1357
+ routeMap.get(pool.base).set(pool.quote, pool);
1358
+ if (!routeMap.has(pool.quote)) {
1359
+ routeMap.set(pool.quote, /* @__PURE__ */ new Map());
1360
+ }
1361
+ routeMap.get(pool.quote).set(pool.base, pool);
1362
+ }
1363
+ return routeMap;
1364
+ }
1365
+ findOptimalRoute(fromDenom, toDenom, amountIn, maxHops, useCache = true) {
1366
+ const cacheKey = this.getCacheKey(fromDenom, toDenom, maxHops);
1367
+ if (useCache) {
1368
+ const cached = this.routeCache.get(cacheKey);
1369
+ if (cached) {
1370
+ return __spreadValues(__spreadValues({}, cached.result), this.calculateRouteOutput(cached.result.pools, cached.result.path, amountIn));
1371
+ }
1372
+ }
1373
+ const result = this.findOptimalSwapRoute(fromDenom, toDenom, amountIn, maxHops);
1374
+ if (result) {
1375
+ this.routeCache.set(cacheKey, {
1376
+ result,
1377
+ timestamp: Date.now()
1378
+ });
1379
+ }
1380
+ return result;
1381
+ }
1382
+ calculateRouteOutput(pools, path, amountIn) {
1383
+ let currentAmount = amountIn;
1384
+ const fees = [];
1385
+ for (let i = 0; i < pools.length; i++) {
1386
+ const pool = pools[i];
1387
+ const currentDenom = path[i];
1388
+ const isBaseToQuote = pool.base === currentDenom;
1389
+ const { amountOut, fee } = this.calculateSwapOutput(pool, currentAmount, isBaseToQuote);
1390
+ fees.push(fee);
1391
+ currentAmount = amountOut;
1392
+ }
1393
+ const expectedOutput = currentAmount;
1394
+ const theoretical = this.calculateTheoreticalOutputs(pools, path, amountIn);
1395
+ const totalFees = theoretical.withoutFees.minus(theoretical.withFees);
1396
+ const priceImpact = theoretical.withFees.isZero() ? toBigNumber(0) : theoretical.withFees.minus(expectedOutput).dividedBy(theoretical.withFees).multipliedBy(100);
1397
+ return {
1398
+ expectedOutput,
1399
+ priceImpact,
1400
+ totalFees,
1401
+ feesPerHop: fees
1402
+ };
1403
+ }
1404
+ clearCache(filter) {
1405
+ if (!filter) {
1406
+ this.routeCache.clear();
1407
+ return;
1408
+ }
1409
+ for (const [key, cache] of this.routeCache.entries()) {
1410
+ if (filter(key, cache)) {
1411
+ this.routeCache.delete(key);
1412
+ }
1413
+ }
1414
+ }
1415
+ getCacheStats() {
1416
+ return {
1417
+ size: this.routeCache.size,
1418
+ keys: Array.from(this.routeCache.keys())
1419
+ };
1420
+ }
1421
+ calculateTheoreticalOutputs(pools, path, amountIn) {
1422
+ let theoreticalOutputNoFees = amountIn;
1423
+ let theoreticalOutputWithFees = amountIn;
1424
+ for (let i = 0; i < pools.length; i++) {
1425
+ const pool = pools[i];
1426
+ const currentDenom = path[i];
1427
+ const isBaseToQuote = pool.base === currentDenom;
1428
+ const reserveIn = toBigNumber(isBaseToQuote ? pool.reserve_base : pool.reserve_quote);
1429
+ const reserveOut = toBigNumber(isBaseToQuote ? pool.reserve_quote : pool.reserve_base);
1430
+ const midPrice = reserveOut.dividedBy(reserveIn);
1431
+ theoreticalOutputNoFees = theoreticalOutputNoFees.multipliedBy(midPrice);
1432
+ const fee = toBigNumber(pool.fee);
1433
+ theoreticalOutputWithFees = theoreticalOutputWithFees.multipliedBy(toBigNumber(1).minus(fee)).multipliedBy(midPrice);
1434
+ }
1435
+ return {
1436
+ withoutFees: theoreticalOutputNoFees,
1437
+ withFees: theoreticalOutputWithFees
1438
+ };
1439
+ }
1440
+ calculateSwapOutput(pool, amountIn, isBaseToQuote) {
1441
+ const fee = toBigNumber(pool.fee);
1442
+ const reserveIn = toBigNumber(isBaseToQuote ? pool.reserve_base : pool.reserve_quote);
1443
+ const reserveOut = toBigNumber(isBaseToQuote ? pool.reserve_quote : pool.reserve_base);
1444
+ const feeAmount = amountIn.multipliedBy(fee);
1445
+ const amountInAfterFee = amountIn.minus(feeAmount);
1446
+ const amountOut = amountInAfterFee.multipliedBy(reserveOut).dividedBy(reserveIn.plus(amountInAfterFee));
1447
+ return { amountOut, fee: feeAmount };
1448
+ }
1449
+ findOptimalSwapRoute(fromDenom, toDenom, amountIn, maxHops) {
1450
+ if (fromDenom === toDenom) {
1451
+ return null;
1452
+ }
1453
+ const queue = [{
1454
+ denom: fromDenom,
1455
+ amount: amountIn,
1456
+ path: [fromDenom],
1457
+ poolIds: [],
1458
+ pools: [],
1459
+ fees: [],
1460
+ hops: 0
1461
+ }];
1462
+ const bestAmounts = /* @__PURE__ */ new Map();
1463
+ bestAmounts.set(fromDenom, amountIn);
1464
+ let bestRoute = null;
1465
+ while (queue.length > 0) {
1466
+ queue.sort((a, b) => {
1467
+ var _a2;
1468
+ return (_a2 = b.amount.comparedTo(a.amount)) != null ? _a2 : 0;
1469
+ });
1470
+ const current = queue.shift();
1471
+ if (current.denom === toDenom) {
1472
+ if (!bestRoute || current.amount.isGreaterThan(bestRoute.amount)) {
1473
+ bestRoute = current;
1474
+ }
1475
+ continue;
1476
+ }
1477
+ if (current.hops >= maxHops) {
1478
+ continue;
1479
+ }
1480
+ const neighbors = this.routeMap.get(current.denom);
1481
+ if (!neighbors) continue;
1482
+ for (const [nextDenom, pool] of neighbors.entries()) {
1483
+ if (current.path.includes(nextDenom)) {
1484
+ continue;
1485
+ }
1486
+ const isBaseToQuote = pool.base === current.denom;
1487
+ const { amountOut, fee } = this.calculateSwapOutput(pool, current.amount, isBaseToQuote);
1488
+ if (amountOut.lte(0)) {
1489
+ continue;
1490
+ }
1491
+ const previousBest = bestAmounts.get(nextDenom);
1492
+ if (previousBest && amountOut.lte(previousBest)) {
1493
+ continue;
1494
+ }
1495
+ bestAmounts.set(nextDenom, amountOut);
1496
+ queue.push({
1497
+ denom: nextDenom,
1498
+ amount: amountOut,
1499
+ path: [...current.path, nextDenom],
1500
+ poolIds: [...current.poolIds, pool.id],
1501
+ pools: [...current.pools, pool],
1502
+ fees: [...current.fees, fee],
1503
+ hops: current.hops + 1
1504
+ });
1505
+ }
1506
+ }
1507
+ if (!bestRoute) {
1508
+ return null;
1509
+ }
1510
+ const theoretical = this.calculateTheoreticalOutputs(bestRoute.pools, bestRoute.path, amountIn);
1511
+ const totalFees = theoretical.withoutFees.minus(theoretical.withFees);
1512
+ const priceImpact = theoretical.withFees.isZero() ? toBigNumber(0) : theoretical.withFees.minus(bestRoute.amount).dividedBy(theoretical.withFees).multipliedBy(100);
1513
+ return {
1514
+ route: bestRoute.poolIds,
1515
+ path: bestRoute.path,
1516
+ pools: bestRoute.pools,
1517
+ expectedOutput: bestRoute.amount,
1518
+ priceImpact,
1519
+ totalFees,
1520
+ feesPerHop: bestRoute.fees
1521
+ };
1522
+ }
1523
+ getCacheKey(fromDenom, toDenom, maxHops) {
1524
+ return `${fromDenom}_${toDenom}_${maxHops}`;
1525
+ }
1526
+ };
1527
+ var ammRouter = AmmRouter.getInstance();
1528
+
1529
+ // src/service/blockchain_event_manager.ts
1530
+ var BlockchainEventManager = class _BlockchainEventManager {
1531
+ constructor() {
1532
+ this.listeners = /* @__PURE__ */ new Map();
1533
+ }
1534
+ static getInstance() {
1535
+ if (!_BlockchainEventManager.instance) {
1536
+ _BlockchainEventManager.instance = new _BlockchainEventManager();
1537
+ }
1538
+ return _BlockchainEventManager.instance;
1539
+ }
1540
+ subscribe(eventType, callback) {
1541
+ if (!this.listeners.has(eventType)) {
1542
+ this.listeners.set(eventType, /* @__PURE__ */ new Set());
1543
+ }
1544
+ this.listeners.get(eventType).add(callback);
1545
+ return () => {
1546
+ const handlers = this.listeners.get(eventType);
1547
+ if (handlers) {
1548
+ handlers.delete(callback);
1549
+ if (handlers.size === 0) {
1550
+ this.listeners.delete(eventType);
1551
+ }
1552
+ }
1553
+ };
1554
+ }
1555
+ emit(eventType, event) {
1556
+ const generalListeners = this.listeners.get(eventType);
1557
+ if (generalListeners) {
1558
+ generalListeners.forEach((callback) => callback(event));
1559
+ }
1560
+ if (!event) {
1561
+ return;
1562
+ }
1563
+ if (event.marketId) {
1564
+ const marketListeners = this.listeners.get(getMarketEventKey(eventType, event.marketId));
1565
+ if (marketListeners) {
1566
+ marketListeners.forEach((callback) => callback(event));
1567
+ }
1568
+ }
1569
+ }
1570
+ };
1571
+ var blockchainEventManager = BlockchainEventManager.getInstance();
1572
+
1573
+ // src/query/supply.ts
1574
+ import { QueryDenomsMetadataRequest, QueryTotalSupplyRequest } from "@bze/bzejs/cosmos/bank/v1beta1/query";
1575
+ var { fromPartial: TotalSupplyRequest } = QueryTotalSupplyRequest;
1576
+ var { fromPartial: MetadataRequest } = QueryDenomsMetadataRequest;
1577
+ var DEFAULT_LIMIT = 200;
1578
+ var getAllSupply = async () => {
1579
+ try {
1580
+ const client = await getRestClient();
1581
+ const resp = await client.cosmos.bank.v1beta1.totalSupply(
1582
+ TotalSupplyRequest(
1583
+ { pagination: getPageRequestWithLimit(DEFAULT_LIMIT) }
1584
+ )
1585
+ );
1586
+ return resp.supply;
1587
+ } catch (error) {
1588
+ console.error("failed to get supply: ", error);
1589
+ }
1590
+ return void 0;
1591
+ };
1592
+ var getAllSupplyMetadata = async () => {
1593
+ try {
1594
+ const client = await getRestClient();
1595
+ const resp = await client.cosmos.bank.v1beta1.denomsMetadata(MetadataRequest({
1596
+ pagination: getPageRequestWithLimit(DEFAULT_LIMIT)
1597
+ }));
1598
+ return resp.metadatas;
1599
+ } catch (error) {
1600
+ console.error("failed to get supply metadata: ", error);
1601
+ }
1602
+ return void 0;
1603
+ };
1604
+
1605
+ // src/service/assets_factory.ts
1606
+ import { getExponentByDenomFromAsset } from "@chain-registry/utils";
1607
+
1608
+ // src/query/ibc.ts
1609
+ var TRACES_CACHE_KEY = "ibc:traces";
1610
+ var TRACES_CACHE_TTL = 5 * 60;
1611
+ var HASH_TRACE_CACHE_TTL = 0;
1612
+ var IBC_COUNTERPARTY_CACHE_TTL = 0;
1613
+ var DEFAULT_LIMIT2 = 1e3;
1614
+ var getDenomTracesUrl = (limit) => {
1615
+ const settings = getSettings();
1616
+ return `${settings.endpoints.restEndpoint}/ibc/apps/transfer/v1/denom_traces?pagination.limit=${limit}`;
1617
+ };
1618
+ var getHashDenomTracesUrl = (hash) => {
1619
+ const settings = getSettings();
1620
+ return `${settings.endpoints.restEndpoint}/ibc/apps/transfer/v1/denom_traces/${hash}`;
1621
+ };
1622
+ var getIBCTraces = async () => {
1623
+ const cached = getFromLocalStorage(TRACES_CACHE_KEY);
1624
+ if (cached) {
1625
+ return JSON.parse(cached);
1626
+ }
1627
+ try {
1628
+ const resp = await fetch(getDenomTracesUrl(DEFAULT_LIMIT2));
1629
+ if (resp.status !== 200) {
1630
+ console.error("failed to fetch denom traces. status: ", resp.status);
1631
+ return [];
1632
+ }
1633
+ const responseJson = await resp.json();
1634
+ if (!responseJson.denom_traces) {
1635
+ return [];
1636
+ }
1637
+ setInLocalStorage(TRACES_CACHE_KEY, JSON.stringify(responseJson.denom_traces), TRACES_CACHE_TTL);
1638
+ return responseJson.denom_traces;
1639
+ } catch (e) {
1640
+ console.error("[IBC] failed to fetch denom traces", e);
1641
+ return [];
1642
+ }
1643
+ };
1644
+ var createHashTraceCacheKey = (hash) => {
1645
+ return `${TRACES_CACHE_KEY}:${hash}`;
1646
+ };
1647
+ var getHashIBCTrace = async (hash) => {
1648
+ const cacheKey = createHashTraceCacheKey(hash);
1649
+ const cached = getFromLocalStorage(cacheKey);
1650
+ if (cached) {
1651
+ return JSON.parse(cached);
1652
+ }
1653
+ try {
1654
+ const resp = await fetch(getHashDenomTracesUrl(hash));
1655
+ if (resp.status !== 200) {
1656
+ console.error("failed to fetch hash denom trace. status: ", resp.status);
1657
+ return;
1658
+ }
1659
+ const responseJson = await resp.json();
1660
+ if (!responseJson.denom_trace) {
1661
+ return;
1662
+ }
1663
+ setInLocalStorage(cacheKey, JSON.stringify(responseJson.denom_trace), HASH_TRACE_CACHE_TTL);
1664
+ return responseJson.denom_trace;
1665
+ } catch (e) {
1666
+ console.error("[IBC] failed to fetch denom traces", e);
1667
+ }
1668
+ return;
1669
+ };
1670
+ var getChannelIdUrl = (channelId, portId) => {
1671
+ const settings = getSettings();
1672
+ return `${settings.endpoints.restEndpoint}/ibc/core/channel/v1/channels/${channelId}/ports/${portId}`;
1673
+ };
1674
+ var getConnectionIdUrl = (connectionId) => {
1675
+ const settings = getSettings();
1676
+ return `${settings.endpoints.restEndpoint}/ibc/core/connection/v1/connections/${connectionId}`;
1677
+ };
1678
+ var getClientStateUrl = (clientId) => {
1679
+ const settings = getSettings();
1680
+ return `${settings.endpoints.restEndpoint}/ibc/core/client/v1/client_states/${clientId}`;
1681
+ };
1682
+ var getIbcCounterpartyChainIdCacheKey = (channelId, portId) => {
1683
+ return `ibc:counterparty:${channelId}:${portId}`;
1684
+ };
1685
+ var counterpartyChainForChannel = async (channelId, portId = "transfer") => {
1686
+ var _a2, _b2, _c, _d, _e, _f, _g, _h;
1687
+ const cacheKey = getIbcCounterpartyChainIdCacheKey(channelId, portId);
1688
+ const cached = getFromLocalStorage(cacheKey);
1689
+ if (cached) {
1690
+ return JSON.parse(cached);
1691
+ }
1692
+ const result = {
1693
+ chainId: "",
1694
+ channelId: ""
1695
+ };
1696
+ try {
1697
+ const chRes = await fetch(getChannelIdUrl(channelId, portId));
1698
+ if (!chRes.ok) {
1699
+ console.error(`[counterpartyChainForChannel] channel fetch failed: ${chRes.status} ${chRes.statusText}`);
1700
+ return void 0;
1701
+ }
1702
+ const chJson = await chRes.json();
1703
+ const connectionId = (_b2 = (_a2 = chJson == null ? void 0 : chJson.channel) == null ? void 0 : _a2.connection_hops) == null ? void 0 : _b2[0];
1704
+ result.channelId = (_d = (_c = chJson == null ? void 0 : chJson.channel) == null ? void 0 : _c.counterparty) == null ? void 0 : _d.channel_id;
1705
+ if (!connectionId || !result.channelId) {
1706
+ console.error(`[counterpartyChainForChannel] no connection_hops for ${channelId}/${portId}`);
1707
+ return void 0;
1708
+ }
1709
+ const connRes = await fetch(getConnectionIdUrl(connectionId));
1710
+ if (!connRes.ok) {
1711
+ console.error(`[counterpartyChainForChannel] connection fetch failed: ${connRes.status} ${connRes.statusText}`);
1712
+ return void 0;
1713
+ }
1714
+ const connJson = await connRes.json();
1715
+ const clientId = (_e = connJson == null ? void 0 : connJson.connection) == null ? void 0 : _e.client_id;
1716
+ if (!clientId) {
1717
+ console.error(`[counterpartyChainForChannel] no client_id on ${connectionId}`);
1718
+ return void 0;
1719
+ }
1720
+ const csRes = await fetch(getClientStateUrl(clientId));
1721
+ if (!csRes.ok) {
1722
+ console.error(`[counterpartyChainForChannel] client_state fetch failed: ${csRes.status} ${csRes.statusText}`);
1723
+ return void 0;
1724
+ }
1725
+ const csJson = await csRes.json();
1726
+ const clientState = (_g = (_f = csJson == null ? void 0 : csJson.client_state) == null ? void 0 : _f.value) != null ? _g : csJson == null ? void 0 : csJson.client_state;
1727
+ const chainId = (_h = clientState == null ? void 0 : clientState.chain_id) != null ? _h : clientState == null ? void 0 : clientState.chainId;
1728
+ if (!chainId) {
1729
+ console.error(`[counterpartyChainForChannel] chain_id missing in client_state for ${clientId}`);
1730
+ return void 0;
1731
+ }
1732
+ result.chainId = chainId;
1733
+ setInLocalStorage(cacheKey, JSON.stringify(result), IBC_COUNTERPARTY_CACHE_TTL);
1734
+ return result;
1735
+ } catch (err) {
1736
+ console.error("[counterpartyChainForChannel] unexpected error:", err);
1737
+ return void 0;
1738
+ }
1739
+ };
1740
+
1741
+ // src/service/assets_factory.ts
1742
+ var ORIGIN_CHAIN_PLACEHOLDER = "Unknown chain";
1743
+ var getChainAssets = async () => {
1744
+ const [metadata, supply] = await Promise.all([getAllMetadataMap(), getAllSupply()]);
1745
+ const result = {
1746
+ assets: /* @__PURE__ */ new Map(),
1747
+ ibcData: /* @__PURE__ */ new Map()
1748
+ };
1749
+ if (!metadata || !supply) {
1750
+ return result;
1751
+ }
1752
+ const filtered = supply.filter((asset) => !EXCLUDED_ASSETS[asset.denom]);
1753
+ const lpAssets = [];
1754
+ for (const asset of filtered) {
1755
+ const baseAsset = createAsset(asset.denom, BigInt(asset.amount));
1756
+ if (isLpDenom(asset.denom)) {
1757
+ lpAssets.push(baseAsset);
1758
+ continue;
1759
+ }
1760
+ let finalAsset = await populateAssetFromChainRegistry(baseAsset);
1761
+ if (!finalAsset) {
1762
+ const metadataEntry = metadata[asset.denom];
1763
+ finalAsset = populateAssetFromBlockchainMetadata(baseAsset, metadataEntry);
1764
+ }
1765
+ result.assets.set(finalAsset.denom, finalAsset);
1766
+ if (isIbcDenom(finalAsset.denom) && finalAsset.IBCData && finalAsset.IBCData.chain.channelId !== "") {
1767
+ result.ibcData.set(finalAsset.IBCData.chain.channelId, finalAsset.IBCData);
1768
+ }
1769
+ }
1770
+ for (const lpAsset of lpAssets) {
1771
+ const split = lpAsset.denom.split("_");
1772
+ if (split.length !== 3) {
1773
+ continue;
1774
+ }
1775
+ const baseAsset = result.assets.get(split[1]);
1776
+ const quoteAsset = result.assets.get(split[2]);
1777
+ if (!baseAsset || !quoteAsset) {
1778
+ result.assets.set(lpAsset.denom, lpAsset);
1779
+ continue;
1780
+ }
1781
+ lpAsset.name = `${baseAsset.ticker}/${quoteAsset.ticker} LP Shares`;
1782
+ lpAsset.ticker = `${baseAsset.ticker}/${quoteAsset.ticker} LP`;
1783
+ lpAsset.verified = true;
1784
+ lpAsset.decimals = LP_ASSETS_DECIMALS;
1785
+ result.assets.set(lpAsset.denom, lpAsset);
1786
+ }
1787
+ return result;
1788
+ };
1789
+ var populateIBCAsset = async (asset) => {
1790
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1791
+ const ibcList = getIBCAssetList();
1792
+ const ibcData2 = ibcList.find((item) => item.base === asset.denom);
1793
+ if (ibcData2 && ibcData2.traces && ibcData2.traces.length > 0) {
1794
+ const firstTrace = ibcData2.traces.find((t) => t.type === "ibc");
1795
+ if (firstTrace) {
1796
+ const ibcAssetChain = getChains().find((c) => c.chainName === firstTrace.counterparty.chain_name);
1797
+ if (ibcAssetChain) {
1798
+ asset.name = ibcData2.name;
1799
+ asset.ticker = ibcData2.symbol.toUpperCase();
1800
+ asset.decimals = (_a2 = getExponentByDenomFromAsset(ibcData2, ibcData2.display)) != null ? _a2 : 0;
1801
+ asset.logo = (_e = (_d = (_b2 = ibcData2.logoURIs) == null ? void 0 : _b2.svg) != null ? _d : (_c = ibcData2.logoURIs) == null ? void 0 : _c.png) != null ? _e : TOKEN_LOGO_PLACEHOLDER;
1802
+ asset.verified = true;
1803
+ asset.IBCData = {
1804
+ chain: {
1805
+ channelId: firstTrace.chain.channel_id
1806
+ },
1807
+ counterparty: {
1808
+ chainName: firstTrace.counterparty.chain_name,
1809
+ channelId: firstTrace.counterparty.channel_id,
1810
+ baseDenom: firstTrace.counterparty.base_denom,
1811
+ chainPrettyName: (_f = ibcAssetChain.prettyName) != null ? _f : ibcAssetChain.chainName
1812
+ }
1813
+ };
1814
+ return asset;
1815
+ }
1816
+ }
1817
+ }
1818
+ const ibcTrace = await getHashIBCTrace(asset.denom.replace("ibc/", ""));
1819
+ if (!ibcTrace) {
1820
+ return;
1821
+ }
1822
+ const splitPath = ibcTrace.path.split("/");
1823
+ if (splitPath.length < 2) {
1824
+ return;
1825
+ }
1826
+ asset.IBCData = {
1827
+ chain: {
1828
+ channelId: splitPath[1]
1829
+ },
1830
+ counterparty: {
1831
+ chainName: "",
1832
+ channelId: "",
1833
+ baseDenom: "",
1834
+ chainPrettyName: ORIGIN_CHAIN_PLACEHOLDER
1835
+ }
1836
+ };
1837
+ const denomOnCounterparty = await denomOnFirstHopChainFromTrace(ibcTrace);
1838
+ if (denomOnCounterparty) {
1839
+ asset.IBCData.counterparty.baseDenom = denomOnCounterparty;
1840
+ }
1841
+ const counterPartyChain = await counterpartyChainForChannel(splitPath[1], splitPath[0]);
1842
+ if (counterPartyChain) {
1843
+ asset.IBCData.counterparty.channelId = counterPartyChain.channelId;
1844
+ const fullChain = getChainByChainId(counterPartyChain.chainId);
1845
+ if (fullChain) {
1846
+ asset.IBCData.counterparty.chainName = fullChain.chainName;
1847
+ asset.IBCData.counterparty.chainPrettyName = (_g = fullChain.prettyName) != null ? _g : fullChain.chainName;
1848
+ }
1849
+ }
1850
+ const registryAssetChain = getAssetLists().find((item) => {
1851
+ const a = item.assets.find((i) => i.base === ibcTrace.base_denom);
1852
+ return !!a;
1853
+ });
1854
+ if (registryAssetChain) {
1855
+ const registryAsset = registryAssetChain.assets.find((i) => i.base === ibcTrace.base_denom);
1856
+ asset.name = registryAsset.name;
1857
+ asset.ticker = registryAsset.symbol.toUpperCase();
1858
+ asset.decimals = (_h = getExponentByDenomFromAsset(registryAsset, registryAsset.display)) != null ? _h : 0;
1859
+ asset.logo = (_l = (_k = (_i = registryAsset.logoURIs) == null ? void 0 : _i.svg) != null ? _k : (_j = registryAsset.logoURIs) == null ? void 0 : _j.png) != null ? _l : TOKEN_LOGO_PLACEHOLDER;
1860
+ asset.verified = true;
1861
+ return asset;
1862
+ }
1863
+ const localAsset = await populateAssetFromBZEChainRegistryAssetList(asset);
1864
+ if (localAsset) {
1865
+ localAsset.verified = true;
1866
+ return localAsset;
1867
+ }
1868
+ if (!ibcTrace.base_denom.includes("/")) {
1869
+ let counterPartyDenom = ibcTrace.base_denom;
1870
+ if (counterPartyDenom.length > 10) {
1871
+ counterPartyDenom = truncateDenom(counterPartyDenom);
1872
+ }
1873
+ asset.name = counterPartyDenom;
1874
+ }
1875
+ asset.verified = false;
1876
+ asset.decimals = 0;
1877
+ return asset;
1878
+ };
1879
+ var populateAssetFromChainRegistry = async (asset) => {
1880
+ if (isIbcDenom(asset.denom)) {
1881
+ return populateIBCAsset(asset);
1882
+ }
1883
+ if (isNativeDenom(asset.denom) || isFactoryDenom(asset.denom)) {
1884
+ return populateAssetFromBZEChainRegistryAssetList(asset);
1885
+ }
1886
+ return void 0;
1887
+ };
1888
+ var populateAssetFromBZEChainRegistryAssetList = async (asset) => {
1889
+ var _a2, _b2, _c, _d, _e;
1890
+ const data = getAssetLists().find((item) => item.chainName.toLowerCase() === getChainName().toLowerCase());
1891
+ if (!data) {
1892
+ return void 0;
1893
+ }
1894
+ const assetData = data.assets.find((item) => item.base === asset.denom);
1895
+ if (!assetData) {
1896
+ return void 0;
1897
+ }
1898
+ asset.decimals = (_a2 = getExponentByDenomFromAsset(assetData, assetData.display)) != null ? _a2 : 0;
1899
+ asset.name = assetData.name;
1900
+ asset.ticker = assetData.display.toUpperCase();
1901
+ asset.logo = isNativeDenom(asset.denom) ? BZE_CIRCLE_LOGO : (_e = (_d = (_b2 = assetData.logoURIs) == null ? void 0 : _b2.svg) != null ? _d : (_c = assetData.logoURIs) == null ? void 0 : _c.png) != null ? _e : TOKEN_LOGO_PLACEHOLDER;
1902
+ return asset;
1903
+ };
1904
+ var populateAssetFromBlockchainMetadata = (asset, meta) => {
1905
+ if (!meta || meta.base !== asset.denom) {
1906
+ return asset;
1907
+ }
1908
+ if (meta.name.length > 0) {
1909
+ asset.name = meta.name;
1910
+ }
1911
+ if (meta.symbol.length > 0) {
1912
+ asset.ticker = meta.symbol.toUpperCase();
1913
+ }
1914
+ if (meta.denom_units.length === 0) {
1915
+ return asset;
1916
+ }
1917
+ meta.denom_units.map((unit) => {
1918
+ if (unit.denom === meta.display) {
1919
+ asset.decimals = unit.exponent;
1920
+ asset.ticker = unit.denom.toUpperCase();
1921
+ }
1922
+ });
1923
+ return asset;
1924
+ };
1925
+ var createAsset = (denom, supply) => {
1926
+ var _a2, _b2;
1927
+ return {
1928
+ denom,
1929
+ type: getDenomType(denom),
1930
+ name: truncateDenom(denom),
1931
+ ticker: truncateDenom(denom),
1932
+ decimals: 0,
1933
+ logo: TOKEN_LOGO_PLACEHOLDER,
1934
+ stable: (_a2 = STABLE_COINS[denom]) != null ? _a2 : false,
1935
+ verified: (_b2 = VERIFIED_ASSETS[denom]) != null ? _b2 : false,
1936
+ supply
1937
+ };
1938
+ };
1939
+ var getAllMetadataMap = async () => {
1940
+ const allMetadata = await getAllSupplyMetadata();
1941
+ if (!allMetadata) {
1942
+ return {};
1943
+ }
1944
+ return allMetadata.reduce((acc, asset) => {
1945
+ acc[asset.base] = asset;
1946
+ return acc;
1947
+ }, {});
1948
+ };
1949
+
1950
+ // src/service/keplr.ts
1951
+ async function getKeplrMainnetChainInfo() {
1952
+ const localKey = "ci:keplr:mainnet";
1953
+ const cachedData = getFromLocalStorage(localKey);
1954
+ if (cachedData) {
1955
+ return JSON.parse(cachedData);
1956
+ }
1957
+ const url = "https://raw.githubusercontent.com/faneaatiku/keplr-chain-registry/main/cosmos/beezee.json";
1958
+ try {
1959
+ const response = await fetch(url);
1960
+ if (!response.ok) {
1961
+ console.error(`HTTP error when fetching mainnet keplr data. status: ${response.status}`);
1962
+ return MAINNET_CHAIN_INFO_FALLBACK;
1963
+ }
1964
+ const json = await response.json();
1965
+ setInLocalStorage(localKey, JSON.stringify(json), 60 * 60 * 24);
1966
+ return json;
1967
+ } catch (error) {
1968
+ console.error(`Error fetching mainnet keplr data from ${url}:`, error);
1969
+ return MAINNET_CHAIN_INFO_FALLBACK;
1970
+ }
1971
+ }
1972
+ async function getKeplrTestnetChainInfo() {
1973
+ const localKey = "ci:keplr:testnet";
1974
+ const cachedData = getFromLocalStorage(localKey);
1975
+ if (cachedData) {
1976
+ return JSON.parse(cachedData);
1977
+ }
1978
+ const url = "https://raw.githubusercontent.com/faneaatiku/keplr-chain-registry/refs/heads/patch-2/cosmos/bzetestnet.json";
1979
+ try {
1980
+ const response = await fetch(url);
1981
+ if (!response.ok) {
1982
+ console.error(`HTTP error when fetching testnet keplr data. status: ${response.status}`);
1983
+ return TESTNET_CHAIN_INFO_FALLBACK;
1984
+ }
1985
+ const json = await response.json();
1986
+ setInLocalStorage(localKey, JSON.stringify(json), 60 * 60 * 24);
1987
+ return json;
1988
+ } catch (error) {
1989
+ console.error(`Error fetching testnet keplr data from ${url}:`, error);
1990
+ return TESTNET_CHAIN_INFO_FALLBACK;
1991
+ }
1992
+ }
1993
+ async function getKeplrChainInfo(chainId) {
1994
+ if (chainId !== "beezee") {
1995
+ return getKeplrTestnetChainInfo();
1996
+ }
1997
+ return getKeplrMainnetChainInfo();
1998
+ }
1999
+ async function keplrSuggestChain(chainId) {
2000
+ var _a2;
2001
+ return await ((_a2 = window.keplr) == null ? void 0 : _a2.experimentalSuggestChain(await getKeplrChainInfo(chainId)));
2002
+ }
2003
+
2004
+ // src/query/bank.ts
2005
+ async function getAddressBalances(address) {
2006
+ try {
2007
+ const client = await getRestClient();
2008
+ const response = await client.cosmos.bank.v1beta1.spendableBalances({ address });
2009
+ return response.balances;
2010
+ } catch (e) {
2011
+ console.error("failed to get balances", e);
2012
+ return [];
2013
+ }
2014
+ }
2015
+ async function getLockedBalances() {
2016
+ try {
2017
+ const lockerAddress = getLockerAddress();
2018
+ if (!lockerAddress) {
2019
+ console.warn("Locker address not configured");
2020
+ return [];
2021
+ }
2022
+ return await getAddressBalances(lockerAddress);
2023
+ } catch (e) {
2024
+ console.error("failed to get locked balances", e);
2025
+ return [];
2026
+ }
2027
+ }
2028
+
2029
+ // src/query/epoch.ts
2030
+ var EPOCH_HOUR = "hour";
2031
+ var EPOCH_DAY = "day";
2032
+ var EPOCH_WEEK = "week";
2033
+ var EPOCHS_INFO_CACHE_KEY = "epochs:info";
2034
+ var EPOCHS_INFO_CACHE_TTL = 60 * 60;
2035
+ async function getEpochsInfo() {
2036
+ try {
2037
+ const cachedData = getFromLocalStorage(EPOCHS_INFO_CACHE_KEY);
2038
+ let shouldFetchFromEndpoint = false;
2039
+ if (cachedData !== null) {
2040
+ const cached = JSON.parse(cachedData);
2041
+ const now = (/* @__PURE__ */ new Date()).getTime();
2042
+ for (const epoch of cached.epochs) {
2043
+ if (epoch.current_epoch_start_time) {
2044
+ const startTime = new Date(epoch.current_epoch_start_time).getTime();
2045
+ const duration = getEpochDurationByIdentifier(epoch.identifier);
2046
+ const epochEndTime = startTime + duration - 15 * 1e3;
2047
+ if (now >= epochEndTime) {
2048
+ shouldFetchFromEndpoint = true;
2049
+ break;
2050
+ }
2051
+ }
2052
+ }
2053
+ if (!shouldFetchFromEndpoint) {
2054
+ return cached;
2055
+ }
2056
+ }
2057
+ const client = await getRestClient();
2058
+ const response = await client.bze.epochs.epochInfos();
2059
+ setInLocalStorage(EPOCHS_INFO_CACHE_KEY, JSON.stringify(response), EPOCHS_INFO_CACHE_TTL);
2060
+ return response;
2061
+ } catch (e) {
2062
+ console.error(e);
2063
+ return { epochs: [] };
2064
+ }
2065
+ }
2066
+ async function getCurrentEpoch(identifier) {
2067
+ const all = await getEpochsInfo();
2068
+ return all.epochs.find((item) => item.identifier === identifier);
2069
+ }
2070
+ async function getHourEpochInfo() {
2071
+ return getCurrentEpoch(EPOCH_HOUR);
2072
+ }
2073
+ async function getWeekEpochInfo() {
2074
+ return getCurrentEpoch(EPOCH_WEEK);
2075
+ }
2076
+ async function getCurrentWeekEpochEndTime() {
2077
+ return getPeriodicEpochEndTime(EPOCH_WEEK);
2078
+ }
2079
+ async function getPeriodicWeekEpochEndTime(modWeek = 1) {
2080
+ return getPeriodicEpochEndTime(EPOCH_WEEK, modWeek);
2081
+ }
2082
+ async function getPeriodicEpochEndTime(identifier, mod = 1) {
2083
+ const epoch = await getCurrentEpoch(identifier);
2084
+ if (!epoch || !epoch.current_epoch_start_time) {
2085
+ return void 0;
2086
+ }
2087
+ const current = toBigNumber(epoch.current_epoch);
2088
+ let remainingEpochs = mod - current.toNumber() % mod;
2089
+ if (remainingEpochs === mod) {
2090
+ remainingEpochs = 0;
2091
+ }
2092
+ const startAt = new Date(epoch.current_epoch_start_time);
2093
+ const duration = getEpochDurationByIdentifier(identifier);
2094
+ startAt.setTime(startAt.getTime() + duration + duration * remainingEpochs);
2095
+ return startAt;
2096
+ }
2097
+ function getEpochDurationByIdentifier(identifier) {
2098
+ const hourMs = 60 * 60 * 1e3;
2099
+ switch (identifier) {
2100
+ case EPOCH_HOUR:
2101
+ return hourMs;
2102
+ case EPOCH_DAY:
2103
+ return hourMs * 24;
2104
+ case EPOCH_WEEK:
2105
+ return hourMs * 24 * 7;
2106
+ default:
2107
+ return hourMs;
2108
+ }
2109
+ }
2110
+
2111
+ // src/query/factory.ts
2112
+ async function getFactoryDenomAdminAddress(denom) {
2113
+ var _a2, _b2;
2114
+ try {
2115
+ const client = await getRestClient();
2116
+ const res = await client.bze.tokenfactory.denomAuthority({ denom });
2117
+ return (_b2 = (_a2 = res.denomAuthority) == null ? void 0 : _a2.admin) != null ? _b2 : "";
2118
+ } catch (e) {
2119
+ console.error(e);
2120
+ return "";
2121
+ }
2122
+ }
2123
+
2124
+ // src/query/liquidity_pools.ts
2125
+ import { QueryAllLiquidityPoolsRequest, QueryLiquidityPoolRequest } from "@bze/bzejs/bze/tradebin/query";
2126
+ var { fromPartial: AllLpsRequest } = QueryAllLiquidityPoolsRequest;
2127
+ var { fromPartial: LpRequest } = QueryLiquidityPoolRequest;
2128
+ var DEFAULT_LIMIT3 = 1e3;
2129
+ var getLiquidityPools = async () => {
2130
+ try {
2131
+ const client = await getRestClient();
2132
+ const resp = await client.bze.tradebin.allLiquidityPools(
2133
+ AllLpsRequest(
2134
+ { pagination: getPageRequestWithLimit(DEFAULT_LIMIT3) }
2135
+ )
2136
+ );
2137
+ return resp.list;
2138
+ } catch (error) {
2139
+ console.error("failed to get markets: ", error);
2140
+ }
2141
+ return [];
2142
+ };
2143
+ var getLiquidityPool = async (poolId) => {
2144
+ try {
2145
+ const client = await getRestClient();
2146
+ const resp = await client.bze.tradebin.liquidityPool(LpRequest({
2147
+ poolId
2148
+ }));
2149
+ return resp.pool;
2150
+ } catch (error) {
2151
+ console.error("failed to get markets: ", error);
2152
+ }
2153
+ return void 0;
2154
+ };
2155
+
2156
+ // src/query/markets.ts
2157
+ import {
2158
+ QueryAllMarketsRequest,
2159
+ QueryMarketAggregatedOrdersRequest,
2160
+ QueryMarketHistoryRequest,
2161
+ QueryMarketOrderRequest,
2162
+ QueryUserMarketOrdersRequest
2163
+ } from "@bze/bzejs/bze/tradebin/query";
2164
+ import { PageRequest as PageRequest3 } from "@bze/bzejs/cosmos/base/query/v1beta1/pagination";
2165
+ var { fromPartial: AllMarketsRequest } = QueryAllMarketsRequest;
2166
+ var { fromPartial: QueryMarketAggregatedOrdersRequestFromPartyal } = QueryMarketAggregatedOrdersRequest;
2167
+ var { fromPartial: QueryMarketHistoryRequestFromPartial } = QueryMarketHistoryRequest;
2168
+ var { fromPartial: QueryUserMarketOrdersRequestFromPartial } = QueryUserMarketOrdersRequest;
2169
+ var { fromPartial: QueryMarketOrderRequestFromPartial } = QueryMarketOrderRequest;
2170
+ var DEFAULT_LIMIT4 = 1e3;
2171
+ var getMarkets = async () => {
2172
+ try {
2173
+ const client = await getRestClient();
2174
+ const resp = await client.bze.tradebin.allMarkets(
2175
+ AllMarketsRequest(
2176
+ { pagination: getPageRequestWithLimit(DEFAULT_LIMIT4) }
2177
+ )
2178
+ );
2179
+ return resp.market;
2180
+ } catch (error) {
2181
+ console.error("failed to get markets: ", error);
2182
+ }
2183
+ return [];
2184
+ };
2185
+ async function getMarketBuyOrders(marketId) {
2186
+ return getMarketOrders(marketId, ORDER_TYPE_BUY);
2187
+ }
2188
+ async function getMarketSellOrders(marketId) {
2189
+ return getMarketOrders(marketId, ORDER_TYPE_SELL);
2190
+ }
2191
+ async function getMarketOrders(marketId, orderType) {
2192
+ try {
2193
+ const reversed = orderType === ORDER_TYPE_BUY;
2194
+ const client = await getRestClient();
2195
+ return client.bze.tradebin.marketAggregatedOrders(QueryMarketAggregatedOrdersRequestFromPartyal({
2196
+ market: marketId,
2197
+ orderType,
2198
+ pagination: PageRequest3.fromPartial({ limit: BigInt(15), reverse: reversed })
2199
+ }));
2200
+ } catch (e) {
2201
+ console.error(e);
2202
+ return { list: [] };
2203
+ }
2204
+ }
2205
+ async function getMarketHistory(marketId) {
2206
+ try {
2207
+ const client = await getRestClient();
2208
+ return client.bze.tradebin.marketHistory(QueryMarketHistoryRequestFromPartial({
2209
+ market: marketId,
2210
+ pagination: PageRequest3.fromPartial({ limit: BigInt(50), reverse: true })
2211
+ }));
2212
+ } catch (e) {
2213
+ console.error(e);
2214
+ return { list: [] };
2215
+ }
2216
+ }
2217
+ async function getAddressMarketOrders(marketId, address) {
2218
+ try {
2219
+ const client = await getRestClient();
2220
+ return client.bze.tradebin.userMarketOrders(QueryUserMarketOrdersRequestFromPartial({
2221
+ market: marketId,
2222
+ address,
2223
+ pagination: PageRequest3.fromPartial({ limit: BigInt(100), reverse: true })
2224
+ }));
2225
+ } catch (e) {
2226
+ console.error(e);
2227
+ return { list: [] };
2228
+ }
2229
+ }
2230
+ async function getAddressFullMarketOrders(marketId, address) {
2231
+ const addressOrders = await getAddressMarketOrders(marketId, address);
2232
+ if (addressOrders.list.length === 0) {
2233
+ return [];
2234
+ }
2235
+ const promises = [];
2236
+ for (const reference of addressOrders.list) {
2237
+ promises.push(getMarketOrder(reference.market_id, reference.order_type, reference.id));
2238
+ }
2239
+ const orders = await Promise.all(promises);
2240
+ return orders.filter((item) => item !== void 0).map((resp) => resp.order);
2241
+ }
2242
+ async function getMarketOrder(marketId, orderType, orderId) {
2243
+ try {
2244
+ const client = await getRestClient();
2245
+ return client.bze.tradebin.marketOrder(QueryMarketOrderRequestFromPartial({
2246
+ market: marketId,
2247
+ orderType,
2248
+ orderId
2249
+ }));
2250
+ } catch (e) {
2251
+ console.error(e);
2252
+ return void 0;
2253
+ }
2254
+ }
2255
+
2256
+ // src/query/prices.ts
2257
+ var PRICE_PATH = "/api/prices";
2258
+ var usdPriceDenom = "usd";
2259
+ var usdPriceCacheKey = "price:usd";
2260
+ var priceCacheTtl = 5 * 60;
2261
+ var getPriceUrl = () => {
2262
+ return `${getAggregatorHost()}${PRICE_PATH}`;
2263
+ };
2264
+ var getAssetPriceCacheKey = (asset) => {
2265
+ return `${usdPriceCacheKey}:${asset.toLowerCase()};`;
2266
+ };
2267
+ var fetchAssetUsdPrice = async (asset) => {
2268
+ const cacheKey = getAssetPriceCacheKey(asset);
2269
+ const cached = getFromLocalStorage(cacheKey);
2270
+ if (cached) {
2271
+ return JSON.parse(cached);
2272
+ }
2273
+ try {
2274
+ const resp = await fetch(getPriceUrl());
2275
+ if (resp.status !== 200) {
2276
+ return void 0;
2277
+ }
2278
+ const decodedResp = await resp.json();
2279
+ const result = decodedResp.find((item) => item.denom.toLowerCase() === asset.toLowerCase() && item.price_denom.toLowerCase() === usdPriceDenom);
2280
+ setInLocalStorage(cacheKey, JSON.stringify(result), priceCacheTtl);
2281
+ return result;
2282
+ } catch (e) {
2283
+ console.log("error on getAssetUsdPrice: ", e);
2284
+ return void 0;
2285
+ }
2286
+ };
2287
+ var getBZEUSDPrice = async () => {
2288
+ const usdPrice = await fetchAssetUsdPrice("bzedge");
2289
+ if (!usdPrice) {
2290
+ return 0;
2291
+ }
2292
+ return usdPrice.price;
2293
+ };
2294
+
2295
+ // src/query/rewards.ts
2296
+ import { bze as bze3 } from "@bze/bzejs";
2297
+ import { PageRequest as PageRequest4 } from "@bze/bzejs/cosmos/base/query/v1beta1/pagination";
2298
+ import BigNumber6 from "bignumber.js";
2299
+ var { fromPartial: QueryAllStakingRewardRequestFromPartial } = bze3.rewards.QueryAllStakingRewardsRequest;
2300
+ var { fromPartial: QueryGetStakingRewardParticipantRequestFromPartial } = bze3.rewards.QueryStakingRewardParticipantRequest;
2301
+ var { fromPartial: QueryAllPendingUnlockParticipantRequestFromPartial } = bze3.rewards.QueryAllPendingUnlockParticipantsRequest;
2302
+ async function getStakingRewards(reverse = true) {
2303
+ try {
2304
+ const client = await getRestClient();
2305
+ return await client.bze.rewards.allStakingRewards(QueryAllStakingRewardRequestFromPartial({
2306
+ pagination: PageRequest4.fromPartial({
2307
+ reverse,
2308
+ limit: BigInt(1e3)
2309
+ })
2310
+ }));
2311
+ } catch (e) {
2312
+ console.error(e);
2313
+ return { list: [] };
2314
+ }
2315
+ }
2316
+ async function getAddressPendingUnlock(address) {
2317
+ const all = await getPendingUnlockParticipants();
2318
+ if (!all || all.list.length === 0) {
2319
+ return [];
2320
+ }
2321
+ return all.list.filter((item) => item.address === address);
2322
+ }
2323
+ async function getPendingUnlockParticipants() {
2324
+ try {
2325
+ const client = await getRestClient();
2326
+ return client.bze.rewards.allPendingUnlockParticipants(QueryAllPendingUnlockParticipantRequestFromPartial({
2327
+ pagination: PageRequest4.fromPartial({ limit: BigInt(1e3) })
2328
+ }));
2329
+ } catch (e) {
2330
+ console.error(e);
2331
+ return { list: [] };
2332
+ }
2333
+ }
2334
+ async function getStakingRewardParticipantByAddress(address) {
2335
+ try {
2336
+ const client = await getRestClient();
2337
+ return client.bze.rewards.stakingRewardParticipant(QueryGetStakingRewardParticipantRequestFromPartial({
2338
+ address,
2339
+ pagination: PageRequest4.fromPartial({ limit: BigInt(500) })
2340
+ }));
2341
+ } catch (e) {
2342
+ console.error(e);
2343
+ return { list: [] };
2344
+ }
2345
+ }
2346
+ async function getAddressStakingRewards(address) {
2347
+ const result = {
2348
+ address,
2349
+ active: /* @__PURE__ */ new Map(),
2350
+ unlocking: /* @__PURE__ */ new Map()
2351
+ };
2352
+ if (address === "") {
2353
+ return result;
2354
+ }
2355
+ try {
2356
+ const [participantRewards, pending] = await Promise.all([getStakingRewardParticipantByAddress(address), getAddressPendingUnlock(address)]);
2357
+ [result.active, result.unlocking] = await Promise.all([mapParticipantRewards(participantRewards.list), mapPendingUnlock(pending)]);
2358
+ return result;
2359
+ } catch (e) {
2360
+ console.error(e);
2361
+ return result;
2362
+ }
2363
+ }
2364
+ async function mapParticipantRewards(participantRewards) {
2365
+ const result = /* @__PURE__ */ new Map();
2366
+ for (let i = 0; i < participantRewards.length; i++) {
2367
+ result.set(participantRewards[i].reward_id, participantRewards[i]);
2368
+ }
2369
+ return result;
2370
+ }
2371
+ async function mapPendingUnlock(pending) {
2372
+ var _a2;
2373
+ const result = /* @__PURE__ */ new Map();
2374
+ for (let i = 0; i < pending.length; i++) {
2375
+ const splitIndex = pending[i].index.split("/");
2376
+ if (splitIndex.length !== 3) {
2377
+ console.error("invalid pending unlock index", pending[i].index);
2378
+ continue;
2379
+ }
2380
+ const item = __spreadProps(__spreadValues({}, pending[i]), {
2381
+ rewardId: splitIndex[1],
2382
+ unlockEpoch: new BigNumber6(splitIndex[0])
2383
+ });
2384
+ const allItems = (_a2 = result.get(item.rewardId)) != null ? _a2 : [];
2385
+ allItems.push(item);
2386
+ result.set(item.rewardId, allItems);
2387
+ }
2388
+ return result;
2389
+ }
2390
+
2391
+ // src/query/staking.ts
2392
+ import { PageRequest as PageRequest5 } from "@bze/bzejs/cosmos/base/query/v1beta1/pagination";
2393
+ import BigNumber7 from "bignumber.js";
2394
+ var getAddressDelegations = async (address) => {
2395
+ try {
2396
+ const client = await getRestClient();
2397
+ const response = await client.cosmos.staking.v1beta1.delegatorDelegations({
2398
+ delegatorAddr: address,
2399
+ pagination: PageRequest5.fromPartial({
2400
+ limit: BigInt(1e3)
2401
+ })
2402
+ });
2403
+ return response.delegation_responses;
2404
+ } catch (e) {
2405
+ console.error("failed to get address delegations", e);
2406
+ return [];
2407
+ }
2408
+ };
2409
+ var getAddressNativeDelegatedBalance = async (address) => {
2410
+ const delegations = await getAddressDelegations(address);
2411
+ const total = delegations.reduce((acc, delegation) => {
2412
+ if (!delegation.balance) return acc;
2413
+ if (delegation.balance.denom !== getChainNativeAssetDenom()) return acc;
2414
+ return acc.plus(delegation.balance.amount);
2415
+ }, new BigNumber7(0));
2416
+ return {
2417
+ denom: getChainNativeAssetDenom(),
2418
+ amount: total
2419
+ };
2420
+ };
2421
+ var getAddressUnbondingDelegations = async (address) => {
2422
+ try {
2423
+ const client = await getRestClient();
2424
+ const resp = await client.cosmos.staking.v1beta1.delegatorUnbondingDelegations({
2425
+ delegatorAddr: address,
2426
+ pagination: PageRequest5.fromPartial({
2427
+ limit: BigInt(1e3)
2428
+ })
2429
+ });
2430
+ return resp.unbonding_responses;
2431
+ } catch (e) {
2432
+ console.error("failed to get address delegations", e);
2433
+ return [];
2434
+ }
2435
+ };
2436
+ var getAddressUnbondingDelegationsSummary = async (address) => {
2437
+ const unbondingDelegations = await getAddressUnbondingDelegations(address);
2438
+ let totalAmount = new BigNumber7(0);
2439
+ let firstUnlockDate = void 0;
2440
+ let firstUnlock = void 0;
2441
+ unbondingDelegations.map((delegation) => {
2442
+ delegation.entries.forEach((entry) => {
2443
+ totalAmount = totalAmount.plus(entry.balance);
2444
+ const entryDate = new Date(entry.completion_time);
2445
+ if (!firstUnlockDate || entryDate < firstUnlockDate) {
2446
+ firstUnlockDate = entryDate;
2447
+ firstUnlock = {
2448
+ amount: new BigNumber7(entry.balance),
2449
+ denom: getChainNativeAssetDenom()
2450
+ };
2451
+ }
2452
+ });
2453
+ });
2454
+ return {
2455
+ total: {
2456
+ amount: totalAmount,
2457
+ denom: getChainNativeAssetDenom()
2458
+ },
2459
+ firstUnlock: {
2460
+ amount: firstUnlock,
2461
+ unlockTime: firstUnlockDate
2462
+ }
2463
+ };
2464
+ };
2465
+ var getAddressRewards = async (address) => {
2466
+ try {
2467
+ const client = await getRestClient();
2468
+ return await client.cosmos.distribution.v1beta1.delegationTotalRewards({ delegatorAddress: address });
2469
+ } catch (e) {
2470
+ console.error("failed to get address rewards", e);
2471
+ return {
2472
+ rewards: [],
2473
+ total: []
2474
+ };
2475
+ }
2476
+ };
2477
+ var getAddressNativeTotalRewards = async (address) => {
2478
+ const rewards = await getAddressRewards(address);
2479
+ const total = rewards.total.find((r) => r.denom === getChainNativeAssetDenom());
2480
+ if (!total) {
2481
+ return {
2482
+ total: {
2483
+ denom: getChainNativeAssetDenom(),
2484
+ amount: new BigNumber7(0)
2485
+ },
2486
+ validators: []
2487
+ };
2488
+ }
2489
+ const validators = [];
2490
+ rewards.rewards.map((r) => {
2491
+ var _a2, _b2;
2492
+ const rewards2 = new BigNumber7((_b2 = (_a2 = r.reward.find((r2) => r2.denom === getChainNativeAssetDenom())) == null ? void 0 : _a2.amount) != null ? _b2 : "0").integerValue();
2493
+ if (!rewards2.gt(0)) {
2494
+ return;
2495
+ }
2496
+ validators.push(r.validator_address);
2497
+ });
2498
+ return {
2499
+ total: {
2500
+ denom: getChainNativeAssetDenom(),
2501
+ amount: new BigNumber7(total.amount).integerValue()
2502
+ },
2503
+ validators
2504
+ };
2505
+ };
2506
+ var getAnnualProvisions = async () => {
2507
+ try {
2508
+ const client = await getRestClient();
2509
+ const resp = await client.cosmos.mint.v1beta1.annualProvisions();
2510
+ return new BigNumber7(resp.annual_provisions).integerValue();
2511
+ } catch (e) {
2512
+ console.error("failed to get annual provisions", e);
2513
+ return new BigNumber7(0);
2514
+ }
2515
+ };
2516
+ var getDistributionParams = async () => {
2517
+ try {
2518
+ const client = await getRestClient();
2519
+ const resp = await client.cosmos.distribution.v1beta1.params();
2520
+ return resp.params;
2521
+ } catch (e) {
2522
+ console.error("failed to get distribution params", e);
2523
+ return {
2524
+ community_tax: "0.05",
2525
+ base_proposer_reward: "0.1",
2526
+ bonus_proposer_reward: "0.2",
2527
+ withdraw_addr_enabled: true
2528
+ };
2529
+ }
2530
+ };
2531
+ var getStakingParams = async () => {
2532
+ try {
2533
+ const client = await getRestClient();
2534
+ const resp = await client.cosmos.staking.v1beta1.params();
2535
+ return resp.params;
2536
+ } catch (e) {
2537
+ console.error("failed to get distribution params", e);
2538
+ return {
2539
+ unbonding_time: "1814400s",
2540
+ max_validators: 100,
2541
+ max_entries: 7,
2542
+ historical_entries: 0,
2543
+ bond_denom: "ubze"
2544
+ };
2545
+ }
2546
+ };
2547
+ var getStakingPool = async () => {
2548
+ try {
2549
+ const client = await getRestClient();
2550
+ const resp = await client.cosmos.staking.v1beta1.pool();
2551
+ return resp.pool;
2552
+ } catch (e) {
2553
+ console.error("failed to get staking pool", e);
2554
+ return {
2555
+ not_bonded_tokens: "0",
2556
+ bonded_tokens: "0"
2557
+ };
2558
+ }
2559
+ };
2560
+
2561
+ // src/query/aggregator.ts
2562
+ var getAllTickersUrl = () => {
2563
+ return `${getAggregatorHost()}/api/dex/tickers`;
2564
+ };
2565
+ var getHistoryUrl = () => {
2566
+ return `${getAggregatorHost()}/api/dex/history`;
2567
+ };
2568
+ async function getAllTickers() {
2569
+ try {
2570
+ const resp = await fetch(getAllTickersUrl());
2571
+ if (resp.status !== 200) {
2572
+ console.error("failed to fetch tickers. status: ", resp.status);
2573
+ return [];
2574
+ }
2575
+ return await resp.json();
2576
+ } catch (e) {
2577
+ console.error("[AGG] failed to fetch tickers", e);
2578
+ return [];
2579
+ }
2580
+ }
2581
+ async function getMarketOrdersHistory(marketId, limit = 1) {
2582
+ try {
2583
+ const url = `${getHistoryUrl()}?market_id=${marketId}&limit=${limit}`;
2584
+ const resp = await fetch(url);
2585
+ if (resp.status !== 200) {
2586
+ return [];
2587
+ }
2588
+ return await resp.json();
2589
+ } catch (e) {
2590
+ console.error("[AGG] failed to fetch market orders", e);
2591
+ return [];
2592
+ }
2593
+ }
2594
+ async function getAddressHistory(address, market) {
2595
+ try {
2596
+ const url = `${getHistoryUrl()}?address=${address}&market_id=${market}&limit=100`;
2597
+ const resp = await fetch(url);
2598
+ if (resp.status !== 200) {
2599
+ return [];
2600
+ }
2601
+ return await resp.json();
2602
+ } catch (e) {
2603
+ console.error("failed to fetch address orders", e);
2604
+ return [];
2605
+ }
2606
+ }
2607
+ async function getTradingViewIntervals(market, minutes, limit) {
2608
+ try {
2609
+ const url = `${getAggregatorHost()}/api/dex/intervals?market_id=${market}&minutes=${minutes}&limit=${limit}&format=tv`;
2610
+ const resp = await fetch(url);
2611
+ if (resp.status !== 200) {
2612
+ return [];
2613
+ }
2614
+ const jsonResponse = await resp.json();
2615
+ if (!jsonResponse) {
2616
+ return [];
2617
+ }
2618
+ return jsonResponse;
2619
+ } catch (e) {
2620
+ console.error("failed to fetch trading view intervals", e);
2621
+ return [];
2622
+ }
2623
+ }
2624
+ async function getAddressSwapHistory(address) {
2625
+ try {
2626
+ const url = `${getAggregatorHost()}/api/dex/swaps?address=${address}`;
2627
+ const resp = await fetch(url);
2628
+ if (resp.status !== 200) {
2629
+ console.error("failed to fetch swap history. status: ", resp.status);
2630
+ return [];
2631
+ }
2632
+ return await resp.json();
2633
+ } catch (e) {
2634
+ console.error("[AGG] failed to fetch swap history", e);
2635
+ return [];
2636
+ }
2637
+ }
2638
+
2639
+ // src/contexts/assets_context.ts
2640
+ import { createContext } from "react";
2641
+ var AssetsContext = createContext(void 0);
2642
+
2643
+ // src/hooks/useAssets.ts
2644
+ import { useCallback, useContext, useMemo } from "react";
2645
+ function useAssetsContext() {
2646
+ const context = useContext(AssetsContext);
2647
+ if (context === void 0) {
2648
+ throw new Error("useAssets must be used within an AssetsProvider");
2649
+ }
2650
+ return context;
2651
+ }
2652
+ function useAssets() {
2653
+ const { assetsMap, isLoading } = useAssetsContext();
2654
+ const nativeAsset = useMemo(
2655
+ () => assetsMap.get(getChainNativeAssetDenom()),
2656
+ [assetsMap]
2657
+ );
2658
+ const assets = useMemo(
2659
+ () => Array.from(assetsMap.values()),
2660
+ [assetsMap]
2661
+ );
2662
+ const isVerifiedAsset = useCallback((denom) => {
2663
+ const asset = assetsMap.get(denom);
2664
+ if (!asset) {
2665
+ return false;
2666
+ }
2667
+ return asset.verified;
2668
+ }, [assetsMap]);
2669
+ const denomTicker = useCallback((denom) => {
2670
+ const asset = assetsMap.get(denom);
2671
+ if (!asset) {
2672
+ return truncateDenom(denom);
2673
+ }
2674
+ return asset.ticker;
2675
+ }, [assetsMap]);
2676
+ const denomDecimals = useCallback((denom) => {
2677
+ const asset = assetsMap.get(denom);
2678
+ if (!asset) {
2679
+ return 0;
2680
+ }
2681
+ return asset.decimals;
2682
+ }, [assetsMap]);
2683
+ const getAsset = useCallback((denom) => {
2684
+ return assetsMap.get(denom);
2685
+ }, [assetsMap]);
2686
+ const assetsLpExcluded = useMemo(() => {
2687
+ return assets == null ? void 0 : assets.filter((item) => !isLpDenom(item.denom));
2688
+ }, [assets]);
2689
+ return {
2690
+ assets,
2691
+ isLoading,
2692
+ nativeAsset,
2693
+ isVerifiedAsset,
2694
+ denomTicker,
2695
+ denomDecimals,
2696
+ getAsset,
2697
+ assetsLpExcluded
2698
+ };
2699
+ }
2700
+ function useAsset(denom) {
2701
+ const { assetsMap, isLoading } = useAssetsContext();
2702
+ const asset = useMemo(
2703
+ () => assetsMap.get(denom),
2704
+ [assetsMap, denom]
2705
+ );
2706
+ return {
2707
+ asset,
2708
+ isLoading
2709
+ };
2710
+ }
2711
+ function useAssetsManager() {
2712
+ const { updateAssets, isLoading } = useAssetsContext();
2713
+ return {
2714
+ updateAssets,
2715
+ isLoading
2716
+ };
2717
+ }
2718
+ function useIBCChains() {
2719
+ const { ibcChains, isLoading } = useAssetsContext();
2720
+ return {
2721
+ ibcChains,
2722
+ isLoading
2723
+ };
2724
+ }
2725
+
2726
+ // src/hooks/useConnectionType.ts
2727
+ function useConnectionType() {
2728
+ const { connectionType, updateConnectionType } = useAssetsContext();
2729
+ return {
2730
+ connectionType,
2731
+ updateConnectionType
2732
+ };
2733
+ }
2734
+
2735
+ // src/hooks/useSigningClient.ts
2736
+ import {
2737
+ getSigningBzeClient,
2738
+ getSigningCosmosClient,
2739
+ getSigningIbcClient
2740
+ } from "@bze/bzejs";
2741
+ import { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo3, useRef, useState as useState2 } from "react";
2742
+ import { useChain } from "@interchain-kit/react";
2743
+
2744
+ // src/hooks/useSettings.ts
2745
+ import { useState, useEffect, useCallback as useCallback2, useMemo as useMemo2 } from "react";
2746
+ function useSettings() {
2747
+ const [settings, setSettingsState] = useState(DEFAULT_SETTINGS);
2748
+ const [isLoaded, setIsLoaded] = useState(false);
2749
+ useEffect(() => {
2750
+ setSettingsState(getSettings());
2751
+ setIsLoaded(true);
2752
+ }, []);
2753
+ const saveSettings = useCallback2((newSettings) => {
2754
+ setSettings(newSettings);
2755
+ setSettingsState(newSettings);
2756
+ return true;
2757
+ }, []);
2758
+ const updateEndpoints = useCallback2((endpoints) => {
2759
+ const newSettings = __spreadProps(__spreadValues({}, settings), { endpoints });
2760
+ return saveSettings(newSettings);
2761
+ }, [settings, saveSettings]);
2762
+ const updatePreferredFeeDenom = useCallback2((preferredFeeDenom) => {
2763
+ const newSettings = __spreadProps(__spreadValues({}, settings), { preferredFeeDenom });
2764
+ return saveSettings(newSettings);
2765
+ }, [settings, saveSettings]);
2766
+ const resetToDefaults = useCallback2(() => {
2767
+ saveSettings(DEFAULT_SETTINGS);
2768
+ return true;
2769
+ }, [saveSettings]);
2770
+ const getEndpoints = useCallback2(() => {
2771
+ return settings.endpoints;
2772
+ }, [settings.endpoints]);
2773
+ const defaultSettings = useMemo2(() => DEFAULT_SETTINGS, []);
2774
+ const feeDenom = useMemo2(() => settings.preferredFeeDenom || getChainNativeAssetDenom(), [settings.preferredFeeDenom]);
2775
+ return {
2776
+ settings,
2777
+ isLoaded,
2778
+ saveSettings,
2779
+ updateEndpoints,
2780
+ updatePreferredFeeDenom,
2781
+ resetToDefaults,
2782
+ getEndpoints,
2783
+ defaultSettings,
2784
+ feeDenom
2785
+ };
2786
+ }
2787
+
2788
+ // src/hooks/useSigningClient.ts
2789
+ var useSigningClient = ({ chainName, isIbc, isCosmos }) => {
2790
+ const { getSigningClient, signingClientError, wallet, chain } = useChain(chainName != null ? chainName : getChainName());
2791
+ const [signingClient, setSigningClient] = useState2(null);
2792
+ const [isSigningClientReady, setIsSigningClientReady] = useState2(false);
2793
+ const { settings } = useSettings();
2794
+ const hasInitialized = useRef(false);
2795
+ const defaultChainName = useMemo3(() => getChainName(), []);
2796
+ const createSigningClient = useCallback3(async () => {
2797
+ var _a2;
2798
+ const signingResult = await getSigningClient();
2799
+ const offlineSigner = signingResult == null ? void 0 : signingResult.offlineSigner;
2800
+ const rpcEndpoint = settings.endpoints.rpcEndpoint.replace("wss://", "https://").replace("ws://", "http://");
2801
+ if (!offlineSigner) {
2802
+ return;
2803
+ }
2804
+ let clientFn = getSigningBzeClient;
2805
+ if (isIbc) {
2806
+ clientFn = getSigningIbcClient;
2807
+ } else if (isCosmos) {
2808
+ clientFn = getSigningCosmosClient;
2809
+ }
2810
+ const signer = (_a2 = offlineSigner == null ? void 0 : offlineSigner.offlineSigner) != null ? _a2 : offlineSigner;
2811
+ const getRpcForChain = (name) => {
2812
+ switch (name) {
2813
+ case "archway":
2814
+ return getArchwayRpcURL();
2815
+ case "osmosis":
2816
+ return getOsmosisRpcUrl();
2817
+ case "noble":
2818
+ return getNobleRpcUrl();
2819
+ case "jackal":
2820
+ return getJackalRpcUrl();
2821
+ case "omniflixhub":
2822
+ return getOmniFlixRpcUrl();
2823
+ case "atomone":
2824
+ return getAtomOneRpcUrl();
2825
+ default:
2826
+ return rpcEndpoint;
2827
+ }
2828
+ };
2829
+ const endpoint = chainName && chainName !== defaultChainName ? getRpcForChain(chainName) : rpcEndpoint;
2830
+ return clientFn({ rpcEndpoint: endpoint, signer });
2831
+ }, [getSigningClient, settings.endpoints.rpcEndpoint, isIbc, isCosmos, chainName, defaultChainName]);
2832
+ useEffect2(() => {
2833
+ if (!wallet || !chain || hasInitialized.current) {
2834
+ return;
2835
+ }
2836
+ const load = async () => {
2837
+ const client = await createSigningClient();
2838
+ if (client) {
2839
+ setSigningClient(client);
2840
+ setIsSigningClientReady(true);
2841
+ hasInitialized.current = true;
2842
+ }
2843
+ };
2844
+ load();
2845
+ }, [wallet, chain, createSigningClient]);
2846
+ return {
2847
+ signingClientError,
2848
+ signingClient,
2849
+ isSigningClientReady
2850
+ };
2851
+ };
2852
+
2853
+ // src/hooks/usePrices.ts
2854
+ import { useCallback as useCallback4, useMemo as useMemo4 } from "react";
2855
+ function useAssetPrice(denom) {
2856
+ const { usdPricesMap, marketsDataMap, isLoadingPrices } = useAssetsContext();
2857
+ const usdDenom = useMemo4(() => getUSDCDenom(), []);
2858
+ const bzeDenom = useMemo4(() => getChainNativeAssetDenom(), []);
2859
+ const change = useMemo4(() => {
2860
+ const marketData = marketsDataMap.get(createMarketId(denom, usdDenom));
2861
+ if (marketData) {
2862
+ return marketData.change;
2863
+ }
2864
+ const marketData2 = marketsDataMap.get(createMarketId(denom, bzeDenom));
2865
+ if (marketData2) {
2866
+ return marketData2.change;
2867
+ }
2868
+ return 0;
2869
+ }, [marketsDataMap, denom, usdDenom, bzeDenom]);
2870
+ const price = useMemo4(() => {
2871
+ const zeroBN = toBigNumber(0);
2872
+ if (denom === "") return zeroBN;
2873
+ if (denom === usdDenom) return toBigNumber(1);
2874
+ return usdPricesMap.get(denom) || zeroBN;
2875
+ }, [usdPricesMap, denom, usdDenom]);
2876
+ const totalUsdValue = useCallback4((amount) => {
2877
+ return price.multipliedBy(amount);
2878
+ }, [price]);
2879
+ const uAmountUsdValue = useCallback4((amount, decimals) => {
2880
+ return totalUsdValue(uAmountToBigNumberAmount(amount, decimals));
2881
+ }, [totalUsdValue]);
2882
+ const isUSDC = useMemo4(() => denom === usdDenom, [denom, usdDenom]);
2883
+ const hasPrice = useMemo4(() => price.gt(0), [price]);
2884
+ return {
2885
+ price,
2886
+ change,
2887
+ totalUsdValue,
2888
+ uAmountUsdValue,
2889
+ isLoading: isLoadingPrices,
2890
+ hasPrice,
2891
+ isUSDC
2892
+ };
2893
+ }
2894
+
2895
+ // src/hooks/useBalances.ts
2896
+ import BigNumber8 from "bignumber.js";
2897
+ import { useMemo as useMemo5, useCallback as useCallback5 } from "react";
2898
+ function useBalances() {
2899
+ const { balancesMap, isLoading, assetsMap, usdPricesMap } = useAssetsContext();
2900
+ const balances = useMemo5(() => Array.from(balancesMap.values()), [balancesMap]);
2901
+ const getBalanceByDenom = useCallback5((denom) => {
2902
+ return balancesMap.get(denom) || { denom, amount: BigNumber8(0) };
2903
+ }, [balancesMap]);
2904
+ const assetsBalances = useMemo5(() => {
2905
+ const result = [];
2906
+ balances.map((bal) => {
2907
+ const asset = assetsMap.get(bal.denom);
2908
+ if (!asset) {
2909
+ return;
2910
+ }
2911
+ let usdPrice = usdPricesMap.get(bal.denom);
2912
+ if (!usdPrice) {
2913
+ usdPrice = BigNumber8(0);
2914
+ }
2915
+ if (asset.denom === getUSDCDenom()) {
2916
+ usdPrice = BigNumber8(1);
2917
+ }
2918
+ result.push(__spreadProps(__spreadValues({}, asset), {
2919
+ amount: bal.amount,
2920
+ USDValue: uAmountToBigNumberAmount(bal.amount, asset.decimals).multipliedBy(usdPrice)
2921
+ }));
2922
+ });
2923
+ return result;
2924
+ }, [balances, assetsMap, usdPricesMap]);
2925
+ return {
2926
+ isLoading,
2927
+ balances,
2928
+ assetsBalances,
2929
+ getBalanceByDenom
2930
+ };
2931
+ }
2932
+ function useBalance(denom) {
2933
+ const { balancesMap, isLoading } = useAssetsContext();
2934
+ const balance = useMemo5(
2935
+ () => balancesMap.get(denom) || {
2936
+ denom,
2937
+ amount: BigNumber8(0)
2938
+ },
2939
+ [balancesMap, denom]
2940
+ );
2941
+ const hasAmount = useCallback5((amount) => {
2942
+ return balance.amount.gte(amount);
2943
+ }, [balance]);
2944
+ return {
2945
+ balance,
2946
+ isLoading,
2947
+ hasAmount
2948
+ };
2949
+ }
2950
+
2951
+ // src/hooks/useEpochs.ts
2952
+ import { useMemo as useMemo6 } from "react";
2953
+ var EPOCH_HOUR2 = "hour";
2954
+ var EPOCH_DAY2 = "day";
2955
+ var EPOCH_WEEK2 = "week";
2956
+ function useEpochs() {
2957
+ const { epochs, isLoading, updateEpochs } = useAssetsContext();
2958
+ const hourEpochInfo = useMemo6(() => {
2959
+ return epochs.get(EPOCH_HOUR2);
2960
+ }, [epochs]);
2961
+ const dayEpochInfo = useMemo6(() => {
2962
+ return epochs.get(EPOCH_DAY2);
2963
+ }, [epochs]);
2964
+ const weekEpochInfo = useMemo6(() => {
2965
+ return epochs.get(EPOCH_WEEK2);
2966
+ }, [epochs]);
2967
+ return {
2968
+ epochs,
2969
+ hourEpochInfo,
2970
+ dayEpochInfo,
2971
+ weekEpochInfo,
2972
+ isLoading,
2973
+ updateEpochs
2974
+ };
2975
+ }
2976
+
2977
+ // src/hooks/useLiquidityPools.ts
2978
+ import { useCallback as useCallback6, useMemo as useMemo7 } from "react";
2979
+ function useLiquidityPools() {
2980
+ const { poolsMap, poolsDataMap, updateLiquidityPools, isLoading, assetsMap } = useAssetsContext();
2981
+ const pools = useMemo7(() => {
2982
+ return Array.from(poolsMap.values());
2983
+ }, [poolsMap]);
2984
+ const getPoolByLpDenom = (lpDenom) => {
2985
+ const poolId = poolIdFromPoolDenom(lpDenom);
2986
+ return poolsMap.get(poolId);
2987
+ };
2988
+ const getDenomsPool = useCallback6((denomA, denomB) => {
2989
+ const poolId = createPoolId(denomA, denomB);
2990
+ return poolsMap.get(poolId);
2991
+ }, [poolsMap]);
2992
+ const liquidAssets = useMemo7(() => {
2993
+ if (!assetsMap || assetsMap.size === 0) return [];
2994
+ const result = /* @__PURE__ */ new Map();
2995
+ pools.forEach((pool) => {
2996
+ result.set(pool.base, assetsMap.get(pool.base));
2997
+ result.set(pool.quote, assetsMap.get(pool.quote));
2998
+ });
2999
+ return Array.from(result.values()).filter((asset) => asset !== void 0);
3000
+ }, [assetsMap, pools]);
3001
+ return {
3002
+ pools,
3003
+ poolsMap,
3004
+ poolsDataMap,
3005
+ isLoading,
3006
+ updateLiquidityPools,
3007
+ getPoolByLpDenom,
3008
+ getDenomsPool,
3009
+ liquidAssets
3010
+ };
3011
+ }
3012
+ function useAssetLiquidityPools(denom) {
3013
+ const { poolsMap, poolsDataMap } = useAssetsContext();
3014
+ const assetPools = useMemo7(() => {
3015
+ return Array.from(poolsMap.values()).filter(
3016
+ (pool) => pool.base === denom || pool.quote === denom
3017
+ );
3018
+ }, [poolsMap, denom]);
3019
+ return {
3020
+ assetPools,
3021
+ poolsDataMap
3022
+ };
3023
+ }
3024
+
3025
+ // src/hooks/useAssetsValue.ts
3026
+ import { useMemo as useMemo8 } from "react";
3027
+ function useAssetsValue() {
3028
+ const { assetsMap, usdPricesMap, balancesMap, isLoading } = useAssetsContext();
3029
+ const totalUsdValue = useMemo8(() => {
3030
+ let total = toBigNumber(0);
3031
+ balancesMap.forEach((balance, denom) => {
3032
+ const price = usdPricesMap.get(denom);
3033
+ if (!price || !price.gt(0)) return;
3034
+ const asset = assetsMap.get(denom);
3035
+ if (!asset) return;
3036
+ total = total.plus(price.multipliedBy(uAmountToBigNumberAmount(balance.amount, asset.decimals)));
3037
+ });
3038
+ return total;
3039
+ }, [balancesMap, usdPricesMap, assetsMap]);
3040
+ const denomUsdValue = (denom, uAmount) => {
3041
+ const price = usdPricesMap.get(denom);
3042
+ if (!price || !price.gt(0)) return toBigNumber(0);
3043
+ const asset = assetsMap.get(denom);
3044
+ if (!asset) return toBigNumber(0);
3045
+ return price.multipliedBy(uAmountToBigNumberAmount(uAmount, asset.decimals));
3046
+ };
3047
+ return {
3048
+ totalUsdValue,
3049
+ denomUsdValue,
3050
+ isLoading
3051
+ };
3052
+ }
3053
+
3054
+ // src/hooks/useFeeTokens.ts
3055
+ import { useMemo as useMemo9 } from "react";
3056
+ var MIN_LIQUIDITY_FOR_FEE_TOKEN = 5e10;
3057
+ function useFeeTokens() {
3058
+ const { pools, isLoading: poolsLoading } = useLiquidityPools();
3059
+ const { assetsMap, isLoading: assetsLoading } = useAssetsContext();
3060
+ const nativeDenom = getChainNativeAssetDenom();
3061
+ const feeTokens = useMemo9(() => {
3062
+ if (poolsLoading || assetsLoading) {
3063
+ return [];
3064
+ }
3065
+ const feeTokenDenoms = /* @__PURE__ */ new Set();
3066
+ pools.forEach((pool) => {
3067
+ if (pool.base === nativeDenom && toBigNumber(pool.reserve_base).gt(MIN_LIQUIDITY_FOR_FEE_TOKEN)) {
3068
+ feeTokenDenoms.add(pool.quote);
3069
+ } else if (pool.quote === nativeDenom && toBigNumber(pool.reserve_quote).gt(MIN_LIQUIDITY_FOR_FEE_TOKEN)) {
3070
+ feeTokenDenoms.add(pool.base);
3071
+ }
3072
+ });
3073
+ const tokens = Array.from(feeTokenDenoms).map((denom) => assetsMap.get(denom)).filter((asset) => asset !== void 0).sort((a, b) => {
3074
+ if (!a || !b) return 0;
3075
+ return a.denom.localeCompare(b.denom);
3076
+ });
3077
+ const bzeAsset = assetsMap.get(nativeDenom);
3078
+ if (!bzeAsset) {
3079
+ return tokens;
3080
+ }
3081
+ return [bzeAsset, ...tokens];
3082
+ }, [pools, poolsLoading, assetsLoading, nativeDenom, assetsMap]);
3083
+ return {
3084
+ feeTokens,
3085
+ isLoading: poolsLoading || assetsLoading,
3086
+ nativeDenom
3087
+ };
3088
+ }
3089
+
3090
+ // src/hooks/useMarkets.ts
3091
+ import { useMemo as useMemo10 } from "react";
3092
+ function useMarkets() {
3093
+ const { marketsMap, marketsDataMap, updateMarkets, isLoading } = useAssetsContext();
3094
+ const markets = useMemo10(() => {
3095
+ return Array.from(marketsMap.values());
3096
+ }, [marketsMap]);
3097
+ return {
3098
+ markets,
3099
+ marketsMap,
3100
+ marketsDataMap,
3101
+ isLoading,
3102
+ updateMarkets
3103
+ };
3104
+ }
3105
+ function useAssetMarkets(denom) {
3106
+ const { marketsMap } = useAssetsContext();
3107
+ const assetMarkets = useMemo10(() => {
3108
+ return Array.from(marketsMap.values()).filter(
3109
+ (market) => market.base === denom || market.quote === denom
3110
+ );
3111
+ }, [marketsMap, denom]);
3112
+ return {
3113
+ assetMarkets
3114
+ };
3115
+ }
3116
+ function useMarket(base, quote) {
3117
+ const { marketsMap, marketsDataMap, assetsMap, isLoading } = useAssetsContext();
3118
+ const marketId = useMemo10(() => createMarketId(base, quote), [base, quote]);
3119
+ const market = useMemo10(() => {
3120
+ return marketsMap.get(marketId);
3121
+ }, [marketsMap, marketId]);
3122
+ const marketData = useMemo10(() => {
3123
+ return marketsDataMap.get(marketId);
3124
+ }, [marketsDataMap, marketId]);
3125
+ const marketExists = useMemo10(() => !!market, [market]);
3126
+ const volume24h = useMemo10(() => {
3127
+ if (!marketData) return toBigNumber(0);
3128
+ const quoteAsset = assetsMap.get(quote);
3129
+ if (!quoteAsset) return toBigNumber(0);
3130
+ return uAmountToBigNumberAmount(toBigNumber(marketData.quote_volume), quoteAsset.decimals);
3131
+ }, [marketData, assetsMap, quote]);
3132
+ return {
3133
+ market,
3134
+ marketData,
3135
+ marketExists,
3136
+ volume24h,
3137
+ isLoading
3138
+ };
3139
+ }
3140
+
3141
+ // src/hooks/useToast.tsx
3142
+ import { useCallback as useCallback8, useMemo as useMemo11 } from "react";
3143
+
3144
+ // src/components/toaster.tsx
3145
+ import {
3146
+ Toaster as ChakraToaster,
3147
+ Portal,
3148
+ Spinner,
3149
+ Stack,
3150
+ Toast,
3151
+ createToaster
3152
+ } from "@chakra-ui/react";
3153
+ import { jsx, jsxs } from "react/jsx-runtime";
3154
+ var toaster = createToaster({
3155
+ placement: "top-end",
3156
+ pauseOnPageIdle: true
3157
+ });
3158
+ var Toaster = () => {
3159
+ return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(ChakraToaster, { toaster, insetInline: { mdDown: "4" }, children: (toast) => /* @__PURE__ */ jsxs(Toast.Root, { width: { md: "sm" }, children: [
3160
+ toast.type === "loading" ? /* @__PURE__ */ jsx(Spinner, { size: "sm", color: "blue.solid" }) : /* @__PURE__ */ jsx(Toast.Indicator, {}),
3161
+ /* @__PURE__ */ jsxs(Stack, { gap: "1", flex: "1", maxWidth: "100%", children: [
3162
+ toast.title && /* @__PURE__ */ jsx(Toast.Title, { children: toast.title }),
3163
+ toast.description && /* @__PURE__ */ jsx(Toast.Description, { children: toast.description })
3164
+ ] }),
3165
+ toast.action && /* @__PURE__ */ jsx(Toast.ActionTrigger, { children: toast.action.label }),
3166
+ toast.closable && /* @__PURE__ */ jsx(Toast.CloseTrigger, {})
3167
+ ] }) }) });
3168
+ };
3169
+
3170
+ // src/hooks/useToast.tsx
3171
+ var useToast = () => {
3172
+ const clickableSuccess = useCallback8((title, actionFn, actionLabel, description, duration = 5e3) => {
3173
+ toaster.create({
3174
+ title,
3175
+ description,
3176
+ type: "success",
3177
+ duration,
3178
+ closable: true,
3179
+ action: {
3180
+ label: actionLabel != null ? actionLabel : "",
3181
+ onClick: actionFn
3182
+ }
3183
+ });
3184
+ }, []);
3185
+ const success = useCallback8((title, description, duration = 5e3) => {
3186
+ toaster.create({
3187
+ title,
3188
+ description,
3189
+ type: "success",
3190
+ duration,
3191
+ closable: true
3192
+ });
3193
+ }, []);
3194
+ const error = useCallback8((title, description, duration = 8e3) => {
3195
+ toaster.create({
3196
+ title,
3197
+ description,
3198
+ type: "error",
3199
+ duration,
3200
+ closable: true
3201
+ });
3202
+ }, []);
3203
+ const warning = useCallback8((title, description, duration = 6e3) => {
3204
+ toaster.create({
3205
+ title,
3206
+ description,
3207
+ type: "warning",
3208
+ duration,
3209
+ closable: true
3210
+ });
3211
+ }, []);
3212
+ const info = useCallback8((title, description, duration = 5e3) => {
3213
+ toaster.create({
3214
+ title,
3215
+ description,
3216
+ type: "info",
3217
+ duration,
3218
+ closable: true
3219
+ });
3220
+ }, []);
3221
+ const loading = useCallback8((title, description) => {
3222
+ return toaster.create({
3223
+ title,
3224
+ description,
3225
+ type: "loading",
3226
+ closable: false
3227
+ });
3228
+ }, []);
3229
+ const dismiss = useCallback8((id) => {
3230
+ toaster.dismiss(id);
3231
+ }, []);
3232
+ const toast = useMemo11(() => ({
3233
+ clickableSuccess,
3234
+ success,
3235
+ error,
3236
+ warning,
3237
+ info,
3238
+ loading,
3239
+ dismiss
3240
+ }), [clickableSuccess, success, error, warning, info, loading, dismiss]);
3241
+ return { toast };
3242
+ };
3243
+
3244
+ // src/hooks/useTx.tsx
3245
+ import { coins, isDeliverTxSuccess } from "@cosmjs/stargate";
3246
+ import { useChain as useChain2 } from "@interchain-kit/react";
3247
+ import BigNumber9 from "bignumber.js";
3248
+ import { useCallback as useCallback9, useMemo as useMemo12, useState as useState3 } from "react";
3249
+ var TxStatus = /* @__PURE__ */ ((TxStatus2) => {
3250
+ TxStatus2["Failed"] = "Transaction Failed";
3251
+ TxStatus2["Successful"] = "Transaction Successful";
3252
+ TxStatus2["Broadcasting"] = "Transaction Pending";
3253
+ return TxStatus2;
3254
+ })(TxStatus || {});
3255
+ var defaultFee = {
3256
+ amount: coins(2e4, getChainNativeAssetDenom()),
3257
+ gas: "500000"
3258
+ };
3259
+ var useSDKTx = (chainName) => {
3260
+ const { tx, progressTrack } = useTx(chainName != null ? chainName : getChainName(), true, false);
3261
+ return {
3262
+ tx,
3263
+ progressTrack
3264
+ };
3265
+ };
3266
+ var useBZETx = () => {
3267
+ const { tx, progressTrack } = useTx(getChainName(), false, false);
3268
+ return {
3269
+ tx,
3270
+ progressTrack
3271
+ };
3272
+ };
3273
+ var useIBCTx = (chainName) => {
3274
+ const { tx, progressTrack } = useTx(chainName != null ? chainName : getChainName(), false, true);
3275
+ return {
3276
+ tx,
3277
+ progressTrack
3278
+ };
3279
+ };
3280
+ var useTx = (chainName, isCosmos, isIBC) => {
3281
+ const { address, disconnect } = useChain2(chainName);
3282
+ const { toast } = useToast();
3283
+ const { signingClient, isSigningClientReady, signingClientError } = useSigningClient({ chainName, isCosmos, isIbc: isIBC });
3284
+ const [progressTrack, setProgressTrack] = useState3("");
3285
+ const { getDenomsPool } = useLiquidityPools();
3286
+ const { feeDenom } = useSettings();
3287
+ const defaultChainName = useMemo12(() => getChainName(), []);
3288
+ const canUseClient = useCallback9(async () => {
3289
+ if (!isSigningClientReady) {
3290
+ console.error("waiting for signing client to be ready", signingClientError);
3291
+ await sleep(1e3);
3292
+ }
3293
+ return isSigningClientReady;
3294
+ }, [isSigningClientReady, signingClientError]);
3295
+ const simulateFee = useCallback9(async (messages, memo) => {
3296
+ const gasPrice = 0.02;
3297
+ const nativeDenom = getChainNativeAssetDenom();
3298
+ const gasEstimated = await signingClient.simulate(address, messages, memo);
3299
+ const gasAmount = BigNumber9(gasEstimated).multipliedBy(1.5);
3300
+ const gasPayment = gasAmount.multipliedBy(gasPrice);
3301
+ const nativeFee = {
3302
+ amount: coins(gasPayment.toFixed(0).toString(), nativeDenom),
3303
+ gas: gasAmount.toFixed(0)
3304
+ };
3305
+ if (feeDenom === nativeDenom) {
3306
+ return nativeFee;
3307
+ }
3308
+ const pool = getDenomsPool(feeDenom, nativeDenom);
3309
+ if (!pool) {
3310
+ return nativeFee;
3311
+ }
3312
+ let expectedAmount = calculatePoolOppositeAmount(pool, gasPayment, pool.base === nativeDenom);
3313
+ if (!expectedAmount.isPositive()) {
3314
+ return nativeFee;
3315
+ }
3316
+ expectedAmount = expectedAmount.multipliedBy(1.5).integerValue(BigNumber9.ROUND_FLOOR);
3317
+ if (expectedAmount.multipliedBy(pool.fee).lt(1)) {
3318
+ expectedAmount = toBigNumber(1).dividedBy(pool.fee).integerValue(BigNumber9.ROUND_CEIL);
3319
+ }
3320
+ return {
3321
+ amount: coins(expectedAmount.toFixed(0).toString(), feeDenom),
3322
+ gas: gasAmount.multipliedBy(1.5).toFixed(0)
3323
+ };
3324
+ }, [signingClient, address, feeDenom, getDenomsPool]);
3325
+ const getFee = useCallback9(async (messages, options) => {
3326
+ try {
3327
+ if (options == null ? void 0 : options.fee) {
3328
+ return options.fee;
3329
+ } else {
3330
+ setProgressTrack("Simulating transaction");
3331
+ return await simulateFee(messages, options == null ? void 0 : options.memo);
3332
+ }
3333
+ } catch (e) {
3334
+ console.error("could not get fee: ", e);
3335
+ if (options == null ? void 0 : options.fallbackOnSimulate) {
3336
+ return defaultFee;
3337
+ } else {
3338
+ throw e;
3339
+ }
3340
+ }
3341
+ }, [simulateFee]);
3342
+ const tx = useCallback9(async (msgs, options) => {
3343
+ var _a2;
3344
+ if (!address) {
3345
+ toast.error("Transaction Failed" /* Failed */, "Please connect the wallet");
3346
+ return;
3347
+ }
3348
+ if (!await canUseClient()) {
3349
+ toast.error("Transaction Failed" /* Failed */, "Can not find suitable signing client. Make sure your wallet is installed, connected and unlocked.");
3350
+ disconnect();
3351
+ return;
3352
+ }
3353
+ setProgressTrack("Getting fee");
3354
+ const broadcastToastId = toast.loading("Transaction Pending" /* Broadcasting */, "Waiting for transaction to be signed and included in block");
3355
+ if (signingClient) {
3356
+ try {
3357
+ const fee = await getFee(msgs, options);
3358
+ setProgressTrack("Signing transaction");
3359
+ const resp = await signingClient.signAndBroadcast(address, msgs, fee, (_a2 = options == null ? void 0 : options.memo) != null ? _a2 : DEFAULT_TX_MEMO);
3360
+ if (isDeliverTxSuccess(resp)) {
3361
+ setProgressTrack("Transaction sent");
3362
+ toast.clickableSuccess("Transaction Successful" /* Successful */, () => {
3363
+ openExternalLink(`${getChainExplorerURL(chainName != null ? chainName : defaultChainName)}/tx/${resp.transactionHash}`);
3364
+ }, "View in Explorer");
3365
+ if (options == null ? void 0 : options.onSuccess) {
3366
+ options.onSuccess(resp);
3367
+ }
3368
+ } else {
3369
+ setProgressTrack("Transaction failed");
3370
+ toast.error("Transaction Failed" /* Failed */, prettyError(resp == null ? void 0 : resp.rawLog));
3371
+ if (options == null ? void 0 : options.onFailure) {
3372
+ options.onFailure(prettyError(resp == null ? void 0 : resp.rawLog) || "Unknown error");
3373
+ }
3374
+ }
3375
+ } catch (e) {
3376
+ console.error(e);
3377
+ if (e.message.includes("Failed to retrieve account from signer")) {
3378
+ disconnect();
3379
+ }
3380
+ toast.error("Transaction Failed" /* Failed */, prettyError(e == null ? void 0 : e.message));
3381
+ if (options == null ? void 0 : options.onFailure) {
3382
+ options.onFailure(prettyError(e == null ? void 0 : e.message) || "Unknown error");
3383
+ }
3384
+ }
3385
+ }
3386
+ toast.dismiss(broadcastToastId);
3387
+ setTimeout(() => {
3388
+ setProgressTrack("");
3389
+ }, (options == null ? void 0 : options.progressTrackerTimeout) || 5e3);
3390
+ }, [address, canUseClient, toast, signingClient, disconnect, getFee, chainName, defaultChainName]);
3391
+ return {
3392
+ tx,
3393
+ progressTrack
3394
+ };
3395
+ };
3396
+
3397
+ // src/components/highlight.tsx
3398
+ import { Text } from "@chakra-ui/react";
3399
+ import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
3400
+ import { jsx as jsx2 } from "react/jsx-runtime";
3401
+ var HighlightText = (_a2) => {
3402
+ var _b2 = _a2, {
3403
+ duration = 200,
3404
+ highlightOnMount = false,
3405
+ highlightColor = "blue.500",
3406
+ highlightIntensity = "subtle",
3407
+ children
3408
+ } = _b2, textProps = __objRest(_b2, [
3409
+ "duration",
3410
+ "highlightOnMount",
3411
+ "highlightColor",
3412
+ "highlightIntensity",
3413
+ "children"
3414
+ ]);
3415
+ const [isHighlighted, setIsHighlighted] = useState4(false);
3416
+ const isMountedRef = useRef2(false);
3417
+ const timeoutRef = useRef2(void 0);
3418
+ const childrenString = String(children);
3419
+ const previousValueRef = useRef2(childrenString);
3420
+ const highlightOpacity = highlightIntensity === "subtle" ? "15" : "50";
3421
+ const boxShadowStrength = highlightIntensity === "subtle" ? "10" : "25";
3422
+ useEffect3(() => {
3423
+ if (!isMountedRef.current) {
3424
+ isMountedRef.current = true;
3425
+ if (highlightOnMount) {
3426
+ setIsHighlighted(true);
3427
+ timeoutRef.current = setTimeout(() => {
3428
+ setIsHighlighted(false);
3429
+ }, duration);
3430
+ }
3431
+ previousValueRef.current = childrenString;
3432
+ return;
3433
+ }
3434
+ if (previousValueRef.current !== childrenString) {
3435
+ if (timeoutRef.current) {
3436
+ clearTimeout(timeoutRef.current);
3437
+ }
3438
+ setIsHighlighted(true);
3439
+ timeoutRef.current = setTimeout(() => {
3440
+ setIsHighlighted(false);
3441
+ }, duration);
3442
+ previousValueRef.current = childrenString;
3443
+ }
3444
+ return () => {
3445
+ if (timeoutRef.current) {
3446
+ clearTimeout(timeoutRef.current);
3447
+ }
3448
+ };
3449
+ }, [childrenString, duration, highlightOnMount]);
3450
+ return /* @__PURE__ */ jsx2(
3451
+ Text,
3452
+ __spreadProps(__spreadValues({}, textProps), {
3453
+ transition: `all ${duration}ms ease-out`,
3454
+ bg: isHighlighted ? `${highlightColor}/${highlightOpacity}` : "transparent",
3455
+ boxShadow: isHighlighted ? `0 0 0 ${highlightIntensity === "evident" ? "4px" : "3px"} ${highlightColor}/${boxShadowStrength}` : "none",
3456
+ borderRadius: "md",
3457
+ px: isHighlighted ? "2" : "0",
3458
+ transform: isHighlighted && highlightIntensity === "evident" ? "scale(1.02)" : "scale(1)",
3459
+ fontWeight: isHighlighted && highlightIntensity === "evident" ? "semibold" : textProps.fontWeight,
3460
+ children
3461
+ })
3462
+ );
3463
+ };
3464
+
3465
+ // src/components/sidebar/sidebar.tsx
3466
+ import { Icon, IconButton, Portal as Portal2 } from "@chakra-ui/react";
3467
+ import { LuX } from "react-icons/lu";
3468
+ import { useState as useState5 } from "react";
3469
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
3470
+ var Sidebar = ({ children, trigger, ariaLabel }) => {
3471
+ const [isOpen, setIsOpen] = useState5(false);
3472
+ const handleTriggerClick = () => {
3473
+ setIsOpen(true);
3474
+ };
3475
+ const handleClose = () => {
3476
+ setIsOpen(false);
3477
+ };
3478
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
3479
+ /* @__PURE__ */ jsx3("div", { onClick: handleTriggerClick, style: { cursor: "pointer" }, children: trigger }),
3480
+ isOpen && /* @__PURE__ */ jsxs2(Portal2, { children: [
3481
+ /* @__PURE__ */ jsx3(
3482
+ "div",
3483
+ {
3484
+ style: {
3485
+ position: "fixed",
3486
+ top: 0,
3487
+ left: 0,
3488
+ right: 0,
3489
+ bottom: 0,
3490
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
3491
+ zIndex: "3",
3492
+ display: "block"
3493
+ },
3494
+ onClick: (e) => {
3495
+ if (e.target === e.currentTarget) {
3496
+ handleClose();
3497
+ }
3498
+ }
3499
+ }
3500
+ ),
3501
+ /* @__PURE__ */ jsxs2(
3502
+ "div",
3503
+ {
3504
+ id: "sidebar-content",
3505
+ style: {
3506
+ position: "fixed",
3507
+ top: 0,
3508
+ right: 0,
3509
+ bottom: 0,
3510
+ width: window.innerWidth < 768 ? "100vw" : "20vw",
3511
+ minWidth: window.innerWidth < 768 ? "100vw" : "300px",
3512
+ maxWidth: window.innerWidth < 768 ? "100vw" : "400px",
3513
+ backgroundColor: "var(--chakra-colors-bg-panel)",
3514
+ borderLeft: "1px solid var(--chakra-colors-border-subtle)",
3515
+ boxShadow: window.innerWidth >= 768 ? "-4px 0 12px rgba(0, 0, 0, 0.15)" : "none",
3516
+ zIndex: "99",
3517
+ display: "flex",
3518
+ flexDirection: "column",
3519
+ overflow: "hidden"
3520
+ },
3521
+ children: [
3522
+ /* @__PURE__ */ jsxs2(
3523
+ "div",
3524
+ {
3525
+ style: {
3526
+ display: "flex",
3527
+ justifyContent: "space-between",
3528
+ alignItems: "center",
3529
+ padding: "1rem",
3530
+ borderBottom: "1px solid var(--chakra-colors-border-subtle)",
3531
+ backgroundColor: "var(--chakra-colors-bg-panel)",
3532
+ flexShrink: 0
3533
+ },
3534
+ children: [
3535
+ /* @__PURE__ */ jsx3(
3536
+ "h3",
3537
+ {
3538
+ style: {
3539
+ fontSize: "1.125rem",
3540
+ fontWeight: "600",
3541
+ margin: 0,
3542
+ color: "var(--chakra-colors-fg)"
3543
+ },
3544
+ children: ariaLabel
3545
+ }
3546
+ ),
3547
+ /* @__PURE__ */ jsx3(
3548
+ IconButton,
3549
+ {
3550
+ "aria-label": "Close sidebar",
3551
+ variant: "ghost",
3552
+ size: "sm",
3553
+ onClick: handleClose,
3554
+ children: /* @__PURE__ */ jsx3(Icon, { size: "md", children: /* @__PURE__ */ jsx3(LuX, {}) })
3555
+ }
3556
+ )
3557
+ ]
3558
+ }
3559
+ ),
3560
+ /* @__PURE__ */ jsx3(
3561
+ "div",
3562
+ {
3563
+ style: {
3564
+ padding: "1rem",
3565
+ flex: 1,
3566
+ overflowY: "auto",
3567
+ backgroundColor: "var(--chakra-colors-bg-panel)",
3568
+ position: "relative"
3569
+ },
3570
+ children
3571
+ }
3572
+ )
3573
+ ]
3574
+ }
3575
+ )
3576
+ ] })
3577
+ ] });
3578
+ };
3579
+
3580
+ // src/components/sidebar/settings-sidebar.tsx
3581
+ import {
3582
+ VStack,
3583
+ HStack,
3584
+ Text as Text2,
3585
+ Switch,
3586
+ Button,
3587
+ Separator,
3588
+ Box,
3589
+ Input,
3590
+ Badge,
3591
+ createListCollection
3592
+ } from "@chakra-ui/react";
3593
+ import { Select, Portal as Portal3 } from "@chakra-ui/react";
3594
+ import { useTheme } from "next-themes";
3595
+ import { useState as useState6, useEffect as useEffect4, useMemo as useMemo13, useCallback as useCallback10 } from "react";
3596
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
3597
+ var SettingsSidebarContent = ({ accentColor = "blue" }) => {
3598
+ const { setTheme, resolvedTheme } = useTheme();
3599
+ const { toast } = useToast();
3600
+ const { settings, isLoaded, updateEndpoints, updatePreferredFeeDenom, defaultSettings } = useSettings();
3601
+ const { connectionType } = useConnectionType();
3602
+ const { feeTokens, isLoading: feeTokensLoading } = useFeeTokens();
3603
+ const [restEndpoint, setRestEndpoint] = useState6("");
3604
+ const [rpcEndpoint, setRpcEndpoint] = useState6("");
3605
+ const [isValidating, setIsValidating] = useState6(false);
3606
+ const [validationResults, setValidationResults] = useState6({});
3607
+ const [preferredFeeDenom, setPreferredFeeDenom] = useState6(void 0);
3608
+ useEffect4(() => {
3609
+ if (isLoaded) {
3610
+ setRestEndpoint(settings.endpoints.restEndpoint);
3611
+ setRpcEndpoint(settings.endpoints.rpcEndpoint);
3612
+ setPreferredFeeDenom(settings.preferredFeeDenom || getChainNativeAssetDenom());
3613
+ }
3614
+ }, [isLoaded, settings]);
3615
+ const handleValidateEndpoints = useCallback10(async (rest, rpc) => {
3616
+ setIsValidating(true);
3617
+ setValidationResults({});
3618
+ try {
3619
+ const results = await validateEndpoints(rest, rpc);
3620
+ setValidationResults({
3621
+ rest: results.rest,
3622
+ rpc: results.rpc
3623
+ });
3624
+ } catch (error) {
3625
+ console.error(error);
3626
+ setValidationResults({
3627
+ rest: { isValid: false, error: "Validation failed" },
3628
+ rpc: { isValid: false, error: "Validation failed" }
3629
+ });
3630
+ } finally {
3631
+ setIsValidating(false);
3632
+ setTimeout(() => setValidationResults({}), 1e4);
3633
+ }
3634
+ }, []);
3635
+ const handleSaveSettings = useCallback10(async (rest, rpc, feeDenom) => {
3636
+ setValidationResults({});
3637
+ const results = await validateEndpoints(rest, rpc);
3638
+ if (!results.isValid) {
3639
+ setValidationResults({
3640
+ rest: results.rest,
3641
+ rpc: results.rpc
3642
+ });
3643
+ setTimeout(() => setValidationResults({}), 1e4);
3644
+ return;
3645
+ }
3646
+ const endpointsSuccess = updateEndpoints({
3647
+ restEndpoint: rest.trim(),
3648
+ rpcEndpoint: convertToWebSocketUrl(rpc.trim())
3649
+ });
3650
+ const feeTokenSuccess = updatePreferredFeeDenom(feeDenom);
3651
+ if (endpointsSuccess && feeTokenSuccess) {
3652
+ toast.success("Success!", "Settings have been saved.");
3653
+ }
3654
+ }, []);
3655
+ const handleResetToDefaults = useCallback10(() => {
3656
+ setRestEndpoint(defaultSettings.endpoints.restEndpoint);
3657
+ setRpcEndpoint(defaultSettings.endpoints.rpcEndpoint);
3658
+ setPreferredFeeDenom(defaultSettings.preferredFeeDenom);
3659
+ setValidationResults({});
3660
+ }, []);
3661
+ const connectionStatusText = useMemo13(() => {
3662
+ switch (connectionType) {
3663
+ case CONNECTION_TYPE_NONE:
3664
+ return "Failed";
3665
+ case CONNECTION_TYPE_POLLING:
3666
+ return "Polling";
3667
+ case CONNECTION_TYPE_WS:
3668
+ return "Connected";
3669
+ }
3670
+ }, [connectionType]);
3671
+ const connectionStatusBadgeColor = useMemo13(() => {
3672
+ switch (connectionType) {
3673
+ case CONNECTION_TYPE_NONE:
3674
+ return "red";
3675
+ case CONNECTION_TYPE_POLLING:
3676
+ return "orange";
3677
+ case CONNECTION_TYPE_WS:
3678
+ return "green";
3679
+ }
3680
+ }, [connectionType]);
3681
+ const feeTokensCollection = useMemo13(() => createListCollection({
3682
+ items: feeTokens.map((token) => ({
3683
+ label: token.ticker || token.name,
3684
+ value: token.denom,
3685
+ name: token.ticker || token.name
3686
+ }))
3687
+ }), [feeTokens]);
3688
+ const handleFeeTokenChange = useCallback10((denom) => {
3689
+ setPreferredFeeDenom(denom || void 0);
3690
+ }, []);
3691
+ const hasUnsavedChanges = restEndpoint !== settings.endpoints.restEndpoint || rpcEndpoint !== settings.endpoints.rpcEndpoint || preferredFeeDenom !== settings.preferredFeeDenom;
3692
+ return /* @__PURE__ */ jsxs3(VStack, { gap: "6", align: "stretch", children: [
3693
+ /* @__PURE__ */ jsxs3(Box, { children: [
3694
+ /* @__PURE__ */ jsx4(Text2, { fontSize: "sm", fontWeight: "medium", mb: "3", children: "Appearance" }),
3695
+ /* @__PURE__ */ jsx4(VStack, { gap: "3", align: "stretch", children: /* @__PURE__ */ jsxs3(HStack, { justify: "space-between", children: [
3696
+ /* @__PURE__ */ jsx4(Text2, { fontSize: "sm", children: "Dark Mode" }),
3697
+ /* @__PURE__ */ jsxs3(
3698
+ Switch.Root,
3699
+ {
3700
+ checked: resolvedTheme === "dark",
3701
+ onCheckedChange: (details) => {
3702
+ const newTheme = details.checked ? "dark" : "light";
3703
+ setTheme(newTheme);
3704
+ },
3705
+ children: [
3706
+ /* @__PURE__ */ jsx4(Switch.HiddenInput, {}),
3707
+ /* @__PURE__ */ jsx4(Switch.Control, { children: /* @__PURE__ */ jsx4(Switch.Thumb, {}) })
3708
+ ]
3709
+ }
3710
+ )
3711
+ ] }) })
3712
+ ] }),
3713
+ /* @__PURE__ */ jsx4(Separator, {}),
3714
+ /* @__PURE__ */ jsxs3(Box, { children: [
3715
+ /* @__PURE__ */ jsx4(Text2, { fontSize: "sm", fontWeight: "medium", mb: "3", children: "Fee Token Preference" }),
3716
+ /* @__PURE__ */ jsx4(VStack, { gap: "3", align: "stretch", children: /* @__PURE__ */ jsxs3(Box, { children: [
3717
+ /* @__PURE__ */ jsxs3(
3718
+ Select.Root,
3719
+ {
3720
+ collection: feeTokensCollection,
3721
+ size: "sm",
3722
+ value: preferredFeeDenom ? [preferredFeeDenom] : [""],
3723
+ onValueChange: (details) => handleFeeTokenChange(details.value[0] || ""),
3724
+ disabled: feeTokensLoading,
3725
+ children: [
3726
+ /* @__PURE__ */ jsx4(Select.Label, { children: "Preferred Fee Token" }),
3727
+ /* @__PURE__ */ jsx4(Select.HiddenSelect, {}),
3728
+ /* @__PURE__ */ jsxs3(Select.Control, { children: [
3729
+ /* @__PURE__ */ jsx4(Select.Trigger, { children: /* @__PURE__ */ jsx4(Select.ValueText, { placeholder: "Native Token (default)" }) }),
3730
+ /* @__PURE__ */ jsx4(Select.IndicatorGroup, { children: /* @__PURE__ */ jsx4(Select.Indicator, {}) })
3731
+ ] }),
3732
+ /* @__PURE__ */ jsx4(Portal3, { children: /* @__PURE__ */ jsx4(Select.Positioner, { children: /* @__PURE__ */ jsx4(Select.Content, { children: feeTokensCollection.items.map((item) => /* @__PURE__ */ jsxs3(Select.Item, { item, children: [
3733
+ /* @__PURE__ */ jsx4(Text2, { children: item.label }),
3734
+ /* @__PURE__ */ jsx4(Select.ItemIndicator, {})
3735
+ ] }, item.value)) }) }) })
3736
+ ]
3737
+ }
3738
+ ),
3739
+ /* @__PURE__ */ jsx4(Text2, { fontSize: "xs", color: "fg.muted", mt: "2", children: "Select your preferred token for paying transaction fees. Only tokens with liquidity pools paired with the native token are available." })
3740
+ ] }) })
3741
+ ] }),
3742
+ /* @__PURE__ */ jsx4(Separator, {}),
3743
+ /* @__PURE__ */ jsxs3(Box, { children: [
3744
+ /* @__PURE__ */ jsx4(Text2, { fontSize: "sm", fontWeight: "medium", mb: "3", children: "BeeZee Endpoints" }),
3745
+ /* @__PURE__ */ jsxs3(VStack, { gap: "4", align: "stretch", children: [
3746
+ /* @__PURE__ */ jsx4(Box, { children: /* @__PURE__ */ jsxs3(HStack, { gap: "2", align: "center", justify: "space-between", children: [
3747
+ /* @__PURE__ */ jsx4(Text2, { fontSize: "sm", mb: "1", children: "Status: " }),
3748
+ /* @__PURE__ */ jsx4(Badge, { colorPalette: connectionStatusBadgeColor, children: connectionStatusText })
3749
+ ] }) }),
3750
+ /* @__PURE__ */ jsxs3(Box, { children: [
3751
+ /* @__PURE__ */ jsx4(Text2, { fontSize: "sm", mb: "1", children: "REST Endpoint" }),
3752
+ /* @__PURE__ */ jsx4(Text2, { fontSize: "xs", color: "fg.muted", mb: "2", children: "Note: Endpoint must have CORS enabled to work in browser" }),
3753
+ /* @__PURE__ */ jsx4(
3754
+ Input,
3755
+ {
3756
+ size: "sm",
3757
+ placeholder: "https://rest.getbze.com",
3758
+ value: restEndpoint,
3759
+ onChange: (e) => setRestEndpoint(e.target.value)
3760
+ }
3761
+ ),
3762
+ validationResults.rest && /* @__PURE__ */ jsx4(
3763
+ Box,
3764
+ {
3765
+ mt: "2",
3766
+ p: "3",
3767
+ bgGradient: "to-br",
3768
+ gradientFrom: validationResults.rest.isValid ? "green.500/15" : "red.500/15",
3769
+ gradientTo: validationResults.rest.isValid ? "green.600/15" : "red.600/15",
3770
+ borderWidth: "1px",
3771
+ borderColor: validationResults.rest.isValid ? "green.500/30" : "red.500/30",
3772
+ borderRadius: "md",
3773
+ children: /* @__PURE__ */ jsx4(Text2, { fontSize: "sm", color: validationResults.rest.isValid ? "green.700" : "red.700", _dark: { color: validationResults.rest.isValid ? "green.300" : "red.300" }, children: validationResults.rest.error || "REST endpoint is valid" })
3774
+ }
3775
+ )
3776
+ ] }),
3777
+ /* @__PURE__ */ jsxs3(Box, { children: [
3778
+ /* @__PURE__ */ jsx4(Text2, { fontSize: "sm", mb: "1", children: "RPC Endpoint" }),
3779
+ /* @__PURE__ */ jsx4(Text2, { fontSize: "xs", color: "fg.muted", mb: "2", children: "Note: Must support WebSocket (WS/WSS) connections" }),
3780
+ /* @__PURE__ */ jsx4(
3781
+ Input,
3782
+ {
3783
+ size: "sm",
3784
+ placeholder: "wss://rpc.getbze.com",
3785
+ value: rpcEndpoint,
3786
+ onChange: (e) => setRpcEndpoint(e.target.value)
3787
+ }
3788
+ ),
3789
+ validationResults.rpc && /* @__PURE__ */ jsx4(
3790
+ Box,
3791
+ {
3792
+ mt: "2",
3793
+ p: "3",
3794
+ bgGradient: "to-br",
3795
+ gradientFrom: validationResults.rpc.isValid ? "green.500/15" : "red.500/15",
3796
+ gradientTo: validationResults.rpc.isValid ? "green.600/15" : "red.600/15",
3797
+ borderWidth: "1px",
3798
+ borderColor: validationResults.rpc.isValid ? "green.500/30" : "red.500/30",
3799
+ borderRadius: "md",
3800
+ children: /* @__PURE__ */ jsx4(Text2, { fontSize: "sm", color: validationResults.rpc.isValid ? "green.700" : "red.700", _dark: { color: validationResults.rpc.isValid ? "green.300" : "red.300" }, children: validationResults.rpc.error || "RPC endpoint is valid" })
3801
+ }
3802
+ )
3803
+ ] }),
3804
+ /* @__PURE__ */ jsx4(
3805
+ Button,
3806
+ {
3807
+ size: "sm",
3808
+ variant: "outline",
3809
+ onClick: () => handleValidateEndpoints(restEndpoint, rpcEndpoint),
3810
+ loading: isValidating,
3811
+ disabled: !restEndpoint.trim() || !rpcEndpoint.trim(),
3812
+ children: isValidating ? "Validating..." : "Validate Endpoints"
3813
+ }
3814
+ )
3815
+ ] })
3816
+ ] }),
3817
+ /* @__PURE__ */ jsx4(Box, { children: /* @__PURE__ */ jsxs3(VStack, { gap: "3", children: [
3818
+ /* @__PURE__ */ jsx4(
3819
+ Button,
3820
+ {
3821
+ size: "sm",
3822
+ width: "full",
3823
+ onClick: () => handleSaveSettings(restEndpoint, rpcEndpoint, preferredFeeDenom),
3824
+ colorPalette: accentColor,
3825
+ disabled: !hasUnsavedChanges,
3826
+ children: "Save Settings"
3827
+ }
3828
+ ),
3829
+ /* @__PURE__ */ jsx4(
3830
+ Button,
3831
+ {
3832
+ size: "sm",
3833
+ width: "full",
3834
+ variant: "outline",
3835
+ onClick: handleResetToDefaults,
3836
+ children: "Reset to Defaults"
3837
+ }
3838
+ )
3839
+ ] }) })
3840
+ ] });
3841
+ };
3842
+
3843
+ // src/components/sidebar/wallet-sidebar.tsx
3844
+ import "@interchain-kit/react/styles.css";
3845
+ import { InterchainWalletModal, useChain as useChain3 } from "@interchain-kit/react";
3846
+ import {
3847
+ Badge as Badge2,
3848
+ Box as Box2,
3849
+ Button as Button2,
3850
+ createListCollection as createListCollection2,
3851
+ Field,
3852
+ Group,
3853
+ HStack as HStack2,
3854
+ Image,
3855
+ Input as Input2,
3856
+ Portal as Portal4,
3857
+ Select as Select2,
3858
+ Separator as Separator2,
3859
+ Text as Text3,
3860
+ Textarea,
3861
+ VStack as VStack2
3862
+ } from "@chakra-ui/react";
3863
+ import { LuCopy, LuExternalLink, LuX as LuX2 } from "react-icons/lu";
3864
+ import { useCallback as useCallback11, useEffect as useEffect5, useMemo as useMemo14, useRef as useRef3, useState as useState7 } from "react";
3865
+ import { WalletState } from "@interchain-kit/core";
3866
+ import BigNumber10 from "bignumber.js";
3867
+ import { cosmos } from "@bze/bzejs";
3868
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
3869
+ var validateAmount = (amount, coin, onError) => {
3870
+ if (!coin) return;
3871
+ if (amount === "") return;
3872
+ const amountNumber = BigNumber10(amount);
3873
+ if (amountNumber.isNaN()) {
3874
+ onError("Invalid amount");
3875
+ return;
3876
+ }
3877
+ const coinBalance = uAmountToBigNumberAmount(coin.amount, coin.decimals);
3878
+ if (coinBalance.isLessThan(amount)) {
3879
+ onError("Insufficient balance");
3880
+ } else {
3881
+ onError("");
3882
+ }
3883
+ };
3884
+ var BalanceItem = ({ asset, onClick, accentColor }) => {
3885
+ const [showSendButton, setShowSendButton] = useState7(false);
3886
+ const formattedBalanceAmount = useMemo14(() => {
3887
+ var _a2;
3888
+ return prettyAmount(uAmountToBigNumberAmount(asset.amount, (_a2 = asset.decimals) != null ? _a2 : 0));
3889
+ }, [asset.amount, asset.decimals]);
3890
+ const formattedBalanceUSDValue = useMemo14(() => {
3891
+ return shortNumberFormat(asset.USDValue);
3892
+ }, [asset.USDValue]);
3893
+ return /* @__PURE__ */ jsxs4(
3894
+ Box2,
3895
+ {
3896
+ p: "3",
3897
+ bgGradient: "to-br",
3898
+ gradientFrom: `${accentColor}.500/5`,
3899
+ gradientTo: `${accentColor}.600/5`,
3900
+ borderRadius: "md",
3901
+ borderWidth: "1px",
3902
+ borderColor: `${accentColor}.500/15`,
3903
+ _hover: {
3904
+ gradientFrom: `${accentColor}.500/10`,
3905
+ gradientTo: `${accentColor}.600/10`,
3906
+ borderColor: `${accentColor}.500/25`
3907
+ },
3908
+ transition: "all 0.2s",
3909
+ onMouseLeave: () => setShowSendButton(false),
3910
+ onMouseEnter: () => setShowSendButton(true),
3911
+ children: [
3912
+ /* @__PURE__ */ jsxs4(HStack2, { justify: "space-between", mb: "2", children: [
3913
+ /* @__PURE__ */ jsxs4(HStack2, { children: [
3914
+ /* @__PURE__ */ jsx5(
3915
+ Image,
3916
+ {
3917
+ src: asset.logo,
3918
+ alt: asset.ticker,
3919
+ width: "20px",
3920
+ height: "20px",
3921
+ borderRadius: "full"
3922
+ }
3923
+ ),
3924
+ /* @__PURE__ */ jsx5(Text3, { fontSize: "sm", fontWeight: "medium", children: asset.ticker }),
3925
+ /* @__PURE__ */ jsx5(Text3, { fontSize: "xs", color: "fg.muted", children: asset.name }),
3926
+ isIbcDenom(asset.denom) && /* @__PURE__ */ jsx5(Badge2, { size: "xs", colorPalette: accentColor, children: "IBC" })
3927
+ ] }),
3928
+ showSendButton && /* @__PURE__ */ jsx5(HStack2, { justify: "end", children: /* @__PURE__ */ jsx5(Button2, { size: "2xs", variant: "outline", onClick, children: "Send" }) })
3929
+ ] }),
3930
+ /* @__PURE__ */ jsxs4(HStack2, { justify: "space-between", children: [
3931
+ /* @__PURE__ */ jsx5(HighlightText, { fontSize: "sm", fontFamily: "mono", children: formattedBalanceAmount }),
3932
+ /* @__PURE__ */ jsxs4(HighlightText, { fontSize: "sm", color: "fg.muted", children: [
3933
+ "$",
3934
+ formattedBalanceUSDValue
3935
+ ] })
3936
+ ] })
3937
+ ]
3938
+ }
3939
+ );
3940
+ };
3941
+ var SendForm = ({ balances, onClose, selectedTicker, accentColor }) => {
3942
+ const [isLoading, setIsLoading] = useState7(false);
3943
+ const [selectedCoin, setSelectedCoin] = useState7();
3944
+ const [sendAmount, setSendAmount] = useState7("");
3945
+ const [sendAmountError, setSendAmountError] = useState7("");
3946
+ const [recipient, setRecipient] = useState7("");
3947
+ const [recipientError, setRecipientError] = useState7("");
3948
+ const [memo, setMemo] = useState7("");
3949
+ const [memoError, setMemoError] = useState7("");
3950
+ const { toast } = useToast();
3951
+ const { status, address } = useChain3(getChainName());
3952
+ const { tx } = useSDKTx(getChainName());
3953
+ const coinsCollection = createListCollection2({
3954
+ items: balances.map((item) => {
3955
+ var _a2;
3956
+ return {
3957
+ label: `${item.ticker} - ${shortNumberFormat(uAmountToBigNumberAmount(item.amount, (_a2 = item == null ? void 0 : item.decimals) != null ? _a2 : 0))}`,
3958
+ value: item.ticker,
3959
+ logo: item.logo
3960
+ };
3961
+ })
3962
+ });
3963
+ const isValidForm = useMemo14(() => {
3964
+ return selectedCoin && memoError === "" && recipientError === "" && sendAmountError === "" && sendAmount !== "" && recipient !== "";
3965
+ }, [selectedCoin, memoError, recipientError, sendAmountError, sendAmount, recipient]);
3966
+ const resetSendForm = useCallback11(() => {
3967
+ setSelectedCoin(void 0);
3968
+ setSendAmount("");
3969
+ setRecipient("");
3970
+ setMemo("");
3971
+ }, []);
3972
+ const handleSend = useCallback11(async () => {
3973
+ var _a2, _b2;
3974
+ if (!isValidForm) {
3975
+ toast.error("Can not send coins!", "Please check the input data.");
3976
+ return;
3977
+ }
3978
+ if (status !== WalletState.Connected) {
3979
+ toast.error("Wallet not connected!", "Please connect your wallet first.");
3980
+ return;
3981
+ }
3982
+ const { send } = cosmos.bank.v1beta1.MessageComposer.withTypeUrl;
3983
+ const msg = send({
3984
+ fromAddress: address,
3985
+ toAddress: recipient,
3986
+ amount: [{
3987
+ denom: (_a2 = selectedCoin == null ? void 0 : selectedCoin.denom) != null ? _a2 : "",
3988
+ amount: amountToUAmount(sendAmount, (_b2 = selectedCoin == null ? void 0 : selectedCoin.decimals) != null ? _b2 : 0)
3989
+ }]
3990
+ });
3991
+ setIsLoading(true);
3992
+ await tx([msg], { memo: memo.length > 0 ? memo : void 0 });
3993
+ resetSendForm();
3994
+ setIsLoading(false);
3995
+ onClose();
3996
+ }, [address, memo, onClose, recipient, selectedCoin, sendAmount, status]);
3997
+ const handleCancel = useCallback11(() => {
3998
+ resetSendForm();
3999
+ onClose();
4000
+ }, [onClose, resetSendForm]);
4001
+ const onRecipientChange = useCallback11((recipient2) => {
4002
+ setRecipient(recipient2);
4003
+ if (recipient2.length === 0) {
4004
+ setRecipientError("");
4005
+ return;
4006
+ }
4007
+ const validate = validateBZEBech32Address(recipient2);
4008
+ if (validate.isValid) {
4009
+ setRecipientError("");
4010
+ } else {
4011
+ setRecipientError(validate.message);
4012
+ }
4013
+ }, []);
4014
+ const onAmountChange = useCallback11((amount) => {
4015
+ setSendAmount(sanitizeNumberInput(amount));
4016
+ setSendAmountError("");
4017
+ }, []);
4018
+ const onCoinSelectChange = useCallback11((ticker) => {
4019
+ if (ticker === "") return;
4020
+ const selectedCoin2 = balances.find((item) => item.ticker === ticker);
4021
+ if (selectedCoin2) {
4022
+ setSelectedCoin(selectedCoin2);
4023
+ validateAmount(sendAmount, selectedCoin2, setSendAmountError);
4024
+ }
4025
+ }, [sendAmount, balances]);
4026
+ const setMaxAmount = useCallback11(() => {
4027
+ if (!selectedCoin) return;
4028
+ const maxAmount = uAmountToBigNumberAmount(selectedCoin.amount, selectedCoin.decimals);
4029
+ onAmountChange(maxAmount.toString());
4030
+ validateAmount(maxAmount.toString(), selectedCoin, setSendAmountError);
4031
+ }, [selectedCoin, onAmountChange]);
4032
+ const onMemoChange = useCallback11((memo2) => {
4033
+ setMemo(memo2);
4034
+ if (memo2.length > 256) {
4035
+ setMemoError("Memo must be less than or equal to 256 characters");
4036
+ } else {
4037
+ setMemoError("");
4038
+ }
4039
+ }, []);
4040
+ useEffect5(() => {
4041
+ if (selectedTicker !== "") {
4042
+ onCoinSelectChange(selectedTicker);
4043
+ }
4044
+ }, [onCoinSelectChange, selectedTicker]);
4045
+ return /* @__PURE__ */ jsxs4(VStack2, { gap: "4", align: "stretch", children: [
4046
+ /* @__PURE__ */ jsxs4(HStack2, { justify: "space-between", align: "center", children: [
4047
+ /* @__PURE__ */ jsx5(Text3, { fontSize: "sm", fontWeight: "medium", children: "Send Coins" }),
4048
+ /* @__PURE__ */ jsx5(
4049
+ Button2,
4050
+ {
4051
+ size: "xs",
4052
+ variant: "ghost",
4053
+ onClick: handleCancel,
4054
+ disabled: isLoading,
4055
+ children: /* @__PURE__ */ jsx5(LuX2, { size: "14" })
4056
+ }
4057
+ )
4058
+ ] }),
4059
+ /* @__PURE__ */ jsxs4(Box2, { children: [
4060
+ /* @__PURE__ */ jsxs4(
4061
+ Select2.Root,
4062
+ {
4063
+ collection: coinsCollection,
4064
+ size: "sm",
4065
+ value: (selectedCoin == null ? void 0 : selectedCoin.ticker) ? [selectedCoin.ticker] : [],
4066
+ onValueChange: (details) => onCoinSelectChange(details.value[0] || ""),
4067
+ children: [
4068
+ /* @__PURE__ */ jsx5(Select2.Label, { children: "Coin" }),
4069
+ /* @__PURE__ */ jsx5(Select2.HiddenSelect, {}),
4070
+ /* @__PURE__ */ jsxs4(Select2.Control, { children: [
4071
+ /* @__PURE__ */ jsx5(Select2.Trigger, { children: /* @__PURE__ */ jsx5(Select2.ValueText, { placeholder: "Select coin" }) }),
4072
+ /* @__PURE__ */ jsx5(Select2.IndicatorGroup, { children: /* @__PURE__ */ jsx5(Select2.Indicator, {}) })
4073
+ ] }),
4074
+ /* @__PURE__ */ jsx5(Portal4, { children: /* @__PURE__ */ jsx5(Select2.Positioner, { children: /* @__PURE__ */ jsx5(Select2.Content, { children: coinsCollection.items.map((item) => /* @__PURE__ */ jsxs4(Select2.Item, { item, children: [
4075
+ /* @__PURE__ */ jsxs4(HStack2, { gap: "2", children: [
4076
+ /* @__PURE__ */ jsx5(
4077
+ Image,
4078
+ {
4079
+ src: item.logo,
4080
+ alt: item.value,
4081
+ width: "16px",
4082
+ height: "16px",
4083
+ borderRadius: "full"
4084
+ }
4085
+ ),
4086
+ /* @__PURE__ */ jsx5(Text3, { children: item.label })
4087
+ ] }),
4088
+ /* @__PURE__ */ jsx5(Select2.ItemIndicator, {})
4089
+ ] }, item.value)) }) }) })
4090
+ ]
4091
+ }
4092
+ ),
4093
+ selectedCoin && /* @__PURE__ */ jsx5(
4094
+ Box2,
4095
+ {
4096
+ mt: "2",
4097
+ p: "3",
4098
+ bgGradient: "to-br",
4099
+ gradientFrom: `${accentColor}.500/10`,
4100
+ gradientTo: `${accentColor}.600/10`,
4101
+ borderRadius: "md",
4102
+ borderWidth: "1px",
4103
+ borderColor: `${accentColor}.500/30`,
4104
+ children: /* @__PURE__ */ jsxs4(HStack2, { justify: "space-between", children: [
4105
+ /* @__PURE__ */ jsx5(Text3, { fontSize: "xs", color: "fg.muted", children: "Available:" }),
4106
+ /* @__PURE__ */ jsxs4(VStack2, { gap: "0", align: "end", children: [
4107
+ /* @__PURE__ */ jsxs4(Text3, { fontSize: "sm", fontWeight: "medium", children: [
4108
+ uAmountToAmount(selectedCoin.amount, selectedCoin.decimals),
4109
+ " ",
4110
+ selectedCoin.ticker
4111
+ ] }),
4112
+ selectedCoin.USDValue.gt(0) && /* @__PURE__ */ jsxs4(Text3, { fontSize: "xs", color: "fg.muted", children: [
4113
+ "\u2248 $",
4114
+ shortNumberFormat(selectedCoin.USDValue)
4115
+ ] })
4116
+ ] })
4117
+ ] })
4118
+ }
4119
+ )
4120
+ ] }),
4121
+ /* @__PURE__ */ jsx5(Box2, { children: /* @__PURE__ */ jsxs4(Field.Root, { invalid: sendAmountError !== "", children: [
4122
+ /* @__PURE__ */ jsx5(Field.Label, { children: "Amount" }),
4123
+ /* @__PURE__ */ jsxs4(Group, { attached: true, w: "full", maxW: "sm", children: [
4124
+ /* @__PURE__ */ jsx5(
4125
+ Input2,
4126
+ {
4127
+ size: "sm",
4128
+ placeholder: "Amount to send",
4129
+ value: sendAmount,
4130
+ onChange: (e) => onAmountChange(e.target.value),
4131
+ onBlur: () => validateAmount(sendAmount, selectedCoin, setSendAmountError)
4132
+ }
4133
+ ),
4134
+ /* @__PURE__ */ jsx5(Button2, { variant: "outline", size: "sm", onClick: setMaxAmount, disabled: isLoading, children: "Max" })
4135
+ ] }),
4136
+ /* @__PURE__ */ jsx5(Field.ErrorText, { children: sendAmountError })
4137
+ ] }) }),
4138
+ /* @__PURE__ */ jsx5(Box2, { children: /* @__PURE__ */ jsxs4(Field.Root, { invalid: recipientError !== "", children: [
4139
+ /* @__PURE__ */ jsx5(Field.Label, { children: "Recipient Address" }),
4140
+ /* @__PURE__ */ jsx5(
4141
+ Input2,
4142
+ {
4143
+ size: "sm",
4144
+ placeholder: "bze...2a1b",
4145
+ value: recipient,
4146
+ onChange: (e) => onRecipientChange(e.target.value)
4147
+ }
4148
+ ),
4149
+ /* @__PURE__ */ jsx5(Field.ErrorText, { children: recipientError })
4150
+ ] }) }),
4151
+ /* @__PURE__ */ jsx5(Box2, { children: /* @__PURE__ */ jsxs4(Field.Root, { invalid: memoError !== "", children: [
4152
+ /* @__PURE__ */ jsxs4(Field.Label, { children: [
4153
+ "Memo",
4154
+ /* @__PURE__ */ jsx5(
4155
+ Field.RequiredIndicator,
4156
+ {
4157
+ fallback: /* @__PURE__ */ jsx5(Badge2, { size: "xs", variant: "surface", children: "Optional" })
4158
+ }
4159
+ )
4160
+ ] }),
4161
+ /* @__PURE__ */ jsx5(
4162
+ Textarea,
4163
+ {
4164
+ size: "sm",
4165
+ placeholder: "Transaction memo",
4166
+ rows: 3,
4167
+ value: memo,
4168
+ onChange: (e) => onMemoChange(e.target.value),
4169
+ resize: "none"
4170
+ }
4171
+ ),
4172
+ /* @__PURE__ */ jsx5(Field.ErrorText, { children: memoError })
4173
+ ] }) }),
4174
+ /* @__PURE__ */ jsxs4(HStack2, { gap: "2", children: [
4175
+ /* @__PURE__ */ jsx5(
4176
+ Button2,
4177
+ {
4178
+ size: "sm",
4179
+ flex: "1",
4180
+ onClick: handleSend,
4181
+ colorPalette: accentColor,
4182
+ disabled: !isValidForm || isLoading,
4183
+ loading: isLoading,
4184
+ loadingText: "Sending...",
4185
+ children: "Send"
4186
+ }
4187
+ ),
4188
+ /* @__PURE__ */ jsx5(
4189
+ Button2,
4190
+ {
4191
+ size: "sm",
4192
+ flex: "1",
4193
+ variant: "outline",
4194
+ onClick: handleCancel,
4195
+ disabled: isLoading,
4196
+ children: "Cancel"
4197
+ }
4198
+ )
4199
+ ] })
4200
+ ] });
4201
+ };
4202
+ var WalletSidebarContent = ({ accentColor = "blue" }) => {
4203
+ const [viewState, setViewState] = useState7("balances");
4204
+ const [isDisconnecting, setIsDisconnecting] = useState7(false);
4205
+ const [showCopiedTooltip, setShowCopiedTooltip] = useState7(false);
4206
+ const [clickedBalance, setClickedBalance] = useState7("");
4207
+ const copyButtonRef = useRef3(null);
4208
+ const {
4209
+ status,
4210
+ username,
4211
+ address,
4212
+ disconnect,
4213
+ connect
4214
+ } = useChain3(getChainName());
4215
+ const { assetsBalances, isLoading: assetsLoading } = useBalances();
4216
+ const balancesWithoutLps = useMemo14(() => {
4217
+ if (assetsLoading) return [];
4218
+ return assetsBalances.filter((asset) => !isLpDenom(asset.denom));
4219
+ }, [assetsLoading, assetsBalances]);
4220
+ const nativeDenom = getChainNativeAssetDenom();
4221
+ const sortedBalances = useMemo14(() => {
4222
+ return balancesWithoutLps.sort((a, b) => {
4223
+ if (a.denom === nativeDenom) return -1;
4224
+ if (b.denom === nativeDenom) return 1;
4225
+ if (a.verified && !b.verified) return -1;
4226
+ if (!a.verified && b.verified) return 1;
4227
+ const aHasBalance = a.amount.gt(0);
4228
+ const bHasBalance = b.amount.gt(0);
4229
+ if (aHasBalance && !bHasBalance) return -1;
4230
+ if (!aHasBalance && bHasBalance) return 1;
4231
+ if (aHasBalance && bHasBalance) {
4232
+ return a.USDValue.gt(b.USDValue) ? -1 : 1;
4233
+ }
4234
+ return 0;
4235
+ });
4236
+ }, [balancesWithoutLps]);
4237
+ const walletAddress = useMemo14(() => stringTruncateFromCenter(address != null ? address : "", 16), [address]);
4238
+ const handleCopyAddress = () => {
4239
+ navigator.clipboard.writeText(address);
4240
+ setShowCopiedTooltip(true);
4241
+ setTimeout(() => setShowCopiedTooltip(false), 2e3);
4242
+ };
4243
+ const handleCancel = useCallback11(() => {
4244
+ setViewState("balances");
4245
+ setClickedBalance("");
4246
+ }, []);
4247
+ const onBalanceClick = useCallback11((ticker) => {
4248
+ setClickedBalance(ticker);
4249
+ setViewState("send");
4250
+ }, []);
4251
+ const handleDisconnectAll = useCallback11(async () => {
4252
+ setIsDisconnecting(true);
4253
+ try {
4254
+ console.log("Disconnected from all chains");
4255
+ } catch (error) {
4256
+ console.error("Error disconnecting:", error);
4257
+ } finally {
4258
+ disconnect();
4259
+ setIsDisconnecting(false);
4260
+ }
4261
+ }, [disconnect]);
4262
+ const renderBalancesView = () => /* @__PURE__ */ jsxs4(VStack2, { gap: "6", align: "stretch", children: [
4263
+ /* @__PURE__ */ jsxs4(Box2, { children: [
4264
+ /* @__PURE__ */ jsx5(Text3, { fontSize: "sm", fontWeight: "medium", mb: "3", children: "Balances" }),
4265
+ /* @__PURE__ */ jsx5(VStack2, { gap: "2", align: "stretch", children: sortedBalances.map((bal) => /* @__PURE__ */ jsx5(BalanceItem, { asset: bal, onClick: () => onBalanceClick(bal.ticker), accentColor }, bal.denom)) })
4266
+ ] }),
4267
+ /* @__PURE__ */ jsxs4(Box2, { children: [
4268
+ /* @__PURE__ */ jsx5(Text3, { fontSize: "sm", fontWeight: "medium", mb: "3", children: "Quick Actions" }),
4269
+ /* @__PURE__ */ jsxs4(VStack2, { gap: "2", align: "stretch", children: [
4270
+ /* @__PURE__ */ jsx5(
4271
+ Button2,
4272
+ {
4273
+ size: "sm",
4274
+ variant: "outline",
4275
+ onClick: () => setViewState("send"),
4276
+ w: "full",
4277
+ disabled: assetsLoading,
4278
+ children: "Send"
4279
+ }
4280
+ ),
4281
+ /* @__PURE__ */ jsxs4(
4282
+ Button2,
4283
+ {
4284
+ size: "sm",
4285
+ variant: "outline",
4286
+ w: "full",
4287
+ onClick: () => openExternalLink("https://go.skip.build/?src_chain=1&src_asset=ethereum-native&dest_chain=beezee-1&dest_asset=ubze"),
4288
+ children: [
4289
+ /* @__PURE__ */ jsx5(LuExternalLink, {}),
4290
+ "Cross-chain Deposit"
4291
+ ]
4292
+ }
4293
+ ),
4294
+ /* @__PURE__ */ jsxs4(
4295
+ Button2,
4296
+ {
4297
+ size: "sm",
4298
+ variant: "outline",
4299
+ w: "full",
4300
+ onClick: () => openExternalLink(`${getChainExplorerURL(getChainName())}/account/${address}`),
4301
+ children: [
4302
+ /* @__PURE__ */ jsx5(LuExternalLink, {}),
4303
+ "View on Explorer"
4304
+ ]
4305
+ }
4306
+ )
4307
+ ] })
4308
+ ] }),
4309
+ /* @__PURE__ */ jsx5(Box2, { children: /* @__PURE__ */ jsx5(
4310
+ Button2,
4311
+ {
4312
+ size: "sm",
4313
+ width: "full",
4314
+ variant: "outline",
4315
+ colorPalette: "red",
4316
+ onClick: handleDisconnectAll,
4317
+ loading: isDisconnecting,
4318
+ loadingText: "Disconnecting...",
4319
+ children: "Disconnect Wallet"
4320
+ }
4321
+ ) })
4322
+ ] });
4323
+ const statusColor = useMemo14(() => {
4324
+ switch (status) {
4325
+ case WalletState.Connected:
4326
+ return "green";
4327
+ case WalletState.Connecting:
4328
+ return "yellow";
4329
+ case WalletState.Disconnected:
4330
+ return "red";
4331
+ default:
4332
+ return "gray";
4333
+ }
4334
+ }, [status]);
4335
+ return /* @__PURE__ */ jsxs4(VStack2, { gap: "6", align: "stretch", children: [
4336
+ /* @__PURE__ */ jsxs4(Box2, { children: [
4337
+ /* @__PURE__ */ jsx5(InterchainWalletModal, {}),
4338
+ /* @__PURE__ */ jsxs4(HStack2, { justify: "space-between", mb: "3", children: [
4339
+ /* @__PURE__ */ jsx5(Text3, { fontSize: "sm", fontWeight: "medium", children: "Wallet Status" }),
4340
+ /* @__PURE__ */ jsx5(Badge2, { colorPalette: statusColor, size: "sm", children: status })
4341
+ ] }),
4342
+ status === WalletState.Connected && /* @__PURE__ */ jsxs4(
4343
+ Box2,
4344
+ {
4345
+ p: "3",
4346
+ bgGradient: "to-br",
4347
+ gradientFrom: `${accentColor}.500/8`,
4348
+ gradientTo: `${accentColor}.600/8`,
4349
+ borderRadius: "md",
4350
+ borderWidth: "1px",
4351
+ borderColor: `${accentColor}.500/20`,
4352
+ children: [
4353
+ /* @__PURE__ */ jsx5(Text3, { fontSize: "xs", color: "fg.muted", mb: "1", children: username != null ? username : "Address" }),
4354
+ /* @__PURE__ */ jsxs4(HStack2, { justify: "space-between", children: [
4355
+ /* @__PURE__ */ jsx5(Text3, { fontSize: "sm", fontFamily: "mono", children: walletAddress }),
4356
+ /* @__PURE__ */ jsxs4(Box2, { position: "relative", children: [
4357
+ /* @__PURE__ */ jsx5(
4358
+ Button2,
4359
+ {
4360
+ ref: copyButtonRef,
4361
+ size: "xs",
4362
+ variant: "ghost",
4363
+ onClick: handleCopyAddress,
4364
+ children: /* @__PURE__ */ jsx5(LuCopy, {})
4365
+ }
4366
+ ),
4367
+ showCopiedTooltip && /* @__PURE__ */ jsx5(
4368
+ Box2,
4369
+ {
4370
+ position: "absolute",
4371
+ top: "-35px",
4372
+ right: "0",
4373
+ bgGradient: "to-br",
4374
+ gradientFrom: `${accentColor}.500`,
4375
+ gradientTo: `${accentColor}.600`,
4376
+ color: "white",
4377
+ px: "3",
4378
+ py: "1.5",
4379
+ borderRadius: "md",
4380
+ fontSize: "xs",
4381
+ fontWeight: "semibold",
4382
+ whiteSpace: "nowrap",
4383
+ zIndex: "tooltip",
4384
+ shadow: "md",
4385
+ children: "Copied!"
4386
+ }
4387
+ )
4388
+ ] })
4389
+ ] })
4390
+ ]
4391
+ }
4392
+ ),
4393
+ status !== WalletState.Connected && /* @__PURE__ */ jsx5(
4394
+ Button2,
4395
+ {
4396
+ size: "sm",
4397
+ variant: "solid",
4398
+ w: "full",
4399
+ onClick: connect,
4400
+ children: "Connect Wallet"
4401
+ }
4402
+ )
4403
+ ] }),
4404
+ /* @__PURE__ */ jsx5(Separator2, {}),
4405
+ status === WalletState.Connected && viewState === "balances" && renderBalancesView(),
4406
+ status === WalletState.Connected && viewState === "send" && /* @__PURE__ */ jsx5(SendForm, { balances: sortedBalances, onClose: handleCancel, selectedTicker: clickedBalance, accentColor })
4407
+ ] });
4408
+ };
4409
+
4410
+ // src/components/settings-toggle.tsx
4411
+ import { Button as Button3 } from "@chakra-ui/react";
4412
+ import { LuSettings } from "react-icons/lu";
4413
+ import { jsx as jsx6 } from "react/jsx-runtime";
4414
+ function SettingsToggle({ accentColor }) {
4415
+ return /* @__PURE__ */ jsx6(
4416
+ Sidebar,
4417
+ {
4418
+ ariaLabel: "Settings",
4419
+ trigger: /* @__PURE__ */ jsx6(Button3, { variant: "subtle", size: { base: "sm", md: "md" }, children: /* @__PURE__ */ jsx6(LuSettings, {}) }),
4420
+ children: /* @__PURE__ */ jsx6(SettingsSidebarContent, { accentColor })
4421
+ }
4422
+ );
4423
+ }
4424
+ export {
4425
+ ASSET_TYPE_FACTORY,
4426
+ ASSET_TYPE_IBC,
4427
+ ASSET_TYPE_LP,
4428
+ ASSET_TYPE_NATIVE,
4429
+ AssetsContext,
4430
+ BZE_CIRCLE_LOGO,
4431
+ BZE_TESTNET_2_SUGGEST_CHAIN,
4432
+ BZE_TESTNET_NETWORK,
4433
+ CHART_1D,
4434
+ CHART_1Y,
4435
+ CHART_30D,
4436
+ CHART_4H,
4437
+ CHART_7D,
4438
+ CONNECTION_TYPE_NONE,
4439
+ CONNECTION_TYPE_POLLING,
4440
+ CONNECTION_TYPE_WS,
4441
+ CURRENT_WALLET_BALANCE_EVENT,
4442
+ DEFAULT_SETTINGS,
4443
+ DEFAULT_TX_MEMO,
4444
+ ECOSYSTEM_MENU_LABEL,
4445
+ EPOCH_START_EVENT,
4446
+ EXCLUDED_ASSETS,
4447
+ EXCLUDED_MARKETS,
4448
+ HighlightText,
4449
+ LOCK_CHANGED_EVENT,
4450
+ LP_ASSETS_DECIMALS,
4451
+ MAINNET_CHAIN_INFO_FALLBACK,
4452
+ NEXT_BURN_CHANGED_EVENT,
4453
+ ORDER_BOOK_CHANGED_EVENT,
4454
+ ORDER_EXECUTED_EVENT,
4455
+ ORDER_TYPE_BUY,
4456
+ ORDER_TYPE_SELL,
4457
+ RAFFLE_CHANGED_EVENT,
4458
+ SETTINGS_STORAGE_KEY,
4459
+ STABLE_COINS,
4460
+ SUPPLY_CHANGED_EVENT,
4461
+ SWAP_EXECUTED_EVENT,
4462
+ SettingsSidebarContent,
4463
+ SettingsToggle,
4464
+ Sidebar,
4465
+ TESTNET_CHAIN_INFO_FALLBACK,
4466
+ TOKEN_LOGO_PLACEHOLDER,
4467
+ TTL_NO_EXPIRY,
4468
+ Toaster,
4469
+ TxStatus,
4470
+ VALIDATION_ERRORS,
4471
+ VERIFIED_ASSETS,
4472
+ WalletSidebarContent,
4473
+ addDebounce,
4474
+ addMultipleDebounce,
4475
+ ammRouter,
4476
+ amountToBigNumberUAmount,
4477
+ amountToUAmount,
4478
+ blockchainEventManager,
4479
+ calcNativeStakingApr,
4480
+ calculateAmountFromPrice,
4481
+ calculatePoolOppositeAmount,
4482
+ calculatePoolPrice,
4483
+ calculatePricePerUnit,
4484
+ calculateRewardsStakingApr,
4485
+ calculateRewardsStakingPendingRewards,
4486
+ calculateTotalAmount,
4487
+ calculateUserPoolData,
4488
+ canDepositFromIBC,
4489
+ canSendToIBC,
4490
+ cancelDebounce,
4491
+ convertToWebSocketUrl,
4492
+ counterpartyChainForChannel,
4493
+ createMarketId,
4494
+ createPoolId,
4495
+ createRestClient,
4496
+ denomOnFirstHopChainFromTrace,
4497
+ formatDate,
4498
+ formatTimeRemaining,
4499
+ formatTimeRemainingFromEpochs,
4500
+ formatUsdAmount,
4501
+ getAddressBalances,
4502
+ getAddressDelegations,
4503
+ getAddressFullMarketOrders,
4504
+ getAddressHistory,
4505
+ getAddressMarketOrders,
4506
+ getAddressNativeDelegatedBalance,
4507
+ getAddressNativeTotalRewards,
4508
+ getAddressPendingUnlock,
4509
+ getAddressRewards,
4510
+ getAddressStakingRewards,
4511
+ getAddressSwapHistory,
4512
+ getAddressUnbondingDelegations,
4513
+ getAddressUnbondingDelegationsSummary,
4514
+ getAggregatorHost,
4515
+ getAllBurnedCoins,
4516
+ getAllSupply,
4517
+ getAllSupplyMetadata,
4518
+ getAllTickers,
4519
+ getAnnualProvisions,
4520
+ getAppName,
4521
+ getArchwayRestURL,
4522
+ getArchwayRpcURL,
4523
+ getAssetLists,
4524
+ getAtomOneRestURL,
4525
+ getAtomOneRpcUrl,
4526
+ getBZEUSDPrice,
4527
+ getBurnerParams,
4528
+ getBurnerParamsWithClient,
4529
+ getChainAddressPrefix,
4530
+ getChainAssets,
4531
+ getChainByChainId,
4532
+ getChainByName,
4533
+ getChainExplorerURL,
4534
+ getChainId,
4535
+ getChainName,
4536
+ getChainNativeAssetDenom,
4537
+ getChains,
4538
+ getChartIntervalsLimit,
4539
+ getChartMinutes,
4540
+ getCurrentEpoch,
4541
+ getCurrentWeekEpochEndTime,
4542
+ getDefaultTxMemo,
4543
+ getDenomType,
4544
+ getDistributionParams,
4545
+ getEcosystemApps,
4546
+ getEpochDurationByIdentifier,
4547
+ getEpochsInfo,
4548
+ getFactoryDenomAdminAddress,
4549
+ getFromLocalStorage,
4550
+ getHashIBCTrace,
4551
+ getHourEpochInfo,
4552
+ getIBCAssetList,
4553
+ getIBCTraces,
4554
+ getIbcTransferTimeout,
4555
+ getJackalRestURL,
4556
+ getJackalRpcUrl,
4557
+ getKeyExpiry,
4558
+ getLiquidityPool,
4559
+ getLiquidityPools,
4560
+ getLockedBalances,
4561
+ getLockerAddress,
4562
+ getMarketBuyOrders,
4563
+ getMarketEventKey,
4564
+ getMarketHistory,
4565
+ getMarketOrder,
4566
+ getMarketOrderBookChangedEvent,
4567
+ getMarketOrders,
4568
+ getMarketOrdersHistory,
4569
+ getMarketSellOrders,
4570
+ getMarkets,
4571
+ getMinAmount,
4572
+ getNoOfIntervalsNeeded,
4573
+ getNobleRestURL,
4574
+ getNobleRpcUrl,
4575
+ getOmniFlixRestURL,
4576
+ getOmniFlixRpcUrl,
4577
+ getOsmosisRestURL,
4578
+ getOsmosisRpcUrl,
4579
+ getPageRequestWithLimit,
4580
+ getPendingUnlockParticipants,
4581
+ getPeriodicEpochEndTime,
4582
+ getPeriodicWeekEpochEndTime,
4583
+ getRestClient,
4584
+ getRestURL,
4585
+ getRpcURL,
4586
+ getSettings,
4587
+ getStakingParams,
4588
+ getStakingPool,
4589
+ getStakingRewardParticipantByAddress,
4590
+ getStakingRewards,
4591
+ getTradingViewIntervals,
4592
+ getUSDCDenom,
4593
+ getValidatorPageUrl,
4594
+ getValidatorSupportedDenoms,
4595
+ getWalletChainsNames,
4596
+ getWeekEpochInfo,
4597
+ intlDateFormat,
4598
+ isFactoryDenom,
4599
+ isIbcAsset,
4600
+ isIbcDenom,
4601
+ isLpDenom,
4602
+ isNativeDenom,
4603
+ isPoolSupportedByValidator,
4604
+ isTestnetChain,
4605
+ keplrSuggestChain,
4606
+ mapEventAttributes,
4607
+ openExternalLink,
4608
+ parseUnbondingDays,
4609
+ poolIdFromPoolDenom,
4610
+ prettyAmount,
4611
+ prettyError,
4612
+ priceToBigNumberUPrice,
4613
+ priceToUPrice,
4614
+ removeFromLocalStorage,
4615
+ removeLeadingZeros,
4616
+ sanitizeIntegerInput,
4617
+ sanitizeNumberInput,
4618
+ setDefaultTxMemo,
4619
+ setInLocalStorage,
4620
+ setKeyExpiry,
4621
+ setSettings,
4622
+ setStorageKeyVersion,
4623
+ shortNumberFormat,
4624
+ sleep,
4625
+ stringTruncateFromCenter,
4626
+ toBigNumber,
4627
+ toPercentage,
4628
+ truncateAddress,
4629
+ truncateDenom,
4630
+ uAmountToAmount,
4631
+ uAmountToBigNumberAmount,
4632
+ uPriceToBigNumberPrice,
4633
+ uPriceToPrice,
4634
+ useAsset,
4635
+ useAssetLiquidityPools,
4636
+ useAssetMarkets,
4637
+ useAssetPrice,
4638
+ useAssets,
4639
+ useAssetsContext,
4640
+ useAssetsManager,
4641
+ useAssetsValue,
4642
+ useBZETx,
4643
+ useBalance,
4644
+ useBalances,
4645
+ useConnectionType,
4646
+ useEpochs,
4647
+ useFeeTokens,
4648
+ useIBCChains,
4649
+ useIBCTx,
4650
+ useLiquidityPools,
4651
+ useMarket,
4652
+ useMarkets,
4653
+ useSDKTx,
4654
+ useSettings,
4655
+ useSigningClient,
4656
+ useToast,
4657
+ validateBZEBech32Address,
4658
+ validateBech32Address,
4659
+ validateEndpoints,
4660
+ validateRestEndpoint,
4661
+ validateRpcEndpoint
4662
+ };
4663
+ //# sourceMappingURL=index.mjs.map