Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TW-1648 Add an overlay for confirming 'silent' signatures on Ledger #1255

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "temple-wallet",
"version": "1.32.1",
"version": "1.32.2",
"private": true,
"scripts": {
"start-run": "cross-env TS_NODE_PROJECT=\"webpack/tsconfig.json\" webpack --watch --stats errors-warnings",
Expand Down
64 changes: 48 additions & 16 deletions src/app/pages/TempleTapAirdrop/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import clsx from 'clsx';
import { OnSubmit, useForm } from 'react-hook-form';

import { Alert, Anchor, FormField, FormSubmitButton } from 'app/atoms';
import ConfirmLedgerOverlay from 'app/atoms/ConfirmLedgerOverlay';
import { ReactComponent as TelegramSvg } from 'app/icons/social-tg.svg';
import { ReactComponent as XSocialSvg } from 'app/icons/social-x.svg';
import PageLayout from 'app/layouts/PageLayout';
Expand All @@ -14,6 +15,7 @@ import { useTypedSWR } from 'lib/swr';
import { useAccount, useTempleClient, useTezos } from 'lib/temple/front';
import { TempleAccountType } from 'lib/temple/types';
import { useLocalStorage } from 'lib/ui/local-storage';
import { navigate } from 'lib/woozie';

import BannerImgSrc from './banner.png';
import { ReactComponent as ConfirmedSvg } from './confirmed.svg';
Expand All @@ -23,15 +25,15 @@ interface FormData {
}

export const TempleTapAirdropPage = memo(() => {
const account = useAccount();
const accountPkh = account.publicKeyHash;
const { type: accountType, publicKeyHash: accountPkh } = useAccount();
const isLedger = accountType === TempleAccountType.Ledger;

const tezos = useTezos();
const { silentSign } = useTempleClient();

const canSign = useMemo(
() => [TempleAccountType.HD, TempleAccountType.Imported, TempleAccountType.Ledger].includes(account.type),
[account.type]
() => [TempleAccountType.HD, TempleAccountType.Imported, TempleAccountType.Ledger].includes(accountType),
[accountType]
);

const [storedRecord, setStoredRecord] = useLocalStorage<LocalStorageRecord | null>(
Expand All @@ -40,6 +42,7 @@ export const TempleTapAirdropPage = memo(() => {
);

const [confirmSent, setConfirmSent] = useState(false);
const [signing, setSigning] = useState(false);
const [confirmed, setConfirmed] = useState(storedRecord?.[accountPkh] ?? false);

const prepSigAuthValues = useCallback(async (): Promise<SigAuthValues> => {
Expand All @@ -53,24 +56,34 @@ export const TempleTapAirdropPage = memo(() => {
return { publicKey, messageBytes, signature };
}, [silentSign, tezos.signer, accountPkh]);

useTypedSWR(
const { data: airdropChecked } = useTypedSWR(
['temple-tap-airdrop-confirm-check', accountPkh],
async () => {
if (confirmed || !canSign) return null;
try {
if (confirmed || !canSign) return true;

const sigAuthValues = await prepSigAuthValues();

const sigAuthValues = await prepSigAuthValues();
const confirmedRes = await checkTempleTapAirdropConfirmation(accountPkh, sigAuthValues);

const confirmedRes = await checkTempleTapAirdropConfirmation(accountPkh, sigAuthValues);
if (!confirmedRes) return true;

if (!confirmedRes) return null;
setConfirmed(true);
setStoredRecord(state => ({ ...state, [accountPkh]: true }));

setConfirmed(true);
setStoredRecord(state => ({ ...state, [accountPkh]: true }));
return true;
} catch (e) {
if (isLedger) {
navigate('/');

return true;
}

return null;
throw e;
}
},
{
suspense: true,
suspense: !isLedger,
revalidateOnFocus: false,
refreshInterval: 60_000,
errorRetryInterval: 60_000
Expand All @@ -86,7 +99,9 @@ export const TempleTapAirdropPage = memo(() => {
clearError();

try {
setSigning(true);
const sigAuthValues = await prepSigAuthValues();
setSigning(false);

const res = await sendTempleTapAirdropUsernameConfirmation(accountPkh, usernameOrId, sigAuthValues);

Expand All @@ -104,14 +119,29 @@ export const TempleTapAirdropPage = memo(() => {
} catch (error: any) {
console.error(error);

setError('usernameOrId', 'submit-error', error?.response?.data?.message || 'Something went wrong...');
if (isLedger) {
navigate('/');
} else {
setError('usernameOrId', 'submit-error', error?.response?.data?.message || 'Something went wrong...');
setSigning(false);
}
}
},
[reset, clearError, setError, setStoredRecord, prepSigAuthValues, accountPkh]
[reset, clearError, setError, setStoredRecord, prepSigAuthValues, accountPkh, isLedger]
);

if (!airdropChecked && isLedger) {
return (
<PageLayout pageTitle="Temple Tap Airdrop" withBell contentContainerStyle={{ position: 'relative' }}>
<div className="flex flex-col w-full max-w-sm mx-auto pb-6" style={{ height: 660 }} />

<ConfirmLedgerOverlay displayed />
</PageLayout>
);
}

return (
<PageLayout pageTitle="Temple Tap Airdrop" withBell>
<PageLayout pageTitle="Temple Tap Airdrop" withBell contentContainerStyle={{ position: 'relative' }}>
<div className="flex flex-col w-full max-w-sm mx-auto pb-6">
<img src={BannerImgSrc} alt="Banner" className="self-center h-28" />

Expand Down Expand Up @@ -187,6 +217,8 @@ export const TempleTapAirdropPage = memo(() => {
<SocialItem title="MadFish Community" IconComp={TelegramSvg} followUrl="https://t.me/MadFishCommunity" />
</BlockComp>
</div>

<ConfirmLedgerOverlay displayed={signing && isLedger} />
</PageLayout>
);
});
Expand Down
Loading