Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into bugfix/android-34
Browse files Browse the repository at this point in the history
  • Loading branch information
ChewingGlass committed Sep 6, 2024
2 parents 0eaf0b6 + 790b9d5 commit 780ceb6
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 138 deletions.
4 changes: 2 additions & 2 deletions ios/HeliumWallet/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Allow this app to use your location to add your Hotspots to the network</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Allow Location</string>
<string>Allow this app to use your location to add your Hotspots to the network</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Allow Location</string>
<string>Allow this app to use your location to add your Hotspots to the network</string>
<key>NSUserActivityTypes</key>
<array>
<string>ConfigurationIntent</string>
Expand Down
15 changes: 11 additions & 4 deletions src/features/browser/BrowserWebViewScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const BrowserWebViewScreen = () => {
const { favorites, addFavorite, removeFavorite } = useBrowser()
const isAndroid = useMemo(() => Platform.OS === 'android', [])
const spacing = useSpacing()
const [injected, setInjected] = useState(false)

const isFavorite = useMemo(() => {
return favorites.some((favorite) => favorite === currentUrl)
Expand Down Expand Up @@ -455,6 +456,14 @@ const BrowserWebViewScreen = () => {
injectModule()
}, [injectModule])

const onLoadEnd = useCallback(() => {
if (!injected) {
webview.current?.injectJavaScript('')
webview.current?.injectJavaScript(injectedJavascript())
setInjected(true)
}
}, [injectedJavascript, injected, setInjected])

const BrowserFooter = useCallback(() => {
return (
<Box padding="m" flexDirection="row" backgroundColor="black900">
Expand Down Expand Up @@ -503,12 +512,10 @@ const BrowserWebViewScreen = () => {
ref={webview}
originWhitelist={['*']}
javaScriptEnabled
injectedJavaScript={injectedJavascript()}
onLoadEnd={onLoadEnd}
onNavigationStateChange={onNavigationChange}
onMessage={onMessage}
source={{
uri,
}}
source={{ uri }}
onShouldStartLoadWithRequest={(event) => {
// Sites should not do this, but if you click MWA on realms it bricks us
return !event.url.startsWith('solana-wallet:')
Expand Down
87 changes: 54 additions & 33 deletions src/features/onboarding/AccountAssignScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@ import { useAsyncCallback } from 'react-async-hook'
import { useTranslation } from 'react-i18next'
import { KeyboardAvoidingView, Platform, StyleSheet } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { accountNetType } from '@utils/accountUtils'
import { RootNavigationProp } from '../../navigation/rootTypes'
import { useSolana } from '../../solana/SolanaProvider'
import { useAccountStorage } from '../../storage/AccountStorageProvider'
import { HomeStackParamList } from '../home/homeTypes'
import { useOnboarding } from './OnboardingProvider'
import { CreateAccountNavigationProp } from './create/createAccountNavTypes'
import { ImportAccountNavigationProp } from './import/importAccountNavTypes'
import { useOnboarding } from './OnboardingProvider'

type Route = RouteProp<HomeStackParamList, 'AccountAssignScreen'>

const AccountAssignScreen = () => {
const route = useRoute<Route>()
const { connection } = useSolana()
const onboardingNav = useNavigation<
ImportAccountNavigationProp & CreateAccountNavigationProp
>()
Expand All @@ -43,8 +46,13 @@ const AccountAssignScreen = () => {
const insets = useSafeAreaInsets()
const spacing = useSpacing()
const colors = useColors()
const { upsertAccounts, hasAccounts, updateDefaultAccountAddress, accounts } =
useAccountStorage()
const {
setCurrentAccount,
upsertAccounts,
hasAccounts,
updateDefaultAccountAddress,
accounts,
} = useAccountStorage()
const [setAsDefault, toggleSetAsDefault] = useState(false)

const existingNames = useMemo(
Expand Down Expand Up @@ -72,43 +80,48 @@ const AccountAssignScreen = () => {
}, [paths, route.params?.secretKey, route.params?.derivationPath])

const { execute: handlePress, loading } = useAsyncCallback(async () => {
try {
await Promise.all(
allPaths.map(async (p) => {
await storeSecureAccount(
toSecureAccount({
keypair: p.keypair,
words,
derivationPath: p.derivationPath,
}),
)
}),
)
// eslint-disable-next-line no-inner-declarations
function getName(index: number): string {
const name = `${alias} ${index + 1}`
if (!existingNames?.has(name)) {
return name
}

return getName(index + 1)
const getName = (index: number): string => {
const name = `${alias} ${index + 1}`
if (!existingNames?.has(name)) {
return name
}

return getName(index + 1)
}

try {
let mnemonicHash: string | undefined
if (words) {
mnemonicHash = createHash('sha256')
.update(words.join(' '))
.digest('hex')
}
const newAccounts = allPaths.map((p, index) => ({
alias: index === 0 ? alias : getName(index),
address: heliumAddressFromSolAddress(p.keypair.publicKey.toBase58()),
solanaAddress: p.keypair.publicKey.toBase58(),
derivationPath: p.derivationPath,
mnemonicHash,
version: 'v1' as CSAccountVersion,
}))

const newAccounts = await Promise.all(
allPaths.map(async (p, index) => ({
alias: index === 0 ? alias : getName(index),
address: heliumAddressFromSolAddress(p.keypair.publicKey.toBase58()),
solanaAddress: p.keypair.publicKey.toBase58(),
derivationPath: p.derivationPath,
mnemonicHash,
version: 'v1' as CSAccountVersion,
balance: await connection?.getBalance(p.keypair.publicKey),
})),
)

const highestBalanceAcc = newAccounts.reduce((acc, curr) => {
if (
curr.balance !== undefined &&
(acc.balance === undefined || curr.balance > acc.balance)
) {
return curr
}

return acc
}, newAccounts[0])

await Promise.all(
allPaths.map(async (p) => {
allPaths.reverse().map(async (p) => {
await storeSecureAccount(
toSecureAccount({
words,
Expand All @@ -118,16 +131,24 @@ const AccountAssignScreen = () => {
)
}),
)

await upsertAccounts(newAccounts)

setCurrentAccount({
...highestBalanceAcc,
netType: accountNetType(highestBalanceAcc.address),
})

if (setAsDefault) {
await updateDefaultAccountAddress(newAccounts[0].address)
await updateDefaultAccountAddress(highestBalanceAcc.address)
}

reset()
} catch (e) {
console.error(e)
return
}

if (hasAccounts) {
rootNav.reset({
index: 0,
Expand Down
74 changes: 57 additions & 17 deletions src/features/onboarding/import/AccountImportScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { FlatList } from 'react-native'
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
import { MAIN_DERIVATION_PATHS } from '@hooks/useDerivationAccounts'
import { Keypair } from '@solana/web3.js'
import { CSAccount } from '@storage/cloudStorage'
import { useAccountStorage } from '../../../storage/AccountStorageProvider'
import {
DEFAULT_DERIVATION_PATH,
createKeypair,
toSecureAccount,
} from '../../../storage/secureStorage'
import { createKeypair, toSecureAccount } from '../../../storage/secureStorage'
import { useOnboarding } from '../OnboardingProvider'
import { OnboardingNavigationProp } from '../onboardingTypes'
import PassphraseAutocomplete from './PassphraseAutocomplete'
Expand Down Expand Up @@ -149,27 +148,68 @@ const AccountImportScreen = () => {

const handleNext = useCallback(async () => {
try {
let keypair: Keypair | undefined
const filteredWords: string[] = words.flatMap((w) => (w ? [w] : []))
const { keypair } = await createKeypair({
givenMnemonic: filteredWords,
use24Words: words?.length === 24,
derivationPath:
Object.values(accounts || {}).find(
(a) => a.address === accountAddress,
)?.derivationPath || DEFAULT_DERIVATION_PATH,
})
const foundDerivation = Object.values(accounts || {}).find(
(a) => a.address === accountAddress,
)?.derivationPath

if (foundDerivation) {
keypair = (
await createKeypair({
givenMnemonic: filteredWords,
use24Words: words?.length === 24,
derivationPath: foundDerivation,
})
).keypair
}

if (restoringAccount) {
let restoredAccount: CSAccount | undefined
if (!accounts || !accountAddress) {
await showOKAlert({
title: t('restoreAccount.errorAlert.title'),
message: t('restoreAccount.errorAlert.message'),
})
return
}
const restoredAccount = Object.values(accounts).find(
(a) => a.solanaAddress === keypair.publicKey.toBase58(),
)
if (!restoredAccount || accountAddress !== restoredAccount.address) {

if (keypair) {
restoredAccount = Object.values(accounts).find(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
(a) => a.solanaAddress === keypair!.publicKey.toBase58(),
)
} else {
const keypairs = await Promise.all(
MAIN_DERIVATION_PATHS.map((dpath) =>
createKeypair({
givenMnemonic: filteredWords,
use24Words: words?.length === 24,
derivationPath: dpath,
}),
),
)

restoredAccount = Object.values(accounts).find((a) =>
keypairs.some(
(k) => a.solanaAddress === k.keypair.publicKey.toBase58(),
),
)

if (restoredAccount) {
keypair = keypairs.find(
(k) =>
restoredAccount?.solanaAddress ===
k.keypair.publicKey.toBase58(),
)?.keypair
}
}

if (
!keypair ||
!restoredAccount ||
accountAddress !== restoredAccount.address
) {
await showOKAlert({
title: t('restoreAccount.errorAlert.title'),
message: t('restoreAccount.errorAlert.message'),
Expand Down
8 changes: 4 additions & 4 deletions src/features/onboarding/import/ImportSubAccountsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,13 @@ export default () => {
const { hasAccounts } = useAccountStorage()
const { onboardingData, setOnboardingData } = useOnboarding()
const { words } = onboardingData
const mnemonic = useMemo(() => words?.join(' '), [words])
const {
error,
loading,
derivationAccounts: foundAccounts,
fetchMore,
} = useDerivationAccounts({
mnemonic: words?.join(' '),
})
} = useDerivationAccounts({ mnemonic })

const derivationAccounts = useMemo(() => {
return foundAccounts.filter(
Expand All @@ -47,10 +46,10 @@ export default () => {
}, [foundAccounts])

const colors = useColors()

const [selected, setSelected] = React.useState<Set<string>>(
new Set([DEFAULT_DERIVATION_PATH]),
)

useEffect(() => {
setSelected(
new Set([
Expand All @@ -59,6 +58,7 @@ export default () => {
]),
)
}, [derivationAccounts])

useEffect(() => {
setOnboardingData((data) => ({
...data,
Expand Down
Loading

0 comments on commit 780ceb6

Please sign in to comment.