Skip to content

Commit

Permalink
Make WalletListResult a union type
Browse files Browse the repository at this point in the history
  • Loading branch information
swansontec committed Dec 26, 2023
1 parent 0b23969 commit 8fd7595
Show file tree
Hide file tree
Showing 26 changed files with 112 additions and 90 deletions.
4 changes: 2 additions & 2 deletions src/actions/DeepLinkingActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export async function handleLink(navigation: NavigationBase, dispatch: Dispatch,
case 'azteco': {
if (!allWalletsLoaded) return false
const result = await pickWallet({ account, assets: [{ pluginId: 'bitcoin' }], navigation, showCreateWallet: true })
if (result == null) {
if (result?.type !== 'wallet') {
// pickWallet returning undefined means user has no matching wallet.
// This should never happen. Even if the user doesn't have a bitcoin wallet, they will be presented with
// the option to create one.
Expand Down Expand Up @@ -235,7 +235,7 @@ export async function handleLink(navigation: NavigationBase, dispatch: Dispatch,
}

// User backed out of choosing a wallet
if (walletListResult.walletId == null) return true
if (walletListResult.type !== 'wallet') return true
const widUri = matchingWalletIdsAndUris.find(({ walletId }) => walletId === walletListResult.walletId)

if (widUri == null) {
Expand Down
9 changes: 4 additions & 5 deletions src/actions/PaymentProtoActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,13 @@ export async function launchPaymentProto(navigation: NavigationBase, account: Ed
selectedWallet = wallet
selectedCurrencyCode = currencyCode
} else {
const walletListResult = await pickWallet({ account, assets: paymentAssets, navigation })
if (walletListResult == null) {
const result = await pickWallet({ account, assets: paymentAssets, navigation })
if (result?.type !== 'wallet') {
throw new PaymentProtoError('NoPaymentOption', { text: paymentCurrencies.join(', ') })
}

const { walletId } = walletListResult
const { walletId, currencyCode } = result
selectedWallet = currencyWallets[walletId ?? '']
selectedCurrencyCode = walletListResult.currencyCode
selectedCurrencyCode = currencyCode
}
if (selectedWallet == null) return

Expand Down
5 changes: 3 additions & 2 deletions src/actions/ScanActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ export const doRequestAddress = async (navigation: NavigationBase, account: Edge

await Airship.show<WalletListResult>(bridge => (
<WalletListModal bridge={bridge} navigation={navigation} headerTitle={lstrings.select_wallet} allowedAssets={tokenId} showCreateWallet />
)).then(async ({ walletId, currencyCode }) => {
if (walletId != null && currencyCode != null) {
)).then(async result => {
if (result?.type === 'wallet') {
const { walletId, currencyCode } = result
const { currencyWallets } = account
const wallet = currencyWallets[walletId]

Expand Down
5 changes: 3 additions & 2 deletions src/components/FioAddress/FioActionSubmit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,9 @@ class FioActionSubmitComponent extends React.Component<Props, State> {
Airship.show<WalletListResult>(bridge => (
<WalletListModal bridge={bridge} navigation={this.props.navigation} headerTitle={lstrings.fio_src_wallet} allowedAssets={[{ pluginId: 'fio' }]} />
))
.then(({ walletId, currencyCode }: WalletListResult) => {
if (walletId && currencyCode) {
.then(result => {
if (result?.type === 'wallet') {
const { walletId } = result
this.props.currencyWallets[walletId] &&
this.setState({ paymentWallet: this.props.currencyWallets[walletId] }, () => {
this.setBalance()
Expand Down
10 changes: 6 additions & 4 deletions src/components/modals/TransferModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,24 @@ export const TransferModal = ({ account, bridge, depositOrSend, navigation }: Pr
Airship.clear()
})
const handleSend = useHandler(async () => {
const { walletId, tokenId } = await Airship.show<WalletListResult>(bridge => (
const result = await Airship.show<WalletListResult>(bridge => (
<WalletListModal bridge={bridge} headerTitle={lstrings.select_wallet_to_send_from} navigation={navigation} />
))
if (walletId != null) {
if (result?.type === 'wallet') {
const { walletId, tokenId } = result
navigation.push('send2', { walletId, tokenId, hiddenFeaturesMap: { scamWarning: false } })
}
Airship.clear()
})

const handleReceive = useHandler(async () => {
Airship.clear()
const { walletId, tokenId } = await Airship.show<WalletListResult>(bridge => (
const result = await Airship.show<WalletListResult>(bridge => (
<WalletListModal bridge={bridge} headerTitle={lstrings.select_receive_asset} navigation={navigation} showCreateWallet />
))

if (walletId != null) {
if (result?.type === 'wallet') {
const { walletId, tokenId } = result
await dispatch(selectWalletToken({ navigation, walletId, tokenId }))
navigation.navigate('request', {})
}
Expand Down
45 changes: 26 additions & 19 deletions src/components/modals/WalletListModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { config } from '../../theme/appConfig'
import { useSelector } from '../../types/reactRedux'
import { NavigationBase } from '../../types/routerTypes'
import { BooleanMap, EdgeAsset } from '../../types/types'
import { getCurrencyCode, isKeysOnlyPlugin } from '../../util/CurrencyInfoHelpers'
import { getCurrencyCode, getTokenId, isKeysOnlyPlugin } from '../../util/CurrencyInfoHelpers'
import { CustomAsset } from '../data/row/CustomAssetRow'
import { PaymentMethodRow } from '../data/row/PaymentMethodRow'
import { Airship, showError } from '../services/AirshipInstance'
Expand All @@ -28,18 +28,20 @@ import { WalletList } from '../themed/WalletList'
import { WalletListCurrencyRow } from '../themed/WalletListCurrencyRow'
import { ButtonsModal } from './ButtonsModal'

export interface WalletListResult {
currencyCode?: string
tokenId?: string
walletId?: string

// Wyre buy/sell
isBankSignupRequest?: boolean
fiatAccountId?: string

// Custom asset selection
customAsset?: CustomAsset
}
export type WalletListResult =
| {
type: 'wallet'
walletId: string
tokenId: string | undefined
/** @deprecated Use tokenId instead */
currencyCode: string
}
| { type: 'wyre'; fiatAccountId: string }
| { type: 'bankSignupRequest' }
| { type: 'custom'; customAsset?: CustomAsset }
// User cancelled.
// This is consistent with other modals that return `T | undefined`:
| undefined

interface Props {
bridge: AirshipBridge<WalletListResult>
Expand Down Expand Up @@ -123,16 +125,20 @@ export function WalletListModal(props: Props) {
// #region Handlers

const handleCancel = useHandler(() => {
bridge.resolve({})
bridge.resolve(undefined)
})
const handlePaymentMethodPress = useHandler((fiatAccountId: string) => () => {
bridge.resolve({ fiatAccountId })
bridge.resolve({ type: 'wyre', fiatAccountId })
})
const handleWalletListPress = useHandler((walletId: string, currencyCode: string, tokenId?: string, customAsset?: CustomAsset) => {
if (walletId === '') {
handleCancel()
showError(lstrings.network_alert_title)
} else bridge.resolve({ walletId, currencyCode, customAsset, tokenId })
} else if (customAsset != null) {
bridge.resolve({ type: 'custom', customAsset })
} else if (walletId != null && currencyCode != null) {
bridge.resolve({ type: 'wallet', walletId, currencyCode, tokenId })
}
})
const handleSearchClear = useHandler(() => {
setSearchText('')
Expand All @@ -153,7 +159,7 @@ export function WalletListModal(props: Props) {
}}
/>
))
if (result === 'continue') await bridge.resolve({ isBankSignupRequest: true })
if (result === 'continue') await bridge.resolve({ type: 'bankSignupRequest' })
})

// #endregion Handlers
Expand Down Expand Up @@ -280,7 +286,7 @@ export const pickWallet = async ({
headerTitle?: string
navigation: NavigationBase
showCreateWallet?: boolean
}): Promise<WalletListResult | undefined> => {
}): Promise<WalletListResult> => {
const { currencyWallets } = account

const walletIdMap: BooleanMap = {}
Expand Down Expand Up @@ -315,7 +321,8 @@ export const pickWallet = async ({
if (assets != null && matchingAssets.length === 1 && Object.keys(walletIdMap).length === 1) {
// Only one matching wallet and asset. Auto pick the wallet
const [walletId, currencyCode] = Object.keys(walletIdMap)[0].split(':')
return { walletId, currencyCode }
const tokenId = getTokenId(account, currencyWallets[walletId].currencyInfo.pluginId, currencyCode)
return { type: 'wallet', walletId, currencyCode, tokenId }
} else {
const walletListResult = await Airship.show<WalletListResult>(bridge => (
<WalletListModal
Expand Down
5 changes: 3 additions & 2 deletions src/components/scenes/CreateWalletAccountSelectScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ export const CreateWalletAccountSelectScene = (props: Props) => {
Airship.show<WalletListResult>(bridge => (
<WalletListModal bridge={bridge} navigation={props.navigation} headerTitle={lstrings.select_wallet} allowedAssets={supportedAssets} />
))
.then(async ({ walletId, currencyCode }: WalletListResult) => {
if (walletId && currencyCode) {
.then(async result => {
if (result?.type === 'wallet') {
const { walletId, currencyCode } = result
dispatch({ type: 'WALLET_ACCOUNT_ACTIVATION_ESTIMATE_ERROR', data: '' })
setWalletId(walletId)
const createdWalletInstance = await handleRenameAndReturnWallet()
Expand Down
4 changes: 2 additions & 2 deletions src/components/scenes/CryptoExchangeScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,8 @@ export class CryptoExchangeComponent extends React.Component<Props, State> {
/>
))
.then(async result => {
const { walletId, currencyCode } = result
if (walletId != null && currencyCode != null) {
if (result?.type === 'wallet') {
const { walletId, currencyCode } = result
await this.props.onSelectWallet(walletId, currencyCode, whichWallet)
}
})
Expand Down
5 changes: 3 additions & 2 deletions src/components/scenes/Fio/FioAddressRegisterScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,9 @@ export class FioAddressRegister extends React.Component<Props, State> {
selectFioWallet = async () => {
await Airship.show<WalletListResult>(bridge => (
<WalletListModal bridge={bridge} navigation={this.props.navigation} headerTitle={lstrings.select_wallet} allowedAssets={[{ pluginId: 'fio' }]} />
)).then(({ walletId, currencyCode }: WalletListResult) => {
if (walletId && currencyCode) {
)).then(result => {
if (result?.type === 'wallet') {
const { walletId } = result
this.handleFioWalletChange(walletId)
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,11 @@ export class FioAddressRegisterSelectWallet extends React.Component<Props, Local
selectWallet = async () => {
const { supportedAssets } = this.state

const { walletId, currencyCode } = await Airship.show<WalletListResult>(bridge => (
const result = await Airship.show<WalletListResult>(bridge => (
<WalletListModal bridge={bridge} navigation={this.props.navigation} headerTitle={lstrings.select_wallet} allowedAssets={supportedAssets} />
))
if (walletId && currencyCode) {
if (result?.type === 'wallet') {
const { walletId, currencyCode } = result
this.setState({ paymentWallet: { id: walletId, currencyCode } })
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/components/scenes/Fio/FioDomainRegisterScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,11 @@ export class FioDomainRegister extends React.PureComponent<Props, LocalState> {
}

selectFioWallet = async () => {
const { walletId, currencyCode } = await Airship.show<WalletListResult>(bridge => (
const result = await Airship.show<WalletListResult>(bridge => (
<WalletListModal bridge={bridge} navigation={this.props.navigation} headerTitle={lstrings.select_wallet} allowedAssets={[{ pluginId: 'fio' }]} />
))
if (walletId && currencyCode) {
if (result?.type === 'wallet') {
const { walletId } = result
this.handleFioWalletChange(walletId)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ class FioDomainRegisterSelectWallet extends React.PureComponent<Props, LocalStat
selectWallet = async () => {
const { supportedAssets } = this.state

const { walletId, currencyCode } = await Airship.show<WalletListResult>(bridge => (
const result = await Airship.show<WalletListResult>(bridge => (
<WalletListModal bridge={bridge} navigation={this.props.navigation} headerTitle={lstrings.select_wallet} allowedAssets={supportedAssets} />
))
if (walletId && currencyCode) {
if (result?.type === 'wallet') {
const { walletId, currencyCode } = result
this.setState({ paymentWallet: { id: walletId, currencyCode } })
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/components/scenes/Fio/FioRequestListScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -376,10 +376,11 @@ class FioRequestList extends React.Component<Props, LocalState> {
const tokenId = getTokenId(account, pluginId, tokenCode)
const allowedAssets = [{ pluginId, tokenId }]

const { walletId, currencyCode } = await Airship.show<WalletListResult>(bridge => (
const result = await Airship.show<WalletListResult>(bridge => (
<WalletListModal bridge={bridge} navigation={this.props.navigation} headerTitle={lstrings.fio_src_wallet} allowedAssets={allowedAssets} />
))
if (walletId && currencyCode) {
if (result?.type === 'wallet') {
const { walletId, currencyCode } = result
onSelectWallet(walletId, currencyCode)
await this.sendCrypto(selectedFioPendingRequest, walletId, currencyCode)
}
Expand Down
11 changes: 6 additions & 5 deletions src/components/scenes/Loans/LoanCreateScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -250,23 +250,24 @@ export const LoanCreateScene = (props: Props) => {
filterActivation
/>
))
.then(async ({ walletId, currencyCode, isBankSignupRequest, fiatAccountId }) => {
if (isBankSignupRequest) {
.then(async result => {
if (result?.type === 'bankSignupRequest') {
// Open bank plugin for new user signup
navigation.navigate('pluginView', {
plugin: guiPlugins.wyre,
deepPath: '',
deepQuery: {}
})
} else if (fiatAccountId != null) {
} else if (result?.type === 'wyre') {
const { fiatAccountId } = result
// Set a hard-coded intermediate AAVE loan destination asset (USDC) to
// use for the bank sell step that comes after the initial loan
setDestBankId(fiatAccountId)
setDestWallet(borrowEngineWallet)
setDestTokenId(hardDestTokenAddr)
} else if (walletId != null && currencyCode != null) {
} else if (result?.type === 'wallet') {
const { walletId, currencyCode, tokenId } = result
const selectedWallet = wallets[walletId]
const tokenId = getTokenId(account, selectedWallet.currencyInfo.pluginId, currencyCode)
if (isSrc) {
setSrcWalletId(walletId)
setSrcTokenId(tokenId)
Expand Down
6 changes: 4 additions & 2 deletions src/components/scenes/Loans/LoanDashboardScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export const LoanDashboardScene = (props: Props) => {
const allowedAssets = SUPPORTED_WALLET_PLUGIN_IDS.map(pluginId => ({ pluginId }))

// Only show the wallet picker if the user owns more than one polygon wallet.
const { walletId: newWalletId } = await Airship.show<WalletListResult>(bridge => (
const result = await Airship.show<WalletListResult>(bridge => (
<WalletListModal
bridge={bridge}
navigation={navigation}
Expand All @@ -107,7 +107,9 @@ export const LoanDashboardScene = (props: Props) => {
excludeWalletIds={Object.keys(loanAccountsMap)}
/>
))
newLoanWallet = newWalletId == null ? null : currencyWallets[newWalletId]
if (result?.type === 'wallet') {
newLoanWallet = currencyWallets[result.walletId]
}
} else if (hardPluginWalletIds.length === 1) {
// If the user owns one polygon wallet, auto-select that wallet for the loan creation
newLoanWallet = currencyWallets[hardPluginWalletIds[0]]
Expand Down
18 changes: 10 additions & 8 deletions src/components/scenes/Loans/LoanManageScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -369,24 +369,26 @@ export const LoanManageSceneComponent = (props: Props) => {
filterActivation
/>
))
.then(async ({ walletId, currencyCode, isBankSignupRequest, fiatAccountId: wyreAccountId, customAsset }) => {
if (isBankSignupRequest) {
.then(async result => {
if (result?.type === 'bankSignupRequest') {
// Open bank plugin for new user signup
navigation.navigate('pluginView', {
plugin: guiPlugins.wyre,
deepPath: '',
deepQuery: {}
})
} else if (customAsset != null) {
setSelectedAsset({ wallet: borrowEngineWallet, tokenId: hardAllowedDebtAssets[0].tokenId, customAsset: customAsset })
} else if (wyreAccountId != null) {
const paymentMethod = bankAccountsMap[wyreAccountId]
} else if (result?.type === 'custom') {
const { customAsset } = result
setSelectedAsset({ wallet: borrowEngineWallet, tokenId: hardAllowedDebtAssets[0].tokenId, customAsset })
} else if (result?.type === 'wyre') {
const { fiatAccountId } = result
const paymentMethod = bankAccountsMap[fiatAccountId]
// Set a hard-coded intermediate AAVE loan destination asset (USDC) to
// use for the bank sell step that comes after the initial loan
setSelectedAsset({ wallet: borrowEngineWallet, tokenId: hardDebtTokenId, paymentMethod })
} else if (walletId != null && currencyCode != null) {
} else if (result?.type === 'wallet') {
const { walletId, tokenId } = result
const selectedWallet = wallets[walletId]
const tokenId = getTokenId(account, selectedWallet.currencyInfo.pluginId, currencyCode)
setSelectedAsset({ wallet: selectedWallet, tokenId })
}
})
Expand Down
5 changes: 3 additions & 2 deletions src/components/scenes/RequestScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,9 @@ export class RequestSceneComponent extends React.Component<Props, State> {
handleOpenWalletListModal = () => {
const { account } = this.props
Airship.show<WalletListResult>(bridge => <WalletListModal bridge={bridge} headerTitle={lstrings.select_wallet} navigation={this.props.navigation} />)
.then(async ({ walletId, currencyCode }: WalletListResult) => {
if (walletId && currencyCode) {
.then(async result => {
if (result?.type === 'wallet') {
const { walletId, currencyCode } = result
const wallet = account.currencyWallets[walletId]
const tokenId = getTokenId(account, wallet.currencyInfo.pluginId, currencyCode)
await this.props.onSelectWallet(this.props.navigation, walletId, tokenId)
Expand Down
4 changes: 2 additions & 2 deletions src/components/scenes/SendScene2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,8 @@ const SendComponent = (props: Props) => {

const handleWalletPress = useHandler(() => {
Airship.show<WalletListResult>(bridge => <WalletListModal bridge={bridge} headerTitle={lstrings.fio_src_wallet} navigation={navigation} />)
.then((result: WalletListResult) => {
if (result.walletId == null || result.currencyCode == null) {
.then(result => {
if (result?.type !== 'wallet') {
return
}
setWalletId(result.walletId)
Expand Down
5 changes: 3 additions & 2 deletions src/components/scenes/WcConnectScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,11 @@ export const WcConnectScene = (props: Props) => {
}

const handleWalletListModal = useHandler(async () => {
const { walletId, currencyCode } = await Airship.show<WalletListResult>(bridge => (
const result = await Airship.show<WalletListResult>(bridge => (
<WalletListModal bridge={bridge} headerTitle={lstrings.select_wallet} allowedAssets={edgeTokenIds} showCreateWallet navigation={navigation} />
))
if (walletId && currencyCode) {
if (result?.type === 'wallet') {
const { walletId, currencyCode } = result
const wallet = account.currencyWallets[walletId]
const tokenId = getTokenId(account, wallet.currencyInfo.pluginId, currencyCode)
await dispatch(selectWalletToken({ navigation, walletId, tokenId }))
Expand Down
Loading

0 comments on commit 8fd7595

Please sign in to comment.