@mezo-org/passport 0.4.0-dev.81 → 0.4.0-dev.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/api/auth.d.ts +1 -1
- package/dist/src/api/auth.d.ts.map +1 -1
- package/dist/src/components/Dropdown/Content.d.ts +0 -15
- package/dist/src/components/Dropdown/Content.d.ts.map +1 -1
- package/dist/src/components/Dropdown/Content.js +3 -3
- package/dist/src/components/Dropdown/Content.js.map +1 -1
- package/dist/src/components/Dropdown/Dropdown.d.ts +0 -4
- package/dist/src/components/Dropdown/Dropdown.d.ts.map +1 -1
- package/dist/src/components/Dropdown/Dropdown.js +10 -33
- package/dist/src/components/Dropdown/Dropdown.js.map +1 -1
- package/dist/src/components/Dropdown/ListingItem.d.ts +8 -7
- package/dist/src/components/Dropdown/ListingItem.d.ts.map +1 -1
- package/dist/src/components/Dropdown/ListingItem.js +36 -28
- package/dist/src/components/Dropdown/ListingItem.js.map +1 -1
- package/dist/src/components/Dropdown/NestedViewLayout.d.ts +2 -1
- package/dist/src/components/Dropdown/NestedViewLayout.d.ts.map +1 -1
- package/dist/src/components/Dropdown/NestedViewLayout.js +13 -15
- package/dist/src/components/Dropdown/NestedViewLayout.js.map +1 -1
- package/dist/src/components/Dropdown/Receive/Receive.d.ts +1 -4
- package/dist/src/components/Dropdown/Receive/Receive.d.ts.map +1 -1
- package/dist/src/components/Dropdown/Receive/Receive.js +36 -19
- package/dist/src/components/Dropdown/Receive/Receive.js.map +1 -1
- package/dist/src/components/Dropdown/Root/AccountAddressActions.d.ts +2 -5
- package/dist/src/components/Dropdown/Root/AccountAddressActions.d.ts.map +1 -1
- package/dist/src/components/Dropdown/Root/AccountAddressActions.js +28 -12
- package/dist/src/components/Dropdown/Root/AccountAddressActions.js.map +1 -1
- package/dist/src/components/Dropdown/Root/AccountBalance.d.ts +2 -4
- package/dist/src/components/Dropdown/Root/AccountBalance.d.ts.map +1 -1
- package/dist/src/components/Dropdown/Root/AccountBalance.js +24 -8
- package/dist/src/components/Dropdown/Root/AccountBalance.js.map +1 -1
- package/dist/src/components/Dropdown/Root/AccountBtcListing.d.ts +6 -0
- package/dist/src/components/Dropdown/Root/AccountBtcListing.d.ts.map +1 -0
- package/dist/src/components/Dropdown/Root/AccountBtcListing.js +27 -0
- package/dist/src/components/Dropdown/Root/AccountBtcListing.js.map +1 -0
- package/dist/src/components/Dropdown/Root/AccountError.d.ts +8 -0
- package/dist/src/components/Dropdown/Root/AccountError.d.ts.map +1 -0
- package/dist/src/components/Dropdown/Root/AccountError.js +17 -0
- package/dist/src/components/Dropdown/Root/AccountError.js.map +1 -0
- package/dist/src/components/Dropdown/Root/AccountMusdListing.d.ts +4 -0
- package/dist/src/components/Dropdown/Root/AccountMusdListing.d.ts.map +1 -0
- package/dist/src/components/Dropdown/Root/AccountMusdListing.js +21 -0
- package/dist/src/components/Dropdown/Root/AccountMusdListing.js.map +1 -0
- package/dist/src/components/Dropdown/Root/AccountOtherAssets.d.ts +2 -3
- package/dist/src/components/Dropdown/Root/AccountOtherAssets.d.ts.map +1 -1
- package/dist/src/components/Dropdown/Root/AccountOtherAssets.js +34 -39
- package/dist/src/components/Dropdown/Root/AccountOtherAssets.js.map +1 -1
- package/dist/src/components/Dropdown/Root/Root.d.ts +0 -15
- package/dist/src/components/Dropdown/Root/Root.d.ts.map +1 -1
- package/dist/src/components/Dropdown/Root/Root.js +22 -34
- package/dist/src/components/Dropdown/Root/Root.js.map +1 -1
- package/dist/src/components/Dropdown/Root/WalletAddress.d.ts +2 -6
- package/dist/src/components/Dropdown/Root/WalletAddress.d.ts.map +1 -1
- package/dist/src/components/Dropdown/Root/WalletAddress.js +43 -34
- package/dist/src/components/Dropdown/Root/WalletAddress.js.map +1 -1
- package/dist/src/components/Dropdown/Root/WelcomeBlock.d.ts +2 -4
- package/dist/src/components/Dropdown/Root/WelcomeBlock.d.ts.map +1 -1
- package/dist/src/components/Dropdown/Root/WelcomeBlock.js +60 -16
- package/dist/src/components/Dropdown/Root/WelcomeBlock.js.map +1 -1
- package/dist/src/components/Dropdown/SlotNumber.d.ts +19 -0
- package/dist/src/components/Dropdown/SlotNumber.d.ts.map +1 -0
- package/dist/src/components/Dropdown/SlotNumber.js +67 -0
- package/dist/src/components/Dropdown/SlotNumber.js.map +1 -0
- package/dist/src/config.d.ts +1 -11
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +3 -40
- package/dist/src/config.js.map +1 -1
- package/dist/src/constants.d.ts +0 -2
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +0 -2
- package/dist/src/constants.js.map +1 -1
- package/dist/src/hooks/useAssetsConversionRates.d.ts +8 -13
- package/dist/src/hooks/useAssetsConversionRates.d.ts.map +1 -1
- package/dist/src/hooks/useAssetsConversionRates.js +44 -67
- package/dist/src/hooks/useAssetsConversionRates.js.map +1 -1
- package/dist/src/hooks/useAuthenticateWithWallet.d.ts.map +1 -1
- package/dist/src/hooks/useAuthenticateWithWallet.js +1 -1
- package/dist/src/hooks/useAuthenticateWithWallet.js.map +1 -1
- package/dist/src/hooks/useBorrowData.d.ts +31 -5
- package/dist/src/hooks/useBorrowData.d.ts.map +1 -1
- package/dist/src/hooks/useBorrowData.js +53 -11
- package/dist/src/hooks/useBorrowData.js.map +1 -1
- package/dist/src/hooks/useCreateAccount.d.ts.map +1 -1
- package/dist/src/hooks/useCreateAccount.js +3 -3
- package/dist/src/hooks/useCreateAccount.js.map +1 -1
- package/dist/src/hooks/useGetCurrentAccount.d.ts +2 -2
- package/dist/src/hooks/useGetCurrentAccount.d.ts.map +1 -1
- package/dist/src/hooks/useGetCurrentAccount.js +4 -6
- package/dist/src/hooks/useGetCurrentAccount.js.map +1 -1
- package/dist/src/hooks/useLinkAccount.d.ts.map +1 -1
- package/dist/src/hooks/useLinkAccount.js +3 -3
- package/dist/src/hooks/useLinkAccount.js.map +1 -1
- package/dist/src/hooks/useTokensBalances.d.ts +36 -35
- package/dist/src/hooks/useTokensBalances.d.ts.map +1 -1
- package/dist/src/hooks/useTokensBalances.js +93 -52
- package/dist/src/hooks/useTokensBalances.js.map +1 -1
- package/dist/src/hooks/useWalletAccount.d.ts +8 -10
- package/dist/src/hooks/useWalletAccount.d.ts.map +1 -1
- package/dist/src/hooks/useWalletAccount.js +22 -19
- package/dist/src/hooks/useWalletAccount.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib/contracts/index.d.ts +1 -1
- package/dist/src/lib/contracts/index.d.ts.map +1 -1
- package/dist/src/lib/contracts/index.js +4 -0
- package/dist/src/lib/contracts/index.js.map +1 -1
- package/dist/src/provider.d.ts +7 -1
- package/dist/src/provider.d.ts.map +1 -1
- package/dist/src/provider.js +4 -1
- package/dist/src/provider.js.map +1 -1
- package/dist/src/utils/assets.d.ts +145 -0
- package/dist/src/utils/assets.d.ts.map +1 -0
- package/dist/src/utils/assets.js +100 -0
- package/dist/src/utils/assets.js.map +1 -0
- package/dist/src/utils/assets.test.d.ts +2 -0
- package/dist/src/utils/assets.test.d.ts.map +1 -0
- package/dist/src/utils/assets.test.js +46 -0
- package/dist/src/utils/assets.test.js.map +1 -0
- package/dist/src/utils/currency.d.ts +6 -3
- package/dist/src/utils/currency.d.ts.map +1 -1
- package/dist/src/utils/currency.js +13 -10
- package/dist/src/utils/currency.js.map +1 -1
- package/dist/src/utils/currency.test.js +44 -2
- package/dist/src/utils/currency.test.js.map +1 -1
- package/dist/src/utils/numbers.d.ts +13 -53
- package/dist/src/utils/numbers.d.ts.map +1 -1
- package/dist/src/utils/numbers.js +16 -118
- package/dist/src/utils/numbers.js.map +1 -1
- package/dist/src/utils/numbers.test.js +24 -142
- package/dist/src/utils/numbers.test.js.map +1 -1
- package/package.json +2 -1
- package/src/api/auth.ts +1 -1
- package/src/components/Dropdown/Content.tsx +3 -48
- package/src/components/Dropdown/Dropdown.tsx +7 -55
- package/src/components/Dropdown/ListingItem.tsx +155 -59
- package/src/components/Dropdown/NestedViewLayout.tsx +32 -20
- package/src/components/Dropdown/Receive/Receive.tsx +69 -32
- package/src/components/Dropdown/Root/AccountAddressActions.tsx +64 -35
- package/src/components/Dropdown/Root/AccountBalance.tsx +54 -16
- package/src/components/Dropdown/Root/AccountBtcListing.tsx +52 -0
- package/src/components/Dropdown/Root/AccountError.tsx +34 -0
- package/src/components/Dropdown/Root/AccountMusdListing.tsx +45 -0
- package/src/components/Dropdown/Root/AccountOtherAssets.tsx +63 -46
- package/src/components/Dropdown/Root/Root.tsx +28 -98
- package/src/components/Dropdown/Root/WalletAddress.tsx +95 -89
- package/src/components/Dropdown/Root/WelcomeBlock.tsx +109 -29
- package/src/components/Dropdown/SlotNumber.tsx +131 -0
- package/src/config.ts +3 -59
- package/src/constants.ts +0 -6
- package/src/hooks/useAssetsConversionRates.ts +49 -67
- package/src/hooks/useAuthenticateWithWallet.ts +7 -5
- package/src/hooks/useBorrowData.ts +71 -12
- package/src/hooks/useCreateAccount.ts +5 -4
- package/src/hooks/useGetCurrentAccount.ts +5 -7
- package/src/hooks/useLinkAccount.ts +5 -4
- package/src/hooks/useTokensBalances.ts +152 -74
- package/src/hooks/useWalletAccount.ts +27 -36
- package/src/index.ts +0 -1
- package/src/lib/contracts/index.ts +8 -1
- package/src/provider.ts +11 -3
- package/src/utils/assets.test.ts +57 -0
- package/src/utils/assets.ts +103 -0
- package/src/utils/currency.test.ts +76 -2
- package/src/utils/currency.ts +20 -15
- package/src/utils/numbers.test.ts +29 -180
- package/src/utils/numbers.ts +22 -171
- package/dist/src/components/Dropdown/Root/AccountAssetItem.d.ts +0 -11
- package/dist/src/components/Dropdown/Root/AccountAssetItem.d.ts.map +0 -1
- package/dist/src/components/Dropdown/Root/AccountAssetItem.js +0 -9
- package/dist/src/components/Dropdown/Root/AccountAssetItem.js.map +0 -1
- package/dist/src/hooks/useDropdownData.d.ts +0 -47
- package/dist/src/hooks/useDropdownData.d.ts.map +0 -1
- package/dist/src/hooks/useDropdownData.js +0 -97
- package/dist/src/hooks/useDropdownData.js.map +0 -1
- package/dist/src/utils/cryptoAssets.d.ts +0 -44
- package/dist/src/utils/cryptoAssets.d.ts.map +0 -1
- package/dist/src/utils/cryptoAssets.js +0 -129
- package/dist/src/utils/cryptoAssets.js.map +0 -1
- package/dist/src/utils/cryptoAssets.test.d.ts +0 -2
- package/dist/src/utils/cryptoAssets.test.d.ts.map +0 -1
- package/dist/src/utils/cryptoAssets.test.js +0 -67
- package/dist/src/utils/cryptoAssets.test.js.map +0 -1
- package/src/components/Dropdown/Root/AccountAssetItem.tsx +0 -26
- package/src/hooks/useDropdownData.ts +0 -152
- package/src/utils/cryptoAssets.test.ts +0 -79
- package/src/utils/cryptoAssets.ts +0 -171
package/src/provider.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { createContext, createElement } from "react"
|
|
2
2
|
import { AuthApiClient, PortalApiClient } from "./api"
|
|
3
|
+
import { ONE_SECOND_MS } from "./utils/time"
|
|
3
4
|
|
|
4
5
|
export interface PassportContextValue {
|
|
5
6
|
authApiClient: AuthApiClient
|
|
6
7
|
portalApiClient: PortalApiClient
|
|
7
8
|
environment?: Environment
|
|
9
|
+
accountDataRefetchInterval: number
|
|
10
|
+
nativeBalanceRefetchInterval: number
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
export const PassportContext = createContext<PassportContextValue | undefined>(
|
|
@@ -15,12 +18,13 @@ type Environment = "mainnet" | "testnet"
|
|
|
15
18
|
|
|
16
19
|
type PassportProviderProps = {
|
|
17
20
|
children: React.ReactNode
|
|
18
|
-
// eslint-disable-next-line react/require-default-props
|
|
19
21
|
environment?: Environment
|
|
20
|
-
// eslint-disable-next-line react/require-default-props
|
|
21
22
|
authApiUrl?: string
|
|
22
|
-
// eslint-disable-next-line react/require-default-props
|
|
23
23
|
portalApiUrl?: string
|
|
24
|
+
/** Time in milliseconds after which account data (like mats or mezo id) in dropdown should be re-fetched. Default is 90000 (90 secs) */
|
|
25
|
+
accountDataRefetchInterval?: number
|
|
26
|
+
/** Time in milliseconds after which native balance in dropdown should be re-fetched. Default is 90000 (90 secs) */
|
|
27
|
+
nativeBalanceRefetchInterval?: number
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
export function PassportProvider({
|
|
@@ -28,6 +32,8 @@ export function PassportProvider({
|
|
|
28
32
|
authApiUrl,
|
|
29
33
|
portalApiUrl,
|
|
30
34
|
children,
|
|
35
|
+
accountDataRefetchInterval = 90 * ONE_SECOND_MS,
|
|
36
|
+
nativeBalanceRefetchInterval = 90 * ONE_SECOND_MS,
|
|
31
37
|
}: PassportProviderProps) {
|
|
32
38
|
if (environment && !["mainnet", "testnet"].includes(environment)) {
|
|
33
39
|
throw new Error("Wrong environment passed to PassportProvider.")
|
|
@@ -43,6 +49,8 @@ export function PassportProvider({
|
|
|
43
49
|
portalApiUrl,
|
|
44
50
|
),
|
|
45
51
|
environment,
|
|
52
|
+
accountDataRefetchInterval,
|
|
53
|
+
nativeBalanceRefetchInterval,
|
|
46
54
|
},
|
|
47
55
|
},
|
|
48
56
|
children,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAsset,
|
|
3
|
+
isBitcoinLikeCryptoAsset,
|
|
4
|
+
isUsdLikeCryptoAsset,
|
|
5
|
+
isTTokenCryptoAsset,
|
|
6
|
+
} from "./assets"
|
|
7
|
+
|
|
8
|
+
describe("getAsset", () => {
|
|
9
|
+
it("should return correct asset data", () => {
|
|
10
|
+
const asset = getAsset("BTC")
|
|
11
|
+
expect(asset).toEqual({
|
|
12
|
+
name: "Bitcoin",
|
|
13
|
+
symbol: "BTC",
|
|
14
|
+
decimals: 18,
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
describe("isBitcoinLikeCryptoAsset", () => {
|
|
20
|
+
it('should return true for keys containing "btc"', () => {
|
|
21
|
+
expect(isBitcoinLikeCryptoAsset("BTC")).toBe(true)
|
|
22
|
+
expect(isBitcoinLikeCryptoAsset("mFBTC")).toBe(true)
|
|
23
|
+
expect(isBitcoinLikeCryptoAsset("mcbBTC")).toBe(true)
|
|
24
|
+
expect(isBitcoinLikeCryptoAsset("mxSolvBTC")).toBe(true)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it("should return false for non-Bitcoin assets", () => {
|
|
28
|
+
expect(isBitcoinLikeCryptoAsset("ETH")).toBe(false)
|
|
29
|
+
expect(isBitcoinLikeCryptoAsset("mUSDC")).toBe(false)
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe("isUsdLikeCryptoAsset", () => {
|
|
34
|
+
it('should return true for keys containing "usd" or "dai"', () => {
|
|
35
|
+
expect(isUsdLikeCryptoAsset("mUSDC")).toBe(true)
|
|
36
|
+
expect(isUsdLikeCryptoAsset("mUSDT")).toBe(true)
|
|
37
|
+
expect(isUsdLikeCryptoAsset("mUSDe")).toBe(true)
|
|
38
|
+
expect(isUsdLikeCryptoAsset("mDAI")).toBe(true)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it("should return false for other tokens", () => {
|
|
42
|
+
expect(isUsdLikeCryptoAsset("BTC")).toBe(false)
|
|
43
|
+
expect(isUsdLikeCryptoAsset("mT")).toBe(false)
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
describe("isTTokenCryptoAsset", () => {
|
|
48
|
+
it('should return true for keys like "mT" or "t"', () => {
|
|
49
|
+
expect(isTTokenCryptoAsset("mT")).toBe(true)
|
|
50
|
+
expect(isTTokenCryptoAsset("T")).toBe(true)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it("should return false for other tokens", () => {
|
|
54
|
+
expect(isTTokenCryptoAsset("BTC")).toBe(false)
|
|
55
|
+
expect(isTTokenCryptoAsset("mUSDT")).toBe(false)
|
|
56
|
+
})
|
|
57
|
+
})
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const ASSETS = {
|
|
2
|
+
BTC: {
|
|
3
|
+
name: "Bitcoin",
|
|
4
|
+
symbol: "BTC",
|
|
5
|
+
decimals: 18,
|
|
6
|
+
},
|
|
7
|
+
ETH: {
|
|
8
|
+
name: "Ethereum",
|
|
9
|
+
symbol: "ETH",
|
|
10
|
+
decimals: 18,
|
|
11
|
+
},
|
|
12
|
+
MUSD: {
|
|
13
|
+
name: "MUSD",
|
|
14
|
+
symbol: "MUSD",
|
|
15
|
+
decimals: 18,
|
|
16
|
+
},
|
|
17
|
+
mDAI: {
|
|
18
|
+
name: "Mezo Dai Stablecoin",
|
|
19
|
+
symbol: "mDAI",
|
|
20
|
+
decimals: 18,
|
|
21
|
+
},
|
|
22
|
+
mFBTC: {
|
|
23
|
+
name: "Mezo Fire Bitcoin",
|
|
24
|
+
symbol: "mFBTC",
|
|
25
|
+
decimals: 8,
|
|
26
|
+
},
|
|
27
|
+
mcbBTC: {
|
|
28
|
+
name: "Mezo Coinbase Wrapped BTC",
|
|
29
|
+
symbol: "mcbBTC",
|
|
30
|
+
decimals: 8,
|
|
31
|
+
},
|
|
32
|
+
mSolvBTC: {
|
|
33
|
+
name: "Mezo SolvBTC",
|
|
34
|
+
symbol: "mSolvBTC",
|
|
35
|
+
decimals: 18,
|
|
36
|
+
},
|
|
37
|
+
mswBTC: {
|
|
38
|
+
name: "Mezo swBTC",
|
|
39
|
+
symbol: "mswBTC",
|
|
40
|
+
decimals: 8,
|
|
41
|
+
},
|
|
42
|
+
mT: {
|
|
43
|
+
name: "Mezo Threshold Network Token",
|
|
44
|
+
symbol: "mT",
|
|
45
|
+
decimals: 18,
|
|
46
|
+
},
|
|
47
|
+
mUSDC: {
|
|
48
|
+
name: "Mezo Circle USDC",
|
|
49
|
+
symbol: "mUSDC",
|
|
50
|
+
decimals: 6,
|
|
51
|
+
},
|
|
52
|
+
mUSDe: {
|
|
53
|
+
name: "Mezo Ethena USDe",
|
|
54
|
+
symbol: "mUSDe",
|
|
55
|
+
decimals: 18,
|
|
56
|
+
},
|
|
57
|
+
mUSDT: {
|
|
58
|
+
name: "Mezo Tether USDe",
|
|
59
|
+
symbol: "mUSDT",
|
|
60
|
+
decimals: 6,
|
|
61
|
+
},
|
|
62
|
+
mxSolvBTC: {
|
|
63
|
+
name: "Mezo xSolvBTC",
|
|
64
|
+
symbol: "mxSolvBTC",
|
|
65
|
+
decimals: 18,
|
|
66
|
+
},
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Gets details of given crypto asset
|
|
71
|
+
* @param key The key of crypto asset
|
|
72
|
+
* @returns The crypto asset details
|
|
73
|
+
*/
|
|
74
|
+
export function getAsset(key: keyof typeof ASSETS) {
|
|
75
|
+
return ASSETS[key]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Checks if given crypto asset is Bitcoin-like
|
|
80
|
+
* @param key The key of crypto asset
|
|
81
|
+
* @returns True if crypto asset is Bitcoin-like
|
|
82
|
+
*/
|
|
83
|
+
export function isBitcoinLikeCryptoAsset(key: string) {
|
|
84
|
+
return /(btc)/i.test(key)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Checks if given crypto asset is USD-like
|
|
89
|
+
* @param key The key of crypto asset
|
|
90
|
+
* @returns True if crypto asset is USD-like
|
|
91
|
+
*/
|
|
92
|
+
export function isUsdLikeCryptoAsset(key: string) {
|
|
93
|
+
return /(usd|dai)/i.test(key)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Checks if given crypto asset is T token
|
|
98
|
+
* @param key The key of crypto asset
|
|
99
|
+
* @returns True if crypto asset is T token
|
|
100
|
+
*/
|
|
101
|
+
export function isTTokenCryptoAsset(key: string) {
|
|
102
|
+
return /^(mt|t)$/i.test(key)
|
|
103
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { formatCurrency, formatUsd } from "./currency"
|
|
1
|
+
import { convertToUsd, formatCurrency, formatUsd } from "./currency"
|
|
2
2
|
|
|
3
3
|
describe("formatCurrency", () => {
|
|
4
4
|
it("formats a number as currency with default options", () => {
|
|
@@ -37,4 +37,78 @@ describe("formatUsd", () => {
|
|
|
37
37
|
})
|
|
38
38
|
})
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
describe("convertToUsd", () => {
|
|
41
|
+
it("converts 1 BTC (8 decimals) with $30,000 rate (6 decimals)", () => {
|
|
42
|
+
const assetAmount = 1_00000000n // 1 BTC
|
|
43
|
+
const assetDecimals = 8
|
|
44
|
+
const conversionRate = 30_000_000000n // $30,000 in 6 decimals
|
|
45
|
+
const conversionRateDecimals = 6
|
|
46
|
+
|
|
47
|
+
const result = convertToUsd(
|
|
48
|
+
assetAmount,
|
|
49
|
+
assetDecimals,
|
|
50
|
+
conversionRate,
|
|
51
|
+
conversionRateDecimals,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
expect(result.value).toBe(30_000_000000n)
|
|
55
|
+
expect(result.formatted).toBe("30000")
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it("converts 0.5 BTC correctly", () => {
|
|
59
|
+
const assetAmount = 50_000000n // 0.5 BTC
|
|
60
|
+
const assetDecimals = 8
|
|
61
|
+
const conversionRate = 40_000_000000n // $40,000
|
|
62
|
+
const conversionRateDecimals = 6
|
|
63
|
+
|
|
64
|
+
const result = convertToUsd(
|
|
65
|
+
assetAmount,
|
|
66
|
+
assetDecimals,
|
|
67
|
+
conversionRate,
|
|
68
|
+
conversionRateDecimals,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
expect(result.value).toBe(20_000_000000n)
|
|
72
|
+
expect(result.formatted).toBe("20000")
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it("converts 1 ETH (18 decimals) with $2,000 rate (6 decimals)", () => {
|
|
76
|
+
const assetAmount = 1_000000000000000000n // 1 ETH
|
|
77
|
+
const assetDecimals = 18
|
|
78
|
+
const conversionRate = 2_000_000000n
|
|
79
|
+
const conversionRateDecimals = 6
|
|
80
|
+
|
|
81
|
+
const result = convertToUsd(
|
|
82
|
+
assetAmount,
|
|
83
|
+
assetDecimals,
|
|
84
|
+
conversionRate,
|
|
85
|
+
conversionRateDecimals,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
expect(result.value).toBe(2_000_000000n)
|
|
89
|
+
expect(result.formatted).toBe("2000")
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it("handles zero amount correctly", () => {
|
|
93
|
+
const result = convertToUsd(0n, 18, 999_999999n, 6)
|
|
94
|
+
expect(result.value).toBe(0n)
|
|
95
|
+
expect(result.formatted).toBe("0")
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it("handles assets with fewer decimals than conversion rate", () => {
|
|
99
|
+
const assetAmount = 100n
|
|
100
|
+
const assetDecimals = 2
|
|
101
|
+
const conversionRate = 1_500_000000n // $1500
|
|
102
|
+
const conversionRateDecimals = 6
|
|
103
|
+
|
|
104
|
+
const result = convertToUsd(
|
|
105
|
+
assetAmount,
|
|
106
|
+
assetDecimals,
|
|
107
|
+
conversionRate,
|
|
108
|
+
conversionRateDecimals,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
expect(result.value).toBe(1_500_000000n)
|
|
112
|
+
expect(result.formatted).toBe("1500")
|
|
113
|
+
})
|
|
114
|
+
})
|
package/src/utils/currency.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
const DEFAULT_FORMAT_OPTIONS: Intl.NumberFormatOptions = {
|
|
4
|
-
style: "currency",
|
|
5
|
-
minimumFractionDigits: 2,
|
|
6
|
-
maximumFractionDigits: 2,
|
|
7
|
-
}
|
|
1
|
+
import { formatUnits } from "viem"
|
|
2
|
+
import { normalizePrecision } from "./numbers"
|
|
8
3
|
|
|
9
4
|
/**
|
|
10
5
|
* Formats a number as a currency
|
|
@@ -14,10 +9,12 @@ const DEFAULT_FORMAT_OPTIONS: Intl.NumberFormatOptions = {
|
|
|
14
9
|
*/
|
|
15
10
|
export function formatCurrency(
|
|
16
11
|
value: number,
|
|
17
|
-
options: Omit<Intl.NumberFormatOptions, "style"
|
|
12
|
+
options: Omit<Intl.NumberFormatOptions, "style">,
|
|
18
13
|
): string {
|
|
19
14
|
const formatter = new Intl.NumberFormat("en-US", {
|
|
20
|
-
|
|
15
|
+
style: "currency",
|
|
16
|
+
minimumFractionDigits: 2,
|
|
17
|
+
maximumFractionDigits: 2,
|
|
21
18
|
...options,
|
|
22
19
|
})
|
|
23
20
|
|
|
@@ -29,8 +26,8 @@ export function formatCurrency(
|
|
|
29
26
|
* @param value The value to format
|
|
30
27
|
* @returns The formatted currency
|
|
31
28
|
*/
|
|
32
|
-
export function formatUsd(value: number): string {
|
|
33
|
-
return formatCurrency(value, { currency: "USD" })
|
|
29
|
+
export function formatUsd(value: number | string): string {
|
|
30
|
+
return formatCurrency(Number(value), { currency: "USD" })
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
/**
|
|
@@ -45,9 +42,17 @@ export function convertToUsd(
|
|
|
45
42
|
assetDecimals: number,
|
|
46
43
|
conversionRate: bigint,
|
|
47
44
|
conversionRateDecimals: number,
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
assetDecimals,
|
|
45
|
+
) {
|
|
46
|
+
const value = normalizePrecision(
|
|
47
|
+
assetAmount * conversionRate,
|
|
48
|
+
assetDecimals + conversionRateDecimals,
|
|
49
|
+
conversionRateDecimals,
|
|
52
50
|
)
|
|
51
|
+
|
|
52
|
+
const formatted = formatUnits(value, conversionRateDecimals)
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
value,
|
|
56
|
+
formatted,
|
|
57
|
+
}
|
|
53
58
|
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
formatNumberToCompactString,
|
|
3
|
-
fromFixedPoint,
|
|
4
|
-
roundUpNumber,
|
|
5
|
-
formatNumberToLocaleString,
|
|
6
|
-
fromFixedPointToString,
|
|
7
3
|
bigIntMax,
|
|
4
|
+
normalizePrecision,
|
|
8
5
|
} from "./numbers"
|
|
9
6
|
|
|
10
7
|
describe("formatNumberToCompactString", () => {
|
|
@@ -44,182 +41,6 @@ describe("formatNumberToCompactString", () => {
|
|
|
44
41
|
})
|
|
45
42
|
})
|
|
46
43
|
|
|
47
|
-
describe("roundUpNumber", () => {
|
|
48
|
-
it("rounds up to 2 decimals", () => {
|
|
49
|
-
expect(roundUpNumber(1.234)).toBe(1.24)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it("rounds up to 3 decimals", () => {
|
|
53
|
-
expect(roundUpNumber(9.87654, 3)).toBe(9.877)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it("rounds up exact decimal", () => {
|
|
57
|
-
expect(roundUpNumber(2.5, 1)).toBe(2.5)
|
|
58
|
-
})
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
describe("fromFixedPoint", () => {
|
|
62
|
-
it("converts fixed point with 18 decimals to float", () => {
|
|
63
|
-
const raw = 1234567890000000000n // 1.23456789 ETH in 18 decimals
|
|
64
|
-
expect(fromFixedPoint(raw, 18)).toBe(1.2345)
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
it("converts with truncation to 2 decimals", () => {
|
|
68
|
-
const raw = 987654321000000000n // ~0.987654321 ETH
|
|
69
|
-
expect(fromFixedPoint(raw, 18, 2)).toBe(0.98)
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it("handles large fixedPoint decimals", () => {
|
|
73
|
-
const raw = 1_000_000_000_000_000_000_000_000n // 1M with 6 decimals
|
|
74
|
-
expect(fromFixedPoint(raw, 6, 2)).toBe(1000000000000000000)
|
|
75
|
-
})
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
describe("formatNumberToLocaleString", () => {
|
|
79
|
-
it("formats zero with 0 decimals", () => {
|
|
80
|
-
expect(formatNumberToLocaleString(0, 0)).toBe("0")
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it("formats zero with >0 decimals", () => {
|
|
84
|
-
expect(formatNumberToLocaleString(0, 2)).toBe("0.00")
|
|
85
|
-
expect(formatNumberToLocaleString(0, 4)).toBe("0.0000")
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it("formats small decimal number", () => {
|
|
89
|
-
expect(formatNumberToLocaleString(0.123456, 2)).toBe("0.12")
|
|
90
|
-
expect(formatNumberToLocaleString(0.123456, 4)).toBe("0.1235")
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
it("formats number just above 1", () => {
|
|
94
|
-
expect(formatNumberToLocaleString(1.000001, 3)).toBe("1.000")
|
|
95
|
-
expect(formatNumberToLocaleString(1.234567, 2)).toBe("1.23")
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
it("formats whole number", () => {
|
|
99
|
-
expect(formatNumberToLocaleString(1234, 0)).toBe("1,234")
|
|
100
|
-
expect(formatNumberToLocaleString(1000, 2)).toBe("1,000.00")
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it("formats number with trailing decimal zeroes", () => {
|
|
104
|
-
expect(formatNumberToLocaleString(10.1, 3)).toBe("10.100")
|
|
105
|
-
expect(formatNumberToLocaleString(5.0, 2)).toBe("5.00")
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
it("formats string input", () => {
|
|
109
|
-
expect(formatNumberToLocaleString("123.456", 2)).toBe("123.46")
|
|
110
|
-
expect(formatNumberToLocaleString("0.00123", 4)).toBe("0.0012")
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it("formats negative number", () => {
|
|
114
|
-
expect(formatNumberToLocaleString(-123.456, 2)).toBe("-123.46")
|
|
115
|
-
expect(formatNumberToLocaleString("-0.00999", 3)).toBe("-0.010")
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
it("formats large number with commas", () => {
|
|
119
|
-
expect(formatNumberToLocaleString(12345678.9, 2)).toBe("12,345,678.90")
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
it("handles max decimals safely", () => {
|
|
123
|
-
expect(formatNumberToLocaleString(1.123456789, 8)).toBe("1.12345679")
|
|
124
|
-
expect(formatNumberToLocaleString("0.000000000000000001", 18)).toBe(
|
|
125
|
-
"0.000000000000000001",
|
|
126
|
-
)
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
it("defaults to 0 decimals if not passed", () => {
|
|
130
|
-
expect(formatNumberToLocaleString(1234.567)).toBe("1,235") // rounds up by default
|
|
131
|
-
})
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
describe("fromFixedPointToString", () => {
|
|
135
|
-
const toFixedPoint = (num: number) => BigInt(Math.round(num * 1e18))
|
|
136
|
-
|
|
137
|
-
const cases = [
|
|
138
|
-
{ input: 2.0, expected: "2.000" },
|
|
139
|
-
{ input: 2.009, expected: "2.009" },
|
|
140
|
-
{ input: 2.01, expected: "2.010" },
|
|
141
|
-
{ input: 2.015, expected: "2.016" },
|
|
142
|
-
{ input: 2.05, expected: "2.050" },
|
|
143
|
-
{ input: 2.09, expected: "2.090" },
|
|
144
|
-
]
|
|
145
|
-
|
|
146
|
-
describe("withRoundUp: true", () => {
|
|
147
|
-
cases.forEach(({ input, expected }) => {
|
|
148
|
-
it(`formats ${input} → ${expected}`, () => {
|
|
149
|
-
const fixed = toFixedPoint(input)
|
|
150
|
-
expect(fromFixedPointToString(fixed, 18, 3, true)).toBe(expected)
|
|
151
|
-
})
|
|
152
|
-
})
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
describe("withRoundUp: false", () => {
|
|
156
|
-
const noRoundCases = [
|
|
157
|
-
{ input: 2.0099, expected: "2.009" },
|
|
158
|
-
{ input: 2.0159, expected: "2.015" },
|
|
159
|
-
{ input: 2.0101, expected: "2.010" },
|
|
160
|
-
{ input: 2.0199, expected: "2.019" },
|
|
161
|
-
]
|
|
162
|
-
|
|
163
|
-
noRoundCases.forEach(({ input, expected }) => {
|
|
164
|
-
it(`formats ${input} → ${expected} (no rounding)`, () => {
|
|
165
|
-
const fixed = toFixedPoint(input)
|
|
166
|
-
expect(fromFixedPointToString(fixed, 18, 3, false)).toBe(expected)
|
|
167
|
-
})
|
|
168
|
-
})
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
describe("zero handling", () => {
|
|
172
|
-
it("formats 0 → 0.000 (3 decimals)", () => {
|
|
173
|
-
expect(fromFixedPointToString(0n, 18, 3)).toBe("0.000")
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
it("formats 0 → 0.0000 (4 decimals)", () => {
|
|
177
|
-
expect(fromFixedPointToString(0n, 18, 4)).toBe("0.0000")
|
|
178
|
-
})
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
describe("very small numbers below display threshold", () => {
|
|
182
|
-
it("returns <0.0001 for small number (3 decimals)", () => {
|
|
183
|
-
const small = BigInt(123) // ~1.23e-16
|
|
184
|
-
expect(fromFixedPointToString(small, 18, 4)).toBe("<0.0001")
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
it("returns <0.01 for small number with only 2 decimals", () => {
|
|
188
|
-
const tiny = BigInt(9999999999999) // <0.01
|
|
189
|
-
expect(fromFixedPointToString(tiny, 18, 2)).toBe("<0.01")
|
|
190
|
-
})
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
describe("input types", () => {
|
|
194
|
-
it("accepts bigint", () => {
|
|
195
|
-
const amount = 2100000000000000000n
|
|
196
|
-
expect(fromFixedPointToString(amount, 18, 3)).toBe("2.100")
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
it("accepts string", () => {
|
|
200
|
-
expect(fromFixedPointToString("2000000000000000000", 18, 3)).toBe("2.000")
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
it("accepts number", () => {
|
|
204
|
-
expect(fromFixedPointToString(Number("1000000000000000000"), 18, 3)).toBe(
|
|
205
|
-
"1.000",
|
|
206
|
-
)
|
|
207
|
-
})
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
describe("high values", () => {
|
|
211
|
-
it("formats 1_000_000.123456789 correctly", () => {
|
|
212
|
-
const big = toFixedPoint(1_000_000.123456789)
|
|
213
|
-
expect(fromFixedPointToString(big, 18, 6)).toBe("1,000,000.123456")
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
it("formats 1e12 ETH", () => {
|
|
217
|
-
const big = BigInt("1000000000000000000000000000000")
|
|
218
|
-
expect(fromFixedPointToString(big, 18, 2)).toBe("1,000,000,000,000.00")
|
|
219
|
-
})
|
|
220
|
-
})
|
|
221
|
-
})
|
|
222
|
-
|
|
223
44
|
describe("bigIntMax", () => {
|
|
224
45
|
it("returns the maximum of positive bigint values", () => {
|
|
225
46
|
expect(bigIntMax(1n, 2n, 3n)).toBe(3n)
|
|
@@ -245,3 +66,31 @@ describe("bigIntMax", () => {
|
|
|
245
66
|
expect(bigIntMax(5n, 5n, 5n)).toBe(5n)
|
|
246
67
|
})
|
|
247
68
|
})
|
|
69
|
+
|
|
70
|
+
describe("normalizePrecision", () => {
|
|
71
|
+
it("reduces precision correctly (scale down)", () => {
|
|
72
|
+
const result = normalizePrecision(1234500n, 6, 3)
|
|
73
|
+
expect(result).toBe(1234n)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it("increases precision correctly (scale up)", () => {
|
|
77
|
+
const result = normalizePrecision(1234n, 3, 6)
|
|
78
|
+
expect(result).toBe(1234000n)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it("returns the same value when precision is equal", () => {
|
|
82
|
+
const result = normalizePrecision(987654321n, 5, 5)
|
|
83
|
+
expect(result).toBe(987654321n)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it("handles zero value correctly", () => {
|
|
87
|
+
const result = normalizePrecision(0n, 4, 8)
|
|
88
|
+
expect(result).toBe(0n)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it("handles large numbers without precision loss", () => {
|
|
92
|
+
const value = 123456789012345678901234567890n
|
|
93
|
+
const result = normalizePrecision(value, 18, 20)
|
|
94
|
+
expect(result).toBe(value * 100n)
|
|
95
|
+
})
|
|
96
|
+
})
|