Skip to content

Commit

Permalink
Merge pull request #932 from alephium/address-worth-improvements
Browse files Browse the repository at this point in the history
Address worth improvements/fixes
  • Loading branch information
mvaivre authored Oct 30, 2024
2 parents edf221f + 8e41915 commit 5f3658e
Show file tree
Hide file tree
Showing 17 changed files with 395 additions and 122 deletions.
5 changes: 5 additions & 0 deletions .changeset/many-eyes-bow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@alephium/explorer": patch
---

Fix address worth display
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,21 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { explorer } from '@alephium/web3'
import { PRICED_TOKENS } from '@alephium/shared'
import { useQuery } from '@tanstack/react-query'

import { SkipProp } from '@/api/apiDataHooks/apiDataHooksTypes'
import { tokensPriceQuery } from '@/api/queries/priceQueries'
import { useAppSelector } from '@/hooks/redux'
import { selectCurrentlyOnlineNetworkId } from '@/storage/settings/networkSelectors'

const pricedTokens = Object.keys(explorer.TokensWithPrice)

const useFetchTokenPrices = (props?: SkipProp) => {
const fiatCurrency = useAppSelector((s) => s.settings.fiatCurrency)
const networkIsOffline = useAppSelector(selectCurrentlyOnlineNetworkId) === undefined

const { data, isLoading } = useQuery(
tokensPriceQuery({
symbols: pricedTokens,
symbols: PRICED_TOKENS,
currency: fiatCurrency.toLowerCase(),
skip: props?.skip || networkIsOffline
})
Expand All @@ -51,7 +49,7 @@ export const useFetchTokenPrice = (symbol: string) => {
const networkIsOffline = useAppSelector(selectCurrentlyOnlineNetworkId) === undefined

const { data, isLoading } = useQuery({
...tokensPriceQuery({ symbols: pricedTokens, currency: fiatCurrency.toLowerCase(), skip: networkIsOffline }),
...tokensPriceQuery({ symbols: PRICED_TOKENS, currency: fiatCurrency.toLowerCase(), skip: networkIsOffline }),
select: (data) => data.find((tokenPrice) => tokenPrice.symbol === symbol)?.price
})

Expand Down
4 changes: 2 additions & 2 deletions apps/explorer/locales/de-DE/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"Copy token ID": "Token ID kopieren",
"Daily": "täglich",
"Download CSV": "CSV herunterladen",
"Fiat price": "Fiat Preis",
"Gas Amount": "Gasmenge",
"Gas Price": "Gaspreis",
"Hash": "Hash",
Expand Down Expand Up @@ -136,5 +135,6 @@
"uncleBlock_other": "Onkel Blöcke",
"Uncle": "Onkel",
"Unsupported media type": "Nicht unterstützter Medientyp",
"Video thumbnail": "Video Vorschaubild"
"Video thumbnail": "Video Vorschaubild",
"Address worth": "Adresswert"
}
4 changes: 2 additions & 2 deletions apps/explorer/locales/el-GR/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"Copy token ID": "Αντιγραφή αναγνωριστικού διακριτικού",
"Daily": "Ημερησίως",
"Download CSV": "Λήψη CSV",
"Fiat price": "Τιμή σε παραστατικό χρήμα",
"Gas Amount": "Ποσό gas",
"Gas Price": "Τιμή gas",
"Hash": "Κατακερματισμός",
Expand Down Expand Up @@ -130,5 +129,6 @@
"Orphan": "Ορφανό",
"It appears that this block is not part of the main chain.": "Φαίνεται ότι αυτό το μπλοκ δεν αποτελεί μέρος της κύριας αλυσίδας.",
"confirmationsKey_one": "{{ count }} Επαλήθευση",
"confirmationsKey_other": "{{ count }} Επαληθεύσεις"
"confirmationsKey_other": "{{ count }} Επαληθεύσεις",
"Address worth": "Αξία διεύθυνσης"
}
4 changes: 2 additions & 2 deletions apps/explorer/locales/en-US/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"Copy token ID": "Copy token ID",
"Daily": "Daily",
"Download CSV": "Download CSV",
"Fiat price": "Fiat price",
"Gas Amount": "Gas Amount",
"Gas Price": "Gas Price",
"Hash": "Hash",
Expand Down Expand Up @@ -137,5 +136,6 @@
"Uncle": "Uncle",
"Unsupported media type": "Unsupported media type",
"Video thumbnail": "Video thumbnail",
"No media": "No media"
"No media": "No media",
"Address worth": "Address worth"
}
4 changes: 2 additions & 2 deletions apps/explorer/locales/fr-FR/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"Copy token ID": "Copier le token ID",
"Daily": "Par jour",
"Download CSV": "Télécharger CSV",
"Fiat price": "Prix en fiat",
"Gas Amount": "Quantité de gaz",
"Gas Price": "Prix du gaz",
"Hash": "Hash",
Expand Down Expand Up @@ -130,5 +129,6 @@
"Orphan": "Orphelin",
"It appears that this block is not part of the main chain.": "Il semble que ce bloc ne fait pas partie de la chaîne principale.",
"confirmationsKey_one": "{{ count }} confirmation",
"confirmationsKey_other": "{{ count }} confirmations"
"confirmationsKey_other": "{{ count }} confirmations",
"Address worth": "Valeur de l'adresse"
}
4 changes: 2 additions & 2 deletions apps/explorer/locales/id-ID/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"Copy token ID": "Salin ID token",
"Daily": "Harian",
"Download CSV": "Unduh CSV",
"Fiat price": "Harga dalam mata uang fiat",
"Gas Amount": "Jumlah Gas",
"Gas Price": "Harga Gas",
"Hashrate": "hashrate",
Expand Down Expand Up @@ -101,5 +100,6 @@
"Page not found": "Halaman tidak ditemukan",
"letsGoBack": "Mari kembali ke <1>beranda</1>.",
"Unknown error": "Kesalahan yang tidak diketahui",
"It appears that this block is not part of the main chain.": "Tampaknya blok ini bukan bagian dari rantai utama."
"It appears that this block is not part of the main chain.": "Tampaknya blok ini bukan bagian dari rantai utama.",
"Address worth": "Nilai alamat"
}
4 changes: 2 additions & 2 deletions apps/explorer/locales/it-IT/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"Copy token ID": "Copia l'ID del token",
"Daily": "Quotidiano",
"Download CSV": "Scarica il CSV",
"Fiat price": "Prezzo Fiat",
"Gas Amount": "Quantità di Gas",
"Gas Price": "Prezzo del Gas",
"Hashrate": "Tasso di Hashrate",
Expand Down Expand Up @@ -131,5 +130,6 @@
"uncleBlock_other": "Blocchi zio",
"Uncle": "Zio",
"Unsupported media type": "Tipo di contenuto multimediale non supportato",
"Video thumbnail": "Miniatura video"
"Video thumbnail": "Miniatura video",
"Address worth": "Valore dell'indirizzo"
}
4 changes: 2 additions & 2 deletions apps/explorer/locales/pt-PT/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"Copy token ID": "Copiar ID do token",
"Daily": "Diário",
"Download CSV": "Baixar CSV",
"Fiat price": "Preço em moeda fiduciària",
"Gas Amount": "Valor de gás",
"Gas Price": "Preço do gás",
"Hash": "Hash",
Expand Down Expand Up @@ -136,5 +135,6 @@
"uncleBlock_other": "Uncle blocks",
"Uncle": "Uncle",
"Unsupported media type": "Tipo de mídia não suportado",
"Video thumbnail": "Miniatura de vídeo"
"Video thumbnail": "Miniatura de vídeo",
"Address worth": "Valor do endereço"
}
4 changes: 2 additions & 2 deletions apps/explorer/locales/vi-VN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"Copy token ID": "Sao chép token ID",
"Daily": "Hằng ngày",
"Download CSV": "Tải CSV",
"Fiat price": "Trị giá",
"Gas Amount": "Số lượng Gas",
"Gas Price": "Giá Gas",
"Hash": "Hash",
Expand Down Expand Up @@ -129,5 +128,6 @@
"Unknown error": "Lỗi không xác định",
"It appears that this block is not part of the main chain.": "Có vẻ như block này không thuộc về một phần của chain chính.",
"confirmationsKey_one": "{{ count }} Xác nhận",
"confirmationsKey_other": "{{ count }} Xác nhận"
"confirmationsKey_other": "{{ count }} Xác nhận",
"Address worth": "Giá trị của địa chỉ"
}
10 changes: 2 additions & 8 deletions apps/explorer/src/api/assets/assetsHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { PRICED_TOKENS } from '@alephium/shared'
import { ALPH } from '@alephium/token-list'
import { useQuery } from '@tanstack/react-query'
import { flatMap, uniq } from 'lodash'
Expand Down Expand Up @@ -172,15 +173,8 @@ export const useAssetsMetadata = (assetIds: string[] = []) => {
} else return returnedCompleteMetadata
}

// We should get this list from the backend
// See: https://github.com/alephium/explorer-backend/issues/512
export const useTokensWithAvailablePrice = () => ['ALPH', 'USDT', 'USDC', 'DAI', 'WBTC', 'WETH', 'AYIN']

export const useTokensPrices = <T extends string>(assetSymbols: T[] = []) => {
const availableTokensSymbols = useTokensWithAvailablePrice()
const tokensToFetch = uniq(assetSymbols).filter(
(symbol) => !!symbol && !!availableTokensSymbols && availableTokensSymbols.includes(symbol)
)
const tokensToFetch = uniq(assetSymbols).filter((symbol) => !!symbol && PRICED_TOKENS.includes(symbol))

const { data: prices } = useQueriesData(
tokensToFetch.map((symbol) => ({
Expand Down
14 changes: 8 additions & 6 deletions apps/explorer/src/pages/AddressInfoPage/AssetList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { AddressHash, calculateAmountWorth, sortAssets } from '@alephium/shared'
import { AddressHash, calculateAmountWorth, PRICED_TOKENS, sortAssets } from '@alephium/shared'
import { ALPH } from '@alephium/token-list'
import { AddressBalance } from '@alephium/web3/dist/src/api/api-explorer'
import { useQuery } from '@tanstack/react-query'
Expand All @@ -27,7 +27,7 @@ import { RiCopperDiamondLine, RiNftLine, RiQuestionLine } from 'react-icons/ri'
import styled, { useTheme } from 'styled-components'

import { queries } from '@/api'
import { useAssetsMetadata, useTokensPrices, useTokensWithAvailablePrice } from '@/api/assets/assetsHooks'
import { useAssetsMetadata, useTokensPrices } from '@/api/assets/assetsHooks'
import TableTabBar, { TabItem } from '@/components/Table/TableTabBar'
import NFTList from '@/pages/AddressInfoPage/NFTList'
import TokenList from '@/pages/AddressInfoPage/TokenList'
Expand All @@ -54,10 +54,9 @@ const AssetList = ({ addressHash, addressBalance, limit, className }: AssetListP
unknown: unknownAssetsIds
} = useAssetsMetadata(assetIds)

const tokensWithAvailablePrice = useTokensWithAvailablePrice()
const tokensPrices = useTokensPrices([
ALPH.symbol,
...fungibleTokensMetadata.flatMap((t) => (tokensWithAvailablePrice.includes(t.symbol) && t.symbol) || [])
...fungibleTokensMetadata.flatMap((t) => (PRICED_TOKENS.includes(t.symbol) && t.symbol) || [])
])

const isLoading = assetsLoading
Expand All @@ -72,7 +71,9 @@ const AssetList = ({ addressHash, addressBalance, limit, className }: AssetListP
...t,
balance: BigInt(balance.balance),
lockedBalance: BigInt(balance.lockedBalance),
worth: (t.verified && calculateAmountWorth(BigInt(balance.balance), tokensPrices[t.symbol])) || undefined
worth:
(t.verified && calculateAmountWorth(BigInt(balance.balance), tokensPrices[t.symbol], t.decimals)) ||
undefined
}
]
: []
Expand All @@ -84,7 +85,8 @@ const AssetList = ({ addressHash, addressBalance, limit, className }: AssetListP
...alphMetadata,
balance: BigInt(addressBalance.balance),
lockedBalance: BigInt(addressBalance.lockedBalance),
worth: calculateAmountWorth(BigInt(addressBalance.balance), tokensPrices[ALPH.symbol]) || undefined
worth:
calculateAmountWorth(BigInt(addressBalance.balance), tokensPrices[ALPH.symbol], ALPH.decimals) || undefined
})
}

Expand Down
12 changes: 8 additions & 4 deletions apps/explorer/src/pages/AddressInfoPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,12 @@ const AddressInfoPage = () => {

const knownTokensWorth = tokenBalances.reduce((acc, b) => {
const token = fungibleTokensMetadata.find((t) => t.verified && t.id === b.tokenId)
const price = tokensPrices[token?.symbol || '']

return acc + (price ? calculateAmountWorth(BigInt(b.balance), price) : 0)
if (!token) return acc

const price = tokensPrices[token.symbol] || 0

return acc + calculateAmountWorth(BigInt(b.balance), price, token.decimals)
}, 0)

const addressLatestActivity =
Expand All @@ -141,7 +144,8 @@ const AddressInfoPage = () => {
const lockedBalance = addressBalance?.lockedBalance

const addressWorth =
knownTokensWorth + (totalBalance ? calculateAmountWorth(BigInt(totalBalance), tokensPrices[ALPH.symbol] || NaN) : 0)
knownTokensWorth +
(totalBalance ? calculateAmountWorth(BigInt(totalBalance), tokensPrices[ALPH.symbol] || NaN, ALPH.decimals) : 0)

const totalNbOfAssets =
tokenBalances.length +
Expand Down Expand Up @@ -197,7 +201,7 @@ const AddressInfoPage = () => {
}
/>
<InfoGrid.Cell
label={t('Fiat price')}
label={t('Address worth')}
value={addressWorth && <Amount value={addressWorth} isFiat suffix="$" />}
sublabel={client.networkType === 'testnet' && t('Worth of mainnet equivalent')}
/>
Expand Down
4 changes: 3 additions & 1 deletion packages/shared/src/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { NFTTokenUriMetaData } from '@alephium/web3'
import { explorer, NFTTokenUriMetaData } from '@alephium/web3'
import { isArray, orderBy } from 'lodash'
import sanitize from 'sanitize-html'

import { calculateAmountWorth } from '@/numbers'
import { Asset, FungibleToken, NFT, TokenDisplayBalances, TokenPriceEntity } from '@/types'

export const PRICED_TOKENS = Object.keys(explorer.TokensWithPrice)

export const sortAssets = (assets: Asset[]) =>
orderBy(
assets,
Expand Down
6 changes: 1 addition & 5 deletions packages/shared/src/numbers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,11 +367,7 @@ export const isExponentialNotation = (numString: string) => numString.includes('

export const isNumber = (numString: string): boolean => !Number.isNaN(Number(numString)) && numString.length > 0

export const calculateAmountWorth = (
amount: bigint,
fiatPrice: number,
decimals = NUM_OF_ZEROS_IN_QUINTILLION
): number => {
export const calculateAmountWorth = (amount: bigint, fiatPrice: number, decimals: number): number => {
if (fiatPrice < 0) throw `Invalid fiat price: ${fiatPrice}. Fiat price cannot be negative.`

return fiatPrice * parseFloat(toHumanReadableAmount(amount, decimals))
Expand Down
62 changes: 34 additions & 28 deletions packages/shared/test/numbers-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { NUM_OF_ZEROS_IN_QUINTILLION } from '@/constants'

import {
aboveExpLimit,
addApostrophes,
Expand Down Expand Up @@ -377,38 +379,42 @@ it('should convert Set amount to Alph amount', () => {
})

it('should convert Set amount to fiat amount', () => {
expect(calculateAmountWorth(BigInt('1000000000000000000'), 2)).toEqual(2),
expect(calculateAmountWorth(BigInt('100000000000000000'), 2)).toEqual(0.2),
expect(calculateAmountWorth(BigInt('10000000000000000'), 2)).toEqual(0.02),
expect(calculateAmountWorth(BigInt('1000000000000000'), 2)).toEqual(0.002),
expect(calculateAmountWorth(BigInt('100000000000000'), 2)).toEqual(0.0002),
expect(calculateAmountWorth(BigInt('10000000000000'), 2)).toEqual(0.00002),
expect(calculateAmountWorth(BigInt('1000000000000'), 2)).toEqual(0.000002),
expect(calculateAmountWorth(BigInt('100000000000'), 2)).toEqual(0.0000002),
expect(calculateAmountWorth(BigInt('10000000000'), 2)).toEqual(0.00000002),
expect(calculateAmountWorth(BigInt('1000000000'), 2)).toEqual(0.000000002),
expect(calculateAmountWorth(BigInt('100000000'), 2)).toEqual(0.0000000002),
expect(calculateAmountWorth(BigInt('10000000'), 2)).toEqual(0.00000000002),
expect(calculateAmountWorth(BigInt('1000000'), 2)).toEqual(0.000000000002),
expect(calculateAmountWorth(BigInt('100000'), 2)).toEqual(0.0000000000002),
expect(calculateAmountWorth(BigInt('10000'), 2)).toEqual(0.00000000000002),
expect(calculateAmountWorth(BigInt('1000'), 2)).toEqual(0.000000000000002),
expect(calculateAmountWorth(BigInt('100'), 2)).toEqual(0.0000000000000002),
expect(calculateAmountWorth(BigInt('10'), 2)).toEqual(0.00000000000000002),
expect(calculateAmountWorth(BigInt('1'), 2)).toEqual(0.000000000000000002),
expect(calculateAmountWorth(BigInt('1000000000000000000'), 2.1)).toEqual(2.1),
expect(calculateAmountWorth(BigInt('1000000000000000000'), 2.100000000001)).toEqual(2.100000000001),
expect(calculateAmountWorth(BigInt('1000000000000000000'), 0)).toEqual(0),
expect(calculateAmountWorth(BigInt('10000000000000000000'), 3)).toEqual(30),
expect(calculateAmountWorth(BigInt('1000000000000000000000000000'), 3)).toEqual(3000000000),
expect(calculateAmountWorth(BigInt('1000000000000000000'), 1e1)).toEqual(10),
expect(() => calculateAmountWorth(BigInt('1000000000000000000'), -2)).toThrow(
expect(calculateAmountWorth(BigInt('1000000000000000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(2),
expect(calculateAmountWorth(BigInt('100000000000000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.2),
expect(calculateAmountWorth(BigInt('10000000000000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.02),
expect(calculateAmountWorth(BigInt('1000000000000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.002),
expect(calculateAmountWorth(BigInt('100000000000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.0002),
expect(calculateAmountWorth(BigInt('10000000000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.00002),
expect(calculateAmountWorth(BigInt('1000000000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.000002),
expect(calculateAmountWorth(BigInt('100000000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.0000002),
expect(calculateAmountWorth(BigInt('10000000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.00000002),
expect(calculateAmountWorth(BigInt('1000000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.000000002),
expect(calculateAmountWorth(BigInt('100000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.0000000002),
expect(calculateAmountWorth(BigInt('10000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.00000000002),
expect(calculateAmountWorth(BigInt('1000000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.000000000002),
expect(calculateAmountWorth(BigInt('100000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.0000000000002),
expect(calculateAmountWorth(BigInt('10000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.00000000000002),
expect(calculateAmountWorth(BigInt('1000'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.000000000000002),
expect(calculateAmountWorth(BigInt('100'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.0000000000000002),
expect(calculateAmountWorth(BigInt('10'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.00000000000000002),
expect(calculateAmountWorth(BigInt('1'), 2, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0.000000000000000002),
expect(calculateAmountWorth(BigInt('1000000000000000000'), 2.1, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(2.1),
expect(calculateAmountWorth(BigInt('1000000000000000000'), 2.100000000001, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(
2.100000000001
),
expect(calculateAmountWorth(BigInt('1000000000000000000'), 0, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(0),
expect(calculateAmountWorth(BigInt('10000000000000000000'), 3, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(30),
expect(calculateAmountWorth(BigInt('1000000000000000000000000000'), 3, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(
3000000000
),
expect(calculateAmountWorth(BigInt('1000000000000000000'), 1e1, NUM_OF_ZEROS_IN_QUINTILLION)).toEqual(10),
expect(() => calculateAmountWorth(BigInt('1000000000000000000'), -2, NUM_OF_ZEROS_IN_QUINTILLION)).toThrow(
'Invalid fiat price: -2. Fiat price cannot be negative.'
),
expect(() => calculateAmountWorth(BigInt('1000000000000000000'), -0.2)).toThrow(
expect(() => calculateAmountWorth(BigInt('1000000000000000000'), -0.2, NUM_OF_ZEROS_IN_QUINTILLION)).toThrow(
'Invalid fiat price: -0.2. Fiat price cannot be negative.'
),
expect(() => calculateAmountWorth(BigInt('1000000000000000000'), -1e-1)).toThrow(
expect(() => calculateAmountWorth(BigInt('1000000000000000000'), -1e-1, NUM_OF_ZEROS_IN_QUINTILLION)).toThrow(
'Invalid fiat price: -0.1. Fiat price cannot be negative.'
)
})
Expand Down
Loading

0 comments on commit 5f3658e

Please sign in to comment.