Skip to content

Commit

Permalink
update restore components
Browse files Browse the repository at this point in the history
  • Loading branch information
KKA11010 committed Apr 1, 2024
1 parent e4f55ca commit f7b975f
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 176 deletions.
212 changes: 108 additions & 104 deletions src/components/hooks/Restore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,139 +15,143 @@ import { useTranslation } from 'react-i18next'

type StackNavigation = NavigationProp<RootStackParamList>

type TRestoreInterval = Promise<{ proofs: Proof[]; newKeys?: MintKeys; lastCount: number } | undefined>
type TRestoreInterval = Promise<{ proofs: Proof[]; newKeys?: MintKeys; start: number; lastCount: number } | undefined>

interface IUseRestoreProps {
from?: number
to?: number
from: number
to: number
mintUrl: string
keysetId: string
mnemonic: string
comingFromOnboarding?: boolean
shouldOvershoot?: boolean
}

export function useRestore({ from, to, mintUrl, keysetId, mnemonic, comingFromOnboarding }: IUseRestoreProps) {
export function useRestore({ from, to, mintUrl, keysetId, mnemonic, comingFromOnboarding, shouldOvershoot }: IUseRestoreProps) {

const navigation = useNavigation<StackNavigation>()
const { t } = useTranslation([NS.common])
const { openPromptAutoClose } = usePromptContext()

const [restored, setRestored] = useState({
proofs: [] as Proof[],
start: from ?? 0,
end: to ?? RESTORE_INTERVAL,
start: from,
end: to,
overshoot: 0,
})

useEffect(() => {
const restore = async () => {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const proofs = await restoreWallet(mintUrl, mnemonic)
if (!proofs?.length) {
openPromptAutoClose({ msg: t('noProofsRestored'), success: false })
setRestored({
proofs: [] as Proof[],
start: from ?? 0,
end: to ?? RESTORE_INTERVAL,
overshoot: 0,
})
if (comingFromOnboarding) {
return navigation.navigate('auth', { pinHash: '' })
}
return navigation.navigate('dashboard')
const resetRestoredState = () => {
setRestored({
proofs: [] as Proof[],
start: from,
end: to,
overshoot: 0,
})
}

const restore = async () => {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { proofs, start, end } = await restoreWallet(mintUrl, mnemonic)
if (!proofs?.length) {
openPromptAutoClose({ msg: t('noProofsRestored'), success: false })
resetRestoredState()
if (comingFromOnboarding) {
return navigation.navigate('auth', { pinHash: '' })
}
const bal = await getMintBalance(mintUrl)
await addToHistory({
mints: [mintUrl],
amount: bal,
type: 4,
value: '',
})
setRestored({
proofs: [] as Proof[],
start: from ?? 0,
end: to ?? RESTORE_INTERVAL,
overshoot: 0,
})
navigation.navigate('restoreSuccess', {
mint: mintUrl,
keysetID: keysetId,
cycle: { start: restored.start, end: restored.end },
amount: bal,
comingFromOnboarding,
})
} catch (e) {
l('[handleRecovery] error: ', e)
setRestored({
proofs: [] as Proof[],
start: from ?? 0,
end: to ?? RESTORE_INTERVAL,
overshoot: 0,
})
navigation.navigate('processingError', {
errorMsg: isErr(e) ? e.message : t('restoreErr'),
comingFromOnboarding,
})
return navigation.navigate('dashboard')
}
const bal = await getMintBalance(mintUrl)
await addToHistory({
mints: [mintUrl],
amount: bal,
type: 4,
value: '',
})
navigation.navigate('restoreSuccess', {
mnemonic,
mint: mintUrl,
keysetID: keysetId,
cycle: { start, end },
amount: bal,
comingFromOnboarding,
})
} catch (e) {
l('[handleRecovery] error: ', e)
resetRestoredState()
navigation.navigate('processingError', {
errorMsg: isErr(e) ? e.message : t('restoreErr'),
comingFromOnboarding,
})
}
const restoreWallet = async (mintUrl: string, mnemonic: string) => {
try {
const { wallet, seed } = await getSeedWalletByMnemonic({ mintUrl, mnemonic })
const resp = await restoreInterval(wallet, from ?? 0, to ?? RESTORE_INTERVAL)
if (!resp) {
l('[restoreWallet] restore interval did not return a proper object!')
throw new Error('[restoreWallet] restore interval did not return a proper object!')
}
await saveSeed(seed)
// adds counter if not exists
await getCounterByMintUrl(mintUrl)
if (!resp.proofs.length) {
l('[restoreWallet] no proofs found during the restore process!')
return []
}
const proofsSpent = await wallet.checkProofsSpent(resp.proofs)
const proofs = resp.proofs.filter(p => !proofsSpent.map(x => x.secret).includes(p.secret))
if (resp.newKeys) { _setKeys(mintUrl, resp.newKeys) }
await addToken({ token: [{ mint: mintUrl, proofs }] })
await incrementCounterByMintUrl(mintUrl, resp.lastCount + 1)
return proofs
} catch (e) {
l('[restoreWallet] error', { e })
}

const restoreWallet = async (mintUrl: string, mnemonic: string) => {
try {
const { wallet, seed } = await getSeedWalletByMnemonic({ mintUrl, mnemonic })
const resp = await restoreInterval(wallet, from, to)
if (!resp) {
l('[restoreWallet] restore interval did not return a proper object!')
throw new Error('[restoreWallet] restore interval did not return a proper object!')
}
const { proofs, newKeys, start, lastCount } = resp
await saveSeed(seed)
// adds counter if not exists
await getCounterByMintUrl(mintUrl)
if (!proofs.length) {
l('[restoreWallet] no proofs found during the restore process!')
return { proofs: [], start: from, end: to }
}
const proofsSpent = await wallet.checkProofsSpent(proofs)
const proofsUnspent = proofs.filter(p => !proofsSpent.map(x => x.secret).includes(p.secret))
if (newKeys) { _setKeys(mintUrl, newKeys) }
await addToken({ token: [{ mint: mintUrl, proofs: proofsUnspent }] })
await incrementCounterByMintUrl(mintUrl, lastCount + 1)
return { proofs: proofsUnspent, start, end: lastCount }
} catch (e) {
l('[restoreWallet] error', { e })
return { proofs: [], start: from, end: to }
}
const restoreInterval = async (
wallet: CashuWallet,
start: number,
end: number,
restoredProofs: Proof[] = [],
overshoot: number = 0
): TRestoreInterval => {
try {
}

const restoreInterval = async (
wallet: CashuWallet,
start: number,
end: number,
restoredProofs: Proof[] = [],
overshoot: number = 0
): TRestoreInterval => {
try {
const { proofs, newKeys } = await wallet.restore(start, end, keysetId)
l('[restoreInterval] restored proofs: ', { from: start, to: end, proofsLength: proofs.length })
if (proofs.length) {
restoredProofs.push(...proofs)
overshoot = 0
start += RESTORE_INTERVAL
end += RESTORE_INTERVAL
setRestored({ proofs: restoredProofs, start, end, overshoot })
const { proofs, newKeys } = await wallet.restore(start, end, keysetId)
return restoreInterval(wallet, start, end, restoredProofs, overshoot)
}
if (shouldOvershoot && overshoot < RESTORE_OVERSHOOT) {
l('[restoreInterval] no proofs to restore! overshooting now: ', { proofsLength: proofs.length, overshoot })
overshoot++
start += RESTORE_INTERVAL
end += RESTORE_INTERVAL
if (proofs.length) {
l('[restoreInterval] restored proofs: ', { from, to, proofsLength: proofs.length })
restoredProofs.push(...proofs)
overshoot = 0
return restoreInterval(wallet, start, end, restoredProofs, overshoot)
}
if (overshoot < RESTORE_OVERSHOOT) {
l('[restoreInterval] no proofs to restore! overshooting now: ', { from, to, proofsLength: proofs.length, overshoot })
overshoot++
return restoreInterval(wallet, start, end, restoredProofs, overshoot)
}
l('[restoreInterval] no proofs to restore! overshooting limit reached: ', { from, to, restoredProofs: restoredProofs.length, overshoot })
return { proofs: restoredProofs, newKeys, lastCount: end }
} catch (e) {
l('[restoreInterval] error', { e })
setRestored({ proofs: restoredProofs, start, end, overshoot })
return restoreInterval(wallet, start, end, restoredProofs, overshoot)
}
l('[restoreInterval] no proofs to restore! overshooting limit reached: ', { restoredProofsLength: restoredProofs.length, overshoot })
return { proofs: restoredProofs, newKeys, start, lastCount: end }
} catch (e) {
l('[restoreInterval] error', { e })
return { proofs: restoredProofs, newKeys: undefined, start, lastCount: end }
}
}

useEffect(() => {
void restore()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
}, [mintUrl, keysetId, from, to])

return { ...restored }
return restored
}
7 changes: 4 additions & 3 deletions src/model/nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ export type RootStackParamList = {
isZap?: boolean
nostr?: INostrSendData
isScanned?: boolean
isRestored?: boolean
change?: number
comingFromOnboarding?: boolean
}
Expand Down Expand Up @@ -236,17 +235,19 @@ export type RootStackParamList = {
comingFromOnboarding?: boolean
}
Recovering: {
from?: number
to?: number
from: number
to: number
mintUrl: string
keysetId: string
mnemonic: string
comingFromOnboarding?: boolean
shouldOvershoot?: boolean
}
'Restore warning': {
comingFromOnboarding?: boolean
}
restoreSuccess: {
mnemonic: string
amount: number
mint: string
keysetID: string
Expand Down
32 changes: 16 additions & 16 deletions src/screens/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -307,14 +307,14 @@ export default function Dashboard({ navigation, route }: TDashboardPageProps) {
txt={t('send', { ns: NS.wallet })}
color={hi[highlight]}
onPress={() => {
// setModal(prev => ({ ...prev, sendOpts: true }))
navigation.navigate('restoreSuccess', {
mint: 'https://testnut.cashu.space',
keysetID: 'jkasfhgkjg',
cycle: { start: 300, end: 350 },
amount: 100,
comingFromOnboarding: true,
})
setModal(prev => ({ ...prev, sendOpts: true }))
// navigation.navigate('restoreSuccess', {
// mint: 'https://testnut.cashu.space',
// keysetID: 'jkasfhgkjg',
// cycle: { start: 300, end: 350 },
// amount: 100,
// comingFromOnboarding: true,
// })
}}
/>
:
Expand All @@ -323,14 +323,14 @@ export default function Dashboard({ navigation, route }: TDashboardPageProps) {
txt={t('mint')}
color={hi[highlight]}
onPress={() => {
// navigation.navigate('mints')
navigation.navigate('restoreSuccess', {
mint: 'https://testnut.cashu.space',
keysetID: 'jkasfhgkjg',
cycle: { start: 300, end: 350 },
amount: 100,
comingFromOnboarding: true,
})
navigation.navigate('mints')
// navigation.navigate('restoreSuccess', {
// mint: 'https://testnut.cashu.space',
// keysetID: 'jkasfhgkjg',
// cycle: { start: 300, end: 350 },
// amount: 100,
// comingFromOnboarding: true,
// })
}}
/>
}
Expand Down
13 changes: 5 additions & 8 deletions src/screens/Payment/Success.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function SuccessPage({ navigation, route }: TSuccessPageProps) {
isZap,
nostr,
isScanned,
isRestored,
comingFromOnboarding
} = route.params
const { t } = useTranslation([NS.common])
const { color } = useThemeContext()
Expand Down Expand Up @@ -68,13 +68,10 @@ export default function SuccessPage({ navigation, route }: TSuccessPageProps) {
isAutoSwap ?
t('autoSwapSuccess')
:
isRestored ?
<>{formatSatStr(amount || 0)} {t('restored')}!</>
!nostr ?
<>{formatSatStr(amount || 0)} {isClaim ? t('claimed') : t('minted')}!</>
:
!nostr ?
<>{formatSatStr(amount || 0)} {isClaim ? t('claimed') : t('minted')}!</>
:
null
null
}
</Text>
{memo &&
Expand Down Expand Up @@ -120,7 +117,7 @@ export default function SuccessPage({ navigation, route }: TSuccessPageProps) {
<Button
txt={t('backToDashboard')}
onPress={() => {
if (route.params?.comingFromOnboarding) {
if (comingFromOnboarding) {
return navigation.navigate('auth', { pinHash: '' })
}
const routes = navigation.getState()?.routes
Expand Down
6 changes: 5 additions & 1 deletion src/screens/Restore/Recover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Txt from '@comps/Txt'
import TxtInput from '@comps/TxtInput'
import { isIOS } from '@consts'
import type { IRecoverPageProps } from '@model/nav'
import { RESTORE_INTERVAL } from '@src/consts/mints'
import { NS } from '@src/i18n'
import { getMintCurrentKeySetId } from '@src/wallet'
import { createRef, useEffect, useState } from 'react'
Expand All @@ -24,10 +25,13 @@ export default function RecoverScreen({ navigation, route }: IRecoverPageProps)
if (loading || !input.length) { return }
const keysetId = await getMintCurrentKeySetId(route.params.mintUrl)
navigation.navigate('Recovering', {
mnemonic: input,
mintUrl: route.params.mintUrl,
keysetId,
mnemonic: input,
from: 0,
to: RESTORE_INTERVAL,
comingFromOnboarding: route.params.comingFromOnboarding,
shouldOvershoot: true,
})
}

Expand Down
4 changes: 2 additions & 2 deletions src/screens/Restore/Recovering.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import { s, ScaledSheet } from 'react-native-size-matters'

export default function RecoveringScreen({ navigation, route }: IRecoveringPageProps) {

const { from, to, mintUrl, keysetId, mnemonic, comingFromOnboarding } = route.params
const { from, to, mintUrl, keysetId, mnemonic, comingFromOnboarding, shouldOvershoot } = route.params

const { t } = useTranslation([NS.common])
// Seed recovery process in useRestore hook
const { proofs, start, end, overshoot } = useRestore({ from, to, mintUrl, keysetId, mnemonic, comingFromOnboarding })
const { proofs, start, end, overshoot } = useRestore({ from, to, mintUrl, keysetId, mnemonic, comingFromOnboarding, shouldOvershoot })

const { color } = useThemeContext()

Expand Down
Loading

0 comments on commit f7b975f

Please sign in to comment.