diff --git a/src/components/AddTokenDialog.js b/src/components/AddTokenDialog.js
index 8d762a1..34512c1 100644
--- a/src/components/AddTokenDialog.js
+++ b/src/components/AddTokenDialog.js
@@ -82,7 +82,7 @@ export default function AddTokenDialog({ open, onClose }) {
{tokenAccountCost ? (
Add a token to your wallet. This will cost{' '}
- {feeFormat.format(tokenAccountCost / LAMPORTS_PER_SOL)} Solana.
+ {feeFormat.format(tokenAccountCost / LAMPORTS_PER_SOL)} SOL.
) : (
diff --git a/src/components/BalancesList.js b/src/components/BalancesList.js
index 553ae81..f795bfb 100644
--- a/src/components/BalancesList.js
+++ b/src/components/BalancesList.js
@@ -13,6 +13,7 @@ import LoadingIndicator from './LoadingIndicator';
import Collapse from '@material-ui/core/Collapse';
import { Typography } from '@material-ui/core';
import TokenInfoDialog from './TokenInfoDialog';
+import Link from '@material-ui/core/Link';
import ExpandLess from '@material-ui/icons/ExpandLess';
import ExpandMore from '@material-ui/icons/ExpandMore';
import { makeStyles } from '@material-ui/core/styles';
@@ -25,12 +26,16 @@ import Toolbar from '@material-ui/core/Toolbar';
import AddIcon from '@material-ui/icons/Add';
import RefreshIcon from '@material-ui/icons/Refresh';
import IconButton from '@material-ui/core/IconButton';
-import InfoIcon from '@material-ui/icons/Info';
+import InfoIcon from '@material-ui/icons/InfoOutlined';
import Tooltip from '@material-ui/core/Tooltip';
import AddTokenDialog from './AddTokenDialog';
import SendDialog from './SendDialog';
import DepositDialog from './DepositDialog';
-import { refreshAccountInfo } from '../utils/connection';
+import {
+ refreshAccountInfo,
+ useSolanaExplorerUrlSuffix,
+} from '../utils/connection';
+import { showTokenInfoDialog } from '../utils/config';
const balanceFormat = new Intl.NumberFormat(undefined, {
minimumFractionDigits: 4,
@@ -106,15 +111,12 @@ function BalanceListItem({ publicKey }) {
const balanceInfo = useBalanceInfo(publicKey);
const classes = useStyles();
const [open, setOpen] = useState(false);
- const [sendDialogOpen, setSendDialogOpen] = useState(false);
- const [depositDialogOpen, setDepositDialogOpen] = useState(false);
- const [tokenInfoDialogOpen, setTokenInfoDialogOpen] = useState(false);
if (!balanceInfo) {
return ;
}
- let { amount, decimals, mint, tokenName, tokenSymbol, owner } = balanceInfo;
+ let { amount, decimals, mint, tokenName, tokenSymbol } = balanceInfo;
return (
<>
@@ -133,37 +135,86 @@ function BalanceListItem({ publicKey }) {
{open ? : }
-
-
- {!publicKey.equals(owner) && (
- }
- onClick={() => setTokenInfoDialogOpen(true)}
- >
- Token Info
-
- )}
- }
- onClick={() => setDepositDialogOpen(true)}
- >
- Receive
-
- }
- onClick={() => setSendDialogOpen(true)}
- >
- Send
-
-
-
+
+ >
+ );
+}
+
+function BalanceListItemDetails({ publicKey, balanceInfo }) {
+ const urlSuffix = useSolanaExplorerUrlSuffix();
+ const classes = useStyles();
+ const [sendDialogOpen, setSendDialogOpen] = useState(false);
+ const [depositDialogOpen, setDepositDialogOpen] = useState(false);
+ const [tokenInfoDialogOpen, setTokenInfoDialogOpen] = useState(false);
+
+ if (!balanceInfo) {
+ return ;
+ }
+
+ let { mint, tokenName, tokenSymbol, owner } = balanceInfo;
+
+ return (
+ <>
+
+
+ {!publicKey.equals(owner) && showTokenInfoDialog ? (
+ }
+ onClick={() => setTokenInfoDialogOpen(true)}
+ >
+ Token Info
+
+ ) : null}
+ }
+ onClick={() => setDepositDialogOpen(true)}
+ >
+ Receive
+
+ }
+ onClick={() => setSendDialogOpen(true)}
+ >
+ Send
+
+
+
+ Deposit Address: {publicKey.toBase58()}
+
+
+ Token Name: {tokenName ?? 'Unknown'}
+
+
+ Token Symbol: {tokenSymbol ?? 'Unknown'}
+
+ {mint ? (
+
+ Token Address: {mint.toBase58()}
+
+ ) : null}
+
+
+ View on Solana Explorer
+
+
+
setSendDialogOpen(false)}
diff --git a/src/components/CopyableDisplay.js b/src/components/CopyableDisplay.js
index 0991fcf..236d75e 100644
--- a/src/components/CopyableDisplay.js
+++ b/src/components/CopyableDisplay.js
@@ -1,8 +1,13 @@
import React, { useRef } from 'react';
-import { Button, TextField } from '@material-ui/core';
+import { TextField } from '@material-ui/core';
import CopyIcon from 'mdi-material-ui/ContentCopy';
import { makeStyles } from '@material-ui/core/styles';
import { useSnackbar } from 'notistack';
+import QrcodeIcon from 'mdi-material-ui/Qrcode';
+import QRCode from 'qrcode.react';
+import DialogForm from './DialogForm';
+import DialogContent from '@material-ui/core/DialogContent';
+import IconButton from '@material-ui/core/IconButton';
const useStyles = makeStyles((theme) => ({
root: {
@@ -10,21 +15,13 @@ const useStyles = makeStyles((theme) => ({
marginTop: theme.spacing(1),
marginBottom: theme.spacing(1),
},
- button: {
- marginLeft: theme.spacing(3),
- whiteSpace: 'nowrap',
- marginTop: theme.spacing(2),
- },
- buttonIcon: {
- marginRight: theme.spacing(1),
- },
}));
export default function CopyableDisplay({
value,
label,
autoFocus,
- buttonProps,
+ qrCode,
helperText,
}) {
const { enqueueSnackbar } = useSnackbar();
@@ -57,14 +54,37 @@ export default function CopyableDisplay({
label={label}
spellCheck={false}
/>
-
+
+
+
+ {qrCode ? : null}
);
}
+
+const useQrCodeStyles = makeStyles((theme) => ({
+ qrcodeContainer: {
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ marginBottom: theme.spacing(2),
+ },
+}));
+
+function Qrcode({ value }) {
+ const [showQrcode, setShowQrcode] = React.useState(false);
+ const classes = useQrCodeStyles();
+
+ return (
+ <>
+ setShowQrcode(true)}>
+
+
+ setShowQrcode(false)}>
+
+
+
+
+ >
+ );
+}
diff --git a/src/components/DepositDialog.js b/src/components/DepositDialog.js
index 5503532..258c722 100644
--- a/src/components/DepositDialog.js
+++ b/src/components/DepositDialog.js
@@ -3,11 +3,12 @@ import DialogTitle from '@material-ui/core/DialogTitle';
import DialogContent from '@material-ui/core/DialogContent';
import DialogForm from './DialogForm';
import { abbreviateAddress } from '../utils/utils';
-import { Button, Typography } from '@material-ui/core';
import CopyableDisplay from './CopyableDisplay';
-import { makeStyles } from '@material-ui/core/styles';
-import QrcodeIcon from 'mdi-material-ui/Qrcode';
-import QRCode from 'qrcode.react';
+import Link from '@material-ui/core/Link';
+import { useSolanaExplorerUrlSuffix } from '../utils/connection';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogActions from '@material-ui/core/DialogActions';
+import Button from '@material-ui/core/Button';
export default function DepositDialog({
open,
@@ -15,72 +16,50 @@ export default function DepositDialog({
publicKey,
balanceInfo,
}) {
+ const urlSuffix = useSolanaExplorerUrlSuffix();
let { mint, tokenName, tokenSymbol, owner } = balanceInfo;
return (
- Deposit {tokenName ?? abbreviateAddress(mint)}
+ Deposit {tokenName ?? mint.toBase58()}
{tokenSymbol ? ` (${tokenSymbol})` : null}
{publicKey.equals(owner) ? (
-
+
This address can only be used to receive SOL. Do not send other
tokens to this address.
-
+
) : (
-
- This address can only be used to receive {tokenSymbol}. Do not send
- SOL to this address.
-
+
+ This address can only be used to receive{' '}
+ {tokenSymbol ?? abbreviateAddress(mint)}. Do not send SOL to this
+ address.
+
)}
-
+
+
+ View on Solana Explorer
+
+
+
+
+
);
}
-
-const useQrCodeStyles = makeStyles((theme) => ({
- qrcodeButton: {
- marginTop: theme.spacing(1),
- marginBottom: theme.spacing(2),
- },
- qrcodeIcon: {
- marginRight: theme.spacing(1),
- },
- qrcodeContainer: {
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- marginBottom: theme.spacing(2),
- },
-}));
-
-function Qrcode({ value }) {
- const [showQrcode, setShowQrcode] = React.useState(false);
-
- const classes = useQrCodeStyles();
- return (
- <>
-
- {showQrcode && (
-
-
-
- )}
- >
- );
-}
diff --git a/src/components/NavigationFrame.js b/src/components/NavigationFrame.js
index 966f545..09228a7 100644
--- a/src/components/NavigationFrame.js
+++ b/src/components/NavigationFrame.js
@@ -22,6 +22,7 @@ import Tooltip from '@material-ui/core/Tooltip';
const useStyles = makeStyles((theme) => ({
content: {
+ flexGrow: 1,
paddingTop: theme.spacing(3),
paddingBottom: theme.spacing(3),
paddingLeft: theme.spacing(1),
@@ -49,34 +50,10 @@ export default function NavigationFrame({ children }) {
-
-
-
-
-
-
-
-
-
-
{children}
+
>
);
}
@@ -215,3 +192,30 @@ function WalletSelector() {
>
);
}
+
+const useFooterStyles = makeStyles((theme) => ({
+ footer: {
+ display: 'flex',
+ justifyContent: 'flex-end',
+ margin: theme.spacing(2),
+ },
+}));
+
+function Footer() {
+ const classes = useFooterStyles();
+ return (
+
+ );
+}
diff --git a/src/index.css b/src/index.css
index ec2585e..d7d11d5 100644
--- a/src/index.css
+++ b/src/index.css
@@ -7,7 +7,11 @@ body {
-moz-osx-font-smoothing: grayscale;
}
-code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
- monospace;
+html, body, #root {
+ height: 100%;
+}
+
+#root {
+ display: flex;
+ flex-direction: column;
}
diff --git a/src/utils/config.js b/src/utils/config.js
new file mode 100644
index 0000000..c756dda
--- /dev/null
+++ b/src/utils/config.js
@@ -0,0 +1,3 @@
+export const showTokenInfoDialog = !!localStorage.getItem(
+ 'showTokenInfoDialog',
+);