@movebridge/react 0.0.1 → 0.2.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.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +196 -85
- package/dist/index.mjs +195 -84
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -340,7 +340,7 @@ declare function useWaitForTransaction(hash: string | null | undefined, options?
|
|
|
340
340
|
|
|
341
341
|
/**
|
|
342
342
|
* @movebridge/react - WalletButton component
|
|
343
|
-
* Drop-in wallet connect button
|
|
343
|
+
* Drop-in wallet connect button with improved UX
|
|
344
344
|
*/
|
|
345
345
|
/**
|
|
346
346
|
* Props for WalletButton component
|
|
@@ -354,6 +354,7 @@ interface WalletButtonProps {
|
|
|
354
354
|
/**
|
|
355
355
|
* WalletButton component
|
|
356
356
|
* Shows connect button when disconnected, address when connected
|
|
357
|
+
* Supports Razor, Nightly, and OKX wallets
|
|
357
358
|
*
|
|
358
359
|
* @example
|
|
359
360
|
* ```tsx
|
|
@@ -365,7 +366,7 @@ declare function WalletButton({ className, connectText }: WalletButtonProps): re
|
|
|
365
366
|
|
|
366
367
|
/**
|
|
367
368
|
* @movebridge/react - WalletModal component
|
|
368
|
-
* Modal for wallet selection
|
|
369
|
+
* Modal for wallet selection with Razor, Nightly, and OKX wallet support
|
|
369
370
|
*/
|
|
370
371
|
/**
|
|
371
372
|
* Props for WalletModal component
|
|
@@ -378,7 +379,7 @@ interface WalletModalProps {
|
|
|
378
379
|
}
|
|
379
380
|
/**
|
|
380
381
|
* WalletModal component
|
|
381
|
-
* Displays available wallets for selection
|
|
382
|
+
* Displays available wallets for selection with improved UX
|
|
382
383
|
*
|
|
383
384
|
* @example
|
|
384
385
|
* ```tsx
|
package/dist/index.d.ts
CHANGED
|
@@ -340,7 +340,7 @@ declare function useWaitForTransaction(hash: string | null | undefined, options?
|
|
|
340
340
|
|
|
341
341
|
/**
|
|
342
342
|
* @movebridge/react - WalletButton component
|
|
343
|
-
* Drop-in wallet connect button
|
|
343
|
+
* Drop-in wallet connect button with improved UX
|
|
344
344
|
*/
|
|
345
345
|
/**
|
|
346
346
|
* Props for WalletButton component
|
|
@@ -354,6 +354,7 @@ interface WalletButtonProps {
|
|
|
354
354
|
/**
|
|
355
355
|
* WalletButton component
|
|
356
356
|
* Shows connect button when disconnected, address when connected
|
|
357
|
+
* Supports Razor, Nightly, and OKX wallets
|
|
357
358
|
*
|
|
358
359
|
* @example
|
|
359
360
|
* ```tsx
|
|
@@ -365,7 +366,7 @@ declare function WalletButton({ className, connectText }: WalletButtonProps): re
|
|
|
365
366
|
|
|
366
367
|
/**
|
|
367
368
|
* @movebridge/react - WalletModal component
|
|
368
|
-
* Modal for wallet selection
|
|
369
|
+
* Modal for wallet selection with Razor, Nightly, and OKX wallet support
|
|
369
370
|
*/
|
|
370
371
|
/**
|
|
371
372
|
* Props for WalletModal component
|
|
@@ -378,7 +379,7 @@ interface WalletModalProps {
|
|
|
378
379
|
}
|
|
379
380
|
/**
|
|
380
381
|
* WalletModal component
|
|
381
|
-
* Displays available wallets for selection
|
|
382
|
+
* Displays available wallets for selection with improved UX
|
|
382
383
|
*
|
|
383
384
|
* @example
|
|
384
385
|
* ```tsx
|
package/dist/index.js
CHANGED
|
@@ -409,35 +409,48 @@ function useWaitForTransaction(hash, options) {
|
|
|
409
409
|
}
|
|
410
410
|
|
|
411
411
|
// src/components/WalletButton.tsx
|
|
412
|
-
var
|
|
412
|
+
var import_react7 = require("react");
|
|
413
413
|
|
|
414
414
|
// src/components/WalletModal.tsx
|
|
415
|
+
var import_react6 = require("react");
|
|
415
416
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
416
417
|
var WALLET_INFO = {
|
|
417
|
-
|
|
418
|
-
name: "
|
|
419
|
-
icon: "\
|
|
420
|
-
description: "
|
|
421
|
-
|
|
422
|
-
pontem: {
|
|
423
|
-
name: "Pontem",
|
|
424
|
-
icon: "\u{1F309}",
|
|
425
|
-
description: "Multi-chain with Movement support"
|
|
418
|
+
razor: {
|
|
419
|
+
name: "Razor Wallet",
|
|
420
|
+
icon: "\u26A1",
|
|
421
|
+
description: "Secure wallet for Movement",
|
|
422
|
+
installUrl: "https://razorwallet.xyz/"
|
|
426
423
|
},
|
|
427
424
|
nightly: {
|
|
428
425
|
name: "Nightly",
|
|
429
426
|
icon: "\u{1F319}",
|
|
430
|
-
description: "Movement
|
|
427
|
+
description: "Multi-chain Movement wallet",
|
|
428
|
+
installUrl: "https://nightly.app/"
|
|
429
|
+
},
|
|
430
|
+
okx: {
|
|
431
|
+
name: "OKX Wallet",
|
|
432
|
+
icon: "\u{1F537}",
|
|
433
|
+
description: "OKX Web3 wallet",
|
|
434
|
+
installUrl: "https://www.okx.com/web3"
|
|
431
435
|
}
|
|
432
436
|
};
|
|
433
437
|
function WalletModal({ open, onClose }) {
|
|
434
438
|
const { wallets, connect, connecting } = useMovement();
|
|
439
|
+
const [connectingWallet, setConnectingWallet] = (0, import_react6.useState)(null);
|
|
435
440
|
if (!open) return null;
|
|
436
441
|
const handleConnect = async (wallet) => {
|
|
442
|
+
setConnectingWallet(wallet);
|
|
437
443
|
try {
|
|
438
444
|
await connect(wallet);
|
|
439
445
|
onClose();
|
|
440
446
|
} catch {
|
|
447
|
+
} finally {
|
|
448
|
+
setConnectingWallet(null);
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
const handleKeyDown = (e) => {
|
|
452
|
+
if (e.key === "Escape") {
|
|
453
|
+
onClose();
|
|
441
454
|
}
|
|
442
455
|
};
|
|
443
456
|
const overlayStyles = {
|
|
@@ -493,88 +506,148 @@ function WalletModal({ open, onClose }) {
|
|
|
493
506
|
marginBottom: "8px",
|
|
494
507
|
transition: "all 0.2s ease"
|
|
495
508
|
};
|
|
509
|
+
const walletButtonDisabledStyles = {
|
|
510
|
+
...walletButtonStyles,
|
|
511
|
+
opacity: 0.6,
|
|
512
|
+
cursor: "not-allowed"
|
|
513
|
+
};
|
|
514
|
+
const walletButtonConnectingStyles = {
|
|
515
|
+
...walletButtonStyles,
|
|
516
|
+
backgroundColor: "#f3f4f6",
|
|
517
|
+
borderColor: "#6366f1"
|
|
518
|
+
};
|
|
496
519
|
const emptyStyles = {
|
|
497
520
|
textAlign: "center",
|
|
498
521
|
color: "#6b7280",
|
|
499
522
|
padding: "20px"
|
|
500
523
|
};
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
524
|
+
const installLinkStyles = {
|
|
525
|
+
display: "inline-block",
|
|
526
|
+
padding: "10px 16px",
|
|
527
|
+
backgroundColor: "#6366f1",
|
|
528
|
+
color: "white",
|
|
529
|
+
borderRadius: "8px",
|
|
530
|
+
textDecoration: "none",
|
|
531
|
+
fontSize: "14px",
|
|
532
|
+
fontWeight: 500,
|
|
533
|
+
transition: "background-color 0.2s ease"
|
|
534
|
+
};
|
|
535
|
+
const getButtonStyle = (wallet) => {
|
|
536
|
+
if (connectingWallet === wallet) return walletButtonConnectingStyles;
|
|
537
|
+
if (connecting) return walletButtonDisabledStyles;
|
|
538
|
+
return walletButtonStyles;
|
|
539
|
+
};
|
|
540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
541
|
+
"div",
|
|
542
|
+
{
|
|
543
|
+
style: overlayStyles,
|
|
544
|
+
onClick: onClose,
|
|
545
|
+
onKeyDown: handleKeyDown,
|
|
546
|
+
role: "dialog",
|
|
547
|
+
"aria-modal": "true",
|
|
548
|
+
"aria-labelledby": "wallet-modal-title",
|
|
549
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: modalStyles, onClick: (e) => e.stopPropagation(), children: [
|
|
550
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: headerStyles, children: [
|
|
551
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { id: "wallet-modal-title", style: titleStyles, children: "Connect Wallet" }),
|
|
552
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
553
|
+
"button",
|
|
554
|
+
{
|
|
555
|
+
style: closeButtonStyles,
|
|
556
|
+
onClick: onClose,
|
|
557
|
+
"aria-label": "Close wallet modal",
|
|
558
|
+
children: "\xD7"
|
|
559
|
+
}
|
|
560
|
+
)
|
|
561
|
+
] }),
|
|
562
|
+
wallets.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: emptyStyles, children: [
|
|
563
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { marginBottom: "12px" }, children: "No wallets detected." }),
|
|
564
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { style: { marginBottom: "16px" }, children: [
|
|
565
|
+
"Install a wallet that supports ",
|
|
566
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "Movement Network" }),
|
|
567
|
+
":"
|
|
568
|
+
] }),
|
|
569
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "10px" }, children: [
|
|
570
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
571
|
+
"a",
|
|
572
|
+
{
|
|
573
|
+
href: WALLET_INFO.razor.installUrl,
|
|
574
|
+
target: "_blank",
|
|
575
|
+
rel: "noopener noreferrer",
|
|
576
|
+
style: installLinkStyles,
|
|
577
|
+
"aria-label": "Install Razor Wallet",
|
|
578
|
+
children: [
|
|
579
|
+
WALLET_INFO.razor.icon,
|
|
580
|
+
" Get ",
|
|
581
|
+
WALLET_INFO.razor.name
|
|
582
|
+
]
|
|
583
|
+
}
|
|
584
|
+
),
|
|
585
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
586
|
+
"a",
|
|
587
|
+
{
|
|
588
|
+
href: WALLET_INFO.nightly.installUrl,
|
|
589
|
+
target: "_blank",
|
|
590
|
+
rel: "noopener noreferrer",
|
|
591
|
+
style: installLinkStyles,
|
|
592
|
+
"aria-label": "Install Nightly Wallet",
|
|
593
|
+
children: [
|
|
594
|
+
WALLET_INFO.nightly.icon,
|
|
595
|
+
" Get ",
|
|
596
|
+
WALLET_INFO.nightly.name
|
|
597
|
+
]
|
|
598
|
+
}
|
|
599
|
+
),
|
|
600
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
601
|
+
"a",
|
|
602
|
+
{
|
|
603
|
+
href: WALLET_INFO.okx.installUrl,
|
|
604
|
+
target: "_blank",
|
|
605
|
+
rel: "noopener noreferrer",
|
|
606
|
+
style: installLinkStyles,
|
|
607
|
+
"aria-label": "Install OKX Wallet",
|
|
608
|
+
children: [
|
|
609
|
+
WALLET_INFO.okx.icon,
|
|
610
|
+
" Get ",
|
|
611
|
+
WALLET_INFO.okx.name
|
|
612
|
+
]
|
|
613
|
+
}
|
|
614
|
+
)
|
|
615
|
+
] })
|
|
616
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { role: "list", "aria-label": "Available wallets", children: wallets.map((wallet) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
617
|
+
"button",
|
|
534
618
|
{
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
619
|
+
style: getButtonStyle(wallet),
|
|
620
|
+
onClick: () => handleConnect(wallet),
|
|
621
|
+
disabled: connecting,
|
|
622
|
+
role: "listitem",
|
|
623
|
+
"aria-label": `Connect to ${WALLET_INFO[wallet].name}`,
|
|
624
|
+
children: [
|
|
625
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "24px" }, "aria-hidden": "true", children: connectingWallet === wallet ? "\u23F3" : WALLET_INFO[wallet].icon }),
|
|
626
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { textAlign: "left", flex: 1 }, children: [
|
|
627
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontWeight: 500 }, children: [
|
|
628
|
+
WALLET_INFO[wallet].name,
|
|
629
|
+
connectingWallet === wallet && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { marginLeft: "8px", fontSize: "12px", color: "#6366f1" }, children: "Connecting..." })
|
|
630
|
+
] }),
|
|
631
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontSize: "12px", color: "#6b7280" }, children: WALLET_INFO[wallet].description })
|
|
632
|
+
] })
|
|
633
|
+
]
|
|
634
|
+
},
|
|
635
|
+
wallet
|
|
636
|
+
)) })
|
|
550
637
|
] })
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
{
|
|
554
|
-
style: walletButtonStyles,
|
|
555
|
-
onClick: () => handleConnect(wallet),
|
|
556
|
-
disabled: connecting,
|
|
557
|
-
children: [
|
|
558
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "24px" }, children: WALLET_INFO[wallet].icon }),
|
|
559
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { textAlign: "left" }, children: [
|
|
560
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children: WALLET_INFO[wallet].name }),
|
|
561
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontSize: "12px", color: "#6b7280" }, children: WALLET_INFO[wallet].description })
|
|
562
|
-
] })
|
|
563
|
-
]
|
|
564
|
-
},
|
|
565
|
-
wallet
|
|
566
|
-
)) })
|
|
567
|
-
] }) });
|
|
638
|
+
}
|
|
639
|
+
);
|
|
568
640
|
}
|
|
569
641
|
|
|
570
642
|
// src/components/WalletButton.tsx
|
|
571
643
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
572
644
|
function truncateAddress(address) {
|
|
645
|
+
if (address.length <= 10) return address;
|
|
573
646
|
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
574
647
|
}
|
|
575
648
|
function WalletButton({ className = "", connectText = "Connect Wallet" }) {
|
|
576
649
|
const { address, connected, connecting, disconnect } = useMovement();
|
|
577
|
-
const [modalOpen, setModalOpen] = (0,
|
|
650
|
+
const [modalOpen, setModalOpen] = (0, import_react7.useState)(false);
|
|
578
651
|
const baseStyles = {
|
|
579
652
|
padding: "10px 20px",
|
|
580
653
|
borderRadius: "8px",
|
|
@@ -582,7 +655,11 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
|
|
|
582
655
|
cursor: "pointer",
|
|
583
656
|
fontSize: "14px",
|
|
584
657
|
fontWeight: 500,
|
|
585
|
-
transition: "all 0.2s ease"
|
|
658
|
+
transition: "all 0.2s ease",
|
|
659
|
+
display: "inline-flex",
|
|
660
|
+
alignItems: "center",
|
|
661
|
+
justifyContent: "center",
|
|
662
|
+
gap: "8px"
|
|
586
663
|
};
|
|
587
664
|
const connectedStyles = {
|
|
588
665
|
...baseStyles,
|
|
@@ -594,15 +671,49 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
|
|
|
594
671
|
backgroundColor: "#6366f1",
|
|
595
672
|
color: "white"
|
|
596
673
|
};
|
|
674
|
+
const connectingStyles = {
|
|
675
|
+
...baseStyles,
|
|
676
|
+
backgroundColor: "#818cf8",
|
|
677
|
+
color: "white",
|
|
678
|
+
cursor: "wait"
|
|
679
|
+
};
|
|
597
680
|
if (connected && address) {
|
|
598
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.
|
|
681
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
599
682
|
"button",
|
|
600
683
|
{
|
|
601
684
|
className,
|
|
602
685
|
style: connectedStyles,
|
|
603
686
|
onClick: disconnect,
|
|
604
687
|
title: "Click to disconnect",
|
|
605
|
-
|
|
688
|
+
"aria-label": `Connected as ${truncateAddress(address)}. Click to disconnect.`,
|
|
689
|
+
children: [
|
|
690
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: {
|
|
691
|
+
width: "8px",
|
|
692
|
+
height: "8px",
|
|
693
|
+
borderRadius: "50%",
|
|
694
|
+
backgroundColor: "#22c55e",
|
|
695
|
+
display: "inline-block"
|
|
696
|
+
}, "aria-hidden": "true" }),
|
|
697
|
+
truncateAddress(address)
|
|
698
|
+
]
|
|
699
|
+
}
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
if (connecting) {
|
|
703
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
704
|
+
"button",
|
|
705
|
+
{
|
|
706
|
+
className,
|
|
707
|
+
style: connectingStyles,
|
|
708
|
+
disabled: true,
|
|
709
|
+
"aria-label": "Connecting to wallet",
|
|
710
|
+
children: [
|
|
711
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: {
|
|
712
|
+
display: "inline-block",
|
|
713
|
+
animation: "spin 1s linear infinite"
|
|
714
|
+
}, "aria-hidden": "true", children: "\u23F3" }),
|
|
715
|
+
"Connecting..."
|
|
716
|
+
]
|
|
606
717
|
}
|
|
607
718
|
);
|
|
608
719
|
}
|
|
@@ -613,8 +724,8 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
|
|
|
613
724
|
className,
|
|
614
725
|
style: disconnectedStyles,
|
|
615
726
|
onClick: () => setModalOpen(true),
|
|
616
|
-
|
|
617
|
-
children:
|
|
727
|
+
"aria-label": connectText,
|
|
728
|
+
children: connectText
|
|
618
729
|
}
|
|
619
730
|
),
|
|
620
731
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(WalletModal, { open: modalOpen, onClose: () => setModalOpen(false) })
|
|
@@ -622,7 +733,7 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
|
|
|
622
733
|
}
|
|
623
734
|
|
|
624
735
|
// src/components/AddressDisplay.tsx
|
|
625
|
-
var
|
|
736
|
+
var import_react8 = require("react");
|
|
626
737
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
627
738
|
function truncateAddress2(address, startChars = 6, endChars = 4) {
|
|
628
739
|
if (address.length <= startChars + endChars + 3) {
|
|
@@ -636,8 +747,8 @@ function AddressDisplay({
|
|
|
636
747
|
copyable = true,
|
|
637
748
|
className = ""
|
|
638
749
|
}) {
|
|
639
|
-
const [copied, setCopied] = (0,
|
|
640
|
-
const handleCopy = (0,
|
|
750
|
+
const [copied, setCopied] = (0, import_react8.useState)(false);
|
|
751
|
+
const handleCopy = (0, import_react8.useCallback)(async () => {
|
|
641
752
|
try {
|
|
642
753
|
await navigator.clipboard.writeText(address);
|
|
643
754
|
setCopied(true);
|
package/dist/index.mjs
CHANGED
|
@@ -375,35 +375,48 @@ function useWaitForTransaction(hash, options) {
|
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
// src/components/WalletButton.tsx
|
|
378
|
-
import { useState as
|
|
378
|
+
import { useState as useState7 } from "react";
|
|
379
379
|
|
|
380
380
|
// src/components/WalletModal.tsx
|
|
381
|
+
import { useState as useState6 } from "react";
|
|
381
382
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
382
383
|
var WALLET_INFO = {
|
|
383
|
-
|
|
384
|
-
name: "
|
|
385
|
-
icon: "\
|
|
386
|
-
description: "
|
|
387
|
-
|
|
388
|
-
pontem: {
|
|
389
|
-
name: "Pontem",
|
|
390
|
-
icon: "\u{1F309}",
|
|
391
|
-
description: "Multi-chain with Movement support"
|
|
384
|
+
razor: {
|
|
385
|
+
name: "Razor Wallet",
|
|
386
|
+
icon: "\u26A1",
|
|
387
|
+
description: "Secure wallet for Movement",
|
|
388
|
+
installUrl: "https://razorwallet.xyz/"
|
|
392
389
|
},
|
|
393
390
|
nightly: {
|
|
394
391
|
name: "Nightly",
|
|
395
392
|
icon: "\u{1F319}",
|
|
396
|
-
description: "Movement
|
|
393
|
+
description: "Multi-chain Movement wallet",
|
|
394
|
+
installUrl: "https://nightly.app/"
|
|
395
|
+
},
|
|
396
|
+
okx: {
|
|
397
|
+
name: "OKX Wallet",
|
|
398
|
+
icon: "\u{1F537}",
|
|
399
|
+
description: "OKX Web3 wallet",
|
|
400
|
+
installUrl: "https://www.okx.com/web3"
|
|
397
401
|
}
|
|
398
402
|
};
|
|
399
403
|
function WalletModal({ open, onClose }) {
|
|
400
404
|
const { wallets, connect, connecting } = useMovement();
|
|
405
|
+
const [connectingWallet, setConnectingWallet] = useState6(null);
|
|
401
406
|
if (!open) return null;
|
|
402
407
|
const handleConnect = async (wallet) => {
|
|
408
|
+
setConnectingWallet(wallet);
|
|
403
409
|
try {
|
|
404
410
|
await connect(wallet);
|
|
405
411
|
onClose();
|
|
406
412
|
} catch {
|
|
413
|
+
} finally {
|
|
414
|
+
setConnectingWallet(null);
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
const handleKeyDown = (e) => {
|
|
418
|
+
if (e.key === "Escape") {
|
|
419
|
+
onClose();
|
|
407
420
|
}
|
|
408
421
|
};
|
|
409
422
|
const overlayStyles = {
|
|
@@ -459,88 +472,148 @@ function WalletModal({ open, onClose }) {
|
|
|
459
472
|
marginBottom: "8px",
|
|
460
473
|
transition: "all 0.2s ease"
|
|
461
474
|
};
|
|
475
|
+
const walletButtonDisabledStyles = {
|
|
476
|
+
...walletButtonStyles,
|
|
477
|
+
opacity: 0.6,
|
|
478
|
+
cursor: "not-allowed"
|
|
479
|
+
};
|
|
480
|
+
const walletButtonConnectingStyles = {
|
|
481
|
+
...walletButtonStyles,
|
|
482
|
+
backgroundColor: "#f3f4f6",
|
|
483
|
+
borderColor: "#6366f1"
|
|
484
|
+
};
|
|
462
485
|
const emptyStyles = {
|
|
463
486
|
textAlign: "center",
|
|
464
487
|
color: "#6b7280",
|
|
465
488
|
padding: "20px"
|
|
466
489
|
};
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
490
|
+
const installLinkStyles = {
|
|
491
|
+
display: "inline-block",
|
|
492
|
+
padding: "10px 16px",
|
|
493
|
+
backgroundColor: "#6366f1",
|
|
494
|
+
color: "white",
|
|
495
|
+
borderRadius: "8px",
|
|
496
|
+
textDecoration: "none",
|
|
497
|
+
fontSize: "14px",
|
|
498
|
+
fontWeight: 500,
|
|
499
|
+
transition: "background-color 0.2s ease"
|
|
500
|
+
};
|
|
501
|
+
const getButtonStyle = (wallet) => {
|
|
502
|
+
if (connectingWallet === wallet) return walletButtonConnectingStyles;
|
|
503
|
+
if (connecting) return walletButtonDisabledStyles;
|
|
504
|
+
return walletButtonStyles;
|
|
505
|
+
};
|
|
506
|
+
return /* @__PURE__ */ jsx2(
|
|
507
|
+
"div",
|
|
508
|
+
{
|
|
509
|
+
style: overlayStyles,
|
|
510
|
+
onClick: onClose,
|
|
511
|
+
onKeyDown: handleKeyDown,
|
|
512
|
+
role: "dialog",
|
|
513
|
+
"aria-modal": "true",
|
|
514
|
+
"aria-labelledby": "wallet-modal-title",
|
|
515
|
+
children: /* @__PURE__ */ jsxs("div", { style: modalStyles, onClick: (e) => e.stopPropagation(), children: [
|
|
516
|
+
/* @__PURE__ */ jsxs("div", { style: headerStyles, children: [
|
|
517
|
+
/* @__PURE__ */ jsx2("h2", { id: "wallet-modal-title", style: titleStyles, children: "Connect Wallet" }),
|
|
518
|
+
/* @__PURE__ */ jsx2(
|
|
519
|
+
"button",
|
|
520
|
+
{
|
|
521
|
+
style: closeButtonStyles,
|
|
522
|
+
onClick: onClose,
|
|
523
|
+
"aria-label": "Close wallet modal",
|
|
524
|
+
children: "\xD7"
|
|
525
|
+
}
|
|
526
|
+
)
|
|
527
|
+
] }),
|
|
528
|
+
wallets.length === 0 ? /* @__PURE__ */ jsxs("div", { style: emptyStyles, children: [
|
|
529
|
+
/* @__PURE__ */ jsx2("p", { style: { marginBottom: "12px" }, children: "No wallets detected." }),
|
|
530
|
+
/* @__PURE__ */ jsxs("p", { style: { marginBottom: "16px" }, children: [
|
|
531
|
+
"Install a wallet that supports ",
|
|
532
|
+
/* @__PURE__ */ jsx2("strong", { children: "Movement Network" }),
|
|
533
|
+
":"
|
|
534
|
+
] }),
|
|
535
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "10px" }, children: [
|
|
536
|
+
/* @__PURE__ */ jsxs(
|
|
537
|
+
"a",
|
|
538
|
+
{
|
|
539
|
+
href: WALLET_INFO.razor.installUrl,
|
|
540
|
+
target: "_blank",
|
|
541
|
+
rel: "noopener noreferrer",
|
|
542
|
+
style: installLinkStyles,
|
|
543
|
+
"aria-label": "Install Razor Wallet",
|
|
544
|
+
children: [
|
|
545
|
+
WALLET_INFO.razor.icon,
|
|
546
|
+
" Get ",
|
|
547
|
+
WALLET_INFO.razor.name
|
|
548
|
+
]
|
|
549
|
+
}
|
|
550
|
+
),
|
|
551
|
+
/* @__PURE__ */ jsxs(
|
|
552
|
+
"a",
|
|
553
|
+
{
|
|
554
|
+
href: WALLET_INFO.nightly.installUrl,
|
|
555
|
+
target: "_blank",
|
|
556
|
+
rel: "noopener noreferrer",
|
|
557
|
+
style: installLinkStyles,
|
|
558
|
+
"aria-label": "Install Nightly Wallet",
|
|
559
|
+
children: [
|
|
560
|
+
WALLET_INFO.nightly.icon,
|
|
561
|
+
" Get ",
|
|
562
|
+
WALLET_INFO.nightly.name
|
|
563
|
+
]
|
|
564
|
+
}
|
|
565
|
+
),
|
|
566
|
+
/* @__PURE__ */ jsxs(
|
|
567
|
+
"a",
|
|
568
|
+
{
|
|
569
|
+
href: WALLET_INFO.okx.installUrl,
|
|
570
|
+
target: "_blank",
|
|
571
|
+
rel: "noopener noreferrer",
|
|
572
|
+
style: installLinkStyles,
|
|
573
|
+
"aria-label": "Install OKX Wallet",
|
|
574
|
+
children: [
|
|
575
|
+
WALLET_INFO.okx.icon,
|
|
576
|
+
" Get ",
|
|
577
|
+
WALLET_INFO.okx.name
|
|
578
|
+
]
|
|
579
|
+
}
|
|
580
|
+
)
|
|
581
|
+
] })
|
|
582
|
+
] }) : /* @__PURE__ */ jsx2("div", { role: "list", "aria-label": "Available wallets", children: wallets.map((wallet) => /* @__PURE__ */ jsxs(
|
|
583
|
+
"button",
|
|
500
584
|
{
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
585
|
+
style: getButtonStyle(wallet),
|
|
586
|
+
onClick: () => handleConnect(wallet),
|
|
587
|
+
disabled: connecting,
|
|
588
|
+
role: "listitem",
|
|
589
|
+
"aria-label": `Connect to ${WALLET_INFO[wallet].name}`,
|
|
590
|
+
children: [
|
|
591
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: "24px" }, "aria-hidden": "true", children: connectingWallet === wallet ? "\u23F3" : WALLET_INFO[wallet].icon }),
|
|
592
|
+
/* @__PURE__ */ jsxs("div", { style: { textAlign: "left", flex: 1 }, children: [
|
|
593
|
+
/* @__PURE__ */ jsxs("div", { style: { fontWeight: 500 }, children: [
|
|
594
|
+
WALLET_INFO[wallet].name,
|
|
595
|
+
connectingWallet === wallet && /* @__PURE__ */ jsx2("span", { style: { marginLeft: "8px", fontSize: "12px", color: "#6366f1" }, children: "Connecting..." })
|
|
596
|
+
] }),
|
|
597
|
+
/* @__PURE__ */ jsx2("div", { style: { fontSize: "12px", color: "#6b7280" }, children: WALLET_INFO[wallet].description })
|
|
598
|
+
] })
|
|
599
|
+
]
|
|
600
|
+
},
|
|
601
|
+
wallet
|
|
602
|
+
)) })
|
|
516
603
|
] })
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
{
|
|
520
|
-
style: walletButtonStyles,
|
|
521
|
-
onClick: () => handleConnect(wallet),
|
|
522
|
-
disabled: connecting,
|
|
523
|
-
children: [
|
|
524
|
-
/* @__PURE__ */ jsx2("span", { style: { fontSize: "24px" }, children: WALLET_INFO[wallet].icon }),
|
|
525
|
-
/* @__PURE__ */ jsxs("div", { style: { textAlign: "left" }, children: [
|
|
526
|
-
/* @__PURE__ */ jsx2("div", { children: WALLET_INFO[wallet].name }),
|
|
527
|
-
/* @__PURE__ */ jsx2("div", { style: { fontSize: "12px", color: "#6b7280" }, children: WALLET_INFO[wallet].description })
|
|
528
|
-
] })
|
|
529
|
-
]
|
|
530
|
-
},
|
|
531
|
-
wallet
|
|
532
|
-
)) })
|
|
533
|
-
] }) });
|
|
604
|
+
}
|
|
605
|
+
);
|
|
534
606
|
}
|
|
535
607
|
|
|
536
608
|
// src/components/WalletButton.tsx
|
|
537
609
|
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
538
610
|
function truncateAddress(address) {
|
|
611
|
+
if (address.length <= 10) return address;
|
|
539
612
|
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
540
613
|
}
|
|
541
614
|
function WalletButton({ className = "", connectText = "Connect Wallet" }) {
|
|
542
615
|
const { address, connected, connecting, disconnect } = useMovement();
|
|
543
|
-
const [modalOpen, setModalOpen] =
|
|
616
|
+
const [modalOpen, setModalOpen] = useState7(false);
|
|
544
617
|
const baseStyles = {
|
|
545
618
|
padding: "10px 20px",
|
|
546
619
|
borderRadius: "8px",
|
|
@@ -548,7 +621,11 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
|
|
|
548
621
|
cursor: "pointer",
|
|
549
622
|
fontSize: "14px",
|
|
550
623
|
fontWeight: 500,
|
|
551
|
-
transition: "all 0.2s ease"
|
|
624
|
+
transition: "all 0.2s ease",
|
|
625
|
+
display: "inline-flex",
|
|
626
|
+
alignItems: "center",
|
|
627
|
+
justifyContent: "center",
|
|
628
|
+
gap: "8px"
|
|
552
629
|
};
|
|
553
630
|
const connectedStyles = {
|
|
554
631
|
...baseStyles,
|
|
@@ -560,15 +637,49 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
|
|
|
560
637
|
backgroundColor: "#6366f1",
|
|
561
638
|
color: "white"
|
|
562
639
|
};
|
|
640
|
+
const connectingStyles = {
|
|
641
|
+
...baseStyles,
|
|
642
|
+
backgroundColor: "#818cf8",
|
|
643
|
+
color: "white",
|
|
644
|
+
cursor: "wait"
|
|
645
|
+
};
|
|
563
646
|
if (connected && address) {
|
|
564
|
-
return /* @__PURE__ */
|
|
647
|
+
return /* @__PURE__ */ jsxs2(
|
|
565
648
|
"button",
|
|
566
649
|
{
|
|
567
650
|
className,
|
|
568
651
|
style: connectedStyles,
|
|
569
652
|
onClick: disconnect,
|
|
570
653
|
title: "Click to disconnect",
|
|
571
|
-
|
|
654
|
+
"aria-label": `Connected as ${truncateAddress(address)}. Click to disconnect.`,
|
|
655
|
+
children: [
|
|
656
|
+
/* @__PURE__ */ jsx3("span", { style: {
|
|
657
|
+
width: "8px",
|
|
658
|
+
height: "8px",
|
|
659
|
+
borderRadius: "50%",
|
|
660
|
+
backgroundColor: "#22c55e",
|
|
661
|
+
display: "inline-block"
|
|
662
|
+
}, "aria-hidden": "true" }),
|
|
663
|
+
truncateAddress(address)
|
|
664
|
+
]
|
|
665
|
+
}
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
if (connecting) {
|
|
669
|
+
return /* @__PURE__ */ jsxs2(
|
|
670
|
+
"button",
|
|
671
|
+
{
|
|
672
|
+
className,
|
|
673
|
+
style: connectingStyles,
|
|
674
|
+
disabled: true,
|
|
675
|
+
"aria-label": "Connecting to wallet",
|
|
676
|
+
children: [
|
|
677
|
+
/* @__PURE__ */ jsx3("span", { style: {
|
|
678
|
+
display: "inline-block",
|
|
679
|
+
animation: "spin 1s linear infinite"
|
|
680
|
+
}, "aria-hidden": "true", children: "\u23F3" }),
|
|
681
|
+
"Connecting..."
|
|
682
|
+
]
|
|
572
683
|
}
|
|
573
684
|
);
|
|
574
685
|
}
|
|
@@ -579,8 +690,8 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
|
|
|
579
690
|
className,
|
|
580
691
|
style: disconnectedStyles,
|
|
581
692
|
onClick: () => setModalOpen(true),
|
|
582
|
-
|
|
583
|
-
children:
|
|
693
|
+
"aria-label": connectText,
|
|
694
|
+
children: connectText
|
|
584
695
|
}
|
|
585
696
|
),
|
|
586
697
|
/* @__PURE__ */ jsx3(WalletModal, { open: modalOpen, onClose: () => setModalOpen(false) })
|
|
@@ -588,7 +699,7 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
|
|
|
588
699
|
}
|
|
589
700
|
|
|
590
701
|
// src/components/AddressDisplay.tsx
|
|
591
|
-
import { useState as
|
|
702
|
+
import { useState as useState8, useCallback as useCallback5 } from "react";
|
|
592
703
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
593
704
|
function truncateAddress2(address, startChars = 6, endChars = 4) {
|
|
594
705
|
if (address.length <= startChars + endChars + 3) {
|
|
@@ -602,7 +713,7 @@ function AddressDisplay({
|
|
|
602
713
|
copyable = true,
|
|
603
714
|
className = ""
|
|
604
715
|
}) {
|
|
605
|
-
const [copied, setCopied] =
|
|
716
|
+
const [copied, setCopied] = useState8(false);
|
|
606
717
|
const handleCopy = useCallback5(async () => {
|
|
607
718
|
try {
|
|
608
719
|
await navigator.clipboard.writeText(address);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@movebridge/react",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "React hooks and components for Movement Network",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@movebridge/core": "0.0
|
|
19
|
+
"@movebridge/core": "0.2.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@testing-library/react": "^14.1.0",
|