Skip to content
This repository has been archived by the owner on Oct 10, 2023. It is now read-only.

Commit

Permalink
Sync keystore/ledger states (#2361)
Browse files Browse the repository at this point in the history
- [x] Remove related ledger addresses by removing a wallet
- [x] `keystore` service: Rename `kestore$` -> `keystoreState$` /
`keystoreWallets` -> `keystoreWalletsPersistent$` etc.
- [x] Subscribe to `keystoreWalletsPersistent$` to update internal state
in memory
- [x] Fix: Wallet change from WalletSettings failed
  • Loading branch information
veado authored Aug 18, 2022
1 parent 69a356b commit b388255
Show file tree
Hide file tree
Showing 23 changed files with 177 additions and 96 deletions.
2 changes: 1 addition & 1 deletion src/renderer/components/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const Header: React.FC = (): JSX.Element => {
const { keystoreService } = useWalletContext()
const { mimir$ } = useThorchainContext()
const { lock } = keystoreService
const keystore = useObservableState(keystoreService.keystore$, O.none)
const keystore = useObservableState(keystoreService.keystoreState$, O.none)
const mimir = useObservableState(mimir$, RD.initial)
const { service: midgardService } = useMidgardContext()
const {
Expand Down
20 changes: 15 additions & 5 deletions src/renderer/components/settings/WalletSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useMemo, useState } from 'react'
import React, { useCallback, useEffect, useMemo, useState } from 'react'

import { SearchOutlined } from '@ant-design/icons'
import * as RD from '@devexperts/remote-data-ts'
Expand Down Expand Up @@ -453,10 +453,8 @@ export const WalletSettings: React.FC<Props> = (props): JSX.Element => {
const changeWalletHandler = useCallback(
(id: KeystoreId) => {
subscribeChangeWalletState(changeKeystoreWallet$(id))
// Jump to `UnlockView` to avoid staying at wallet settings
navigate(walletRoutes.locked.path())
},
[changeKeystoreWallet$, navigate, subscribeChangeWalletState]
[changeKeystoreWallet$, subscribeChangeWalletState]
)

const renderChangeWalletError = useMemo(
Expand All @@ -478,6 +476,13 @@ export const WalletSettings: React.FC<Props> = (props): JSX.Element => {
[changeWalletState, intl]
)

useEffect(() => {
if (RD.isSuccess(changeWalletState)) {
// Jump to `UnlockView` to avoid staying at wallet settings
navigate(walletRoutes.locked.path())
}
}, [changeWalletState, navigate])

const { state: renameWalletState, subscribe: subscribeRenameWalletState } =
useSubscriptionState<RenameKeystoreWalletRD>(RD.initial)

Expand Down Expand Up @@ -612,7 +617,12 @@ export const WalletSettings: React.FC<Props> = (props): JSX.Element => {
<h2 className="w-full text-center font-main text-[12px] uppercase text-text2 dark:text-text2d">
{intl.formatMessage({ id: 'wallet.change.title' })}
</h2>
<WalletSelector wallets={wallets} onChange={changeWalletHandler} className="min-w-[200px]" />
<WalletSelector
className="min-w-[200px]"
disabled={RD.isPending(changeWalletState)}
wallets={wallets}
onChange={changeWalletHandler}
/>
{renderChangeWalletError}
</div>
</div>
Expand Down
10 changes: 5 additions & 5 deletions src/renderer/hooks/useKeystoreState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const useKeystoreState = (): {
} => {
const {
keystoreService: {
keystore$,
keystoreState$,
unlock,
lock,
removeKeystoreWallet: remove,
Expand All @@ -36,11 +36,11 @@ export const useKeystoreState = (): {
}
} = useWalletContext()

const state = useObservableState(keystore$, INITIAL_KEYSTORE_STATE)
const state = useObservableState(keystoreState$, INITIAL_KEYSTORE_STATE)

const [phrase] = useObservableState(() => FP.pipe(keystore$, RxOp.map(FP.flow(getPhrase))), O.none)
const [walletName] = useObservableState(() => FP.pipe(keystore$, RxOp.map(FP.flow(getWalletName))), O.none)
const [locked] = useObservableState(() => FP.pipe(keystore$, RxOp.map(FP.flow(isLocked))), false)
const [phrase] = useObservableState(() => FP.pipe(keystoreState$, RxOp.map(FP.flow(getPhrase))), O.none)
const [walletName] = useObservableState(() => FP.pipe(keystoreState$, RxOp.map(FP.flow(getWalletName))), O.none)
const [locked] = useObservableState(() => FP.pipe(keystoreState$, RxOp.map(FP.flow(isLocked))), false)

return { state, phrase, walletName, unlock, lock, locked, remove, change$, rename$ }
}
8 changes: 4 additions & 4 deletions src/renderer/hooks/useKeystoreWallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import { useWalletContext } from '../contexts/WalletContext'
import { KeystoreWalletsRD, KeystoreWalletsUI } from '../services/wallet/types'

export const useKeystoreWallets = (): {
wallets: KeystoreWalletsRD
walletsPersistentRD: KeystoreWalletsRD
reload: FP.Lazy<void>
walletsUI: KeystoreWalletsUI
} => {
const {
keystoreService: { reloadKeystoreWallets: reload, keystoreWallets$, keystoreWalletsUI$ }
keystoreService: { reloadPersistentKeystoreWallets: reload, keystoreWalletsPersistent$, keystoreWalletsUI$ }
} = useWalletContext()

const wallets = useObservableState(keystoreWallets$, RD.initial)
const walletsPersistentRD = useObservableState(keystoreWalletsPersistent$, RD.initial)
const walletsUI = useObservableState(keystoreWalletsUI$, [])

return { wallets: wallets, walletsUI, reload }
return { walletsPersistentRD, walletsUI, reload }
}
2 changes: 1 addition & 1 deletion src/renderer/services/binance/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { ClientState, ClientState$, Client$ } from './types'
* A `BinanceClient` will never be created as long as no phrase is available
*/
const clientState$: ClientState$ = FP.pipe(
Rx.combineLatest([keystoreService.keystore$, clientNetwork$]),
Rx.combineLatest([keystoreService.keystoreState$, clientNetwork$]),
RxOp.switchMap(
([keystore, network]): ClientState$ =>
Rx.of(
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/services/bitcoin/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ClientState, ClientState$ } from './types'
* A `BitcoinClient` will never be created as long as no phrase is available
*/
const clientState$: ClientState$ = FP.pipe(
Rx.combineLatest([keystoreService.keystore$, clientNetwork$]),
Rx.combineLatest([keystoreService.keystoreState$, clientNetwork$]),
RxOp.switchMap(
([keystore, network]): ClientState$ =>
Rx.of(
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/services/bitcoincash/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ClientState, ClientState$ } from './types'
* A `BitcoinCashClient` will never be created as long as no phrase is available
*/
const clientState$: ClientState$ = FP.pipe(
Rx.combineLatest([keystoreService.keystore$, clientNetwork$]),
Rx.combineLatest([keystoreService.keystoreState$, clientNetwork$]),
RxOp.switchMap(
([keystore, network]): ClientState$ =>
Rx.of(
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/services/cosmos/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type { Client$, ClientState, ClientState$ } from './types'
* A `CosmosClient` will never be created as long as no phrase is available
*/
const clientState$: ClientState$ = FP.pipe(
Rx.combineLatest([keystoreService.keystore$, clientNetwork$, Rx.of(getClientUrls())]),
Rx.combineLatest([keystoreService.keystoreState$, clientNetwork$, Rx.of(getClientUrls())]),
RxOp.switchMap(
([keystore, network, clientUrls]): ClientState$ =>
FP.pipe(
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/services/doge/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ClientState, ClientState$ } from './types'
* A `DogeClient` will never be created as long as no phrase is available
*/
const clientState$: ClientState$ = FP.pipe(
Rx.combineLatest([keystoreService.keystore$, clientNetwork$]),
Rx.combineLatest([keystoreService.keystoreState$, clientNetwork$]),
RxOp.switchMap(
([keystore, network]): ClientState$ =>
Rx.of(
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/services/ethereum/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { Client$, ClientState, ClientState$ } from './types'
* A `EthereumClient` will never be created as long as no phrase is available
*/
const clientState$: ClientState$ = FP.pipe(
Rx.combineLatest([keystoreService.keystore$, clientNetwork$]),
Rx.combineLatest([keystoreService.keystoreState$, clientNetwork$]),
RxOp.switchMap(
([keystore, network]): ClientState$ =>
Rx.of(
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/services/litecoin/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { Client$, ClientState$, ClientState } from './types'
* A `LitecoinClient` will never be created as long as no phrase is available
*/
const clientState$: ClientState$ = FP.pipe(
Rx.combineLatest([keystoreService.keystore$, clientNetwork$]),
Rx.combineLatest([keystoreService.keystoreState$, clientNetwork$]),
RxOp.switchMap(
([keystore, network]): ClientState$ =>
Rx.of(
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/services/thorchain/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { Client$, ClientState, ClientState$ } from './types'
* A `ThorchainClient` will never be created as long as no phrase is available
*/
const clientState$: ClientState$ = FP.pipe(
Rx.combineLatest([keystoreService.keystore$, clientNetwork$, Rx.of(getClientUrl())]),
Rx.combineLatest([keystoreService.keystoreState$, clientNetwork$, Rx.of(getClientUrl())]),
RxOp.switchMap(
([keystore, network, clientUrl]): ClientState$ =>
FP.pipe(
Expand Down
5 changes: 3 additions & 2 deletions src/renderer/services/wallet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { getTxs$, loadTxs, explorerUrl$, resetTxsPage } from './transaction'

const { askLedgerAddress$, getLedgerAddress$, verifyLedgerAddress, removeLedgerAddress, ledgerAddresses$ } =
createLedgerService({
keystore$: keystoreService.keystore$
keystore$: keystoreService.keystoreState$,
wallets$: keystoreService.keystoreWalletsUI$
})

const { reloadBalances, reloadBalancesByChain, balancesState$, chainBalances$ } = createBalancesService({
keystore$: keystoreService.keystore$,
keystore$: keystoreService.keystoreState$,
network$,
getLedgerAddress$
})
Expand Down
Loading

0 comments on commit b388255

Please sign in to comment.