diff --git a/app/wallet/address-modal.js b/app/wallet/address-modal.js
deleted file mode 100644
index 5c3cde1..0000000
--- a/app/wallet/address-modal.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Modal } from '@mantine/core';
-
-import SendForm from '../../components/send-form';
-
-export default function AddressModal(props) {
- return (
-
-
-
- );
-}
diff --git a/app/wallet/message-tab.js b/app/wallet/message-tab.js
deleted file mode 100644
index 96324e3..0000000
--- a/app/wallet/message-tab.js
+++ /dev/null
@@ -1,48 +0,0 @@
-import { Box, Group, Textarea, Button } from '@mantine/core';
-import { useForm } from '@mantine/form';
-import { useDisclosure } from '@mantine/hooks';
-import { useState } from 'react';
-import { signMessage } from '../../lib/ledger';
-
-import MessageModal from './message-modal';
-
-export default function MessageTab(props) {
- const [signature, setSignature] = useState();
- const [opened, { open, close }] = useDisclosure(false);
-
- const form = useForm({
- initialValues: {
- message: '',
- },
- });
-
- const onClickSignMessage = () => {
- const path = props.selectedAddress.derivationPath.split('/');
- signMessage(form.values.message, Number(path[3]), Number(path[4])).then((result) => {
- setSignature(result.signature);
-
- open();
- });
- };
-
- return (
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/app/wallet/overview-tab.js b/app/wallet/overview-tab.js
index a9093b5..1e66d07 100644
--- a/app/wallet/overview-tab.js
+++ b/app/wallet/overview-tab.js
@@ -7,12 +7,14 @@ import {
Loader,
CopyButton,
UnstyledButton,
+ SegmentedControl,
} from '@mantine/core';
import { useViewportSize } from '@mantine/hooks';
import { notifications } from '@mantine/notifications';
import { useRef, useState, useEffect } from 'react';
import KaspaQrCode from '@/components/kaspa-qrcode';
import SendForm from '@/components/send-form';
+import MessageForm from '@/components/message-form';
import { IconCopy, IconCheck, IconShieldCheckFilled, IconShield } from '@tabler/icons-react';
import AddressText from '@/components/address-text';
import { fetchAddressDetails, getAddress } from '@/lib/ledger';
@@ -25,6 +27,7 @@ export default function OverviewTab(props) {
const groupRef = useRef(null);
const [updatingDetails, setUpdatingDetails] = useState(false);
const [isAddressVerified, setIsAddressVerified] = useState(false);
+ const [signView, setSignView] = useState('Transaction');
const { width, height } = useViewportSize();
const selectedAddress = props.selectedAddress || {};
@@ -148,10 +151,33 @@ export default function OverviewTab(props) {
const scrollHeight =
groupRef && groupRef.current ? height - groupRef.current.offsetTop : height;
+ let signSection = null;
+
+ switch (signView) {
+ case 'Transaction':
+ signSection = (
+
+ );
+ break;
+ case 'Message':
+ signSection = ;
+ break;
+ default:
+ break;
+ }
+
return (
<>
- = 700 ? '2rem' : '1rem'} pb={width >= 700 ? '0rem' : '1rem'}>
+ = 700 ? '2rem' : '1rem'}
+ pb={width >= 700 ? '0rem' : '1rem'}
+ align='top'
+ >
Receive Address:
@@ -210,12 +236,15 @@ export default function OverviewTab(props) {
{divider}
-
+
+
+ {signSection}
+
>
diff --git a/app/wallet/page.js b/app/wallet/page.js
index 46a7098..b22795f 100644
--- a/app/wallet/page.js
+++ b/app/wallet/page.js
@@ -13,7 +13,6 @@ import Header from '../../components/header';
import AddressesTab from './addresses-tab';
import OverviewTab from './overview-tab';
import TransactionsTab from './transactions-tab';
-import MessageTab from './message-tab';
import { useSearchParams } from 'next/navigation';
import { IconCircleX } from '@tabler/icons-react';
import { format } from 'date-fns';
@@ -408,9 +407,6 @@ export default function Dashboard(props) {
Transactions
-
- Message
-
@@ -447,10 +443,6 @@ export default function Dashboard(props) {
containerHeight={containerHeight}
/>
-
-
-
-
diff --git a/components/message-form.js b/components/message-form.js
new file mode 100644
index 0000000..a47da2a
--- /dev/null
+++ b/components/message-form.js
@@ -0,0 +1,83 @@
+import { Box, Group, Textarea, Button } from '@mantine/core';
+import { useForm } from '@mantine/form';
+import { useDisclosure } from '@mantine/hooks';
+import { useState } from 'react';
+import { signMessage } from '../lib/ledger';
+
+import MessageModal from './message-modal';
+import { notifications } from '@mantine/notifications';
+
+export default function MessageForm(props) {
+ const [signature, setSignature] = useState();
+ const [opened, { open, close }] = useDisclosure(false);
+
+ const form = useForm({
+ initialValues: {
+ message: '',
+ },
+ validate: {
+ message: (value) => (!value ? 'message required' : null),
+ },
+ });
+
+ const onClickSignMessage = async () => {
+ const notifId = notifications.show({
+ title: 'Action Required',
+ message: 'Please review the message on your device',
+ loading: true,
+ });
+
+ try {
+ const path = props.selectedAddress.derivationPath.split('/');
+ const result = await signMessage(form.values.message, Number(path[3]), Number(path[4]));
+ setSignature(result.signature);
+
+ open();
+ } catch (e) {
+ if (e.statusText === 'CONDITIONS_OF_USE_NOT_SATISFIED' && e.message) {
+ notifications.show({
+ title: 'Error',
+ message: e.message,
+ });
+ } else if (e.statusCode == 45073) {
+ notifications.show({
+ title: 'Error',
+ message: 'Message too long',
+ });
+ } else {
+ notifications.show({
+ title: 'Error',
+ message: 'Message signing failed',
+ });
+ console.error(e);
+ }
+ } finally {
+ notifications.hide(notifId);
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/wallet/message-modal.js b/components/message-modal.js
similarity index 100%
rename from app/wallet/message-modal.js
rename to components/message-modal.js
diff --git a/components/send-form.js b/components/send-form.js
index c6cbe3e..1353e1f 100644
--- a/components/send-form.js
+++ b/components/send-form.js
@@ -34,8 +34,7 @@ export default function SendForm(props) {
const deviceType = searchParams.get('deviceType');
const { width: viewportWidth } = useViewportSize();
- const cleanupOnSuccess = (notifId, transactionId) => {
- notifications.hide(notifId);
+ const cleanupOnSuccess = (transactionId) => {
const targetAmount = includeFeeInAmount ? Number((amount - fee).toFixed(8)) : amount;
setSentAmount(targetAmount);
setSentTo(sendTo);
@@ -58,10 +57,9 @@ export default function SendForm(props) {
// Hide when ledger confirms
const notifId = args[0];
- cleanupOnSuccess(
- notifId,
- 'c130ca7a3edeeeb2dc0130a8bac188c040415dc3ef2265d541336334c3c75f00',
- );
+ notifications.hide(notifId);
+
+ cleanupOnSuccess('c130ca7a3edeeeb2dc0130a8bac188c040415dc3ef2265d541336334c3c75f00');
}, 3000);
const signAndSend = async () => {
@@ -87,7 +85,7 @@ export default function SendForm(props) {
const transactionId = await sendAmount(tx, deviceType);
- cleanupOnSuccess(notifId, transactionId);
+ cleanupOnSuccess(transactionId);
} catch (e) {
console.error(e);
notifications.show({
@@ -96,6 +94,8 @@ export default function SendForm(props) {
loading: false,
});
setConfirming(false);
+ } finally {
+ notifications.hide(notifId);
}
}
};