Skip to content

Commit

Permalink
Payments working
Browse files Browse the repository at this point in the history
  • Loading branch information
ChewingGlass committed Jul 31, 2023
1 parent 3c52c82 commit 714ba54
Show file tree
Hide file tree
Showing 30 changed files with 648 additions and 451 deletions.
35 changes: 20 additions & 15 deletions src/components/HNTKeyboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
} from '@gorhom/bottom-sheet'
import { Portal } from '@gorhom/portal'
import { useMint, useOwnedAmount } from '@helium/helium-react-hooks'
import { humanReadable } from '@helium/spl-utils'
import useBackHandler from '@hooks/useBackHandler'
import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata'
import { usePublicKey } from '@hooks/usePublicKey'
Expand Down Expand Up @@ -34,6 +33,7 @@ import { Edge } from 'react-native-safe-area-context'
import { Payment } from '../features/payment/PaymentItem'
import { CSAccount } from '../storage/cloudStorage'
import { decimalSeparator, groupSeparator } from '../utils/i18n'
import { humanReadable } from '../utils/solanaUtils'
import AccountIcon from './AccountIcon'
import BackgroundFill from './BackgroundFill'
import Box from './Box'
Expand Down Expand Up @@ -87,7 +87,7 @@ const HNTKeyboardSelector = forwardRef(
const decimals = useMint(mint)?.info?.decimals
const { t } = useTranslation()
const bottomSheetModalRef = useRef<BottomSheetModal>(null)
const { symbol } = useMetaplexMetadata(mint)
const { symbol, loading: loadingMeta } = useMetaplexMetadata(mint)
const { backgroundStyle } = useOpacity('surfaceSecondary', 1)
const [value, setValue] = useState('0')
const [originalValue, setOriginalValue] = useState('')
Expand Down Expand Up @@ -119,12 +119,13 @@ const HNTKeyboardSelector = forwardRef(
}, [payee])

const valueAsBalance = useMemo(() => {
const stripped = value
.replaceAll(groupSeparator, '')
.replaceAll(decimalSeparator, '.')
if (!value || typeof decimals === 'undefined') return undefined
const [whole, dec] = value.split(decimalSeparator)
const decPart = (dec || '').padEnd(decimals, '0').slice(0, decimals)
const fullStr = `${whole.replaceAll(groupSeparator, '')}${decPart}`

return new BN(stripped)
}, [value])
return new BN(fullStr)
}, [value, decimals])

const hasMaxDecimals = useMemo(() => {
if (!valueAsBalance || typeof decimals === 'undefined') return false
Expand Down Expand Up @@ -202,8 +203,7 @@ const HNTKeyboardSelector = forwardRef(
maxBalance = networkFee ? maxBalance?.sub(networkFee) : maxBalance
}

const val =
maxBalance && decimals ? humanReadable(maxBalance, decimals) : '0'
const val = humanReadable(maxBalance, decimals) || '0'

setValue(maxEnabled ? '0' : val)
setMaxEnabled((m) => !m)
Expand Down Expand Up @@ -248,11 +248,13 @@ const HNTKeyboardSelector = forwardRef(
>
<BackdropWrapper>
<Box padding="l" alignItems="center" onLayout={handleHeaderLayout}>
<Text variant="subtitle2">
{t('hntKeyboard.enterAmount', {
ticker: symbol,
})}
</Text>
{!loadingMeta && (
<Text variant="subtitle2">
{t('hntKeyboard.enterAmount', {
ticker: symbol,
})}
</Text>
)}
<Box
flexDirection="row"
alignItems="center"
Expand Down Expand Up @@ -297,6 +299,7 @@ const HNTKeyboardSelector = forwardRef(
[
BackdropWrapper,
handleHeaderLayout,
loadingMeta,
t,
symbol,
payer,
Expand Down Expand Up @@ -351,7 +354,9 @@ const HNTKeyboardSelector = forwardRef(
return false
}

new BN(balanceForMint.toString()).sub(valueAsBalance)
return new BN(balanceForMint.toString())
.sub(valueAsBalance)
.gte(new BN(0))
}, [networkFee, payer, valueAsBalance, balanceForMint])

const handleConfirm = useCallback(() => {
Expand Down
24 changes: 13 additions & 11 deletions src/features/account/AccountActionBar.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { useCallback, useMemo } from 'react'
import { useNavigation } from '@react-navigation/native'
import { useTranslation } from 'react-i18next'
import { LayoutChangeEvent } from 'react-native'
import { Ticker } from '@helium/currency'
import Box from '@components/Box'
import FabButton from '@components/FabButton'
import Text from '@components/Text'
import { useNavigation } from '@react-navigation/native'
import { PublicKey } from '@solana/web3.js'
import React, { useCallback, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { LayoutChangeEvent } from 'react-native'
import { useAccountStorage } from '../../storage/AccountStorageProvider'
import { useAppStorage } from '../../storage/AppStorageProvider'
import { HomeNavigationProp } from '../home/homeTypes'
import { useAccountStorage } from '../../storage/AccountStorageProvider'

export type Action =
| 'send'
Expand All @@ -21,7 +21,7 @@ export type Action =
| 'airdrop'

type Props = {
ticker?: Ticker
mint?: PublicKey
onLayout?: (event: LayoutChangeEvent) => void
compact?: boolean
maxCompact?: boolean
Expand All @@ -43,7 +43,7 @@ const AccountActionBar = ({
hasDelegate,
hasSwaps,
hasAirdrop,
ticker,
mint,
}: Props) => {
const navigation = useNavigation<HomeNavigationProp>()
const { t } = useTranslation()
Expand All @@ -58,7 +58,7 @@ const AccountActionBar = ({
navigation.navigate('ConfirmPin', { action: 'payment' })
} else {
navigation.navigate('PaymentScreen', {
defaultTokenType: ticker,
mint: mint?.toBase58(),
})
}
break
Expand All @@ -72,7 +72,9 @@ const AccountActionBar = ({
break
}
case 'airdrop': {
navigation.navigate('AirdropScreen', { ticker: ticker || 'HNT' })
if (mint) {
navigation.navigate('AirdropScreen', { mint: mint?.toBase58() })
}
break
}
case '5G': {
Expand All @@ -93,7 +95,7 @@ const AccountActionBar = ({
}
}
},
[navigation, pin, requirePinForPayment, ticker],
[pin?.status, requirePinForPayment, navigation, mint],
)

const fabMargin = useMemo(() => {
Expand Down
7 changes: 5 additions & 2 deletions src/features/account/AccountManageTokenListScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import TokenIcon from '@components/TokenIcon'
import TouchableContainer from '@components/TouchableContainer'
import { Ticker } from '@helium/currency'
import { useOwnedAmount } from '@helium/helium-react-hooks'
import { DC_MINT, humanReadable } from '@helium/spl-utils'
import { DC_MINT } from '@helium/spl-utils'
import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata'
import { usePublicKey } from '@hooks/usePublicKey'
import CheckBox from '@react-native-community/checkbox'
Expand All @@ -17,6 +17,7 @@ import { useAccountStorage } from '@storage/AccountStorageProvider'
import { useVisibleTokens } from '@storage/TokensProvider'
import { useColors, useHitSlop } from '@theme/themeHooks'
import { useBalance } from '@utils/Balance'
import { humanReadable } from '@utils/solanaUtils'
import BN from 'bn.js'
import React, { memo, useCallback, useMemo } from 'react'
import { FlatList } from 'react-native-gesture-handler'
Expand All @@ -42,7 +43,9 @@ const CheckableTokenListItem = ({
const { amount, decimals } = useOwnedAmount(wallet, mint)
const { json, symbol } = useMetaplexMetadata(mint)
const balanceToDisplay = useMemo(() => {
return amount ? humanReadable(new BN(amount.toString()), decimals) : ''
return amount && typeof decimals !== 'undefined'
? humanReadable(new BN(amount.toString()), decimals)
: ''
}, [amount, decimals])
const colors = useColors()

Expand Down
136 changes: 75 additions & 61 deletions src/features/account/AccountTokenBalance.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,98 @@
import { Ticker } from '@helium/currency'
import { BoxProps } from '@shopify/restyle'
import React, { memo, useMemo } from 'react'
import Box from '@components/Box'
import Text from '@components/Text'
import TextTransform from '@components/TextTransform'
import Box from '@components/Box'
import { useOwnedAmount, useTokenAccount } from '@helium/helium-react-hooks'
import { DC_MINT } from '@helium/spl-utils'
import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata'
import { usePublicKey } from '@hooks/usePublicKey'
import { BoxProps } from '@shopify/restyle'
import { PublicKey } from '@solana/web3.js'
import { useAccountStorage } from '@storage/AccountStorageProvider'
import { Theme } from '@theme/theme'
import { IOT_SUB_DAO_KEY, MOBILE_SUB_DAO_KEY } from '@utils/constants'
import { getEscrowTokenAccount, humanReadable } from '@utils/solanaUtils'
import BN from 'bn.js'
import React, { memo, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { useBalance } from '../../utils/Balance'

type Props = {
ticker: Ticker
mint: PublicKey
textVariant?: 'h0' | 'h1' | 'h2' | 'h2Medium'
showTicker?: boolean
} & BoxProps<Theme>

const EscrowDetails = () => {
const { t } = useTranslation()
const { currentAccount } = useAccountStorage()

const iotEscrow = getEscrowTokenAccount(
currentAccount?.solanaAddress,
IOT_SUB_DAO_KEY,
)
const mobileEscrow = getEscrowTokenAccount(
currentAccount?.solanaAddress,
MOBILE_SUB_DAO_KEY,
)
const { info: iotEscrowAcct } = useTokenAccount(iotEscrow)
const { info: mobileEscrowAcct } = useTokenAccount(mobileEscrow)

return (
<Box>
<Text variant="body1" color="secondaryText" textAlign="center">
{t('accountsScreen.receivedBalance', {
amount: humanReadable(
new BN(iotEscrowAcct?.amount?.toString() || '0').add(
new BN(mobileEscrowAcct?.amount?.toString() || '0'),
),
6,
),
})}
</Text>
</Box>
)
}

const AccountTokenBalance = ({
ticker,
mint,
textVariant,
showTicker = true,
...boxProps
}: Props) => {
const { currentAccount } = useAccountStorage()
const wallet = usePublicKey(currentAccount?.solanaAddress)
const {
dcBalance,
mobileBalance,
iotBalance,
solBalance,
hntBalance,
dcEscrowBalance,
} = useBalance()
const { t } = useTranslation()

const balance = useMemo(() => {
switch (ticker) {
default:
case 'HNT': {
return hntBalance
}
case 'MOBILE':
return mobileBalance
case 'IOT':
return iotBalance
case 'SOL':
return solBalance
case 'DC':
return dcBalance
}
}, [dcBalance, mobileBalance, hntBalance, solBalance, iotBalance, ticker])
amount: balance,
decimals,
loading: loadingOwned,
} = useOwnedAmount(wallet, mint)
const balanceStr =
typeof decimals !== 'undefined' && balance
? humanReadable(new BN(balance?.toString() || '0'), decimals)
: undefined
const { symbol } = useMetaplexMetadata(mint)

const tokenDetails = useMemo(() => {
if (ticker !== 'DC' || !showTicker) return
if (!mint.equals(DC_MINT) || !showTicker) return

return (
<Box>
<Text variant="body1" color="secondaryText" textAlign="center">
{t('accountsScreen.receivedBalance', {
amount: dcEscrowBalance?.toString(2, { showTicker: false }),
})}
</Text>
</Box>
)
}, [ticker, showTicker, t, dcEscrowBalance])
return <EscrowDetails />
}, [mint, showTicker])

return (
<Box flexDirection="row" justifyContent="center" {...boxProps}>
{!showTicker && (
<Text
variant={textVariant || 'h1'}
color="primaryText"
numberOfLines={1}
maxFontSizeMultiplier={1}
adjustsFontSizeToFit
>
{typeof balance === 'number'
? balance
: `${balance?.toString(2, { showTicker: false })}`}
</Text>
)}
{!showTicker &&
(loadingOwned ? (
<Box width={70} height={20} marginTop="s" backgroundColor="surface" />
) : (
<Text
variant={textVariant || 'h1'}
color="primaryText"
numberOfLines={1}
maxFontSizeMultiplier={1}
adjustsFontSizeToFit
>
{balanceStr}
</Text>
))}
<Box>
{showTicker && (
<TextTransform
Expand All @@ -86,11 +103,8 @@ const AccountTokenBalance = ({
adjustsFontSizeToFit
i18nKey="accountsScreen.tokenBalance"
values={{
amount:
typeof balance === 'number'
? balance
: balance?.toString(2, { showTicker: false }),
ticker,
amount: balanceStr,
ticker: symbol,
}}
/>
)}
Expand Down
13 changes: 9 additions & 4 deletions src/features/account/AccountTokenList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { BottomSheetFlatListProps } from '@gorhom/bottom-sheet/lib/typescript/co
import { DC_MINT, HNT_MINT, IOT_MINT, MOBILE_MINT } from '@helium/spl-utils'
import { useNavigation } from '@react-navigation/native'
import { PublicKey } from '@solana/web3.js'
import { useVisibleTokens } from '@storage/TokensProvider'
import { useVisibleTokens, DEFAULT_TOKENS } from '@storage/TokensProvider'
import { useBalance } from '@utils/Balance'
import { times } from 'lodash'
import React, { useCallback, useMemo } from 'react'
Expand Down Expand Up @@ -40,17 +40,22 @@ const AccountTokenList = ({ onLayout }: Props) => {
const { tokenAccounts } = useBalance()
const { bottom } = useSafeAreaInsets()
const mints = useMemo(() => {
return tokenAccounts
const taMints = tokenAccounts
?.filter(
(ta) =>
visibleTokens.has(ta.mint) &&
ta.balance > 0 &&
(ta.decimals > 0 || ta.mint === DC_MINT.toBase58()),
)
.map((ta) => new PublicKey(ta.mint))
.map((ta) => ta.mint)

const all = [...new Set([...DEFAULT_TOKENS, ...(taMints || [])])]
.sort((a, b) => {
return getSortValue(b.toBase58()) - getSortValue(a.toBase58())
return getSortValue(b) - getSortValue(a)
})
.map((mint) => new PublicKey(mint))

return all
}, [tokenAccounts, visibleTokens])

const bottomSpace = useMemo(() => bottom * 2, [bottom])
Expand Down
Loading

0 comments on commit 714ba54

Please sign in to comment.