@thenamespace/ens-components 0.0.8-alpha → 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.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { forwardRef, createElement, useState, useRef, useEffect, useCallback, useMemo, createContext, useContext } from 'react';
3
- import { isAddress as isAddress$1, parseAbi, namehash, encodeFunctionData, toHex, ContractFunctionExecutionError } from 'viem';
2
+ import { forwardRef, createElement, useState, useRef, useEffect, useMemo, useCallback, createContext, useContext } from 'react';
3
+ import { isAddress as isAddress$1, parseAbi } from 'viem';
4
4
  import { mainnet, base as base$1, arbitrum, polygon, optimism, zora, celo } from 'viem/chains';
5
- import { usePublicClient, useWalletClient, useAccount, useSwitchChain } from 'wagmi';
5
+ import { usePublicClient, useWalletClient } from 'wagmi';
6
6
 
7
7
  const sizeToClass = {
8
8
  sm: "ns-btn--sm",
@@ -222,7 +222,7 @@ const createLucideIcon = (iconName, iconNode) => {
222
222
  */
223
223
 
224
224
 
225
- const __iconNode$h = [
225
+ const __iconNode$l = [
226
226
  [
227
227
  "path",
228
228
  {
@@ -231,7 +231,7 @@ const __iconNode$h = [
231
231
  }
232
232
  ]
233
233
  ];
234
- const Book = createLucideIcon("book", __iconNode$h);
234
+ const Book = createLucideIcon("book", __iconNode$l);
235
235
 
236
236
  /**
237
237
  * @license lucide-react v0.542.0 - ISC
@@ -241,7 +241,7 @@ const Book = createLucideIcon("book", __iconNode$h);
241
241
  */
242
242
 
243
243
 
244
- const __iconNode$g = [
244
+ const __iconNode$k = [
245
245
  [
246
246
  "path",
247
247
  {
@@ -252,7 +252,7 @@ const __iconNode$g = [
252
252
  ["path", { d: "m3.3 7 8.7 5 8.7-5", key: "g66t2b" }],
253
253
  ["path", { d: "M12 22V12", key: "d0xqtd" }]
254
254
  ];
255
- const Box = createLucideIcon("box", __iconNode$g);
255
+ const Box = createLucideIcon("box", __iconNode$k);
256
256
 
257
257
  /**
258
258
  * @license lucide-react v0.542.0 - ISC
@@ -262,12 +262,12 @@ const Box = createLucideIcon("box", __iconNode$g);
262
262
  */
263
263
 
264
264
 
265
- const __iconNode$f = [
265
+ const __iconNode$j = [
266
266
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
267
267
  ["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
268
268
  ["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
269
269
  ];
270
- const CircleAlert = createLucideIcon("circle-alert", __iconNode$f);
270
+ const CircleAlert = createLucideIcon("circle-alert", __iconNode$j);
271
271
 
272
272
  /**
273
273
  * @license lucide-react v0.542.0 - ISC
@@ -277,11 +277,11 @@ const CircleAlert = createLucideIcon("circle-alert", __iconNode$f);
277
277
  */
278
278
 
279
279
 
280
- const __iconNode$e = [
280
+ const __iconNode$i = [
281
281
  ["path", { d: "M21.801 10A10 10 0 1 1 17 3.335", key: "yps3ct" }],
282
282
  ["path", { d: "m9 11 3 3L22 4", key: "1pflzl" }]
283
283
  ];
284
- const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$e);
284
+ const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$i);
285
285
 
286
286
  /**
287
287
  * @license lucide-react v0.542.0 - ISC
@@ -291,7 +291,7 @@ const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$e);
291
291
  */
292
292
 
293
293
 
294
- const __iconNode$d = [
294
+ const __iconNode$h = [
295
295
  ["path", { d: "M12 2a10 10 0 0 1 7.38 16.75", key: "175t95" }],
296
296
  ["path", { d: "M12 8v8", key: "napkw2" }],
297
297
  ["path", { d: "M16 12H8", key: "1fr5h0" }],
@@ -300,7 +300,7 @@ const __iconNode$d = [
300
300
  ["path", { d: "M4.636 5.235a10 10 0 0 1 .891-.857", key: "1szpfk" }],
301
301
  ["path", { d: "M8.644 21.42a10 10 0 0 0 7.631-.38", key: "9yhvd4" }]
302
302
  ];
303
- const CircleFadingPlus = createLucideIcon("circle-fading-plus", __iconNode$d);
303
+ const CircleFadingPlus = createLucideIcon("circle-fading-plus", __iconNode$h);
304
304
 
305
305
  /**
306
306
  * @license lucide-react v0.542.0 - ISC
@@ -310,12 +310,12 @@ const CircleFadingPlus = createLucideIcon("circle-fading-plus", __iconNode$d);
310
310
  */
311
311
 
312
312
 
313
- const __iconNode$c = [
313
+ const __iconNode$g = [
314
314
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
315
315
  ["circle", { cx: "12", cy: "10", r: "3", key: "ilqhr7" }],
316
316
  ["path", { d: "M7 20.662V19a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v1.662", key: "154egf" }]
317
317
  ];
318
- const CircleUser = createLucideIcon("circle-user", __iconNode$c);
318
+ const CircleUser = createLucideIcon("circle-user", __iconNode$g);
319
319
 
320
320
  /**
321
321
  * @license lucide-react v0.542.0 - ISC
@@ -325,12 +325,12 @@ const CircleUser = createLucideIcon("circle-user", __iconNode$c);
325
325
  */
326
326
 
327
327
 
328
- const __iconNode$b = [
328
+ const __iconNode$f = [
329
329
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
330
330
  ["path", { d: "m15 9-6 6", key: "1uzhvr" }],
331
331
  ["path", { d: "m9 9 6 6", key: "z0biqf" }]
332
332
  ];
333
- const CircleX = createLucideIcon("circle-x", __iconNode$b);
333
+ const CircleX = createLucideIcon("circle-x", __iconNode$f);
334
334
 
335
335
  /**
336
336
  * @license lucide-react v0.542.0 - ISC
@@ -340,12 +340,40 @@ const CircleX = createLucideIcon("circle-x", __iconNode$b);
340
340
  */
341
341
 
342
342
 
343
- const __iconNode$a = [
343
+ const __iconNode$e = [
344
+ ["path", { d: "M12 6v6l4 2", key: "mmk7yg" }],
345
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]
346
+ ];
347
+ const Clock = createLucideIcon("clock", __iconNode$e);
348
+
349
+ /**
350
+ * @license lucide-react v0.542.0 - ISC
351
+ *
352
+ * This source code is licensed under the ISC license.
353
+ * See the LICENSE file in the root directory of this source tree.
354
+ */
355
+
356
+
357
+ const __iconNode$d = [
358
+ ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
359
+ ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
360
+ ];
361
+ const Copy = createLucideIcon("copy", __iconNode$d);
362
+
363
+ /**
364
+ * @license lucide-react v0.542.0 - ISC
365
+ *
366
+ * This source code is licensed under the ISC license.
367
+ * See the LICENSE file in the root directory of this source tree.
368
+ */
369
+
370
+
371
+ const __iconNode$c = [
344
372
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
345
373
  ["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
346
374
  ["path", { d: "M2 12h20", key: "9i4pu4" }]
347
375
  ];
348
- const Globe = createLucideIcon("globe", __iconNode$a);
376
+ const Globe = createLucideIcon("globe", __iconNode$c);
349
377
 
350
378
  /**
351
379
  * @license lucide-react v0.542.0 - ISC
@@ -355,12 +383,12 @@ const Globe = createLucideIcon("globe", __iconNode$a);
355
383
  */
356
384
 
357
385
 
358
- const __iconNode$9 = [
386
+ const __iconNode$b = [
359
387
  ["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
360
388
  ["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
361
389
  ["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
362
390
  ];
363
- const Image = createLucideIcon("image", __iconNode$9);
391
+ const Image = createLucideIcon("image", __iconNode$b);
364
392
 
365
393
  /**
366
394
  * @license lucide-react v0.542.0 - ISC
@@ -370,12 +398,12 @@ const Image = createLucideIcon("image", __iconNode$9);
370
398
  */
371
399
 
372
400
 
373
- const __iconNode$8 = [
401
+ const __iconNode$a = [
374
402
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
375
403
  ["path", { d: "M12 16v-4", key: "1dtifu" }],
376
404
  ["path", { d: "M12 8h.01", key: "e9boi3" }]
377
405
  ];
378
- const Info = createLucideIcon("info", __iconNode$8);
406
+ const Info = createLucideIcon("info", __iconNode$a);
379
407
 
380
408
  /**
381
409
  * @license lucide-react v0.542.0 - ISC
@@ -385,11 +413,26 @@ const Info = createLucideIcon("info", __iconNode$8);
385
413
  */
386
414
 
387
415
 
388
- const __iconNode$7 = [
416
+ const __iconNode$9 = [
417
+ ["path", { d: "m16 17 5-5-5-5", key: "1bji2h" }],
418
+ ["path", { d: "M21 12H9", key: "dn1m92" }],
419
+ ["path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4", key: "1uf3rs" }]
420
+ ];
421
+ const LogOut = createLucideIcon("log-out", __iconNode$9);
422
+
423
+ /**
424
+ * @license lucide-react v0.542.0 - ISC
425
+ *
426
+ * This source code is licensed under the ISC license.
427
+ * See the LICENSE file in the root directory of this source tree.
428
+ */
429
+
430
+
431
+ const __iconNode$8 = [
389
432
  ["path", { d: "m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7", key: "132q7q" }],
390
433
  ["rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", key: "izxlao" }]
391
434
  ];
392
- const Mail = createLucideIcon("mail", __iconNode$7);
435
+ const Mail = createLucideIcon("mail", __iconNode$8);
393
436
 
394
437
  /**
395
438
  * @license lucide-react v0.542.0 - ISC
@@ -399,7 +442,7 @@ const Mail = createLucideIcon("mail", __iconNode$7);
399
442
  */
400
443
 
401
444
 
402
- const __iconNode$6 = [
445
+ const __iconNode$7 = [
403
446
  [
404
447
  "path",
405
448
  {
@@ -409,7 +452,7 @@ const __iconNode$6 = [
409
452
  ],
410
453
  ["circle", { cx: "12", cy: "10", r: "3", key: "ilqhr7" }]
411
454
  ];
412
- const MapPin = createLucideIcon("map-pin", __iconNode$6);
455
+ const MapPin = createLucideIcon("map-pin", __iconNode$7);
413
456
 
414
457
  /**
415
458
  * @license lucide-react v0.542.0 - ISC
@@ -419,7 +462,7 @@ const MapPin = createLucideIcon("map-pin", __iconNode$6);
419
462
  */
420
463
 
421
464
 
422
- const __iconNode$5 = [
465
+ const __iconNode$6 = [
423
466
  ["path", { d: "M12 17v5", key: "bb1du9" }],
424
467
  [
425
468
  "path",
@@ -429,7 +472,7 @@ const __iconNode$5 = [
429
472
  }
430
473
  ]
431
474
  ];
432
- const Pin = createLucideIcon("pin", __iconNode$5);
475
+ const Pin = createLucideIcon("pin", __iconNode$6);
433
476
 
434
477
  /**
435
478
  * @license lucide-react v0.542.0 - ISC
@@ -439,11 +482,31 @@ const Pin = createLucideIcon("pin", __iconNode$5);
439
482
  */
440
483
 
441
484
 
442
- const __iconNode$4 = [
485
+ const __iconNode$5 = [
443
486
  ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
444
487
  ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
445
488
  ];
446
- const Search = createLucideIcon("search", __iconNode$4);
489
+ const Search = createLucideIcon("search", __iconNode$5);
490
+
491
+ /**
492
+ * @license lucide-react v0.542.0 - ISC
493
+ *
494
+ * This source code is licensed under the ISC license.
495
+ * See the LICENSE file in the root directory of this source tree.
496
+ */
497
+
498
+
499
+ const __iconNode$4 = [
500
+ ["path", { d: "M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7", key: "1m0v6g" }],
501
+ [
502
+ "path",
503
+ {
504
+ d: "M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",
505
+ key: "ohrbg2"
506
+ }
507
+ ]
508
+ ];
509
+ const SquarePen = createLucideIcon("square-pen", __iconNode$4);
447
510
 
448
511
  /**
449
512
  * @license lucide-react v0.542.0 - ISC
@@ -646,7 +709,11 @@ const icons$1 = {
646
709
  "alert-triangle": TriangleAlert,
647
710
  info: Info,
648
711
  "x-circle": CircleX,
649
- "rotate-circle": CircleFadingPlus
712
+ "rotate-circle": CircleFadingPlus,
713
+ logout: LogOut,
714
+ edit: SquarePen,
715
+ copy: Copy,
716
+ clock: Clock
650
717
  };
651
718
  const Icon = ({
652
719
  name,
@@ -816,7 +883,10 @@ const BaseSvg = ({ size = 20, ...props }) => {
816
883
  );
817
884
  };
818
885
 
819
- const BitcoinSvg = ({ size = 20, ...props }) => {
886
+ const BitcoinSvg = ({
887
+ size = 20,
888
+ ...props
889
+ }) => {
820
890
  return /* @__PURE__ */ jsx(
821
891
  "svg",
822
892
  {
@@ -849,7 +919,13 @@ const MaticSvg = ({ size = 20, ...props }) => {
849
919
  ...props,
850
920
  children: /* @__PURE__ */ jsxs("g", { fill: "none", children: [
851
921
  /* @__PURE__ */ jsx("circle", { fill: "#6F41D8", cx: "16", cy: "16", r: "16" }),
852
- /* @__PURE__ */ jsx("path", { d: "M21.092 12.693c-.369-.215-.848-.215-1.254 0l-2.879 1.654-1.955 1.078-2.879 1.653c-.369.216-.848.216-1.254 0l-2.288-1.294c-.369-.215-.627-.61-.627-1.042V12.19c0-.431.221-.826.627-1.042l2.25-1.258c.37-.216.85-.216 1.256 0l2.25 1.258c.37.216.628.611.628 1.042v1.654l1.955-1.115v-1.653a1.16 1.16 0 00-.627-1.042l-4.17-2.372c-.369-.216-.848-.216-1.254 0l-4.244 2.372A1.16 1.16 0 006 11.076v4.78c0 .432.221.827.627 1.043l4.244 2.372c.369.215.849.215 1.254 0l2.879-1.618 1.955-1.114 2.879-1.617c.369-.216.848-.216 1.254 0l2.251 1.258c.37.215.627.61.627 1.042v2.552c0 .431-.22.826-.627 1.042l-2.25 1.294c-.37.216-.85.216-1.255 0l-2.251-1.258c-.37-.216-.628-.611-.628-1.042v-1.654l-1.955 1.115v1.653c0 .431.221.827.627 1.042l4.244 2.372c.369.216.848.216 1.254 0l4.244-2.372c.369-.215.627-.61.627-1.042v-4.78a1.16 1.16 0 00-.627-1.042l-4.28-2.409z", fill: "#FFF" })
922
+ /* @__PURE__ */ jsx(
923
+ "path",
924
+ {
925
+ d: "M21.092 12.693c-.369-.215-.848-.215-1.254 0l-2.879 1.654-1.955 1.078-2.879 1.653c-.369.216-.848.216-1.254 0l-2.288-1.294c-.369-.215-.627-.61-.627-1.042V12.19c0-.431.221-.826.627-1.042l2.25-1.258c.37-.216.85-.216 1.256 0l2.25 1.258c.37.216.628.611.628 1.042v1.654l1.955-1.115v-1.653a1.16 1.16 0 00-.627-1.042l-4.17-2.372c-.369-.216-.848-.216-1.254 0l-4.244 2.372A1.16 1.16 0 006 11.076v4.78c0 .432.221.827.627 1.043l4.244 2.372c.369.215.849.215 1.254 0l2.879-1.618 1.955-1.114 2.879-1.617c.369-.216.848-.216 1.254 0l2.251 1.258c.37.215.627.61.627 1.042v2.552c0 .431-.22.826-.627 1.042l-2.25 1.294c-.37.216-.85.216-1.255 0l-2.251-1.258c-.37-.216-.628-.611-.628-1.042v-1.654l-1.955 1.115v1.653c0 .431.221.827.627 1.042l4.244 2.372c.369.216.848.216 1.254 0l4.244-2.372c.369-.215.627-.61.627-1.042v-4.78a1.16 1.16 0 00-.627-1.042l-4.28-2.409z",
926
+ fill: "#FFF"
927
+ }
928
+ )
853
929
  ] })
854
930
  }
855
931
  );
@@ -1246,530 +1322,109 @@ const Tooltip = ({
1246
1322
  );
1247
1323
  };
1248
1324
 
1249
- var TransactionState = /* @__PURE__ */ ((TransactionState2) => {
1250
- TransactionState2["InProgress"] = "In Progress";
1251
- TransactionState2["Completed"] = "Completed";
1252
- TransactionState2["Failed"] = "Failed";
1253
- return TransactionState2;
1254
- })(TransactionState || {});
1255
- const PendingTransaction = ({
1256
- state,
1257
- blockExplorerUrl,
1258
- transactionHash,
1259
- className = ""
1260
- }) => {
1261
- const getStatusIcon = () => {
1262
- switch (state) {
1263
- case "In Progress" /* InProgress */:
1264
- return /* @__PURE__ */ jsx("div", { className: "ns-pending-tx__spinner" });
1265
- case "Completed" /* Completed */:
1266
- return /* @__PURE__ */ jsx(Icon, { name: "check-circle", size: 24 });
1267
- case "Failed" /* Failed */:
1268
- return /* @__PURE__ */ jsx(Icon, { name: "x-circle", size: 24 });
1269
- default:
1270
- return null;
1271
- }
1325
+ const Card = ({ children, className = "", ...props }) => {
1326
+ return /* @__PURE__ */ jsx("div", { className: `ns-card ${className}`, ...props, children });
1327
+ };
1328
+
1329
+ const capitalize = (value) => {
1330
+ return value.charAt(0).toLocaleUpperCase() + value.substring(1);
1331
+ };
1332
+ const equalsIgnoreCase = (a, b) => {
1333
+ return a.toLocaleLowerCase() === b.toLocaleLowerCase();
1334
+ };
1335
+ const deepCopy = (a) => {
1336
+ return JSON.parse(JSON.stringify(a));
1337
+ };
1338
+
1339
+ function convertEVMChainIdToCoinType(chainId) {
1340
+ return (2147483648 | chainId) >>> 0;
1341
+ }
1342
+
1343
+ const getEnsRecordsDiff = (oldRecords, newRecords) => {
1344
+ const { textsAdded, textsModified, textsRemoved } = getEnsTextDiff(
1345
+ oldRecords.texts,
1346
+ newRecords.texts
1347
+ );
1348
+ const { addressesAdded, addressesModified, addressesRemoved } = getEnsAddressDiff(oldRecords.addresses, newRecords.addresses);
1349
+ const { contenthashAdded, contenthashModified, contenthashRemoved } = getEnsContenthashDiff(oldRecords.contenthash, newRecords.contenthash);
1350
+ return {
1351
+ addressesAdded,
1352
+ addressesModified,
1353
+ addressesRemoved,
1354
+ textsAdded,
1355
+ textsModified,
1356
+ textsRemoved,
1357
+ contenthashAdded,
1358
+ contenthashModified,
1359
+ contenthashRemoved
1272
1360
  };
1273
- const getStatusMessage = () => {
1274
- switch (state) {
1275
- case "In Progress" /* InProgress */:
1276
- return "Transaction is being executed...";
1277
- case "Completed" /* Completed */:
1278
- return "Transaction completed successfully!";
1279
- case "Failed" /* Failed */:
1280
- return "Transaction failed!";
1281
- default:
1282
- return "";
1361
+ };
1362
+ const getEnsTextDiff = (oldTexts, newTexts) => {
1363
+ if (oldTexts.length === 0) {
1364
+ return {
1365
+ textsAdded: newTexts,
1366
+ textsModified: [],
1367
+ textsRemoved: []
1368
+ };
1369
+ }
1370
+ const oldTextMap = {};
1371
+ const textsRemoved = [];
1372
+ oldTexts.forEach((text) => {
1373
+ oldTextMap[text.key] = text;
1374
+ const existsInNew = newTexts.find((newText) => newText.key === text.key);
1375
+ if (!existsInNew) {
1376
+ textsRemoved.push(text);
1283
1377
  }
1284
- };
1285
- const getStatusClass = () => {
1286
- switch (state) {
1287
- case "In Progress" /* InProgress */:
1288
- return "ns-pending-tx--in-progress";
1289
- case "Completed" /* Completed */:
1290
- return "ns-pending-tx--completed";
1291
- case "Failed" /* Failed */:
1292
- return "ns-pending-tx--failed";
1293
- default:
1294
- return "";
1378
+ });
1379
+ const textsAdded = [];
1380
+ const textsModified = [];
1381
+ newTexts.forEach((newText) => {
1382
+ const matchingOldText = oldTextMap[newText.key];
1383
+ if (!matchingOldText) {
1384
+ textsAdded.push(newText);
1385
+ } else if (matchingOldText.value !== newText.value) {
1386
+ textsModified.push(newText);
1295
1387
  }
1388
+ });
1389
+ return {
1390
+ textsAdded,
1391
+ textsModified,
1392
+ textsRemoved
1296
1393
  };
1297
- const getIconClass = () => {
1298
- switch (state) {
1299
- case "In Progress" /* InProgress */:
1300
- return "ns-pending-tx__icon--in-progress";
1301
- case "Completed" /* Completed */:
1302
- return "ns-pending-tx__icon--completed";
1303
- case "Failed" /* Failed */:
1304
- return "ns-pending-tx__icon--failed";
1305
- default:
1306
- return "";
1394
+ };
1395
+ const getEnsAddressDiff = (oldAddresses, newAddresses) => {
1396
+ if (oldAddresses.length === 0) {
1397
+ return {
1398
+ addressesAdded: newAddresses,
1399
+ addressesModified: [],
1400
+ addressesRemoved: []
1401
+ };
1402
+ }
1403
+ const oldAddressMap = {};
1404
+ const addressesRemoved = [];
1405
+ oldAddresses.forEach((address) => {
1406
+ oldAddressMap[address.coinType] = address;
1407
+ const existsInNew = newAddresses.find(
1408
+ (newAddress) => newAddress.coinType === address.coinType
1409
+ );
1410
+ if (!existsInNew) {
1411
+ addressesRemoved.push(address);
1412
+ }
1413
+ });
1414
+ const addressesAdded = [];
1415
+ const addressesModified = [];
1416
+ newAddresses.forEach((newAddress) => {
1417
+ const matchinOldAddress = oldAddressMap[newAddress.coinType];
1418
+ if (!matchinOldAddress) {
1419
+ addressesAdded.push(newAddress);
1420
+ } else if (matchinOldAddress.value !== newAddress.value) {
1421
+ addressesModified.push(newAddress);
1307
1422
  }
1308
- };
1309
- return /* @__PURE__ */ jsx("div", { className: `ns-pending-tx ${getStatusClass()} ${className}`, children: /* @__PURE__ */ jsxs("div", { className: "ns-pending-tx__content", children: [
1310
- /* @__PURE__ */ jsx("div", { className: `ns-pending-tx__icon ${getIconClass()}`, children: getStatusIcon() }),
1311
- /* @__PURE__ */ jsx("div", { className: "ns-pending-tx__status", children: /* @__PURE__ */ jsx(Text, { children: getStatusMessage() }) }),
1312
- transactionHash && /* @__PURE__ */ jsxs("p", { className: "ns-pending-tx__message", children: [
1313
- "Hash: ",
1314
- transactionHash.slice(0, 10),
1315
- "...",
1316
- transactionHash.slice(-8)
1317
- ] }),
1318
- /* @__PURE__ */ jsxs(
1319
- "a",
1320
- {
1321
- href: blockExplorerUrl,
1322
- target: "_blank",
1323
- rel: "noopener noreferrer",
1324
- className: "ns-pending-tx__link",
1325
- children: [
1326
- /* @__PURE__ */ jsx(Icon, { name: "globe", size: 16, className: "ns-pending-tx__link-icon" }),
1327
- "View on Block Explorer"
1328
- ]
1329
- }
1330
- )
1331
- ] }) });
1332
- };
1333
-
1334
- const Dropdown = ({
1335
- trigger,
1336
- children,
1337
- placement = "bottom",
1338
- align = "start",
1339
- disabled = false,
1340
- dataTestId
1341
- }) => {
1342
- const [isOpen, setIsOpen] = useState(false);
1343
- const triggerRef = useRef(null);
1344
- const dropdownRef = useRef(null);
1345
- const handleToggle = useCallback(() => {
1346
- if (!disabled) {
1347
- setIsOpen((prev) => !prev);
1348
- }
1349
- }, [disabled]);
1350
- const handleClickOutside = useCallback((event) => {
1351
- if (triggerRef.current && !triggerRef.current.contains(event.target) && dropdownRef.current && !dropdownRef.current.contains(event.target)) {
1352
- setIsOpen(false);
1353
- }
1354
- }, []);
1355
- useEffect(() => {
1356
- if (isOpen) {
1357
- document.addEventListener("mousedown", handleClickOutside);
1358
- document.addEventListener("keydown", (e) => {
1359
- if (e.key === "Escape") setIsOpen(false);
1360
- });
1361
- }
1362
- return () => {
1363
- document.removeEventListener("mousedown", handleClickOutside);
1364
- };
1365
- }, [isOpen, handleClickOutside]);
1366
- const getPlacementClasses = () => {
1367
- const placementClass = `ns-dropdown--${placement}`;
1368
- const alignClass = `ns-dropdown--align-${align}`;
1369
- return `${placementClass} ${alignClass}`;
1370
- };
1371
- return /* @__PURE__ */ jsxs("div", { className: "ns-dropdown", "data-test-id": dataTestId, children: [
1372
- /* @__PURE__ */ jsx(
1373
- "div",
1374
- {
1375
- ref: triggerRef,
1376
- className: "ns-dropdown__trigger",
1377
- onClick: handleToggle,
1378
- role: "button",
1379
- tabIndex: disabled ? -1 : 0,
1380
- "aria-expanded": isOpen,
1381
- "aria-haspopup": "true",
1382
- onKeyDown: (e) => {
1383
- if (e.key === "Enter" || e.key === " ") {
1384
- e.preventDefault();
1385
- handleToggle();
1386
- }
1387
- },
1388
- children: trigger
1389
- }
1390
- ),
1391
- isOpen && /* @__PURE__ */ jsx(
1392
- "div",
1393
- {
1394
- ref: dropdownRef,
1395
- className: `ns-dropdown__menu ${getPlacementClasses()}`,
1396
- role: "menu",
1397
- "aria-orientation": "vertical",
1398
- children
1399
- }
1400
- )
1401
- ] });
1402
- };
1403
-
1404
- var ContenthashProtocol = /* @__PURE__ */ ((ContenthashProtocol2) => {
1405
- ContenthashProtocol2["Ipfs"] = "ipfs";
1406
- ContenthashProtocol2["Onion"] = "onion3";
1407
- ContenthashProtocol2["Arweave"] = "arweave";
1408
- ContenthashProtocol2["Skynet"] = "skynet";
1409
- ContenthashProtocol2["Swarm"] = "swarm";
1410
- return ContenthashProtocol2;
1411
- })(ContenthashProtocol || {});
1412
-
1413
- const IpfsIcon = ({ size = 20 }) => {
1414
- return /* @__PURE__ */ jsxs(
1415
- "svg",
1416
- {
1417
- xmlns: "http://www.w3.org/2000/svg",
1418
- width: size,
1419
- height: size,
1420
- viewBox: "0 0 20 22",
1421
- fill: "none",
1422
- children: [
1423
- /* @__PURE__ */ jsx(
1424
- "path",
1425
- {
1426
- fill: "#469EA2",
1427
- d: "m0 16.44 9.56 5.48 9.559-5.48V5.48L9.559 0 0 5.48z"
1428
- }
1429
- ),
1430
- /* @__PURE__ */ jsx(
1431
- "path",
1432
- {
1433
- fill: "#6ACAD1",
1434
- d: "M8.58 1.31 1.64 5.289a2 2 0 0 1 0 .373l6.93 3.977a1.66 1.66 0 0 1 1.97 0l6.93-3.977a2 2 0 0 1 0-.373l-6.92-3.977a1.66 1.66 0 0 1-1.968 0m9.56 5.447-6.942 4.023c.038.348-.036.7-.212 1.005a1.67 1.67 0 0 1-.766.69l.011 7.91q.17.073.319.18l6.93-3.978c-.037-.348.037-.7.213-1.005s.444-.545.766-.69V6.939a2.3 2.3 0 0 1-.319-.181M.98 6.802q-.15.107-.319.181v7.955c.326.139.598.38.775.685.176.306.248.66.204 1.01l6.93 3.977q.15-.107.32-.18v-7.955a1.63 1.63 0 0 1-.775-.686 1.6 1.6 0 0 1-.205-1.01z"
1435
- }
1436
- ),
1437
- /* @__PURE__ */ jsx(
1438
- "path",
1439
- {
1440
- fill: "#469EA2",
1441
- d: "m9.56 1.186 8.546 4.904v9.797L9.56 20.791l-8.547-4.904V6.079zm0-1.163L0 5.503v10.96l9.56 5.48 9.559-5.48V5.503z"
1442
- }
1443
- ),
1444
- /* @__PURE__ */ jsx(
1445
- "path",
1446
- {
1447
- fill: "#469EA2",
1448
- d: "M9.628 12.825H9.49a1.8 1.8 0 0 1-1.264-.518 1.77 1.77 0 0 1-.522-1.256v-.136a1.76 1.76 0 0 1 .521-1.255 1.78 1.78 0 0 1 1.265-.519h.137a1.8 1.8 0 0 1 1.265.519 1.77 1.77 0 0 1 .521 1.255v.136a1.76 1.76 0 0 1-.521 1.256 1.78 1.78 0 0 1-1.265.518m0 7.288H9.49a1.79 1.79 0 0 0-1.559.904l1.628.927 1.627-.927a1.79 1.79 0 0 0-1.56-.904m9.502-5.48h-.068a1.8 1.8 0 0 0-1.265.518 1.77 1.77 0 0 0-.522 1.256v.135a1.7 1.7 0 0 0 .228.86l1.627-.939zM17.503 4.576a1.73 1.73 0 0 0-.228.859v.136a1.76 1.76 0 0 0 .522 1.255 1.78 1.78 0 0 0 1.265.519h.068V5.503zM9.56.023 7.932.949a1.78 1.78 0 0 0 1.56.915h.136A1.79 1.79 0 0 0 11.187.96zM1.627 4.565 0 5.503v1.842h.068a1.8 1.8 0 0 0 1.265-.519 1.77 1.77 0 0 0 .522-1.255v-.136a1.9 1.9 0 0 0-.228-.87M.068 14.633H0v1.83l1.627.938a1.73 1.73 0 0 0 .228-.859v-.135a1.76 1.76 0 0 0-.522-1.256 1.78 1.78 0 0 0-1.265-.518"
1449
- }
1450
- ),
1451
- /* @__PURE__ */ jsx(
1452
- "path",
1453
- {
1454
- fill: "#083B54",
1455
- fillOpacity: "0.15",
1456
- d: "M9.56 22V11.028L0 5.548V16.52z"
1457
- }
1458
- ),
1459
- /* @__PURE__ */ jsx(
1460
- "path",
1461
- {
1462
- fill: "#083B54",
1463
- fillOpacity: "0.05",
1464
- d: "M19.13 16.418V5.458l-9.56 5.48V21.91z"
1465
- }
1466
- )
1467
- ]
1468
- }
1469
- );
1470
- };
1471
-
1472
- const OnionIcon = ({ size = 20 }) => {
1473
- return /* @__PURE__ */ jsx(
1474
- "svg",
1475
- {
1476
- xmlns: "http://www.w3.org/2000/svg",
1477
- width: size,
1478
- height: size * 1.18,
1479
- "data-name": "Layer 1",
1480
- viewBox: "0 0 161 190",
1481
- children: /* @__PURE__ */ jsx(
1482
- "path",
1483
- {
1484
- fill: "#7D50CF",
1485
- d: "M141.67 74.68c-16.3-17.8-41.29-40.85-44-52.41S102.17 0 102.17 0C90.76-.21 84.29 5.54 80.56 12.07 76.9 5.54 70.36-.21 59 0c0 0 7.25 10.62 4.52 22.26s-27.77 34.62-44 52.43c-45.45 49.76-6 115.82 61 115.82s106.53-66.06 61.15-115.83M80.56 175.29c-27 0-57.73-14.51-64.55-43.81-7.76-34.25 25.77-55.29 45.59-75.9l3.23 3.24c1.73 1.65 3.45 3.37 5.25 5-1.44 1.44-2.88 2.8-4.17 4.09C49.47 84 21 102.33 27.21 128.68c5.53 23.63 31.81 34.69 53.35 34.69s47.82-11.06 53.35-34.69c6.18-26.35-22.26-44.73-38.7-60.75C87.45 60.32 79.7 52.57 72 44.81a95 95 0 0 0 8.41-10.05l.14-.14.14.14c20.76 30.09 74.25 54.57 64.49 96.72-6.89 29.3-37.55 43.81-64.62 43.81m20.54-66.14a48 48 0 0 0-4.46-4.67l8.36-8.76c12.07 12.35 23.56 27.79 5.82 42.87-7.68 6.54-19.24 9.48-30.37 9.48s-22.62-2.94-30.31-9.48c-17.8-15.15-6.1-30.66 6-43.08l8.33 8.83a37.3 37.3 0 0 0-4.67 4.81c-13.14 16.3 6.1 26.43 20.61 26.43s33.83-10.13 20.69-26.43m-10.7 10.63a19.71 19.71 0 0 1-19.61-.07l4.1-23.41a11.62 11.62 0 1 1 17.3-10.13 11.44 11.44 0 0 1-6 10.13z"
1486
- }
1487
- )
1488
- }
1489
- );
1490
- };
1491
-
1492
- const ArweaveIcon = ({ size = 20 }) => {
1493
- return /* @__PURE__ */ jsxs(
1494
- "svg",
1495
- {
1496
- xmlns: "http://www.w3.org/2000/svg",
1497
- xmlSpace: "preserve",
1498
- width: size,
1499
- height: size,
1500
- viewBox: "0 0 31.8 31.8",
1501
- children: [
1502
- /* @__PURE__ */ jsx(
1503
- "circle",
1504
- {
1505
- cx: "15.9",
1506
- cy: "15.9",
1507
- r: "14.7",
1508
- fill: "none",
1509
- stroke: "currentColor",
1510
- strokeWidth: "2.5",
1511
- className: "arweave_svg__st0"
1512
- }
1513
- ),
1514
- /* @__PURE__ */ jsx(
1515
- "path",
1516
- {
1517
- fill: "currentColor",
1518
- d: "M18.7 21.2c-.1-.1-.1-.3-.2-.5 0-.2-.1-.4-.1-.6-.2.2-.4.3-.6.5s-.5.3-.7.4c-.3.1-.5.2-.9.3-.3.1-.7.1-1 .1-.6 0-1.1-.1-1.6-.3s-.9-.4-1.3-.7-.6-.7-.8-1.1-.3-.9-.3-1.4c0-1.2.5-2.2 1.4-2.8.9-.7 2.3-1 4.1-1h1.7v-.7c0-.6-.2-1-.5-1.3-.4-.3-.9-.5-1.6-.5-.6 0-1 .1-1.3.4s-.4.6-.4 1h-3c0-.5.1-1 .3-1.4s.5-.8 1-1.2c.4-.3.9-.6 1.5-.8q.9-.3 2.1-.3c.7 0 1.3.1 1.9.3s1.1.4 1.6.8c.4.3.8.8 1 1.3s.4 1.1.4 1.8v5c0 .6 0 1.1.1 1.5s.2.8.3 1v.2zm-2.9-2.1c.3 0 .6 0 .8-.1.3-.1.5-.2.7-.3s.4-.2.5-.4l.4-.4v-2h-1.5c-.5 0-.9 0-1.2.1s-.6.2-.8.4-.4.3-.5.6c-.1.2-.1.5-.1.7 0 .4.1.7.4 1s.8.4 1.3.4",
1519
- className: "arweave_svg__st1"
1520
- }
1521
- )
1522
- ]
1523
- }
1524
- );
1525
- };
1526
-
1527
- const SkynetIcon = ({ size = 20 }) => {
1528
- return /* @__PURE__ */ jsx(
1529
- "svg",
1530
- {
1531
- xmlns: "http://www.w3.org/2000/svg",
1532
- width: size,
1533
- height: size,
1534
- viewBox: "0 0 24 24",
1535
- style: { color: "rgb(0, 198, 94)" },
1536
- children: /* @__PURE__ */ jsx(
1537
- "path",
1538
- {
1539
- fill: "#00c65e",
1540
- d: "m0 6.46 21.389 11.297a.917.917 0 0 1 .2 1.485h-.011a10 10 0 0 1-2.234 1.53c-6.912 3.474-14.991-1.837-14.543-9.56l2.86 1.975c.856 4.508 5.618 7.11 9.874 5.393zm8.647 3.151 14.366 5.679a.87.87 0 0 1 .52 1.046v.018a.872.872 0 0 1-1.257.526zm5.29-7.437c2.71-.233 6.095.787 8.111 3.387 1.7 2.195 2.05 4.877 1.93 7.646V13.2a.878.878 0 0 1-1.197.745l-9.765-3.86 9.065 2.432a7.3 7.3 0 0 0-1.068-4.563c-2.968-4.768-9.984-4.535-12.63.42a8 8 0 0 0-.397.883L5.555 7.961q.104-.15.214-.296c.116-.241.242-.487.38-.727 1.612-2.79 4.31-4.433 7.156-4.697.21-.018.421-.049.632-.067z"
1541
- }
1542
- )
1543
- }
1544
- );
1545
- };
1546
-
1547
- const SwarmIcon = ({ size = 20 }) => {
1548
- return /* @__PURE__ */ jsx(
1549
- "svg",
1550
- {
1551
- xmlns: "http://www.w3.org/2000/svg",
1552
- width: size,
1553
- height: size * 1.03,
1554
- fill: "none",
1555
- children: /* @__PURE__ */ jsxs("g", { fill: "#FF8A00", children: [
1556
- /* @__PURE__ */ jsx("path", { d: "m0 30.47 8.02 4.502 8.022-4.502v-8.986L8.02 16.977 0 21.484zM26.516.03l-4.24 2.381-.006.036v4.758l4.246 2.382.036.017 4.24-2.376V2.43zM34.4 21.484l-8.02-4.507-8.022 4.507v8.986l8.021 4.502L34.4 30.47z" }),
1557
- /* @__PURE__ */ jsx("path", { d: "m17.137 1.285-8.01 4.502v8.986l8.022 4.501 8.02-4.501v-3.58l-3.905-2.19-1.054-.59V3.119z" })
1558
- ] })
1559
- }
1560
- );
1561
- };
1562
-
1563
- const icons = {
1564
- [ContenthashProtocol.Ipfs]: IpfsIcon,
1565
- [ContenthashProtocol.Onion]: OnionIcon,
1566
- [ContenthashProtocol.Arweave]: ArweaveIcon,
1567
- [ContenthashProtocol.Skynet]: SkynetIcon,
1568
- [ContenthashProtocol.Swarm]: SwarmIcon
1569
- };
1570
- const ContenthashIcon = (props) => {
1571
- const { className, size, protocol, ...restProps } = props;
1572
- const _size = size || 20;
1573
- const IconComponent = icons[protocol];
1574
- if (!IconComponent) {
1575
- console.warn(`No icon found for protocol: ${protocol}`);
1576
- return null;
1577
- }
1578
- return /* @__PURE__ */ jsx("div", { className: `ns-chain-icon ${className || ""}`, children: /* @__PURE__ */ jsx(IconComponent, { size: _size }) });
1579
- };
1580
-
1581
- const variantConfig = {
1582
- error: { icon: "x-circle", colorClass: "ns-alert-error" },
1583
- warning: { icon: "alert-triangle", colorClass: "ns-alert-warning" },
1584
- info: { icon: "info", colorClass: "ns-alert-info" },
1585
- success: { icon: "check-circle", colorClass: "ns-alert-success" }
1586
- };
1587
- const Alert = ({
1588
- variant = "info",
1589
- children,
1590
- className = "",
1591
- onClose,
1592
- dismissible = false,
1593
- title
1594
- }) => {
1595
- const config = variantConfig[variant];
1596
- return /* @__PURE__ */ jsx("div", { className: `ns-alert ${config.colorClass} ${className}`, role: "alert", children: /* @__PURE__ */ jsxs("div", { className: "ns-alert-content", children: [
1597
- /* @__PURE__ */ jsx("div", { className: "ns-alert-icon", children: /* @__PURE__ */ jsx(Icon, { name: config.icon, size: 20 }) }),
1598
- /* @__PURE__ */ jsxs("div", { className: "ns-alert-message", children: [
1599
- title && /* @__PURE__ */ jsx("div", { className: "ns-alert-title", children: title }),
1600
- /* @__PURE__ */ jsx("div", { className: "ns-alert-description", children })
1601
- ] }),
1602
- dismissible && onClose && /* @__PURE__ */ jsx(
1603
- "button",
1604
- {
1605
- className: "ns-alert-close",
1606
- onClick: onClose,
1607
- "aria-label": "Close alert",
1608
- type: "button",
1609
- children: /* @__PURE__ */ jsx(Icon, { name: "x", size: 16 })
1610
- }
1611
- )
1612
- ] }) });
1613
- };
1614
-
1615
- const Modal = ({
1616
- isOpen,
1617
- onClose,
1618
- title,
1619
- children,
1620
- footer,
1621
- size = "md",
1622
- isDismissDisabled,
1623
- titleId,
1624
- className = "",
1625
- style
1626
- }) => {
1627
- const overlayRef = useRef(null);
1628
- const dialogRef = useRef(null);
1629
- useEffect(() => {
1630
- if (!isOpen || isDismissDisabled) return;
1631
- const handleKeyDown = (e) => {
1632
- if (e.key === "Escape") onClose();
1633
- };
1634
- window.addEventListener("keydown", handleKeyDown);
1635
- return () => window.removeEventListener("keydown", handleKeyDown);
1636
- }, [isOpen, isDismissDisabled, onClose]);
1637
- const handleOverlayClick = (e) => {
1638
- if (isDismissDisabled) return;
1639
- if (e.target === overlayRef.current) onClose();
1640
- };
1641
- if (!isOpen) return null;
1642
- const sizeClass = `ns-modal--${size}`;
1643
- const classes = ["ns-modal", className, sizeClass].filter(Boolean).join(" ");
1644
- return /* @__PURE__ */ jsx(
1645
- "div",
1646
- {
1647
- ref: overlayRef,
1648
- className: "ns-modal-overlay",
1649
- onMouseDown: handleOverlayClick,
1650
- "aria-hidden": !isOpen,
1651
- children: /* @__PURE__ */ jsxs(
1652
- "div",
1653
- {
1654
- ref: dialogRef,
1655
- className: classes,
1656
- role: "dialog",
1657
- "aria-modal": "true",
1658
- "aria-labelledby": title ? titleId || "ns-modal-title" : void 0,
1659
- style,
1660
- children: [
1661
- (title || !isDismissDisabled) && /* @__PURE__ */ jsxs("div", { className: "ns-modal__header", children: [
1662
- title && /* @__PURE__ */ jsx("div", { className: "ns-modal__title", id: titleId || "ns-modal-title", children: typeof title === "string" ? /* @__PURE__ */ jsx(Text, { size: "lg", weight: "medium", children: title }) : title }),
1663
- !isDismissDisabled && /* @__PURE__ */ jsx("button", { className: "ns-modal__close", "aria-label": "Close", onClick: onClose, children: "\xD7" })
1664
- ] }),
1665
- /* @__PURE__ */ jsx("div", { className: "ns-modal__body", children }),
1666
- /* @__PURE__ */ jsx("div", { className: "ns-modal__footer", children: footer !== void 0 ? footer : /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: onClose, children: "Close" }) })
1667
- ]
1668
- }
1669
- )
1670
- }
1671
- );
1672
- };
1673
-
1674
- const capitalize = (value) => {
1675
- return value.charAt(0).toLocaleUpperCase() + value.substring(1);
1676
- };
1677
- const equalsIgnoreCase = (a, b) => {
1678
- return a.toLocaleLowerCase() === b.toLocaleLowerCase();
1679
- };
1680
- const deepCopy = (a) => {
1681
- return JSON.parse(JSON.stringify(a));
1682
- };
1683
-
1684
- function convertEVMChainIdToCoinType(chainId) {
1685
- return (2147483648 | chainId) >>> 0;
1686
- }
1687
-
1688
- const getEnsRecordsDiff = (oldRecords, newRecords) => {
1689
- const { textsAdded, textsModified, textsRemoved } = getEnsTextDiff(
1690
- oldRecords.texts,
1691
- newRecords.texts
1692
- );
1693
- const { addressesAdded, addressesModified, addressesRemoved } = getEnsAddressDiff(oldRecords.addresses, newRecords.addresses);
1694
- const { contenthashAdded, contenthashModified, contenthashRemoved } = getEnsContenthashDiff(oldRecords.contenthash, newRecords.contenthash);
1695
- return {
1696
- addressesAdded,
1697
- addressesModified,
1698
- addressesRemoved,
1699
- textsAdded,
1700
- textsModified,
1701
- textsRemoved,
1702
- contenthashAdded,
1703
- contenthashModified,
1704
- contenthashRemoved
1705
- };
1706
- };
1707
- const getEnsTextDiff = (oldTexts, newTexts) => {
1708
- if (oldTexts.length === 0) {
1709
- return {
1710
- textsAdded: newTexts,
1711
- textsModified: [],
1712
- textsRemoved: []
1713
- };
1714
- }
1715
- const oldTextMap = {};
1716
- const textsRemoved = [];
1717
- oldTexts.forEach((text) => {
1718
- oldTextMap[text.key] = text;
1719
- const existsInNew = newTexts.find((newText) => newText.key === text.key);
1720
- if (!existsInNew) {
1721
- textsRemoved.push(text);
1722
- }
1723
- });
1724
- const textsAdded = [];
1725
- const textsModified = [];
1726
- newTexts.forEach((newText) => {
1727
- const matchingOldText = oldTextMap[newText.key];
1728
- if (!matchingOldText) {
1729
- textsAdded.push(newText);
1730
- } else if (matchingOldText.value !== newText.value) {
1731
- textsModified.push(newText);
1732
- }
1733
- });
1734
- return {
1735
- textsAdded,
1736
- textsModified,
1737
- textsRemoved
1738
- };
1739
- };
1740
- const getEnsAddressDiff = (oldAddresses, newAddresses) => {
1741
- if (oldAddresses.length === 0) {
1742
- return {
1743
- addressesAdded: newAddresses,
1744
- addressesModified: [],
1745
- addressesRemoved: []
1746
- };
1747
- }
1748
- const oldAddressMap = {};
1749
- const addressesRemoved = [];
1750
- oldAddresses.forEach((address) => {
1751
- oldAddressMap[address.coinType] = address;
1752
- const existsInNew = newAddresses.find(
1753
- (newAddress) => newAddress.coinType === address.coinType
1754
- );
1755
- if (!existsInNew) {
1756
- addressesRemoved.push(address);
1757
- }
1758
- });
1759
- const addressesAdded = [];
1760
- const addressesModified = [];
1761
- newAddresses.forEach((newAddress) => {
1762
- const matchinOldAddress = oldAddressMap[newAddress.coinType];
1763
- if (!matchinOldAddress) {
1764
- addressesAdded.push(newAddress);
1765
- } else if (matchinOldAddress.value !== newAddress.value) {
1766
- addressesModified.push(newAddress);
1767
- }
1768
- });
1769
- return {
1770
- addressesAdded,
1771
- addressesModified,
1772
- addressesRemoved
1423
+ });
1424
+ return {
1425
+ addressesAdded,
1426
+ addressesModified,
1427
+ addressesRemoved
1773
1428
  };
1774
1429
  };
1775
1430
  const getEnsContenthashDiff = (oldRecord, newRecord) => {
@@ -9857,7 +9512,7 @@ const nonEvmCoinTypeToNameMap = Object.freeze({
9857
9512
  "5718350": ["wan", "Wanchain"],
9858
9513
  "5741564": ["waves", "Waves"],
9859
9514
  });
9860
- const coinTypeToNameMap = Object.freeze({
9515
+ Object.freeze({
9861
9516
  ...nonEvmCoinTypeToNameMap,
9862
9517
  ...evmCoinTypeToNameMap,
9863
9518
  });
@@ -9896,31 +9551,6 @@ const getCoderByCoinName = (name) => {
9896
9551
  }
9897
9552
  return format;
9898
9553
  };
9899
- const getCoderByCoinType = (coinType) => {
9900
- const names = coinTypeToNameMap[String(coinType)];
9901
- // https://docs.ens.domains/ens-improvement-proposals/ensip-11-evmchain-address-resolution
9902
- if (coinType >= SLIP44_MSB) {
9903
- // EVM coin
9904
- const evmChainId = coinTypeToEvmChainId(coinType);
9905
- const isUnknownChain = !names;
9906
- const name = isUnknownChain ? `Unknown Chain (${evmChainId})` : names[0]; // name is derivable
9907
- const ethFormat = eth;
9908
- return {
9909
- name,
9910
- coinType: coinType,
9911
- evmChainId,
9912
- isUnknownChain,
9913
- encode: ethFormat.encode,
9914
- decode: ethFormat.decode,
9915
- };
9916
- }
9917
- if (!names) {
9918
- throw new Error(`Unsupported coin type: ${coinType}`);
9919
- }
9920
- const [name] = names;
9921
- const format = formats[name];
9922
- return format;
9923
- };
9924
9554
 
9925
9555
  const isValidEmvAddress = (value) => {
9926
9556
  return isAddress$1(value);
@@ -10038,6 +9668,15 @@ const getSupportedAddressByName = (name) => {
10038
9668
  return supportedAddresses.find((addr) => addr.chainName === name);
10039
9669
  };
10040
9670
 
9671
+ var ContenthashProtocol = /* @__PURE__ */ ((ContenthashProtocol2) => {
9672
+ ContenthashProtocol2["Ipfs"] = "ipfs";
9673
+ ContenthashProtocol2["Onion"] = "onion3";
9674
+ ContenthashProtocol2["Arweave"] = "arweave";
9675
+ ContenthashProtocol2["Skynet"] = "skynet";
9676
+ ContenthashProtocol2["Swarm"] = "swarm";
9677
+ return ContenthashProtocol2;
9678
+ })(ContenthashProtocol || {});
9679
+
10041
9680
  /**
10042
9681
  * @param {Uint8Array} aa
10043
9682
  * @param {Uint8Array} bb
@@ -11791,31 +11430,155 @@ const TextRecords = ({
11791
11430
  onTextsChanged([...texts, { key, value: initialText?.value || "" }]);
11792
11431
  setLastAddedKey(key);
11793
11432
  };
11794
- const handleRemoveText = (key) => {
11795
- onTextsChanged(texts.filter((text) => text.key !== key));
11433
+ const handleRemoveText = (key) => {
11434
+ onTextsChanged(texts.filter((text) => text.key !== key));
11435
+ };
11436
+ const filterSuggestions = (record) => {
11437
+ if (searchFilter && searchFilter.length > 0) {
11438
+ const lowercase = searchFilter.toLocaleLowerCase();
11439
+ const label = record.label || "";
11440
+ return record.key.toLocaleLowerCase().includes(lowercase) || label.toLocaleLowerCase().includes(lowercase);
11441
+ }
11442
+ return true;
11443
+ };
11444
+ const filteredItems = useMemo(() => {
11445
+ const shownTextCategory = [category];
11446
+ if (category === TextRecordCategory.General) {
11447
+ shownTextCategory.push(TextRecordCategory.Image);
11448
+ }
11449
+ return supportedTexts.filter(
11450
+ (record) => filterSuggestions(record) && shownTextCategory.includes(record.category)
11451
+ );
11452
+ }, [searchFilter]);
11453
+ if (filteredItems.length === 0) {
11454
+ return /* @__PURE__ */ jsx(Fragment, {});
11455
+ }
11456
+ return /* @__PURE__ */ jsxs("div", { className: "ns-text-records", children: [
11457
+ /* @__PURE__ */ jsx(Text, { className: "ns-mb-2", weight: "bold", children: capitalize(category) }),
11458
+ filteredItems.filter((record) => existingTextsMap[record.key] !== void 0).map((record) => {
11459
+ const current = existingTextsMap[record.key];
11460
+ return /* @__PURE__ */ jsxs("div", { style: { marginBottom: 10 }, children: [
11461
+ /* @__PURE__ */ jsx(
11462
+ Text,
11463
+ {
11464
+ style: { marginBottom: "4px" },
11465
+ color: "grey",
11466
+ size: "xs",
11467
+ weight: "medium",
11468
+ children: record.label
11469
+ }
11470
+ ),
11471
+ /* @__PURE__ */ jsxs(
11472
+ "div",
11473
+ {
11474
+ style: { width: "100%" },
11475
+ className: "d-flex align-items-center",
11476
+ children: [
11477
+ /* @__PURE__ */ jsx(
11478
+ Input,
11479
+ {
11480
+ ref: (el) => {
11481
+ inputRefs.current[record.key] = el;
11482
+ },
11483
+ style: { width: "100%" },
11484
+ onChange: (e) => handleTextChanged(record.key, e.target.value),
11485
+ prefix: /* @__PURE__ */ jsx(Icon, { name: record.icon, size: 18, color: "grey" }),
11486
+ value: current.value,
11487
+ placeholder: record.placeholder
11488
+ }
11489
+ ),
11490
+ /* @__PURE__ */ jsx(
11491
+ "div",
11492
+ {
11493
+ onClick: () => handleRemoveText(record.key),
11494
+ className: "ns-close-icon ns-ms-1",
11495
+ children: /* @__PURE__ */ jsx(Icon, { name: "x", size: 18 })
11496
+ }
11497
+ )
11498
+ ]
11499
+ }
11500
+ )
11501
+ ] }, record.key);
11502
+ }),
11503
+ /* @__PURE__ */ jsx("div", { className: "row g-2", children: filteredItems.filter(
11504
+ (record) => existingTextsMap[record.key] === void 0 && record.category !== TextRecordCategory.Image && filterSuggestions(record)
11505
+ ).map((record) => /* @__PURE__ */ jsx("div", { className: "col col-lg-3 col-sm-6", children: /* @__PURE__ */ jsxs(
11506
+ "div",
11507
+ {
11508
+ className: "ns-text-suggestion",
11509
+ onClick: () => handleTextAdded(record.key),
11510
+ children: [
11511
+ /* @__PURE__ */ jsx(Icon, { size: 18, color: "grey", name: record.icon }),
11512
+ /* @__PURE__ */ jsx(Text, { className: "ns-mt-1", size: "xs", weight: "medium", children: record.label })
11513
+ ]
11514
+ }
11515
+ ) }, record.key)) })
11516
+ ] });
11517
+ };
11518
+
11519
+ const AddressRecords = ({
11520
+ addresses,
11521
+ onAddressesChanged,
11522
+ initialAddresses,
11523
+ searchFilter
11524
+ }) => {
11525
+ const existingAddressMap = useMemo(() => {
11526
+ const map = {};
11527
+ addresses.forEach((addr) => {
11528
+ map[addr.coinType] = addr;
11529
+ });
11530
+ return map;
11531
+ }, [addresses]);
11532
+ const [lastAddedKey, setLastAddedKey] = useState(null);
11533
+ const inputRefs = useRef({});
11534
+ useEffect(() => {
11535
+ if (lastAddedKey && inputRefs.current[lastAddedKey]) {
11536
+ inputRefs.current[lastAddedKey]?.scrollIntoView({
11537
+ behavior: "smooth",
11538
+ block: "center"
11539
+ });
11540
+ inputRefs.current[lastAddedKey]?.focus();
11541
+ setLastAddedKey(null);
11542
+ }
11543
+ }, [addresses, lastAddedKey]);
11544
+ const handleAddressChanged = (coin, value) => {
11545
+ const _addresses = [...addresses];
11546
+ for (const addr of _addresses) {
11547
+ if (addr.coinType === coin) {
11548
+ addr.value = value;
11549
+ }
11550
+ }
11551
+ onAddressesChanged(_addresses);
11552
+ };
11553
+ const handleAddressAdded = (coin) => {
11554
+ const initialAddress = initialAddresses.find((i) => i.coinType === coin);
11555
+ onAddressesChanged([
11556
+ ...addresses,
11557
+ { coinType: coin, value: initialAddress?.value || "" }
11558
+ ]);
11559
+ setLastAddedKey(`${coin}`);
11796
11560
  };
11797
- const filterSuggestions = (record) => {
11561
+ const handleRemoveAddress = (coin) => {
11562
+ onAddressesChanged(addresses.filter((addr) => addr.coinType !== coin));
11563
+ };
11564
+ const filterAddress = (address) => {
11798
11565
  if (searchFilter && searchFilter.length > 0) {
11799
11566
  const lowercase = searchFilter.toLocaleLowerCase();
11800
- const label = record.label || "";
11801
- return record.key.toLocaleLowerCase().includes(lowercase) || label.toLocaleLowerCase().includes(lowercase);
11567
+ return address.chainName.includes(lowercase) || address.label.toLocaleLowerCase().includes(lowercase);
11802
11568
  }
11803
11569
  return true;
11804
11570
  };
11805
- const filteredItems = useMemo(() => {
11806
- const shownTextCategory = [category];
11807
- if (category === TextRecordCategory.General) {
11808
- shownTextCategory.push(TextRecordCategory.Image);
11809
- }
11810
- return supportedTexts.filter((record) => filterSuggestions(record) && shownTextCategory.includes(record.category));
11571
+ const filteredAddresses = useMemo(() => {
11572
+ return supportedAddresses.filter((record) => filterAddress(record));
11811
11573
  }, [searchFilter]);
11812
- if (filteredItems.length === 0) {
11574
+ if (filteredAddresses.length === 0) {
11813
11575
  return /* @__PURE__ */ jsx(Fragment, {});
11814
11576
  }
11815
11577
  return /* @__PURE__ */ jsxs("div", { className: "ns-text-records", children: [
11816
- /* @__PURE__ */ jsx(Text, { className: "ns-mb-2", weight: "bold", children: capitalize(category) }),
11817
- filteredItems.filter((record) => existingTextsMap[record.key] !== void 0).map((record) => {
11818
- const current = existingTextsMap[record.key];
11578
+ /* @__PURE__ */ jsx(Text, { className: "ns-mb-2", weight: "bold", children: "Addresses" }),
11579
+ filteredAddresses.filter((record) => existingAddressMap[record.coinType] !== void 0).map((record) => {
11580
+ const current = existingAddressMap[record.coinType];
11581
+ const isInvalidAddress = current.value.length > 0 && !record.validateFunc?.(current.value);
11819
11582
  return /* @__PURE__ */ jsxs("div", { style: { marginBottom: 10 }, children: [
11820
11583
  /* @__PURE__ */ jsx(
11821
11584
  Text,
@@ -11827,181 +11590,438 @@ const TextRecords = ({
11827
11590
  children: record.label
11828
11591
  }
11829
11592
  ),
11830
- /* @__PURE__ */ jsxs(
11831
- "div",
11593
+ /* @__PURE__ */ jsxs(
11594
+ "div",
11595
+ {
11596
+ style: { width: "100%" },
11597
+ className: "d-flex align-items-center",
11598
+ children: [
11599
+ /* @__PURE__ */ jsx(
11600
+ Input,
11601
+ {
11602
+ ref: (el) => {
11603
+ inputRefs.current[record.coinType] = el;
11604
+ },
11605
+ error: isInvalidAddress,
11606
+ style: { width: "100%" },
11607
+ onChange: (e) => handleAddressChanged(record.coinType, e.target.value),
11608
+ prefix: /* @__PURE__ */ jsx(ChainIcon, { chain: record.chainName, size: 18 }),
11609
+ value: current.value,
11610
+ placeholder: record.placeholder
11611
+ }
11612
+ ),
11613
+ /* @__PURE__ */ jsx(
11614
+ "div",
11615
+ {
11616
+ onClick: () => handleRemoveAddress(record.coinType),
11617
+ className: "ns-close-icon ns-ms-1",
11618
+ children: /* @__PURE__ */ jsx(Icon, { name: "x", size: 18 })
11619
+ }
11620
+ )
11621
+ ]
11622
+ }
11623
+ ),
11624
+ isInvalidAddress && /* @__PURE__ */ jsx(
11625
+ Text,
11626
+ {
11627
+ size: "xs",
11628
+ color: "danger",
11629
+ className: "ns-mt-1",
11630
+ children: `${record.label} address is not valid`
11631
+ }
11632
+ )
11633
+ ] }, record.chainName);
11634
+ }),
11635
+ /* @__PURE__ */ jsx("div", { className: "row g-2", children: filteredAddresses.filter((record) => existingAddressMap[record.coinType] === void 0).map((record) => /* @__PURE__ */ jsx("div", { className: "col col-lg-3 col-sm-6", children: /* @__PURE__ */ jsxs(
11636
+ "div",
11637
+ {
11638
+ className: "ns-text-suggestion",
11639
+ onClick: () => handleAddressAdded(record.coinType),
11640
+ children: [
11641
+ /* @__PURE__ */ jsx(ChainIcon, { size: 20, chain: record.chainName }),
11642
+ /* @__PURE__ */ jsx(Text, { className: "ns-mt-1", size: "xs", weight: "medium", children: record.label })
11643
+ ]
11644
+ }
11645
+ ) }, record.coinType)) })
11646
+ ] });
11647
+ };
11648
+
11649
+ const Dropdown = ({
11650
+ trigger,
11651
+ children,
11652
+ placement = "bottom",
11653
+ align = "start",
11654
+ disabled = false,
11655
+ dataTestId
11656
+ }) => {
11657
+ const [isOpen, setIsOpen] = useState(false);
11658
+ const triggerRef = useRef(null);
11659
+ const dropdownRef = useRef(null);
11660
+ const handleToggle = useCallback(() => {
11661
+ if (!disabled) {
11662
+ setIsOpen((prev) => !prev);
11663
+ }
11664
+ }, [disabled]);
11665
+ const handleClickOutside = useCallback((event) => {
11666
+ if (triggerRef.current && !triggerRef.current.contains(event.target) && dropdownRef.current && !dropdownRef.current.contains(event.target)) {
11667
+ setIsOpen(false);
11668
+ }
11669
+ }, []);
11670
+ useEffect(() => {
11671
+ if (isOpen) {
11672
+ document.addEventListener("mousedown", handleClickOutside);
11673
+ document.addEventListener("keydown", (e) => {
11674
+ if (e.key === "Escape") setIsOpen(false);
11675
+ });
11676
+ }
11677
+ return () => {
11678
+ document.removeEventListener("mousedown", handleClickOutside);
11679
+ };
11680
+ }, [isOpen, handleClickOutside]);
11681
+ const getPlacementClasses = () => {
11682
+ const placementClass = `ns-dropdown--${placement}`;
11683
+ const alignClass = `ns-dropdown--align-${align}`;
11684
+ return `${placementClass} ${alignClass}`;
11685
+ };
11686
+ return /* @__PURE__ */ jsxs("div", { className: "ns-dropdown", "data-test-id": dataTestId, children: [
11687
+ /* @__PURE__ */ jsx(
11688
+ "div",
11689
+ {
11690
+ ref: triggerRef,
11691
+ className: "ns-dropdown__trigger",
11692
+ onClick: handleToggle,
11693
+ role: "button",
11694
+ tabIndex: disabled ? -1 : 0,
11695
+ "aria-expanded": isOpen,
11696
+ "aria-haspopup": "true",
11697
+ onKeyDown: (e) => {
11698
+ if (e.key === "Enter" || e.key === " ") {
11699
+ e.preventDefault();
11700
+ handleToggle();
11701
+ }
11702
+ },
11703
+ children: trigger
11704
+ }
11705
+ ),
11706
+ isOpen && /* @__PURE__ */ jsx(
11707
+ "div",
11708
+ {
11709
+ ref: dropdownRef,
11710
+ className: `ns-dropdown__menu ${getPlacementClasses()}`,
11711
+ role: "menu",
11712
+ "aria-orientation": "vertical",
11713
+ children
11714
+ }
11715
+ )
11716
+ ] });
11717
+ };
11718
+
11719
+ const IpfsIcon = ({ size = 20 }) => {
11720
+ return /* @__PURE__ */ jsxs(
11721
+ "svg",
11722
+ {
11723
+ xmlns: "http://www.w3.org/2000/svg",
11724
+ width: size,
11725
+ height: size,
11726
+ viewBox: "0 0 20 22",
11727
+ fill: "none",
11728
+ children: [
11729
+ /* @__PURE__ */ jsx(
11730
+ "path",
11731
+ {
11732
+ fill: "#469EA2",
11733
+ d: "m0 16.44 9.56 5.48 9.559-5.48V5.48L9.559 0 0 5.48z"
11734
+ }
11735
+ ),
11736
+ /* @__PURE__ */ jsx(
11737
+ "path",
11738
+ {
11739
+ fill: "#6ACAD1",
11740
+ d: "M8.58 1.31 1.64 5.289a2 2 0 0 1 0 .373l6.93 3.977a1.66 1.66 0 0 1 1.97 0l6.93-3.977a2 2 0 0 1 0-.373l-6.92-3.977a1.66 1.66 0 0 1-1.968 0m9.56 5.447-6.942 4.023c.038.348-.036.7-.212 1.005a1.67 1.67 0 0 1-.766.69l.011 7.91q.17.073.319.18l6.93-3.978c-.037-.348.037-.7.213-1.005s.444-.545.766-.69V6.939a2.3 2.3 0 0 1-.319-.181M.98 6.802q-.15.107-.319.181v7.955c.326.139.598.38.775.685.176.306.248.66.204 1.01l6.93 3.977q.15-.107.32-.18v-7.955a1.63 1.63 0 0 1-.775-.686 1.6 1.6 0 0 1-.205-1.01z"
11741
+ }
11742
+ ),
11743
+ /* @__PURE__ */ jsx(
11744
+ "path",
11745
+ {
11746
+ fill: "#469EA2",
11747
+ d: "m9.56 1.186 8.546 4.904v9.797L9.56 20.791l-8.547-4.904V6.079zm0-1.163L0 5.503v10.96l9.56 5.48 9.559-5.48V5.503z"
11748
+ }
11749
+ ),
11750
+ /* @__PURE__ */ jsx(
11751
+ "path",
11752
+ {
11753
+ fill: "#469EA2",
11754
+ d: "M9.628 12.825H9.49a1.8 1.8 0 0 1-1.264-.518 1.77 1.77 0 0 1-.522-1.256v-.136a1.76 1.76 0 0 1 .521-1.255 1.78 1.78 0 0 1 1.265-.519h.137a1.8 1.8 0 0 1 1.265.519 1.77 1.77 0 0 1 .521 1.255v.136a1.76 1.76 0 0 1-.521 1.256 1.78 1.78 0 0 1-1.265.518m0 7.288H9.49a1.79 1.79 0 0 0-1.559.904l1.628.927 1.627-.927a1.79 1.79 0 0 0-1.56-.904m9.502-5.48h-.068a1.8 1.8 0 0 0-1.265.518 1.77 1.77 0 0 0-.522 1.256v.135a1.7 1.7 0 0 0 .228.86l1.627-.939zM17.503 4.576a1.73 1.73 0 0 0-.228.859v.136a1.76 1.76 0 0 0 .522 1.255 1.78 1.78 0 0 0 1.265.519h.068V5.503zM9.56.023 7.932.949a1.78 1.78 0 0 0 1.56.915h.136A1.79 1.79 0 0 0 11.187.96zM1.627 4.565 0 5.503v1.842h.068a1.8 1.8 0 0 0 1.265-.519 1.77 1.77 0 0 0 .522-1.255v-.136a1.9 1.9 0 0 0-.228-.87M.068 14.633H0v1.83l1.627.938a1.73 1.73 0 0 0 .228-.859v-.135a1.76 1.76 0 0 0-.522-1.256 1.78 1.78 0 0 0-1.265-.518"
11755
+ }
11756
+ ),
11757
+ /* @__PURE__ */ jsx(
11758
+ "path",
11759
+ {
11760
+ fill: "#083B54",
11761
+ fillOpacity: "0.15",
11762
+ d: "M9.56 22V11.028L0 5.548V16.52z"
11763
+ }
11764
+ ),
11765
+ /* @__PURE__ */ jsx(
11766
+ "path",
11767
+ {
11768
+ fill: "#083B54",
11769
+ fillOpacity: "0.05",
11770
+ d: "M19.13 16.418V5.458l-9.56 5.48V21.91z"
11771
+ }
11772
+ )
11773
+ ]
11774
+ }
11775
+ );
11776
+ };
11777
+
11778
+ const OnionIcon = ({ size = 20 }) => {
11779
+ return /* @__PURE__ */ jsx(
11780
+ "svg",
11781
+ {
11782
+ xmlns: "http://www.w3.org/2000/svg",
11783
+ width: size,
11784
+ height: size * 1.18,
11785
+ "data-name": "Layer 1",
11786
+ viewBox: "0 0 161 190",
11787
+ children: /* @__PURE__ */ jsx(
11788
+ "path",
11789
+ {
11790
+ fill: "#7D50CF",
11791
+ d: "M141.67 74.68c-16.3-17.8-41.29-40.85-44-52.41S102.17 0 102.17 0C90.76-.21 84.29 5.54 80.56 12.07 76.9 5.54 70.36-.21 59 0c0 0 7.25 10.62 4.52 22.26s-27.77 34.62-44 52.43c-45.45 49.76-6 115.82 61 115.82s106.53-66.06 61.15-115.83M80.56 175.29c-27 0-57.73-14.51-64.55-43.81-7.76-34.25 25.77-55.29 45.59-75.9l3.23 3.24c1.73 1.65 3.45 3.37 5.25 5-1.44 1.44-2.88 2.8-4.17 4.09C49.47 84 21 102.33 27.21 128.68c5.53 23.63 31.81 34.69 53.35 34.69s47.82-11.06 53.35-34.69c6.18-26.35-22.26-44.73-38.7-60.75C87.45 60.32 79.7 52.57 72 44.81a95 95 0 0 0 8.41-10.05l.14-.14.14.14c20.76 30.09 74.25 54.57 64.49 96.72-6.89 29.3-37.55 43.81-64.62 43.81m20.54-66.14a48 48 0 0 0-4.46-4.67l8.36-8.76c12.07 12.35 23.56 27.79 5.82 42.87-7.68 6.54-19.24 9.48-30.37 9.48s-22.62-2.94-30.31-9.48c-17.8-15.15-6.1-30.66 6-43.08l8.33 8.83a37.3 37.3 0 0 0-4.67 4.81c-13.14 16.3 6.1 26.43 20.61 26.43s33.83-10.13 20.69-26.43m-10.7 10.63a19.71 19.71 0 0 1-19.61-.07l4.1-23.41a11.62 11.62 0 1 1 17.3-10.13 11.44 11.44 0 0 1-6 10.13z"
11792
+ }
11793
+ )
11794
+ }
11795
+ );
11796
+ };
11797
+
11798
+ const ArweaveIcon = ({ size = 20 }) => {
11799
+ return /* @__PURE__ */ jsxs(
11800
+ "svg",
11801
+ {
11802
+ xmlns: "http://www.w3.org/2000/svg",
11803
+ xmlSpace: "preserve",
11804
+ width: size,
11805
+ height: size,
11806
+ viewBox: "0 0 31.8 31.8",
11807
+ children: [
11808
+ /* @__PURE__ */ jsx(
11809
+ "circle",
11810
+ {
11811
+ cx: "15.9",
11812
+ cy: "15.9",
11813
+ r: "14.7",
11814
+ fill: "none",
11815
+ stroke: "currentColor",
11816
+ strokeWidth: "2.5",
11817
+ className: "arweave_svg__st0"
11818
+ }
11819
+ ),
11820
+ /* @__PURE__ */ jsx(
11821
+ "path",
11832
11822
  {
11833
- style: { width: "100%" },
11834
- className: "d-flex align-items-center",
11835
- children: [
11836
- /* @__PURE__ */ jsx(
11837
- Input,
11838
- {
11839
- ref: (el) => {
11840
- inputRefs.current[record.key] = el;
11841
- },
11842
- style: { width: "100%" },
11843
- onChange: (e) => handleTextChanged(record.key, e.target.value),
11844
- prefix: /* @__PURE__ */ jsx(Icon, { name: record.icon, size: 18, color: "grey" }),
11845
- value: current.value,
11846
- placeholder: record.placeholder
11847
- }
11848
- ),
11849
- /* @__PURE__ */ jsx(
11850
- "div",
11851
- {
11852
- onClick: () => handleRemoveText(record.key),
11853
- className: "ns-close-icon ns-ms-1",
11854
- children: /* @__PURE__ */ jsx(Icon, { name: "x", size: 18 })
11855
- }
11856
- )
11857
- ]
11823
+ fill: "currentColor",
11824
+ d: "M18.7 21.2c-.1-.1-.1-.3-.2-.5 0-.2-.1-.4-.1-.6-.2.2-.4.3-.6.5s-.5.3-.7.4c-.3.1-.5.2-.9.3-.3.1-.7.1-1 .1-.6 0-1.1-.1-1.6-.3s-.9-.4-1.3-.7-.6-.7-.8-1.1-.3-.9-.3-1.4c0-1.2.5-2.2 1.4-2.8.9-.7 2.3-1 4.1-1h1.7v-.7c0-.6-.2-1-.5-1.3-.4-.3-.9-.5-1.6-.5-.6 0-1 .1-1.3.4s-.4.6-.4 1h-3c0-.5.1-1 .3-1.4s.5-.8 1-1.2c.4-.3.9-.6 1.5-.8q.9-.3 2.1-.3c.7 0 1.3.1 1.9.3s1.1.4 1.6.8c.4.3.8.8 1 1.3s.4 1.1.4 1.8v5c0 .6 0 1.1.1 1.5s.2.8.3 1v.2zm-2.9-2.1c.3 0 .6 0 .8-.1.3-.1.5-.2.7-.3s.4-.2.5-.4l.4-.4v-2h-1.5c-.5 0-.9 0-1.2.1s-.6.2-.8.4-.4.3-.5.6c-.1.2-.1.5-.1.7 0 .4.1.7.4 1s.8.4 1.3.4",
11825
+ className: "arweave_svg__st1"
11858
11826
  }
11859
11827
  )
11860
- ] }, record.key);
11861
- }),
11862
- /* @__PURE__ */ jsx("div", { className: "row g-2", children: filteredItems.filter(
11863
- (record) => existingTextsMap[record.key] === void 0 && record.category !== TextRecordCategory.Image && filterSuggestions(record)
11864
- ).map((record) => /* @__PURE__ */ jsx("div", { className: "col col-lg-3 col-sm-6", children: /* @__PURE__ */ jsxs(
11865
- "div",
11828
+ ]
11829
+ }
11830
+ );
11831
+ };
11832
+
11833
+ const SkynetIcon = ({ size = 20 }) => {
11834
+ return /* @__PURE__ */ jsx(
11835
+ "svg",
11836
+ {
11837
+ xmlns: "http://www.w3.org/2000/svg",
11838
+ width: size,
11839
+ height: size,
11840
+ viewBox: "0 0 24 24",
11841
+ style: { color: "rgb(0, 198, 94)" },
11842
+ children: /* @__PURE__ */ jsx(
11843
+ "path",
11844
+ {
11845
+ fill: "#00c65e",
11846
+ d: "m0 6.46 21.389 11.297a.917.917 0 0 1 .2 1.485h-.011a10 10 0 0 1-2.234 1.53c-6.912 3.474-14.991-1.837-14.543-9.56l2.86 1.975c.856 4.508 5.618 7.11 9.874 5.393zm8.647 3.151 14.366 5.679a.87.87 0 0 1 .52 1.046v.018a.872.872 0 0 1-1.257.526zm5.29-7.437c2.71-.233 6.095.787 8.111 3.387 1.7 2.195 2.05 4.877 1.93 7.646V13.2a.878.878 0 0 1-1.197.745l-9.765-3.86 9.065 2.432a7.3 7.3 0 0 0-1.068-4.563c-2.968-4.768-9.984-4.535-12.63.42a8 8 0 0 0-.397.883L5.555 7.961q.104-.15.214-.296c.116-.241.242-.487.38-.727 1.612-2.79 4.31-4.433 7.156-4.697.21-.018.421-.049.632-.067z"
11847
+ }
11848
+ )
11849
+ }
11850
+ );
11851
+ };
11852
+
11853
+ const SwarmIcon = ({ size = 20 }) => {
11854
+ return /* @__PURE__ */ jsx(
11855
+ "svg",
11856
+ {
11857
+ xmlns: "http://www.w3.org/2000/svg",
11858
+ width: size,
11859
+ height: size * 1.03,
11860
+ fill: "none",
11861
+ children: /* @__PURE__ */ jsxs("g", { fill: "#FF8A00", children: [
11862
+ /* @__PURE__ */ jsx("path", { d: "m0 30.47 8.02 4.502 8.022-4.502v-8.986L8.02 16.977 0 21.484zM26.516.03l-4.24 2.381-.006.036v4.758l4.246 2.382.036.017 4.24-2.376V2.43zM34.4 21.484l-8.02-4.507-8.022 4.507v8.986l8.021 4.502L34.4 30.47z" }),
11863
+ /* @__PURE__ */ jsx("path", { d: "m17.137 1.285-8.01 4.502v8.986l8.022 4.501 8.02-4.501v-3.58l-3.905-2.19-1.054-.59V3.119z" })
11864
+ ] })
11865
+ }
11866
+ );
11867
+ };
11868
+
11869
+ const icons = {
11870
+ [ContenthashProtocol.Ipfs]: IpfsIcon,
11871
+ [ContenthashProtocol.Onion]: OnionIcon,
11872
+ [ContenthashProtocol.Arweave]: ArweaveIcon,
11873
+ [ContenthashProtocol.Skynet]: SkynetIcon,
11874
+ [ContenthashProtocol.Swarm]: SwarmIcon
11875
+ };
11876
+ const ContenthashIcon = (props) => {
11877
+ const { className, size, protocol, ...restProps } = props;
11878
+ const _size = size || 20;
11879
+ const IconComponent = icons[protocol];
11880
+ if (!IconComponent) {
11881
+ console.warn(`No icon found for protocol: ${protocol}`);
11882
+ return null;
11883
+ }
11884
+ return /* @__PURE__ */ jsx("div", { className: `ns-chain-icon ${className || ""}`, children: /* @__PURE__ */ jsx(IconComponent, { size: _size }) });
11885
+ };
11886
+
11887
+ const variantConfig = {
11888
+ error: { icon: "x-circle", colorClass: "ns-alert-error" },
11889
+ warning: { icon: "alert-triangle", colorClass: "ns-alert-warning" },
11890
+ info: { icon: "info", colorClass: "ns-alert-info" },
11891
+ success: { icon: "check-circle", colorClass: "ns-alert-success" }
11892
+ };
11893
+ const Alert = ({
11894
+ variant = "info",
11895
+ children,
11896
+ className = "",
11897
+ onClose,
11898
+ dismissible = false,
11899
+ title
11900
+ }) => {
11901
+ const config = variantConfig[variant];
11902
+ return /* @__PURE__ */ jsx("div", { className: `ns-alert ${config.colorClass} ${className}`, role: "alert", children: /* @__PURE__ */ jsxs("div", { className: "ns-alert-content", children: [
11903
+ /* @__PURE__ */ jsx("div", { className: "ns-alert-icon", children: /* @__PURE__ */ jsx(Icon, { name: config.icon, size: 20 }) }),
11904
+ /* @__PURE__ */ jsxs("div", { className: "ns-alert-message", children: [
11905
+ title && /* @__PURE__ */ jsx("div", { className: "ns-alert-title", children: title }),
11906
+ /* @__PURE__ */ jsx("div", { className: "ns-alert-description", children })
11907
+ ] }),
11908
+ dismissible && onClose && /* @__PURE__ */ jsx(
11909
+ "button",
11866
11910
  {
11867
- className: "ns-text-suggestion",
11868
- onClick: () => handleTextAdded(record.key),
11869
- children: [
11870
- /* @__PURE__ */ jsx(Icon, { size: 18, color: "grey", name: record.icon }),
11871
- /* @__PURE__ */ jsx(Text, { className: "ns-mt-1", size: "xs", weight: "medium", children: record.label })
11872
- ]
11911
+ className: "ns-alert-close",
11912
+ onClick: onClose,
11913
+ "aria-label": "Close alert",
11914
+ type: "button",
11915
+ children: /* @__PURE__ */ jsx(Icon, { name: "x", size: 16 })
11873
11916
  }
11874
- ) }, record.key)) })
11875
- ] });
11917
+ )
11918
+ ] }) });
11876
11919
  };
11877
11920
 
11878
- const AddressRecords = ({
11879
- addresses,
11880
- onAddressesChanged,
11881
- initialAddresses,
11882
- searchFilter
11921
+ const Modal = ({
11922
+ isOpen,
11923
+ onClose,
11924
+ title,
11925
+ children,
11926
+ footer,
11927
+ size = "md",
11928
+ isDismissDisabled,
11929
+ titleId,
11930
+ className = "",
11931
+ style
11883
11932
  }) => {
11884
- const existingAddressMap = useMemo(() => {
11885
- const map = {};
11886
- addresses.forEach((addr) => {
11887
- map[addr.coinType] = addr;
11888
- });
11889
- return map;
11890
- }, [addresses]);
11891
- const [lastAddedKey, setLastAddedKey] = useState(null);
11892
- const inputRefs = useRef({});
11933
+ const overlayRef = useRef(null);
11934
+ const dialogRef = useRef(null);
11893
11935
  useEffect(() => {
11894
- if (lastAddedKey && inputRefs.current[lastAddedKey]) {
11895
- inputRefs.current[lastAddedKey]?.scrollIntoView({
11896
- behavior: "smooth",
11897
- block: "center"
11898
- });
11899
- inputRefs.current[lastAddedKey]?.focus();
11900
- setLastAddedKey(null);
11901
- }
11902
- }, [addresses, lastAddedKey]);
11903
- const handleAddressChanged = (coin, value) => {
11904
- const _addresses = [...addresses];
11905
- for (const addr of _addresses) {
11906
- if (addr.coinType === coin) {
11907
- addr.value = value;
11908
- }
11909
- }
11910
- onAddressesChanged(_addresses);
11911
- };
11912
- const handleAddressAdded = (coin) => {
11913
- const initialAddress = initialAddresses.find((i) => i.coinType === coin);
11914
- onAddressesChanged([
11915
- ...addresses,
11916
- { coinType: coin, value: initialAddress?.value || "" }
11917
- ]);
11918
- setLastAddedKey(`${coin}`);
11919
- };
11920
- const handleRemoveAddress = (coin) => {
11921
- onAddressesChanged(addresses.filter((addr) => addr.coinType !== coin));
11922
- };
11923
- const filterAddress = (address) => {
11924
- if (searchFilter && searchFilter.length > 0) {
11925
- const lowercase = searchFilter.toLocaleLowerCase();
11926
- return address.chainName.includes(lowercase) || address.label.toLocaleLowerCase().includes(lowercase);
11927
- }
11928
- return true;
11936
+ if (!isOpen || isDismissDisabled) return;
11937
+ const handleKeyDown = (e) => {
11938
+ if (e.key === "Escape") onClose();
11939
+ };
11940
+ window.addEventListener("keydown", handleKeyDown);
11941
+ return () => window.removeEventListener("keydown", handleKeyDown);
11942
+ }, [isOpen, isDismissDisabled, onClose]);
11943
+ const handleOverlayClick = (e) => {
11944
+ if (isDismissDisabled) return;
11945
+ if (e.target === overlayRef.current) onClose();
11929
11946
  };
11930
- const filteredAddresses = useMemo(() => {
11931
- return supportedAddresses.filter((record) => filterAddress(record));
11932
- }, [searchFilter]);
11933
- if (filteredAddresses.length === 0) {
11934
- return /* @__PURE__ */ jsx(Fragment, {});
11935
- }
11936
- return /* @__PURE__ */ jsxs("div", { className: "ns-text-records", children: [
11937
- /* @__PURE__ */ jsx(Text, { className: "ns-mb-2", weight: "bold", children: "Addresses" }),
11938
- filteredAddresses.filter((record) => existingAddressMap[record.coinType] !== void 0).map((record) => {
11939
- const current = existingAddressMap[record.coinType];
11940
- const isInvalidAddress = current.value.length > 0 && !record.validateFunc?.(current.value);
11941
- return /* @__PURE__ */ jsxs("div", { style: { marginBottom: 10 }, children: [
11942
- /* @__PURE__ */ jsx(
11943
- Text,
11944
- {
11945
- style: { marginBottom: "4px" },
11946
- color: "grey",
11947
- size: "xs",
11948
- weight: "medium",
11949
- children: record.label
11950
- }
11951
- ),
11952
- /* @__PURE__ */ jsxs(
11953
- "div",
11954
- {
11955
- style: { width: "100%" },
11956
- className: "d-flex align-items-center",
11957
- children: [
11958
- /* @__PURE__ */ jsx(
11959
- Input,
11960
- {
11961
- ref: (el) => {
11962
- inputRefs.current[record.coinType] = el;
11963
- },
11964
- error: isInvalidAddress,
11965
- style: { width: "100%" },
11966
- onChange: (e) => handleAddressChanged(record.coinType, e.target.value),
11967
- prefix: /* @__PURE__ */ jsx(ChainIcon, { chain: record.chainName, size: 18 }),
11968
- value: current.value,
11969
- placeholder: record.placeholder
11970
- }
11971
- ),
11972
- /* @__PURE__ */ jsx(
11973
- "div",
11947
+ if (!isOpen) return null;
11948
+ const sizeClass = `ns-modal--${size}`;
11949
+ const classes = ["ns-modal", className, sizeClass].filter(Boolean).join(" ");
11950
+ return /* @__PURE__ */ jsx(
11951
+ "div",
11952
+ {
11953
+ ref: overlayRef,
11954
+ className: "ns-modal-overlay",
11955
+ onMouseDown: handleOverlayClick,
11956
+ "aria-hidden": !isOpen,
11957
+ children: /* @__PURE__ */ jsxs(
11958
+ "div",
11959
+ {
11960
+ ref: dialogRef,
11961
+ className: classes,
11962
+ role: "dialog",
11963
+ "aria-modal": "true",
11964
+ "aria-labelledby": title ? titleId || "ns-modal-title" : void 0,
11965
+ style,
11966
+ children: [
11967
+ (title || !isDismissDisabled) && /* @__PURE__ */ jsxs("div", { className: "ns-modal__header", children: [
11968
+ title && /* @__PURE__ */ jsx("div", { className: "ns-modal__title", id: titleId || "ns-modal-title", children: typeof title === "string" ? /* @__PURE__ */ jsx(Text, { size: "lg", weight: "medium", children: title }) : title }),
11969
+ !isDismissDisabled && /* @__PURE__ */ jsx(
11970
+ "button",
11974
11971
  {
11975
- onClick: () => handleRemoveAddress(record.coinType),
11976
- className: "ns-close-icon ns-ms-1",
11977
- children: /* @__PURE__ */ jsx(Icon, { name: "x", size: 18 })
11972
+ className: "ns-modal__close",
11973
+ "aria-label": "Close",
11974
+ onClick: onClose,
11975
+ children: "\xD7"
11978
11976
  }
11979
11977
  )
11980
- ]
11981
- }
11982
- ),
11983
- isInvalidAddress && /* @__PURE__ */ jsx(
11984
- Text,
11985
- {
11986
- size: "xs",
11987
- color: "danger",
11988
- className: "ns-mt-1",
11989
- children: `${record.label} address is not valid`
11990
- }
11991
- )
11992
- ] }, record.chainName);
11993
- }),
11994
- /* @__PURE__ */ jsx("div", { className: "row g-2", children: filteredAddresses.filter((record) => existingAddressMap[record.coinType] === void 0).map((record) => /* @__PURE__ */ jsx("div", { className: "col col-lg-3 col-sm-6", children: /* @__PURE__ */ jsxs(
11995
- "div",
11996
- {
11997
- className: "ns-text-suggestion",
11998
- onClick: () => handleAddressAdded(record.coinType),
11999
- children: [
12000
- /* @__PURE__ */ jsx(ChainIcon, { size: 20, chain: record.chainName }),
12001
- /* @__PURE__ */ jsx(Text, { className: "ns-mt-1", size: "xs", weight: "medium", children: record.label })
12002
- ]
12003
- }
12004
- ) }, record.coinType)) })
11978
+ ] }),
11979
+ /* @__PURE__ */ jsx("div", { className: "ns-modal__body", children }),
11980
+ /* @__PURE__ */ jsx("div", { className: "ns-modal__footer", children: footer !== void 0 ? footer : /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: onClose, children: "Close" }) })
11981
+ ]
11982
+ }
11983
+ )
11984
+ }
11985
+ );
11986
+ };
11987
+
11988
+ const ProfileHeader = ({
11989
+ bannerUrl,
11990
+ avatarUrl,
11991
+ chainIcon = "/icons/eth.svg",
11992
+ name,
11993
+ username,
11994
+ bio,
11995
+ followers = 0,
11996
+ following = 0,
11997
+ primary = false,
11998
+ onFollowClick,
11999
+ dataTestId
12000
+ }) => {
12001
+ return /* @__PURE__ */ jsxs("div", { className: "ns-profile-header", "data-test-id": dataTestId, children: [
12002
+ /* @__PURE__ */ jsx("div", { className: "ns-profile-header__banner", children: /* @__PURE__ */ jsx("img", { src: bannerUrl, alt: "profile banner" }) }),
12003
+ /* @__PURE__ */ jsxs("div", { className: "ns-profile-header__avatar", children: [
12004
+ /* @__PURE__ */ jsx("img", { src: avatarUrl, alt: name, className: "ns-avatar-img" }),
12005
+ chainIcon && /* @__PURE__ */ jsx("span", { className: "ns-profile-header__chain", children: /* @__PURE__ */ jsx("img", { src: chainIcon, alt: "chain icon" }) })
12006
+ ] }),
12007
+ /* @__PURE__ */ jsxs("div", { className: "ns-profile-header__info", children: [
12008
+ username && /* @__PURE__ */ jsx("div", { className: "ns-profile-header__username", children: username }),
12009
+ /* @__PURE__ */ jsx("h2", { className: "ns-profile-header__name", children: name }),
12010
+ primary && /* @__PURE__ */ jsx("span", { className: "ns-profile-header__primary", children: "Your primary name" }),
12011
+ bio && /* @__PURE__ */ jsx("p", { className: "ns-profile-header__bio", children: bio }),
12012
+ /* @__PURE__ */ jsxs("div", { className: "ns-profile-header__stats", children: [
12013
+ /* @__PURE__ */ jsxs("span", { children: [
12014
+ followers,
12015
+ " Followers"
12016
+ ] }),
12017
+ /* @__PURE__ */ jsx("span", { children: "\xB7" }),
12018
+ /* @__PURE__ */ jsxs("span", { children: [
12019
+ following,
12020
+ " Following"
12021
+ ] }),
12022
+ /* @__PURE__ */ jsx("button", { className: "ns-profile-header__follow", onClick: onFollowClick, children: "Follow" })
12023
+ ] })
12024
+ ] })
12005
12025
  ] });
12006
12026
  };
12007
12027
 
@@ -12324,287 +12344,257 @@ const SelectRecordsForm = ({
12324
12344
  ] });
12325
12345
  };
12326
12346
 
12327
- const SET_TEXT_FUNC = "function setText(bytes32 node, string key, string value)";
12328
- const SET_ADDRESS_FUNC = "function setAddr(bytes32 node, uint256 coin, bytes value)";
12329
- const SET_CONTENTHASH_FUNC = "function setContenthash(bytes32 node, bytes value)";
12330
- const MULTICALL = "function multicall(bytes[] data)";
12331
- const ENS_RESOLVER_ABI = parseAbi([
12332
- SET_TEXT_FUNC,
12333
- SET_ADDRESS_FUNC,
12334
- SET_CONTENTHASH_FUNC,
12335
- MULTICALL
12336
- ]);
12337
-
12338
- const convertToMulticallResolverData = (name, recordsDiff) => {
12339
- const node = namehash(name);
12340
- const resolverMulticallData = [];
12341
- convertTextData(node, resolverMulticallData, recordsDiff);
12342
- convertAddressData(node, resolverMulticallData, recordsDiff);
12343
- convertContenthashData(node, resolverMulticallData, recordsDiff);
12344
- return resolverMulticallData;
12345
- };
12346
- const convertTextData = (node, resolverData, diff) => {
12347
- const modifiedTexts = [
12348
- ...diff.textsAdded,
12349
- ...diff.textsModified
12350
- ];
12351
- modifiedTexts.forEach((text) => {
12352
- const data = encodeFunctionData({
12353
- functionName: "setText",
12354
- abi: parseAbi([SET_TEXT_FUNC]),
12355
- args: [node, text.key, text.value]
12356
- });
12357
- resolverData.push(data);
12358
- });
12359
- diff.textsModified.forEach((text) => {
12360
- const data = encodeFunctionData({
12361
- functionName: "setText",
12362
- abi: parseAbi([SET_TEXT_FUNC]),
12363
- args: [node, text.key, ""]
12364
- });
12365
- resolverData.push(data);
12366
- });
12367
- };
12368
- const convertAddressData = (node, resolverData, diff) => {
12369
- const modifiedAddressMap = {};
12370
- diff.addressesAdded.forEach((addr) => {
12371
- modifiedAddressMap[addr.coinType] = addr;
12372
- });
12373
- diff.addressesModified.forEach((addr) => {
12374
- modifiedAddressMap[addr.coinType] = addr;
12375
- });
12376
- const modifiedAddresses = Object.values(modifiedAddressMap);
12377
- modifiedAddresses.forEach((addr) => {
12378
- const coinEncoder = getCoderByCoinType(addr.coinType);
12379
- if (!coinEncoder) {
12380
- throw Error(
12381
- `Coin type is not supported: ${addr.coinType}. Cannot get an encoder`
12382
- );
12383
- }
12384
- const decode = coinEncoder.decode(addr.value);
12385
- const hexValue = toHex(decode);
12386
- const data = encodeFunctionData({
12387
- functionName: "setAddr",
12388
- abi: parseAbi([SET_ADDRESS_FUNC]),
12389
- args: [node, BigInt(addr.coinType), hexValue]
12390
- });
12391
- resolverData.push(data);
12392
- });
12393
- diff.addressesRemoved.forEach((addr) => {
12394
- const data = encodeFunctionData({
12395
- functionName: "setAddr",
12396
- abi: parseAbi([SET_ADDRESS_FUNC]),
12397
- args: [node, BigInt(addr.coinType), "0x"]
12398
- });
12399
- resolverData.push(data);
12400
- });
12401
- };
12402
- const convertContenthashData = (node, resolverData, diff) => {
12403
- if (diff.contenthashRemoved) {
12404
- const data = encodeFunctionData({
12405
- functionName: "setContenthash",
12406
- abi: parseAbi([SET_CONTENTHASH_FUNC]),
12407
- args: [node, "0x"]
12408
- });
12409
- resolverData.push(data);
12410
- return;
12411
- }
12412
- let contenthash = void 0;
12413
- if (diff.contenthashModified !== void 0) {
12414
- contenthash = diff.contenthashModified;
12415
- } else if (diff.contenthashAdded !== void 0) {
12416
- contenthash = diff.contenthashAdded;
12417
- }
12418
- if (contenthash !== void 0) {
12419
- const { protocol, value } = contenthash;
12420
- const encodedValue = `0x${encode(protocol, value)}`;
12421
- const data = encodeFunctionData({
12422
- functionName: "setContenthash",
12423
- abi: parseAbi([SET_CONTENTHASH_FUNC]),
12424
- args: [node, encodedValue]
12425
- });
12426
- resolverData.push(data);
12427
- }
12428
- };
12429
-
12430
- const addressMapByCoin = getSupportedAddressMap();
12431
- const EnsRecordsForm = ({
12432
- name,
12433
- initialRecords,
12434
- chainId,
12435
- resolverAddress,
12436
- onCancel,
12437
- onSuccess
12347
+ var TransactionState = /* @__PURE__ */ ((TransactionState2) => {
12348
+ TransactionState2["InProgress"] = "In Progress";
12349
+ TransactionState2["Completed"] = "Completed";
12350
+ TransactionState2["Failed"] = "Failed";
12351
+ return TransactionState2;
12352
+ })(TransactionState || {});
12353
+ const PendingTransaction = ({
12354
+ state,
12355
+ blockExplorerUrl,
12356
+ transactionHash,
12357
+ className = ""
12438
12358
  }) => {
12439
- const [records, setRecords] = useState(
12440
- initialRecords ? deepCopy(initialRecords) : { texts: [], addresses: [] }
12441
- );
12442
- const currentChainId = chainId || mainnet.id;
12443
- const publicClient = usePublicClient({ chainId: currentChainId });
12444
- const { data: walletClient } = useWalletClient({ chainId: currentChainId });
12445
- const { address, chain, isConnected } = useAccount();
12446
- const { switchChain } = useSwitchChain();
12447
- const [contractError, setContractError] = useState(null);
12448
- const [generalError, setGeneralError] = useState(null);
12449
- const [txIndicator, setTxIndicator] = useState({
12450
- isWaitingForTx: false,
12451
- isWaitingForWallet: false
12452
- });
12453
- const shouldSwitchNetwork = chain && chain.id !== currentChainId;
12454
- useEffect(() => {
12455
- if (!address) {
12456
- setGeneralError({
12457
- title: "Not connected",
12458
- subtitle: "Connect wallet to continue"
12459
- });
12460
- } else {
12461
- setGeneralError(null);
12462
- }
12463
- }, [address, publicClient, walletClient]);
12464
- const areValidAddresses = useMemo(() => {
12465
- for (const addr of records.addresses) {
12466
- const validateFuc = addressMapByCoin[addr.coinType].validateFunc;
12467
- if (!validateFuc) {
12468
- throw Error("Validate function not present for coin:" + addr.coinType);
12469
- }
12470
- if (addr.value?.length === 0 || !validateFuc(addr.value)) {
12471
- return false;
12472
- }
12473
- }
12474
- return true;
12475
- }, [records.addresses]);
12476
- const areValidTexts = useMemo(() => {
12477
- for (const text of records.texts) {
12478
- if (text.value.length === 0) {
12479
- return false;
12480
- }
12359
+ const getStatusIcon = () => {
12360
+ switch (state) {
12361
+ case "In Progress" /* InProgress */:
12362
+ return /* @__PURE__ */ jsx("div", { className: "ns-pending-tx__spinner" });
12363
+ case "Completed" /* Completed */:
12364
+ return /* @__PURE__ */ jsx(Icon, { name: "check-circle", size: 24 });
12365
+ case "Failed" /* Failed */:
12366
+ return /* @__PURE__ */ jsx(Icon, { name: "x-circle", size: 24 });
12367
+ default:
12368
+ return null;
12481
12369
  }
12482
- return true;
12483
- }, [records.texts]);
12484
- useMemo(() => {
12485
- if (!records.contenthash) {
12486
- return true;
12370
+ };
12371
+ const getStatusMessage = () => {
12372
+ switch (state) {
12373
+ case "In Progress" /* InProgress */:
12374
+ return "Transaction is being executed...";
12375
+ case "Completed" /* Completed */:
12376
+ return "Transaction completed successfully!";
12377
+ case "Failed" /* Failed */:
12378
+ return "Transaction failed!";
12379
+ default:
12380
+ return "";
12487
12381
  }
12488
- return isContenthashValid(
12489
- records.contenthash.protocol,
12490
- records.contenthash.value
12491
- );
12492
- }, [records.contenthash]);
12493
- const getInitalRecords = () => {
12494
- return initialRecords ? initialRecords : { texts: [], addresses: [] };
12495
12382
  };
12496
- const isDiffPresent = useMemo(() => {
12497
- const diff = getEnsRecordsDiff(getInitalRecords(), records);
12498
- const {
12499
- addressesAdded,
12500
- addressesModified,
12501
- addressesRemoved,
12502
- textsAdded,
12503
- textsModified,
12504
- textsRemoved,
12505
- contenthashRemoved,
12506
- contenthashAdded,
12507
- contenthashModified
12508
- } = diff;
12509
- return addressesAdded.length > 0 || addressesModified.length > 0 || addressesRemoved.length || textsAdded.length > 0 || textsRemoved.length > 0 || textsModified.length > 0 || contenthashRemoved === true || contenthashModified !== void 0 || contenthashAdded !== void 0;
12510
- }, [records, initialRecords]);
12511
- const handleUpdateRecords = async () => {
12512
- try {
12513
- const old = initialRecords ? initialRecords : { texts: [], addresses: [] };
12514
- const diff = getEnsRecordsDiff(old, records);
12515
- const resolverData = convertToMulticallResolverData(name, diff);
12516
- setTxIndicator({ ...txIndicator, isWaitingForWallet: true });
12517
- const { request } = await publicClient.simulateContract({
12518
- abi: ENS_RESOLVER_ABI,
12519
- args: [resolverData],
12520
- functionName: "multicall",
12521
- address: resolverAddress,
12522
- account: address
12523
- });
12524
- const tx = await walletClient.writeContract(request);
12525
- setTxIndicator({ isWaitingForTx: true, isWaitingForWallet: false });
12526
- await publicClient.waitForTransactionReceipt({ hash: tx });
12527
- onSuccess?.(tx);
12528
- } catch (err) {
12529
- console.error(err);
12530
- if (err instanceof ContractFunctionExecutionError) {
12531
- const _err = err;
12532
- setContractError(_err.details);
12533
- } else {
12534
- setContractError("Transaction failed for unknown reason!");
12535
- }
12536
- } finally {
12537
- setTxIndicator({ isWaitingForTx: false, isWaitingForWallet: false });
12383
+ const getStatusClass = () => {
12384
+ switch (state) {
12385
+ case "In Progress" /* InProgress */:
12386
+ return "ns-pending-tx--in-progress";
12387
+ case "Completed" /* Completed */:
12388
+ return "ns-pending-tx--completed";
12389
+ case "Failed" /* Failed */:
12390
+ return "ns-pending-tx--failed";
12391
+ default:
12392
+ return "";
12538
12393
  }
12539
12394
  };
12540
- const getActionButton = () => {
12541
- const areInputsValue = areValidAddresses && areValidTexts && isContenthashValid;
12542
- const style = { width: "100%" };
12543
- if (!isConnected) {
12544
- return /* @__PURE__ */ jsx(
12545
- Button,
12546
- {
12547
- style,
12548
- size: "lg",
12549
- disabled: true,
12550
- prefix: /* @__PURE__ */ jsx(Icon, { name: "alert-triangle" }),
12551
- children: "Connect Wallet"
12552
- }
12553
- );
12554
- } else if (shouldSwitchNetwork) {
12555
- return /* @__PURE__ */ jsx(
12556
- Button,
12557
- {
12558
- style,
12559
- size: "lg",
12560
- onClick: () => switchChain({ chainId: currentChainId }),
12561
- children: "Switch Network"
12562
- }
12563
- );
12564
- } else if (!areInputsValue) {
12565
- return /* @__PURE__ */ jsx(Tooltip, { content: "Invalid inputs", position: "top", children: /* @__PURE__ */ jsx(Button, { style, size: "lg", disabled: true, children: "Update" }) });
12566
- } else if (!isDiffPresent) {
12567
- return /* @__PURE__ */ jsx(Tooltip, { content: "No Records updated", position: "top", children: /* @__PURE__ */ jsx(Button, { style, size: "lg", disabled: true, children: "Update" }) });
12568
- } else {
12569
- const updateBtnLoading = txIndicator.isWaitingForTx || txIndicator.isWaitingForWallet;
12570
- return /* @__PURE__ */ jsx(
12571
- Button,
12572
- {
12573
- style,
12574
- size: "lg",
12575
- disabled: updateBtnLoading,
12576
- loading: updateBtnLoading,
12577
- onClick: () => handleUpdateRecords(),
12578
- children: "Update"
12579
- }
12580
- );
12395
+ const getIconClass = () => {
12396
+ switch (state) {
12397
+ case "In Progress" /* InProgress */:
12398
+ return "ns-pending-tx__icon--in-progress";
12399
+ case "Completed" /* Completed */:
12400
+ return "ns-pending-tx__icon--completed";
12401
+ case "Failed" /* Failed */:
12402
+ return "ns-pending-tx__icon--failed";
12403
+ default:
12404
+ return "";
12581
12405
  }
12582
12406
  };
12583
- return /* @__PURE__ */ jsxs("div", { className: "ns-edit-records-form", children: [
12407
+ return /* @__PURE__ */ jsx("div", { className: `ns-pending-tx ${getStatusClass()} ${className}`, children: /* @__PURE__ */ jsxs("div", { className: "ns-pending-tx__content", children: [
12408
+ /* @__PURE__ */ jsx("div", { className: `ns-pending-tx__icon ${getIconClass()}`, children: getStatusIcon() }),
12409
+ /* @__PURE__ */ jsx("div", { className: "ns-pending-tx__status", children: /* @__PURE__ */ jsx(Text, { children: getStatusMessage() }) }),
12410
+ transactionHash && /* @__PURE__ */ jsxs("p", { className: "ns-pending-tx__message", children: [
12411
+ "Hash: ",
12412
+ transactionHash.slice(0, 10),
12413
+ "...",
12414
+ transactionHash.slice(-8)
12415
+ ] }),
12416
+ /* @__PURE__ */ jsxs(
12417
+ "a",
12418
+ {
12419
+ href: blockExplorerUrl,
12420
+ target: "_blank",
12421
+ rel: "noopener noreferrer",
12422
+ className: "ns-pending-tx__link",
12423
+ children: [
12424
+ /* @__PURE__ */ jsx(Icon, { name: "globe", size: 16, className: "ns-pending-tx__link-icon" }),
12425
+ "View on Block Explorer"
12426
+ ]
12427
+ }
12428
+ )
12429
+ ] }) });
12430
+ };
12431
+
12432
+ const ENSNameCard = ({
12433
+ name,
12434
+ imageUrl,
12435
+ expires,
12436
+ chain = "eth",
12437
+ className = ""
12438
+ }) => /* @__PURE__ */ jsxs(Card, { className: `ens-name-card ${className}`, children: [
12439
+ /* @__PURE__ */ jsxs("div", { className: "ens-card-image-container", children: [
12440
+ /* @__PURE__ */ jsx("img", { src: imageUrl, alt: `${name} avatar`, className: "ens-card-image" }),
12441
+ /* @__PURE__ */ jsx("div", { className: "ens-card-badge", children: /* @__PURE__ */ jsx(ChainIcon, { chain, size: 25 }) })
12442
+ ] }),
12443
+ /* @__PURE__ */ jsxs("div", { className: "ens-card-body", children: [
12444
+ /* @__PURE__ */ jsx(Text, { weight: "bold", children: name }),
12445
+ /* @__PURE__ */ jsxs("div", { className: "ens-card-expiry", children: [
12446
+ /* @__PURE__ */ jsx(Icon, { name: "clock", size: 14 }),
12447
+ /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
12448
+ "Expires ",
12449
+ expires
12450
+ ] })
12451
+ ] })
12452
+ ] })
12453
+ ] });
12454
+
12455
+ const ProfileCard = ({
12456
+ bannerUrl,
12457
+ avatarUrl,
12458
+ name,
12459
+ username,
12460
+ bio,
12461
+ address,
12462
+ followers = 0,
12463
+ following = 0,
12464
+ ownedBy,
12465
+ expires,
12466
+ records = [],
12467
+ website,
12468
+ subnames = 0,
12469
+ profit = 0,
12470
+ volume = 0,
12471
+ className = ""
12472
+ }) => {
12473
+ return /* @__PURE__ */ jsxs("section", { className: `ns-profile-card ${className}`, children: [
12474
+ /* @__PURE__ */ jsxs("header", { className: "ns-profile-info", children: [
12475
+ /* @__PURE__ */ jsxs("div", { className: "ns-profile-banner", children: [
12476
+ /* @__PURE__ */ jsx("img", { src: bannerUrl, alt: "Profile banner" }),
12477
+ /* @__PURE__ */ jsxs("div", { className: "ns-profile-avatar", children: [
12478
+ /* @__PURE__ */ jsx("img", { src: avatarUrl, alt: name + " avatar" }),
12479
+ /* @__PURE__ */ jsx("div", { className: "ns-avatar-badge", children: /* @__PURE__ */ jsx(
12480
+ "img",
12481
+ {
12482
+ src: "https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png",
12483
+ alt: "chain icon",
12484
+ className: "ns-avatar-badge-icon"
12485
+ }
12486
+ ) })
12487
+ ] })
12488
+ ] }),
12489
+ /* @__PURE__ */ jsxs("div", { className: "ns-profile-body", children: [
12490
+ /* @__PURE__ */ jsx(Text, { color: "primary", weight: "bold", children: name }),
12491
+ /* @__PURE__ */ jsxs("div", { className: "ns-username-container", children: [
12492
+ /* @__PURE__ */ jsx(Text, { size: "xl", weight: "bold", children: username }),
12493
+ /* @__PURE__ */ jsx("span", { className: "ns-edit-btn", children: /* @__PURE__ */ jsx(Icon, { name: "edit", size: 16 }) })
12494
+ ] }),
12495
+ /* @__PURE__ */ jsx(Text, { size: "md", className: "ns-profile-bio", children: bio }),
12496
+ /* @__PURE__ */ jsxs("div", { className: "ns-profile-socials", children: [
12497
+ /* @__PURE__ */ jsxs("div", { className: "ns-address-box", children: [
12498
+ /* @__PURE__ */ jsx(Text, { color: "grey", className: "ns-address-text", size: "sm", children: address }),
12499
+ /* @__PURE__ */ jsx(Icon, { name: "copy", size: 16 })
12500
+ ] }),
12501
+ /* @__PURE__ */ jsx(Button, { children: /* @__PURE__ */ jsx(Icon, { name: "twitter", color: "#000000", size: 16 }) }),
12502
+ /* @__PURE__ */ jsx(Button, { children: /* @__PURE__ */ jsx(Icon, { name: "telegram", color: "#000000", size: 16 }) }),
12503
+ /* @__PURE__ */ jsx(Button, { children: /* @__PURE__ */ jsx(Icon, { name: "globe", color: "#000000", size: 16 }) }),
12504
+ /* @__PURE__ */ jsx(Button, { children: /* @__PURE__ */ jsx(Icon, { name: "github", color: "#000000", size: 16 }) })
12505
+ ] }),
12506
+ /* @__PURE__ */ jsx("div", { className: "ns-profile-stats", children: /* @__PURE__ */ jsxs("div", { className: "ns-stats-row", children: [
12507
+ /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
12508
+ followers,
12509
+ " Followers"
12510
+ ] }),
12511
+ /* @__PURE__ */ jsx(Text, { children: "\u2022" }),
12512
+ /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
12513
+ following,
12514
+ " Following"
12515
+ ] }),
12516
+ /* @__PURE__ */ jsx(Button, { size: "sm", variant: "outline", children: "Follow" })
12517
+ ] }) })
12518
+ ] })
12519
+ ] }),
12520
+ /* @__PURE__ */ jsxs("section", { className: "ns-profile-section ns-profile-links", children: [
12521
+ /* @__PURE__ */ jsxs("div", { className: "ns-extra-item", children: [
12522
+ /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
12523
+ "Owned by ",
12524
+ ownedBy
12525
+ ] }),
12526
+ /* @__PURE__ */ jsx("button", { className: "ns-extra-btn", children: /* @__PURE__ */ jsx(Icon, { name: "check-circle", size: 16 }) })
12527
+ ] }),
12528
+ /* @__PURE__ */ jsxs("div", { className: "ns-extra-item", children: [
12529
+ /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
12530
+ "Expires ",
12531
+ expires
12532
+ ] }),
12533
+ /* @__PURE__ */ jsx(Icon, { name: "info", size: 16 })
12534
+ ] }),
12535
+ /* @__PURE__ */ jsxs("div", { className: "ns-extra-item", children: [
12536
+ /* @__PURE__ */ jsx(Text, { size: "sm", children: address }),
12537
+ /* @__PURE__ */ jsx(Icon, { name: "map-pin", size: 16 })
12538
+ ] }),
12539
+ website && /* @__PURE__ */ jsxs("div", { className: "ns-extra-item", children: [
12540
+ /* @__PURE__ */ jsx(Text, { size: "sm", children: website }),
12541
+ /* @__PURE__ */ jsx("a", { href: website, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsx(Icon, { name: "globe", size: 16 }) })
12542
+ ] })
12543
+ ] }),
12544
+ /* @__PURE__ */ jsxs("footer", { className: "ns-profile-footer", children: [
12545
+ /* @__PURE__ */ jsxs("div", { className: "ns-footer-item", children: [
12546
+ /* @__PURE__ */ jsx(Text, { className: "ns-footer-label", children: subnames }),
12547
+ /* @__PURE__ */ jsx(Text, { className: "ns-footer-text", children: "Subnames" })
12548
+ ] }),
12549
+ /* @__PURE__ */ jsx(Text, { className: "ns-footer-dot", children: "\u2022" }),
12550
+ /* @__PURE__ */ jsxs("div", { className: "ns-footer-item", children: [
12551
+ /* @__PURE__ */ jsx(Text, { className: "ns-footer-label", children: profit }),
12552
+ /* @__PURE__ */ jsx(Text, { className: "ns-footer-text", children: "Profit" })
12553
+ ] }),
12554
+ /* @__PURE__ */ jsx(Text, { className: "ns-footer-dot", children: "\u2022" }),
12555
+ /* @__PURE__ */ jsxs("div", { className: "ns-footer-item", children: [
12556
+ /* @__PURE__ */ jsx(Text, { className: "ns-footer-label", children: volume }),
12557
+ /* @__PURE__ */ jsx(Text, { className: "ns-footer-text", children: "Volume" })
12558
+ ] })
12559
+ ] })
12560
+ ] });
12561
+ };
12562
+
12563
+ const NavbarProfileCard = ({
12564
+ imageUrl,
12565
+ name,
12566
+ address,
12567
+ onLogout,
12568
+ className = ""
12569
+ }) => {
12570
+ return /* @__PURE__ */ jsxs("nav", { className: `ns-navbar-profile ${className}`, "aria-label": "Profile", children: [
12584
12571
  /* @__PURE__ */ jsx(
12585
- SelectRecordsForm,
12572
+ "img",
12586
12573
  {
12587
- records,
12588
- onRecordsUpdated: (records2) => setRecords(records2)
12574
+ src: imageUrl,
12575
+ alt: name + " avatar",
12576
+ className: "ns-navbar-profile-avatar"
12589
12577
  }
12590
12578
  ),
12591
- /* @__PURE__ */ jsx("div", { style: { padding: 15, paddingTop: 0 }, children: /* @__PURE__ */ jsxs("div", { className: "d-flex align-items-center", style: { gap: "8px" }, children: [
12592
- /* @__PURE__ */ jsx(
12593
- Button,
12594
- {
12595
- onClick: () => onCancel?.(),
12596
- size: "lg",
12597
- style: { width: "100%" },
12598
- variant: "outline",
12599
- children: "Cancel"
12600
- }
12601
- ),
12602
- getActionButton()
12603
- ] }) })
12579
+ /* @__PURE__ */ jsxs("div", { className: "ns-navbar-profile-info", children: [
12580
+ /* @__PURE__ */ jsx(Text, { color: "primary", size: "md", children: name }),
12581
+ /* @__PURE__ */ jsx(Text, { color: "grey", size: "sm", children: address })
12582
+ ] }),
12583
+ /* @__PURE__ */ jsx(
12584
+ "button",
12585
+ {
12586
+ className: "ns-navbar-profile-action",
12587
+ onClick: onLogout,
12588
+ "aria-label": "Logout",
12589
+ children: /* @__PURE__ */ jsx(Icon, { name: "logout", size: 18 })
12590
+ }
12591
+ )
12604
12592
  ] });
12605
12593
  };
12606
12594
 
12607
- const useWaitForTransaction = ({ chainId: number }) => {
12595
+ const useWaitForTransaction = ({
12596
+ chainId: number
12597
+ }) => {
12608
12598
  };
12609
12599
 
12610
12600
  const useWeb3Client = ({ chainId }) => {
@@ -12616,6 +12606,17 @@ const useWeb3Client = ({ chainId }) => {
12616
12606
  };
12617
12607
  };
12618
12608
 
12609
+ const SET_TEXT_FUNC = "function setText(bytes32 node, string key, string value)";
12610
+ const SET_ADDRESS_FUNC = "function setAddr(bytes32 node, uint256 coin, bytes value)";
12611
+ const SET_CONTENTHASH_FUNC = "function setContenthash(bytes32 node, bytes value)";
12612
+ const MULTICALL = "function multicall(bytes[] data)";
12613
+ const ENS_RESOLVER_ABI = parseAbi([
12614
+ SET_TEXT_FUNC,
12615
+ SET_ADDRESS_FUNC,
12616
+ SET_CONTENTHASH_FUNC,
12617
+ MULTICALL
12618
+ ]);
12619
+
12619
12620
  const ThemeContext = createContext(void 0);
12620
12621
  const ThemeProvider = ({
12621
12622
  initialTheme = "light",
@@ -12651,5 +12652,5 @@ const useTheme = () => {
12651
12652
  return ctx;
12652
12653
  };
12653
12654
 
12654
- export { Alert, Button, ChainIcon, ContenthashIcon, ContenthashProtocol, Dropdown, ENS_RESOLVER_ABI, EnsRecordsForm, Icon, Input, MULTICALL, Modal, PendingTransaction, SET_ADDRESS_FUNC, SET_CONTENTHASH_FUNC, SET_TEXT_FUNC, SelectRecordsForm, Text, TextRecordCategory, ThemeProvider, Tooltip, TransactionState, capitalize, convertEVMChainIdToCoinType, deepCopy, equalsIgnoreCase, getEnsRecordsDiff, getSupportedAddressByCoin, getSupportedAddressByName, getSupportedAddressMap, getSupportedChashByProtocol, getSupportedText, isContenthashValid, supportedAddresses, supportedContenthashRecords, supportedTexts, useTheme, useWaitForTransaction, useWeb3Client };
12655
+ export { Alert, Button, Card, ChainIcon, ContenthashIcon, ContenthashProtocol, Dropdown, ENSNameCard, ENS_RESOLVER_ABI, Icon, Input, MULTICALL, Modal, NavbarProfileCard, PendingTransaction, ProfileCard, ProfileHeader, SET_ADDRESS_FUNC, SET_CONTENTHASH_FUNC, SET_TEXT_FUNC, SelectRecordsForm, Text, TextRecordCategory, ThemeProvider, Tooltip, TransactionState, capitalize, convertEVMChainIdToCoinType, deepCopy, equalsIgnoreCase, getEnsRecordsDiff, getSupportedAddressByCoin, getSupportedAddressByName, getSupportedAddressMap, getSupportedChashByProtocol, getSupportedText, isContenthashValid, supportedAddresses, supportedContenthashRecords, supportedTexts, useTheme, useWaitForTransaction, useWeb3Client };
12655
12656
  //# sourceMappingURL=index.js.map