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

Feat: restore wallet - get data from cloud storage #15

Merged
merged 8 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
1 change: 1 addition & 0 deletions src/common/assets/gifs/Gift.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/common/assets/gifs/Welcome.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/common/assets/gifs/wallet creation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"nm":"abca840cc58f0ac8fc0443d06aa48cb9","ddd":0,"h":400,"w":400,"meta":{"g":"@lottiefiles/toolkit-js 0.33.2"},"layers":[{"ty":4,"nm":"Shape Layer 1","sr":1,"st":0,"op":154,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"s":true,"x":{"a":0,"k":200,"ix":3},"y":{"a":1,"k":[{"o":{"x":0.48,"y":0},"i":{"x":0.29,"y":1},"s":[208],"t":0},{"o":{"x":0.167,"y":0},"i":{"x":0.29,"y":1},"s":[272],"t":25.2},{"o":{"x":0.71,"y":0},"i":{"x":0.52,"y":1},"s":[272],"t":118},{"s":[208],"t":143.2001953125}],"ix":4},"z":{"a":0,"k":0}},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Rectangle 1","ix":1,"cix":2,"np":7,"it":[{"ty":"rc","bm":0,"hd":false,"mn":"ADBE Vector Shape - Rect","nm":"Rectangle Path 1","d":1,"p":{"a":0,"k":[-10,-7],"ix":3},"r":{"a":0,"k":20,"ix":4},"s":{"a":0,"k":[119,245],"ix":2}},{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[-16,-58],"ix":3},"s":{"a":0,"k":[61,61],"ix":2}},{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":3,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[26.405,-14.469],[5.924,-35.197]]},"ix":2}},{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 3","ix":4,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[-11.046,0],[0,0]],"o":[[0,0],[11.046,0]],"v":[[-50.62,52.112],[28.38,52.112]]},"ix":2}},{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 2","ix":5,"d":1,"ks":{"a":0,"k":{"c":false,"i":[[-11.046,0],[0,0]],"o":[[0,0],[11.046,0]],"v":[[-49.248,70.027],[29.752,70.027]]},"ix":2}},{"ty":"tm","bm":0,"hd":false,"mn":"ADBE Vector Filter - Trim","nm":"Trim Paths 1","ix":6,"e":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":4.5},{"o":{"x":0.167,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":26.101},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":122.5},{"s":[100],"t":144.1005859375}],"ix":2},"o":{"a":0,"k":0,"ix":3},"s":{"a":0,"k":0,"ix":1},"m":1},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":2,"ml":1,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"c":{"a":0,"k":[0.9333,0.9333,0.9333],"ix":3}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":21,"ix":4},"p":{"a":0,"k":[3,-26],"ix":2},"r":{"a":0,"k":29,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":1},{"ty":4,"nm":"Shape Layer 3","sr":1,"st":0,"op":154,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[200,208,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":26.101},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":40.5},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":93},{"s":[100],"t":119.701171875}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Rectangle 2","ix":1,"cix":2,"np":2,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.24,"y":1},"s":[-22,-18],"t":23.4,"ti":[6.5,0],"to":[-6.5,0]},{"o":{"x":0.333,"y":0},"i":{"x":0.24,"y":1},"s":[-61,-18],"t":40.5,"ti":[-6.5,0],"to":[-6.5,0]},{"o":{"x":0.76,"y":0},"i":{"x":0.667,"y":1},"s":[-61,-18],"t":90.3,"ti":[-6.5,0],"to":[6.5,0]},{"s":[-22,-18],"t":119.701171875}],"ix":3},"s":{"a":0,"k":[63,63],"ix":2}},{"ty":"gf","bm":0,"hd":false,"mn":"ADBE Vector Graphic - G-Fill","nm":"Gradient Fill 1","e":{"a":0,"k":[-3.742,-42.483],"ix":6},"g":{"p":3,"k":{"a":0,"k":[0,0.8784313725490196,0.22745098039215686,0.12549019607843137,0.5,0.8274509803921568,0.5019607843137255,0.3058823529411765,1,0.6078431372549019,0.20784313725490197,0.2549019607843137],"ix":9}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"s":{"a":0,"k":[-37.957,6.132],"ix":5},"r":1,"o":{"a":0,"k":100,"ix":10}},{"ty":"tr","a":{"a":0,"k":[-23.07,-17.887],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":21,"ix":4},"p":{"a":0,"k":[-2.5,-49.5],"ix":2},"r":{"a":0,"k":29,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Rectangle 1","ix":2,"cix":2,"np":2,"it":[{"ty":"rc","bm":0,"hd":false,"mn":"ADBE Vector Shape - Rect","nm":"Rectangle Path 1","d":1,"p":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.24,"y":1},"s":[80,81],"t":23.4,"ti":[-9.167,0],"to":[9.167,0]},{"o":{"x":0.333,"y":0},"i":{"x":0.24,"y":1},"s":[135,81],"t":40.5,"ti":[9.167,0],"to":[9.167,0]},{"o":{"x":0.76,"y":0},"i":{"x":0.667,"y":1},"s":[135,81],"t":90.3,"ti":[9.167,0],"to":[-9.167,0]},{"s":[80,81],"t":119.701171875}],"ix":3},"r":{"a":0,"k":0,"ix":4},"s":{"a":0,"k":[95,53],"ix":2}},{"ty":"gf","bm":0,"hd":false,"mn":"ADBE Vector Graphic - G-Fill","nm":"Gradient Fill 2","e":{"a":0,"k":[118.698,59.387],"ix":6},"g":{"p":3,"k":{"a":0,"k":[0,0.8117647058823529,0.25098039215686274,0.16470588235294117,0.5,0.8784313725490196,0.20784313725490197,0.2901960784313726,1,0.4,0.11372549019607843,0.14901960784313725],"ix":9}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"s":{"a":0,"k":[41.725,103.253],"ix":5},"r":1,"o":{"a":0,"k":100,"ix":10}},{"ty":"tr","a":{"a":0,"k":[78.508,81.245],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":21,"ix":4},"p":{"a":0,"k":[5,68],"ix":2},"r":{"a":0,"k":29,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":2},{"ty":4,"nm":"Shape Layer 2","sr":1,"st":0,"op":154,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"s":true,"x":{"a":0,"k":200,"ix":3},"y":{"a":1,"k":[{"o":{"x":0.8,"y":0},"i":{"x":0.14,"y":1},"s":[208],"t":40.5},{"o":{"x":0.67,"y":0},"i":{"x":0.14,"y":1},"s":[248],"t":63.001},{"o":{"x":0.67,"y":0},"i":{"x":0.667,"y":1},"s":[248],"t":72.001},{"s":[208],"t":98}],"ix":4},"z":{"a":0,"k":0}},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":49},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":66},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[0],"t":69},{"s":[100],"t":88}],"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Rectangle 2","ix":1,"cix":2,"np":2,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[42,142],"ix":3},"s":{"a":0,"k":[25,25],"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.0549,0.0549,0.0549],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":21,"ix":4},"p":{"a":0,"k":[3,-26],"ix":2},"r":{"a":0,"k":29,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]},{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Rectangle 1","ix":2,"cix":2,"np":2,"it":[{"ty":"rc","bm":0,"hd":false,"mn":"ADBE Vector Shape - Rect","nm":"Rectangle Path 1","d":1,"p":{"a":0,"k":[42,48],"ix":3},"r":{"a":0,"k":20,"ix":4},"s":{"a":0,"k":[119,245],"ix":2}},{"ty":"gf","bm":0,"hd":false,"mn":"ADBE Vector Graphic - G-Fill","nm":"Gradient Fill 1","e":{"a":0,"k":[81.506,-69.83],"ix":6},"g":{"p":3,"k":{"a":0,"k":[0,0.10588235294117647,0.10588235294117647,0.10588235294117647,0.5,0.16470588235294117,0.16470588235294117,0.16470588235294117,1,0.34509803921568627,0.34509803921568627,0.34509803921568627],"ix":9}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"s":{"a":0,"k":[13.491,142.014],"ix":5},"r":1,"o":{"a":0,"k":100,"ix":10}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":21,"ix":4},"p":{"a":0,"k":[3,-26],"ix":2},"r":{"a":0,"k":29,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":3}],"v":"5.7.8","fr":30,"op":150,"ip":0,"assets":[]}
2 changes: 2 additions & 0 deletions src/common/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const PUBLIC_KEY_STORE = 'publicKey';
export const MNEMONIC_STORE = 'mnemonic';
18 changes: 12 additions & 6 deletions src/common/wallet/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ const CryptoJS = require('crypto-js');

import secureLocalStorage from 'react-secure-storage';

const PUBLIC_KEY_STORE = 'publicKey';
const MNEMONIC_STORE = 'mnemonic';

import { Keyring } from '@polkadot/api';
import { KeyringPair } from '@polkadot/keyring/types';
import { MNEMONIC_STORE, PUBLIC_KEY_STORE } from '../utils/constants';

const keyring = new Keyring({ type: 'sr25519' });

Expand All @@ -28,15 +26,15 @@ export const generateWalletMnemonic = (): string => {
return mnemonicGenerate();
};

export const createWallet = (mnemonic: string): HexString => {
export const createWallet = (mnemonic: string): Wallet => {
const seed = mnemonicToMiniSecret(mnemonic);
const keypair = sr25519PairFromSeed(seed);
const publicKey: HexString = u8aToHex(keypair.publicKey);

localStorage.setItem(PUBLIC_KEY_STORE, publicKey);
secureLocalStorage.setItem(MNEMONIC_STORE, mnemonic);

return publicKey;
return { publicKey: publicKey };
};

export const backupMnemonic = (mnemonic: string, password: string): void => {
Expand Down Expand Up @@ -76,5 +74,13 @@ export const getKeyringPair = (password: string): KeyringPair | undefined => {
export const resetWallet = () => {
localStorage.removeItem(PUBLIC_KEY_STORE);
secureLocalStorage.removeItem(MNEMONIC_STORE);
window.Telegram.WebApp.CloudStorage.removeItem(MNEMONIC_STORE);
};

export const initializeWalletFromCloud = (password: string, encryptedMnemonic: string): boolean => {
const mnemonic = AES.decrypt(encryptedMnemonic, password).toString(CryptoJS.enc.Utf8);
if (!mnemonic) return false;

createWallet(mnemonic);

return true;
};
2 changes: 0 additions & 2 deletions src/components/AssetsList/Asset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ export const AssetBalance = ({ value, asset, className, imgClassName }: Props) =
const { precision, symbol } = asset;
const { formattedValue, suffix } = formatBalance(value, precision);

console.log(suffix, formattedValue);

return (
<span className={cnTw('flex items-center gap-x-2', className)}>
<Icon name={symbol} size={40} alt="logo" className={imgClassName} />
Expand Down
7 changes: 5 additions & 2 deletions src/components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import Image from 'next/image';
import { FootnoteText } from '../Typography';
import AllIcons, { IconNames } from './types';
import Image from 'next/image';

type Props = {
name: IconNames;
size?: number;
className?: string;
alt?: string;
text?: string;
priority?: boolean;
};

const Icon = ({ name, size = 24, className, text, alt = '' }: Props) => {
const Icon = ({ name, size = 24, className, text, priority, alt = '' }: Props) => {
let iconPath = AllIcons[name];

if (!iconPath) {
Expand All @@ -27,6 +28,7 @@ const Icon = ({ name, size = 24, className, text, alt = '' }: Props) => {
alt={alt}
width={size}
height={size}
priority={priority}
data-testid={`${name}-img`}
/>
<FootnoteText as="span">{text}</FootnoteText>
Expand All @@ -38,6 +40,7 @@ const Icon = ({ name, size = 24, className, text, alt = '' }: Props) => {
alt={alt}
width={size}
height={size}
priority={priority}
data-testid={`${name}-img`}
/>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/PasswordForm/PasswordForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export default function PasswordForm({ onSubmit }: PasswordFormProps) {
onValueChange={setConfirmPassword}
onClear={() => setConfirmPassword('')}
/>
<BodyText as="span" className={cnTw('self-start', VariantStyles[hintColor])}>
<BodyText align="left" as="span" className={cnTw('self-start', VariantStyles[hintColor])}>
<ul className="list-disc space-y-1 ml-5">
<li>8 characters minimum</li>
<li>Include 1 number (0-9)</li>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Typography/components/BodyText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import { TypographyProps } from '../common/types';
import TextBase from '../common/TextBase';

export const BodyText = ({ className, ...props }: TypographyProps) => (
<TextBase className={cnTw('text-body', className)} {...props} />
<TextBase className={cnTw('text-body', className)} align="center" {...props} />
);
4 changes: 2 additions & 2 deletions src/pages/onboarding/create-wallet/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default function CreateWalletPage() {

return isLoading ? (
<div className="min-h-screen flex flex-col justify-center items-center">
<Icon name="createWallet" size={256} alt="create wallet" />
<Icon name="createWallet" size={256} alt="create wallet" priority />
<BodyText>Creating your wallet</BodyText>
</div>
) : (
Expand All @@ -53,7 +53,7 @@ export default function CreateWalletPage() {
<Icon name="firework" size={60} alt="firework" />
</div>
<TitleText className="m-3">Your wallet has been created!</TitleText>
<BodyText className="text-text-hint" align="center">
<BodyText className="text-text-hint">
Your gateway to the world of digital assets is now open, and your financial future is in your hands. Safely
store, send, and receive funds with confidence.
<br />
Expand Down
62 changes: 19 additions & 43 deletions src/pages/onboarding/index.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,31 @@
import { useEffect } from 'react';
import { Avatar } from '@nextui-org/react';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';

import { useTelegram } from '@common/providers/telegramProvider';
import { Paths } from '@/common/routing';
import { TitleText, BodyText, CaptionText } from '@/components/Typography';
import Icon from '@/components/Icon/Icon';
import { OnboardingStartPage, RestoreWalletPage } from '@/screens/onboarding';
import { MNEMONIC_STORE } from '@/common/utils/constants';

export default function OnboardingStartPage() {
const router = useRouter();
const { MainButton } = useTelegram();
export default function OnboardingPage() {
const { webApp } = useTelegram();
const [isLoading, setIsLoading] = useState(true);
const [mnemonic, setMnenonic] = useState<string | null>(null);

useEffect(() => {
MainButton?.show();
MainButton?.onClick(() => {
router.push(Paths.ONBOARDING_PASSWORD);
MainButton?.showProgress(false);
webApp?.CloudStorage.getItem(MNEMONIC_STORE, (_err, value) => {
setMnenonic(value);
});

return () => {
MainButton?.hideProgress();
MainButton?.disable();
};
}, [MainButton]);
// to avoid blinking
setTimeout(() => {
setIsLoading(false);
}, 1000);
}, [webApp]);

// TODO: replace with loader
if (isLoading) return <div>LOADING</div>;

return (
<div className="h-screen flex flex-col items-center p-4">
<Avatar src="" size="lg" className="w-[128px] h-[128px]" name="Nova" />
<TitleText className="mt-6 mb-3">Welcome to Nova Wallet!</TitleText>
<BodyText className="text-text-hint mb-7" align="center">
Welcome aboard! Securely store, send, and receive your Polkadot funds with ease. Dive into Polkadot funds
management!
</BodyText>
<div className="flex gap-4 mb-6">
<Icon name="DOT" size={48} />
<div>
<CaptionText>Easy crypto operations</CaptionText>
<BodyText className="text-text-hint">
Welcome aboard! Securely store, send, and receive your Polkadot funds with ease.{' '}
</BodyText>
</div>
</div>
<div className="flex gap-4">
<Icon name="DOT" size={48} />
<div>
<CaptionText>Easy crypto operations</CaptionText>
<BodyText className="text-text-hint">
Welcome aboard! Securely store, send, and receive your Polkadot funds with ease.{' '}
</BodyText>
</div>
</div>
<div className="min-h-screen flex flex-col items-center text-center p-4">
{mnemonic ? <RestoreWalletPage mnemonic={mnemonic} /> : <OnboardingStartPage />}
</div>
);
}
6 changes: 3 additions & 3 deletions src/pages/onboarding/password/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function PasswordPage() {
router.push(Paths.ONBOARDING_CREATE_WALLET);

const mnemonic = generateWalletMnemonic();
const publicKey = createWallet(mnemonic);
const { publicKey } = createWallet(mnemonic);

setPublicKey(publicKey);
backupMnemonic(mnemonic, password);
Expand All @@ -32,8 +32,8 @@ export default function PasswordPage() {
return (
<div className="min-h-screen flex flex-col items-center text-center p-4">
<Avatar src={user?.photo_url} size="lg" className="w-[64px] h-[64px]" name={user?.first_name[0]} />
<TitleText className="m-4 px-6">Hey {user?.first_name}! Let’s secure your new wallet</TitleText>
<BodyText className="text-text-hint px-6" align="center">
<TitleText className="m-4 px-6">Hey {user?.first_name || 'friend'}! Let’s secure your new wallet</TitleText>
<BodyText className="text-text-hint px-6">
It&apos;s like locking the door to your financial fortress. Your chosen password will be the key to ensure your
assets are safe and sound.
</BodyText>
Expand Down
2 changes: 1 addition & 1 deletion src/screens/dashboard/main/DashboardMain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { useGlobalContext } from '@/common/providers/contextProvider';
import { useTelegram } from '@/common/providers/telegramProvider';
import { BodyText, CaptionText, Icon, AssetsList, Plate, Price } from '@/components';

// temp mock
// TODO: remove temp mock
const mockAssets = [
{
name: 'polkadot',
Expand Down
9 changes: 0 additions & 9 deletions src/screens/onboarding/import-wallet/ImportWallet.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions src/screens/onboarding/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { OnboardingStartPage } from './start/Start';
export { ImportWalletPage } from './import-wallet/ImportWallet';
export { OnboardingStartPage } from './start/OnboardingStartPage';
export { RestoreWalletPage } from './restore/RestoreWallet';
73 changes: 73 additions & 0 deletions src/screens/onboarding/restore/RestoreWallet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
'use client';
import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';

import { useTelegram } from '@/common/providers/telegramProvider';
import { Avatar, Input } from '@nextui-org/react';
import { BodyText, TitleText } from '@/components/Typography';
import { Paths } from '@/common/routing';
import { initializeWalletFromCloud } from '@/common/wallet';

type Props = {
mnemonic: string;
};

export const RestoreWalletPage = ({ mnemonic }: Props) => {
const router = useRouter();
const { MainButton, user } = useTelegram();
const [password, setPassword] = useState('');
const [isPasswordValid, setIsPasswordValid] = useState(true);

useEffect(() => {
MainButton?.show();
MainButton?.disable();

return () => {
MainButton?.disable();
};
}, []);

useEffect(() => {
if (password.length) {
MainButton?.enable();

MainButton?.onClick(() => {
if (password.length < 8) {
setIsPasswordValid(false);

return;
}
const isWalletInitialized = initializeWalletFromCloud(password, mnemonic);
setIsPasswordValid(isWalletInitialized);

if (isWalletInitialized) {
router.push(Paths.DASHBOARD);
}
});
} else {
MainButton?.disable();
}
}, [password]);

return (
<>
<Avatar src={user?.photo_url} size="lg" className="w-[64px] h-[64px]" name={user?.first_name[0]} />
<TitleText className="m-4 px-6">Welcome back {user?.first_name || 'friend'}!</TitleText>
<BodyText as="span" className="text-text-hint px-6 mb-8">
We&apos;ve discovered a backup of your existing wallet in the cloud. To restore it just enter your password.
</BodyText>
<Input
isClearable
variant="flat"
placeholder="Enter 8-character password here"
type="password"
className="max-w-sm text-left"
value={password}
isInvalid={!isPasswordValid}
errorMessage={!isPasswordValid && 'It seems your password is incorrect.'}
onValueChange={setPassword}
onClear={() => setPassword('')}
/>
</>
);
};
Loading