Skip to content

Commit

Permalink
chore(wallet-mobile): more helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
stackchain committed May 4, 2024
1 parent acee14a commit 4f6c79b
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {Balance} from '@yoroi/types'

import {FungibilityFilter} from '../useCases/ListAmountsToSend/AddToken/SelectTokenFromListScreen'
import {filterByFungibility} from './filterByFungibility'

describe('filterByFungibility', () => {
Expand Down Expand Up @@ -68,7 +67,7 @@ describe('filterByFungibility', () => {
const nftTokenInfos: Balance.TokenInfo[] = [nft1, nft2]
const ftTokenInfos: Balance.TokenInfo[] = [fakeToken1, fakeToken2]

it.each<{fungibilityFilter: FungibilityFilter; result: Balance.TokenInfo[]}>([
it.each<{fungibilityFilter: 'all' | 'ft' | 'nft'; result: Balance.TokenInfo[]}>([
{
fungibilityFilter: 'all',
result: allTokenInfos,
Expand All @@ -82,7 +81,7 @@ describe('filterByFungibility', () => {
result: ftTokenInfos,
},
{
fungibilityFilter: 'random-value' as FungibilityFilter,
fungibilityFilter: 'random-value' as never,
result: allTokenInfos,
},
])('should return correct tokenInfos if fungibility is "$fungibility"', ({fungibilityFilter, result}) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import {Balance} from '@yoroi/types'

import {FungibilityFilter} from '../useCases/ListAmountsToSend/AddToken/SelectTokenFromListScreen'

export const filterByFungibility = ({fungibilityFilter}: {fungibilityFilter: FungibilityFilter}) => {
export const filterByFungibility = ({fungibilityFilter}: {fungibilityFilter: 'all' | 'ft' | 'nft'}) => {
if (fungibilityFilter === 'all') return () => true
if (fungibilityFilter === 'nft') return (tokenInfo: Balance.TokenInfo) => tokenInfo.kind === 'nft'
if (fungibilityFilter === 'ft') return (tokenInfo: Balance.TokenInfo) => tokenInfo.kind === 'ft'
Expand Down
41 changes: 41 additions & 0 deletions apps/wallet-mobile/src/features/Send/common/toYoroiEntry.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {tokenBalanceMocks} from '@yoroi/portfolio'
import {Transfer} from '@yoroi/types'

import {YoroiEntry} from '../../../yoroi-wallets/types'
import {toYoroiEntry} from './toYoroiEntry'

describe('toYoroiEntry', () => {
it('should convert Transfer.Entry to YoroiEntry correctly', () => {
const entry: YoroiEntry = {
address: 'exampleAddress',
datum: {
hash: 'exampleHash',
},
amounts: {
['']: '10',
[tokenBalanceMocks.nftCryptoKitty.info.id]: '20',
},
}

const transferEntry: Transfer.Entry = {
address: 'exampleAddress',
datum: {
hash: 'exampleHash',
},
amounts: {
[tokenBalanceMocks.primaryETH.info.id]: {
...tokenBalanceMocks.primaryETH,
quantity: 10n,
},
[tokenBalanceMocks.nftCryptoKitty.info.id]: {
...tokenBalanceMocks.nftCryptoKitty,
quantity: 20n,
},
},
}

const result = toYoroiEntry(transferEntry)

expect(result).toEqual(entry)
})
})
20 changes: 20 additions & 0 deletions apps/wallet-mobile/src/features/Send/common/toYoroiEntry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {Transfer} from '@yoroi/types'

import {YoroiEntry} from '../../../yoroi-wallets/types'
import {asQuantity} from '../../../yoroi-wallets/utils'

export function toYoroiEntry(entry: Transfer.Entry): YoroiEntry {
const yoroiEntry: YoroiEntry = {
address: entry.address,
datum: entry.datum,
amounts: Object.fromEntries(
Object.entries(entry.amounts).map(([tokenId, amount]) => [
// createPrimary helper forces '.' and this transformer is temporary
tokenId === '.' ? '' : tokenId,
asQuantity(amount.quantity.toString()),
]),
),
}

return yoroiEntry
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {FlashList} from '@shopify/flash-list'
import {infoFilterByName, isPrimaryToken} from '@yoroi/portfolio'
import {useTheme} from '@yoroi/theme'
import {useTransfer} from '@yoroi/transfer'
import {Portfolio} from '@yoroi/types'
import {Chain, Portfolio} from '@yoroi/types'
import React from 'react'
import {Alert, StyleSheet, TouchableOpacity, View} from 'react-native'

Expand Down Expand Up @@ -106,7 +106,7 @@ export const SelectTokenFromListScreen = () => {
<ListSpendables
canAddAmount={canAddAmount}
spendableAmounts={filteredAmounts}
isMainnet={wallet.isMainnet}
network={wallet.network}
isSearching={isSearching}
isSearchOpened={isSearchOpened}
/>
Expand Down Expand Up @@ -166,14 +166,14 @@ const ListSpendableNfts = ({
type ListSpendableBalancesProps = {
canAddAmount: boolean
spendableAmounts: ReadonlyArray<Portfolio.Token.Amount>
isMainnet: boolean
network: Chain.Network
isSearching: boolean
isSearchOpened: boolean
}
const ListSpendables = ({
canAddAmount,
spendableAmounts,
isMainnet,
network,
isSearching,
isSearchOpened,
}: ListSpendableBalancesProps) => {
Expand All @@ -183,7 +183,7 @@ const ListSpendables = ({
<FlashList
data={spendableAmounts}
renderItem={({item: amount}) => (
<SelectAmount amount={amount} disabled={!canAddAmount && !isPrimaryToken(amount.info)} isMainnet={isMainnet} />
<SelectAmount amount={amount} disabled={!canAddAmount && !isPrimaryToken(amount.info)} network={network} />
)}
bounces={false}
contentContainerStyle={styles.spendableAmountsContent}
Expand Down Expand Up @@ -233,9 +233,9 @@ const Tabs = ({children}: {children: React.ReactNode}) => {
type SelectAmountProps = {
disabled?: boolean
amount: Portfolio.Token.Amount
isMainnet: boolean
network: Chain.Network
}
const SelectAmount = ({amount, disabled, isMainnet = true}: SelectAmountProps) => {
const SelectAmount = ({amount, disabled, network}: SelectAmountProps) => {
const {styles} = useStyles()
const navigation = useNavigation<TxHistoryRouteNavigation>()
const {closeSearch} = useSearch()
Expand Down Expand Up @@ -263,7 +263,7 @@ const SelectAmount = ({amount, disabled, isMainnet = true}: SelectAmountProps) =
testID="selectTokenButton"
disabled={disabled}
>
<TokenAmountItem amount={amount} isMainnet={isMainnet} isPrivacyOff={true} privacyPlaceholder="" />
<TokenAmountItem amount={amount} network={network} isPrivacyOff privacyPlaceholder="" />
</TouchableOpacity>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {useNavigation} from '@react-navigation/native'
import {isNft} from '@yoroi/portfolio'
import {useTheme} from '@yoroi/theme'
import {useTransfer} from '@yoroi/transfer'
import type {Balance} from '@yoroi/types'
import type {Balance, Portfolio} from '@yoroi/types'
import * as React from 'react'
import {useLayoutEffect} from 'react'
import {defineMessages, useIntl} from 'react-intl'
Expand All @@ -15,12 +16,12 @@ import globalMessages from '../../../../i18n/global-messages'
import {assetsToSendProperties} from '../../../../metrics/helpers'
import {useMetrics} from '../../../../metrics/metricsManager'
import {useSearch} from '../../../../Search/SearchContext'
import {sortTokenInfos} from '../../../../utils'
import {useTokenInfo, useTokenInfos} from '../../../../yoroi-wallets/hooks'
import {useTokenInfo} from '../../../../yoroi-wallets/hooks'
import {YoroiEntry} from '../../../../yoroi-wallets/types'
import {Amounts} from '../../../../yoroi-wallets/utils'
import {useSelectedWallet} from '../../../WalletManager/Context'
import {useNavigateTo, useOverridePreviousSendTxRoute} from '../../common/navigation'
import {toYoroiEntry} from '../../common/toYoroiEntry'
import {AddTokenButton} from './AddToken/AddToken'
import {RemoveAmountButton} from './RemoveAmount'

Expand All @@ -46,34 +47,27 @@ export const ListAmountsToSendScreen = () => {
unsignedTxChanged: yoroiUnsignedTxChanged,
} = useTransfer()
const {amounts} = targets[selectedTargetIndex].entry

const selectedTokensCounter = Amounts.toArray(amounts).length
const selectedTokensCounter = Object.keys(amounts).length

const wallet = useSelectedWallet()
const tokenInfos = useTokenInfos({
wallet,
tokenIds: Amounts.toArray(amounts).map(({tokenId}) => tokenId),
})
const tokens = sortTokenInfos({wallet, tokenInfos})
const {mutate: createUnsignedTx, isLoading} = useMutation({
mutationFn: (entries: YoroiEntry[]) => wallet.createUnsignedTx(entries),
retry: false,
useErrorBoundary: true,
})

React.useEffect(() => {
track.sendSelectAssetUpdated(assetsToSendProperties({tokens, amounts}))
track.sendSelectAssetUpdated(assetsToSendProperties({amounts}))
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [amounts, tokens.length, track])
}, [amounts, selectedTokensCounter, track])

const onEdit = (tokenId: string) => {
const tokenInfo = tokenInfos.find((tokenInfo) => tokenInfo.id === tokenId)
if (tokenInfo?.kind === 'nft') return
const onEdit = (tokenId: Portfolio.Token.Id) => {
if (isNft(amounts[tokenId].info)) return

tokenSelectedChanged(tokenId)
navigateTo.editAmount()
}
const onRemove = (tokenId: string) => {
const onRemove = (tokenId: Portfolio.Token.Id) => {
// use case: redirect to add token screen if there is no token left
if (selectedTokensCounter === 1) {
clearSearch()
Expand All @@ -82,8 +76,10 @@ export const ListAmountsToSendScreen = () => {
amountRemoved(tokenId)
}
const onNext = () => {
track.sendSelectAssetSelected(assetsToSendProperties({tokens, amounts}))
createUnsignedTx([targets[selectedTargetIndex].entry], {
track.sendSelectAssetSelected(assetsToSendProperties({amounts}))
// since the user can't see many targets we just send the first one
// NOTE: update on multi target support
createUnsignedTx([toYoroiEntry(targets[selectedTargetIndex].entry)], {
onSuccess: (yoroiUnsignedTx) => {
yoroiUnsignedTxChanged(yoroiUnsignedTx)
navigateTo.confirmTx()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {init} from '@emurgo/cross-csl-mobile'
import {storiesOf} from '@storybook/react-native'
import {tokenBalanceMocks} from '@yoroi/portfolio'
import {resolverApiMaker, resolverManagerMaker, ResolverProvider, resolverStorageMaker} from '@yoroi/resolver'
import {defaultTransferState, TransferProvider, TransferState} from '@yoroi/transfer'
import {Resolver} from '@yoroi/types'
Expand Down Expand Up @@ -75,7 +76,12 @@ const mockSelectedNameServer: TransferState = {
...defaultTransferState,
targets: [
{
entry: {address: 'addr1vxggvx6uq9mtf6e0tyda2mahg84w8azngpvkwr5808ey6qsy2ww7d', amounts: {'': '1000000'}},
entry: {
address: 'addr1vxggvx6uq9mtf6e0tyda2mahg84w8azngpvkwr5808ey6qsy2ww7d',
amounts: {
[tokenBalanceMocks.primaryETH.info.id]: tokenBalanceMocks.primaryETH,
},
},
receiver: {
as: 'domain',
resolve: '$stackchain',
Expand All @@ -92,7 +98,12 @@ const mockUnselectedNameServer: TransferState = {
...defaultTransferState,
targets: [
{
entry: {address: '', amounts: {'': '1000000'}},
entry: {
address: '',
amounts: {
[tokenBalanceMocks.primaryETH.info.id]: tokenBalanceMocks.primaryETH,
},
},
receiver: {
as: 'domain',
resolve: '$stackchain',
Expand Down

0 comments on commit 4f6c79b

Please sign in to comment.