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

refactor: Dynamic password #7804

Merged
merged 9 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from 7 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
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
import { AnimationEnum } from '@auxiliary/animation'
import { showAppNotification } from '@auxiliary/notification'
import { OnboardingLayout } from '@components'
import { buildOnboardingSecretManager, updateOnboardingProfile, verifyAndStoreMnemonic } from '@contexts/onboarding'
import { buildOnboardingSecretManager, updateOnboardingProfile } from '@contexts/onboarding'
import { localize } from '@core/i18n'
import { MAX_STRONGHOLD_PASSWORD_LENGTH } from '@core/profile'
import { Subrouter } from '@core/router'
import { PASSWORD_REASON_MAP } from '@core/stronghold'
import { setStrongholdPassword } from '@core/wallet/actions'
import { Animation, Button, HTMLButtonType, PasswordInput, Text, TextType } from '@ui'
import zxcvbn from 'zxcvbn'

Expand Down Expand Up @@ -44,10 +43,8 @@
} else {
try {
busy = true
await setStrongholdPassword(strongholdPassword)
updateOnboardingProfile({ strongholdPassword, hasStoredMnemonic: true })
await buildOnboardingSecretManager()
await verifyAndStoreMnemonic()
router.next()
} catch (err) {
console.error(err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import {
addWalletPersistedDataToActiveProfile,
addWalletToActiveWallets,
createWallet,
IPersistedProfile,
login,
} from '@core/profile'
import { get } from 'svelte/store'
import { OnboardingType } from '../enums'
import { addWalletPersistedDataToOnboardingProfile, onboardingProfile } from '../stores'
import { onboardingProfile } from '../stores'
import { createNewProfileFromOnboardingProfile } from './createNewProfileFromOnboardingProfile'
import { showBalanceOverviewPopup } from '@contexts/dashboard/stores'
import {
Expand All @@ -18,6 +19,7 @@ import {
} from '@core/wallet'
import { DEFAULT_SYNC_OPTIONS } from '@core/wallet/constants'
import { localize } from '@core/i18n'
import { IOnboardingProfile } from '../interfaces'

export async function completeOnboardingProcess(): Promise<void> {
// if we already have an active profile
Expand All @@ -27,34 +29,44 @@ export async function completeOnboardingProcess(): Promise<void> {
createNewProfileFromOnboardingProfile()
}

const onboardingType = get(onboardingProfile)?.onboardingType
const profile = get(onboardingProfile)
if (!profile) {
return
}
const { onboardingType, strongholdPassword } = profile

const shouldRecoverWallets = onboardingType === OnboardingType.Restore || onboardingType === OnboardingType.Claim
showBalanceOverviewPopup.set(shouldRecoverWallets)

await createOnboardingWallet()
await initWallet(profile, strongholdPassword)
void login({ isFromOnboardingFlow: true, shouldRecoverWallets })

onboardingProfile.set(undefined)
}

export async function createOnboardingWallet(name?: string, color?: string): Promise<IWalletState> {
export async function initWallet(profile: IOnboardingProfile, strongholdPassword?: string): Promise<IWalletState> {
// 1. Get the wallet name
const walletName = name || `${localize('general.wallet')} ${(get(activeWallets)?.length ?? 0) + 1}`
const walletName = `${localize('general.wallet')} ${(get(activeWallets)?.length ?? 0) + 1}`

// 2. Create the wallet instance
const wallet = await createWallet() // TODO(2.0) Not sure about this, I think this should be createWallet instead
const wallet = await createWallet({
address: profile.address,
profile: profile as IPersistedProfile,
})

// 3. Sync the wallet with the Node
// TODO(2.0): test & fix sync when we have iota2.0 nodes
// 3. Load the stronghold password if necessary
if (strongholdPassword) {
await wallet.setStrongholdPassword(strongholdPassword)
}

// 4. Sync the wallet with the Node
await wallet.sync(DEFAULT_SYNC_OPTIONS)
// 4. Create a wrapper over the wallet instance and the persisted data
const [walletState, walletPersistedData] = await buildWalletStateAndPersistedData(wallet, walletName, color)

// TODO(2.0) Fix
// 5. Create a wrapper over the wallet instance and the persisted data
const [walletState, walletPersistedData] = await buildWalletStateAndPersistedData(wallet, walletName)

addWalletToActiveWallets(walletState)
addWalletPersistedDataToOnboardingProfile(walletState.id, walletPersistedData)
addWalletPersistedDataToActiveProfile(walletState.id, walletPersistedData) // TODO(2.0) Not sure about this,
// TODO(2.0) Fix
addWalletPersistedDataToActiveProfile(walletState.id, walletPersistedData)
addEmptyWalletActivitiesToAllWalletActivities(walletState.id)

return walletState
Expand Down
1 change: 0 additions & 1 deletion packages/shared/lib/contexts/onboarding/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,3 @@ export * from './restoreBackupFromStrongholdFile'
export * from './setProfileRecoveryTypeFromFilename'
export * from './subscribeToWalletApiEventsForShimmerClaiming'
export * from './syncShimmerClaimingAccount'
export * from './verifyAndStoreMnemonic'

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ export interface IOnboardingProfile extends Omit<Partial<IPersistedProfile>, 'id
shimmerClaimingAccounts?: IShimmerClaimingWallet[]

hasInitialisedProfileManager?: boolean

address: string
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
import { onboardingProfile } from '@contexts/onboarding/stores'
import { onboardingProfile, updateOnboardingProfile } from '@contexts/onboarding/stores'
import { api } from '@core/api'
import { SecretManager, SecretManagerType } from '@iota/sdk'
import { USE_LEDGER_SIMULATOR } from 'shared/lib/core/ledger'
import { getStorageDirectoryOfProfile, ProfileType } from 'shared/lib/core/profile'
import { SecretManager } from '@iota/sdk'
import { verifyMnemonic } from 'shared/lib/core/secret-manager'
import { get, writable, Writable } from 'svelte/store'

export const onboardingProfileSecretManager: Writable<SecretManager | null> = writable(null)

export async function buildOnboardingSecretManager(): Promise<void> {
const profile = get(onboardingProfile)
if (profile) {
const { id, type, strongholdPassword } = profile
const { strongholdPassword, secretManagerOptions, mnemonic } = profile
const mnemonicStringified = mnemonic?.join(' ') ?? ''

const storagePath = await getStorageDirectoryOfProfile(id)
const secretManagerOptions = getSecretManagerFromProfileType(type, {
storagePath,
strongholdPassword,
})
if (!strongholdPassword || !secretManagerOptions || !mnemonic) {
return
}

// 1. Create SecretManager
const secretManager = await api.createSecretManager(secretManagerOptions)

// 2. Load the stronghold password specified in the onboarding if necessary
if (strongholdPassword) {
await secretManager.setStrongholdPassword(strongholdPassword)
}

// 3. Verify Mnemonic
await verifyMnemonic(mnemonicStringified)

// 4. Store Mnemonic
await secretManager.storeMnemonic(mnemonicStringified)

// 5. Generate address
const address = (await secretManager.generateEd25519Addresses({}))[0]

updateOnboardingProfile({
address,
})
onboardingProfileSecretManager.set(secretManager)
begonaalvarezd marked this conversation as resolved.
Show resolved Hide resolved
} else {
onboardingProfileSecretManager.set(null)
Expand All @@ -29,29 +45,3 @@ export async function buildOnboardingSecretManager(): Promise<void> {
export function isOnboardingSecretManagerInitialized(): boolean {
return !!get(onboardingProfileSecretManager)
}

export function getSecretManagerFromProfileType(
type?: ProfileType,
{
storagePath,
strongholdPassword,
}: {
storagePath?: string
strongholdPassword?: string
} = {}
): SecretManagerType {
const strongholdSecretManager = {
stronghold: { snapshotPath: `${storagePath}/wallet.stronghold`, password: strongholdPassword },
}
const ledgerSecretManager = {
ledgerNano: USE_LEDGER_SIMULATOR,
}

switch (type) {
case ProfileType.Ledger:
return ledgerSecretManager
case ProfileType.Software:
default:
return strongholdSecretManager
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ export async function login(loginOptions?: ILoginOptions): Promise<void> {
// Step 1: create profile manager if its doesn't exist
incrementLoginProgress()
await waitForPreviousManagerToBeDestroyed()
// if (!isOnboardingSecretManagerInitialized()) {
// // TODO(2.0) Not sure about this
// await initialiseOnboardingProfileWithSecretManager(true)
// }

// Step 3: load and build all the profile data
incrementLoginProgress()
Expand Down
24 changes: 13 additions & 11 deletions packages/shared/lib/core/profile/actions/createWallet.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { api } from '@core/api'
import { get } from 'svelte/store'
import { IProfile, IWallet } from '../interfaces'
import { activeProfile as activeProfileStore } from '../stores'
import { IPersistedProfile, IWallet } from '../interfaces'
import { getSecretManagerFromProfileType, getStorageDirectoryOfProfile } from '../utils'
import { WalletOptions } from '@iota/sdk'
import { selectedWalletId } from '../../wallet'

export function getWalletOptions(profile: IProfile, storagePath: string): WalletOptions {
const walletOptions: WalletOptions = {
export function getWalletOptions(profile: IPersistedProfile, storagePath: string, address: string): WalletOptions {
return {
address,
clientOptions: profile.clientOptions,
storagePath,
secretManager: getSecretManagerFromProfileType(profile.type, storagePath),
Expand All @@ -17,8 +16,6 @@ export function getWalletOptions(profile: IProfile, storagePath: string): Wallet
addressIndex: 0,
},
}

return walletOptions
}

// TODO(2.0): Fix and finish this method
Expand All @@ -28,12 +25,17 @@ export function getWalletOptions(profile: IProfile, storagePath: string): Wallet
- __wallet1__/
- __wallet2__/
*/
export async function createWallet(activeProfile = get(activeProfileStore)): Promise<IWallet> {
const id = activeProfile.id
const storagePath = await getStorageDirectoryOfProfile(id)

const walletOptions = getWalletOptions(activeProfile, storagePath)
interface CreateWalletOptions {
profile: IPersistedProfile
address: string
}

export async function createWallet({ profile, address }: CreateWalletOptions): Promise<IWallet> {
const { id } = profile
const storagePath = await getStorageDirectoryOfProfile(id)

const walletOptions = getWalletOptions(profile, storagePath, address)
const wallet = await api.createWallet(id, {
...walletOptions,
storagePath,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ProfileType } from '@core/profile'
// TODO(2.0) Fix all usages
export function getSecretManagerFromProfileType(type?: ProfileType, storagePath?: string): SecretManagerType {
const strongholdSecretManager = {
stronghold: { snapshotPath: `${storagePath}/wallet.stronghold`, password: 'mellamobego' }, // TODO(2.0) Remove this harcoded password
stronghold: { snapshotPath: `${storagePath}/wallet.stronghold` },
}
const ledgerSecretManager = {
ledgerNano: USE_LEDGER_SIMULATOR,
Expand Down
1 change: 0 additions & 1 deletion packages/shared/lib/core/secret-manager/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ export * from './changeStrongholdPassword'
export * from './clearStrongholdPassword'
export * from './generateEd25519Address'
export * from './getLedgerNanoStatus'
export * from './storeMnemonic'
export * from './getSecretManager'
12 changes: 0 additions & 12 deletions packages/shared/lib/core/secret-manager/actions/storeMnemonic.ts

This file was deleted.

12 changes: 9 additions & 3 deletions packages/shared/lib/core/wallet/actions/setStrongholdPassword.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { get } from 'svelte/store'
import { selectedWallet } from '../stores/selected-wallet.store'
import { getSecretManager } from '@core/secret-manager/actions'
import { getSelectedWallet } from '../stores/selected-wallet.store'

export async function setStrongholdPassword(password: string): Promise<void> {
const wallet = get(selectedWallet)
// Set in Wallet
const wallet = getSelectedWallet()
// Otherwise error is thrown, if password is still present in memory
await wallet?.clearStrongholdPassword()
await wallet?.setStrongholdPassword(password)

// Set in SecretManager
const secretManager = getSecretManager()
await secretManager.setStrongholdPassword(password)
// await secretManager?.clearStrongholdPassword() // TODO(2.0)
}
Loading