From f37eac826b0fd6b0a66926b0430bd42d5fff3fd8 Mon Sep 17 00:00:00 2001 From: hunaniangstudio <891863891@qq.com> Date: Thu, 12 Oct 2023 14:48:50 +0800 Subject: [PATCH] feat: support restoring wallet from OW --- src/shared/constant/index.ts | 7 + src/shared/types.ts | 1 + src/ui/pages/Account/CreateHDWalletScreen.tsx | 214 +++++++++++------- src/ui/pages/Main/SettingsTabScreen.tsx | 24 +- .../pages/Settings/ExportMnemonicsScreen.tsx | 2 +- 5 files changed, 154 insertions(+), 94 deletions(-) diff --git a/src/shared/constant/index.ts b/src/shared/constant/index.ts index 611dc436..083b16c3 100644 --- a/src/shared/constant/index.ts +++ b/src/shared/constant/index.ts @@ -162,6 +162,8 @@ export const ADDRESS_TYPES: { } ]; +export const OW_HD_PATH = "m/86'/0'/0'"; + export const RESTORE_WALLETS: { value: RestoreWalletType; name: string; addressTypes: AddressType[] }[] = [ { value: RestoreWalletType.UNISAT, @@ -185,6 +187,11 @@ export const RESTORE_WALLETS: { value: RestoreWalletType; name: string; addressT name: 'Xverse Wallet', addressTypes: [AddressType.P2SH_P2WPKH, AddressType.P2TR] }, + { + value: RestoreWalletType.OW, + name: 'Ordinals Wallet', + addressTypes: [AddressType.P2TR] + }, { value: RestoreWalletType.OTHERS, name: 'Other Wallet', diff --git a/src/shared/types.ts b/src/shared/types.ts index b5917218..d104cb55 100644 --- a/src/shared/types.ts +++ b/src/shared/types.ts @@ -18,6 +18,7 @@ export enum RestoreWalletType { UNISAT, SPARROW, XVERSE, + OW, OTHERS } diff --git a/src/ui/pages/Account/CreateHDWalletScreen.tsx b/src/ui/pages/Account/CreateHDWalletScreen.tsx index 17680a76..2d32b4ff 100644 --- a/src/ui/pages/Account/CreateHDWalletScreen.tsx +++ b/src/ui/pages/Account/CreateHDWalletScreen.tsx @@ -5,7 +5,7 @@ import bitcore from 'bitcore-lib'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { useLocation } from 'react-router-dom'; -import { ADDRESS_TYPES, RESTORE_WALLETS } from '@/shared/constant'; +import { ADDRESS_TYPES, OW_HD_PATH, RESTORE_WALLETS } from '@/shared/constant'; import { AddressType, RestoreWalletType } from '@/shared/types'; import { Button, Card, Column, Content, Grid, Header, Input, Layout, Row, Text } from '@/ui/components'; import { useTools } from '@/ui/components/ActionComponent'; @@ -141,11 +141,22 @@ function Step1_Import({ contextData: ContextData; updateContextData: (params: UpdateContextDataParams) => void; }) { - const [keys, setKeys] = useState>(new Array(wordsItems[contextData.wordsType].count).fill('')); const [curInputIndex, setCurInputIndex] = useState(0); const [hover, setHover] = useState(999); const [disabled, setDisabled] = useState(true); + const wordsItems = useMemo(() => { + if (contextData.restoreWalletType === RestoreWalletType.OW) { + return [WORDS_12_ITEM]; + } else if (contextData.restoreWalletType === RestoreWalletType.XVERSE) { + return [WORDS_12_ITEM]; + } else { + return [WORDS_12_ITEM, WORDS_24_ITEM]; + } + }, [contextData]); + + const [keys, setKeys] = useState>(new Array(wordsItems[contextData.wordsType].count).fill('')); + const handleEventPaste = (event, index: number) => { const copyText = event.clipboardData?.getData('text/plain'); const textArr = copyText.trim().split(' '); @@ -192,9 +203,21 @@ function Step1_Import({ //todo }, [hover]); - const onNext = () => { - const mnemonics = keys.join(' '); - updateContextData({ mnemonics, tabType: TabType.STEP3 }); + const createAccount = useCreateAccountCallback(); + const navigate = useNavigate(); + const tools = useTools(); + const onNext = async () => { + try { + const mnemonics = keys.join(' '); + if (contextData.restoreWalletType === RestoreWalletType.OW) { + await createAccount(mnemonics, OW_HD_PATH, '', AddressType.P2TR, 1); + navigate('MainScreen'); + } else { + updateContextData({ mnemonics, tabType: TabType.STEP3 }); + } + } catch (e) { + tools.toastError((e as any).message); + } }; const handleOnKeyUp = (e: React.KeyboardEvent) => { if (!disabled && 'Enter' == e.key) { @@ -207,21 +230,23 @@ function Step1_Import({ - - { - const wordsType = e.target.value; - updateContextData({ wordsType }); - setKeys(new Array(wordsItems[wordsType].count).fill('')); - }} - value={contextData.wordsType}> - {wordsItems.map((v) => ( - - {v.label} - - ))} - - + {wordsItems.length > 1 ? ( + + { + const wordsType = e.target.value; + updateContextData({ wordsType }); + setKeys(new Array(wordsItems[wordsType].count).fill('')); + }} + value={contextData.wordsType}> + {wordsItems.map((v) => ( + + {v.label} + + ))} + + + ) : null} @@ -320,14 +345,16 @@ function Step2({ }, [contextData]); const allHdPathOptions = useMemo(() => { - return ADDRESS_TYPES.sort((a, b) => a.displayIndex - b.displayIndex).map((v) => { - return { - label: v.name, - hdPath: v.hdPath, - addressType: v.value, - isUnisatLegacy: v.isUnisatLegacy - }; - }); + return ADDRESS_TYPES.map((v) => v) + .sort((a, b) => a.displayIndex - b.displayIndex) + .map((v) => { + return { + label: v.name, + hdPath: v.hdPath, + addressType: v.value, + isUnisatLegacy: v.isUnisatLegacy + }; + }); }, []); const [previewAddresses, setPreviewAddresses] = useState(hdPathOptions.map((v) => '')); @@ -341,6 +368,7 @@ function Step2({ }>({}); const [error, setError] = useState(''); + const [pathError, setPathError] = useState(''); const [loading, setLoading] = useState(false); const createAccount = useCreateAccountCallback(); @@ -432,25 +460,32 @@ function Step2({ fetchAddressesBalance(); }, [previewAddresses]); - const submitCustomHdPath = () => { - if (contextData.customHdPath === pathText) return; - const isValid = bitcore.HDPrivateKey.isValidPath(pathText); - if (!isValid) { - setError('Invalid derivation path.'); - return; + const submitCustomHdPath = (text: string) => { + setPathError(''); + setPathText(text); + if (text !== '') { + const isValid = bitcore.HDPrivateKey.isValidPath(text); + if (!isValid) { + setPathError('Invalid derivation path.'); + return; + } + updateContextData({ + customHdPath: text + }); + } else { + updateContextData({ + customHdPath: '' + }); } - updateContextData({ - customHdPath: pathText - }); }; - const resetCustomHdPath = () => { - updateContextData({ - customHdPath: '' - }); - setError(''); - setPathText(''); - }; + const disabled = useMemo(() => { + if (!error && !pathError) { + return false; + } else { + return true; + } + }, [error, pathError]); const onNext = async () => { try { @@ -607,23 +642,12 @@ function Step2({ { - setError(''); - setPathText(e.target.value); - }} - onBlur={(e) => { - submitCustomHdPath(); + onChange={(e) => { + submitCustomHdPath(e.target.value); }} /> - {contextData.customHdPath && ( - { - resetCustomHdPath(); - }}> - - - )} + {pathError && } {error && } @@ -639,7 +663,7 @@ function Step2({ /> -