@mezo-org/passport 0.4.0-dev.82 → 0.4.0-dev.84
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/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 -36
- 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 +30 -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 +13 -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 +37 -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 +0 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +1 -9
- package/dist/src/config.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 +30 -4
- 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.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 -6
- package/dist/src/hooks/useWalletAccount.d.ts.map +1 -1
- package/dist/src/hooks/useWalletAccount.js +9 -6
- package/dist/src/hooks/useWalletAccount.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/components/Dropdown/Content.tsx +3 -48
- package/src/components/Dropdown/Dropdown.tsx +7 -58
- package/src/components/Dropdown/ListingItem.tsx +155 -59
- package/src/components/Dropdown/NestedViewLayout.tsx +32 -20
- package/src/components/Dropdown/Receive/Receive.tsx +57 -32
- package/src/components/Dropdown/Root/AccountAddressActions.tsx +33 -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 +87 -89
- package/src/components/Dropdown/Root/WelcomeBlock.tsx +112 -30
- package/src/components/Dropdown/SlotNumber.tsx +131 -0
- package/src/config.ts +1 -11
- 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 +19 -13
- 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
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { useConfig } from "wagmi"
|
|
2
|
+
import { Abi, formatUnits } from "viem"
|
|
3
|
+
import {
|
|
4
|
+
useQuery,
|
|
5
|
+
useQueryClient,
|
|
6
|
+
UseQueryOptions,
|
|
7
|
+
} from "@tanstack/react-query"
|
|
8
|
+
import { getBalance, readContracts } from "wagmi/actions"
|
|
6
9
|
import {
|
|
7
10
|
mainnetTokenContracts,
|
|
8
|
-
testnetTokenContracts,
|
|
9
11
|
MezoChainToken,
|
|
12
|
+
testnetTokenContracts,
|
|
10
13
|
} from "../lib/contracts"
|
|
11
14
|
import useWalletAccount from "./useWalletAccount"
|
|
15
|
+
import {
|
|
16
|
+
getAsset,
|
|
17
|
+
isBitcoinLikeCryptoAsset,
|
|
18
|
+
isTTokenCryptoAsset,
|
|
19
|
+
} from "../utils/assets"
|
|
20
|
+
import { convertToUsd } from "../utils/currency"
|
|
12
21
|
import { CHAIN_ID } from "../constants"
|
|
22
|
+
import { useAssetsConversionRates } from "./useAssetsConversionRates"
|
|
23
|
+
import { normalizePrecision } from "../utils/numbers"
|
|
13
24
|
|
|
14
25
|
// Wagmi handles typesafety with ABI const assertions. TypeScript doesn't
|
|
15
26
|
// support importing JSON as const yet so types cannot be inferred from the
|
|
@@ -17,7 +28,7 @@ import { CHAIN_ID } from "../constants"
|
|
|
17
28
|
// be asserted types from.
|
|
18
29
|
// Ref: https://wagmi.sh/core/typescript#const-assert-abis-typed-data
|
|
19
30
|
|
|
20
|
-
const BALANCE_OF_ABI = [
|
|
31
|
+
export const BALANCE_OF_ABI = [
|
|
21
32
|
{
|
|
22
33
|
inputs: [
|
|
23
34
|
{
|
|
@@ -53,11 +64,27 @@ const BALANCE_TOKENS: MezoChainToken[] = [
|
|
|
53
64
|
"MUSD",
|
|
54
65
|
]
|
|
55
66
|
|
|
56
|
-
type UseMezoChainTokensBalancesOptions<T> = {
|
|
67
|
+
type UseMezoChainTokensBalancesOptions<T extends MezoChainToken[]> = {
|
|
57
68
|
tokens?: T
|
|
58
|
-
queryOptions?:
|
|
69
|
+
queryOptions?: Omit<
|
|
70
|
+
UseQueryOptions<Record<T[number], TokenBalance>>,
|
|
71
|
+
"queryKey" | "queryFn" | "select" | "enabled"
|
|
72
|
+
>
|
|
59
73
|
}
|
|
60
74
|
|
|
75
|
+
export type TokenBalance = {
|
|
76
|
+
decimals: number
|
|
77
|
+
formatted: string
|
|
78
|
+
symbol: string
|
|
79
|
+
value: bigint
|
|
80
|
+
usd: {
|
|
81
|
+
value: bigint
|
|
82
|
+
formatted: string
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const TOKEN_BALANCES_QUERY_KEY = "passport.tokenBalances"
|
|
87
|
+
|
|
61
88
|
/**
|
|
62
89
|
* Hook to get the balance of a list of tokens for the current account
|
|
63
90
|
* @param options.tokens The list of tokens to get the balance for. It will
|
|
@@ -67,93 +94,150 @@ type UseMezoChainTokensBalancesOptions<T> = {
|
|
|
67
94
|
* @returns Tanstack's `useQuery` returnings with balance of tokens for the
|
|
68
95
|
* current account in form of typesafe object with token names as keys
|
|
69
96
|
* and balances as values.
|
|
70
|
-
* @dev In case of error data fallbacks to `0n`. To determine if an error
|
|
71
|
-
* occurred, check the `isError` property.
|
|
72
97
|
* @example
|
|
73
98
|
* const mezoTokensBalance = useTokensBalances({
|
|
74
99
|
* tokens: ["mT", "mxSolvBTC"],
|
|
75
100
|
* })
|
|
76
|
-
*
|
|
77
|
-
* console.log(
|
|
101
|
+
* // Assuming the status is "success"
|
|
102
|
+
* console.log(mezoTokensBalance.data.mT) // Eg. { value: 0n ... }
|
|
103
|
+
* console.log(Object.keys(mezoTokensBalance.data)) // ["mT", "mxSolvBTC"]
|
|
78
104
|
*/
|
|
79
105
|
export function useTokensBalances<T extends MezoChainToken[]>(
|
|
80
106
|
options: UseMezoChainTokensBalancesOptions<T> = {},
|
|
81
107
|
) {
|
|
82
|
-
const {
|
|
108
|
+
const { tokens = BALANCE_TOKENS, ...restQueryOptions } = options
|
|
83
109
|
|
|
84
|
-
const {
|
|
110
|
+
const { data: walletAccountData } = useWalletAccount()
|
|
85
111
|
|
|
86
|
-
const
|
|
87
|
-
const contracts =
|
|
88
|
-
environment === "mainnet" ? mainnetTokenContracts : testnetTokenContracts
|
|
112
|
+
const config = useConfig()
|
|
89
113
|
|
|
90
|
-
|
|
91
|
-
Object.entries(contracts).filter(([key]) =>
|
|
92
|
-
BALANCE_TOKENS.includes(key as MezoChainToken),
|
|
93
|
-
),
|
|
94
|
-
) as typeof contracts
|
|
114
|
+
const { data: conversionRatesData } = useAssetsConversionRates()
|
|
95
115
|
|
|
96
|
-
|
|
97
|
-
|
|
116
|
+
return useQuery({
|
|
117
|
+
queryKey: [
|
|
118
|
+
TOKEN_BALANCES_QUERY_KEY,
|
|
119
|
+
walletAccountData?.accountAddress,
|
|
120
|
+
options.tokens,
|
|
121
|
+
],
|
|
122
|
+
enabled: !!walletAccountData?.accountAddress && !!conversionRatesData,
|
|
123
|
+
queryFn: async () => {
|
|
124
|
+
const isMainnet = config.state.chainId === CHAIN_ID.mainnet
|
|
125
|
+
const contractsMap = isMainnet
|
|
126
|
+
? mainnetTokenContracts
|
|
127
|
+
: testnetTokenContracts
|
|
98
128
|
|
|
99
|
-
|
|
129
|
+
const accountAddress = walletAccountData?.accountAddress
|
|
100
130
|
|
|
101
|
-
|
|
102
|
-
|
|
131
|
+
if (!accountAddress) {
|
|
132
|
+
throw new Error("Account address is not available.")
|
|
133
|
+
}
|
|
103
134
|
|
|
104
|
-
|
|
105
|
-
|
|
135
|
+
const tokenContracts = tokens.map((token) => {
|
|
136
|
+
const { address } = contractsMap[token]
|
|
137
|
+
return {
|
|
138
|
+
address,
|
|
139
|
+
abi: BALANCE_OF_ABI,
|
|
140
|
+
functionName: "balanceOf" as const,
|
|
141
|
+
args: [accountAddress],
|
|
142
|
+
chainId: config.state.chainId,
|
|
143
|
+
}
|
|
144
|
+
})
|
|
106
145
|
|
|
107
|
-
return
|
|
108
|
-
address,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
146
|
+
return Promise.all([
|
|
147
|
+
getBalance(config, { address: accountAddress }),
|
|
148
|
+
readContracts(config, {
|
|
149
|
+
contracts: tokenContracts,
|
|
150
|
+
}),
|
|
151
|
+
])
|
|
152
|
+
},
|
|
153
|
+
select: (data) => {
|
|
154
|
+
const [btcBalance, tokensBalancesData] = data
|
|
155
|
+
if (!conversionRatesData) {
|
|
156
|
+
throw new Error("Conversion rates data is not available.")
|
|
113
157
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const token = tokens[data.indexOf(item)]
|
|
124
|
-
|
|
125
|
-
return {
|
|
126
|
-
...acc,
|
|
127
|
-
[token]: item.result ?? 0n,
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
{} as Record<T[number], bigint>,
|
|
158
|
+
|
|
159
|
+
const parsedBtcBalance = {
|
|
160
|
+
...btcBalance,
|
|
161
|
+
symbol: getAsset("BTC").symbol,
|
|
162
|
+
usd: convertToUsd(
|
|
163
|
+
btcBalance.value,
|
|
164
|
+
btcBalance.decimals,
|
|
165
|
+
conversionRatesData.rates.BTC,
|
|
166
|
+
conversionRatesData.decimals,
|
|
131
167
|
),
|
|
132
|
-
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const parsedTokensBalances = tokensBalancesData.map((item, index) => {
|
|
171
|
+
const token = tokens[index]
|
|
172
|
+
const { decimals, symbol } = getAsset(token)
|
|
173
|
+
|
|
174
|
+
if (item.status === "failure") {
|
|
175
|
+
throw new Error(
|
|
176
|
+
`Failed to fetch balance of ${token} for ${walletAccountData?.accountAddress}.`,
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const tokenBalance: Omit<TokenBalance, "usd"> = {
|
|
181
|
+
value: item.result,
|
|
182
|
+
decimals,
|
|
183
|
+
symbol,
|
|
184
|
+
formatted: formatUnits(item.result, decimals),
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
let usd = {
|
|
188
|
+
value: normalizePrecision(
|
|
189
|
+
tokenBalance.value,
|
|
190
|
+
tokenBalance.decimals,
|
|
191
|
+
conversionRatesData.decimals,
|
|
192
|
+
),
|
|
193
|
+
formatted: formatUnits(tokenBalance.value, tokenBalance.decimals),
|
|
194
|
+
}
|
|
195
|
+
if (isBitcoinLikeCryptoAsset(tokenBalance.symbol)) {
|
|
196
|
+
usd = convertToUsd(
|
|
197
|
+
tokenBalance.value,
|
|
198
|
+
tokenBalance.decimals,
|
|
199
|
+
conversionRatesData.rates.BTC,
|
|
200
|
+
conversionRatesData.decimals,
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
if (isTTokenCryptoAsset(tokenBalance.symbol)) {
|
|
204
|
+
usd = convertToUsd(
|
|
205
|
+
tokenBalance.value,
|
|
206
|
+
tokenBalance.decimals,
|
|
207
|
+
conversionRatesData.rates.mT,
|
|
208
|
+
conversionRatesData.decimals,
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return { ...tokenBalance, usd }
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
return [parsedBtcBalance, ...parsedTokensBalances].reduce(
|
|
216
|
+
(acc, token) => ({
|
|
217
|
+
...acc,
|
|
218
|
+
[token.symbol]: token,
|
|
219
|
+
}),
|
|
220
|
+
{} as Record<T[number] | "BTC", TokenBalance>,
|
|
221
|
+
)
|
|
133
222
|
},
|
|
223
|
+
...restQueryOptions,
|
|
134
224
|
})
|
|
135
225
|
}
|
|
136
226
|
|
|
137
227
|
/**
|
|
138
228
|
* Hook for invalidating current user's token balances. Can be used to
|
|
139
229
|
* invalidate the balances manually, which forces the data to be re-fetched.
|
|
140
|
-
* @param tokens The list of tokens (as string arrays) for which we want to
|
|
141
|
-
* invalidate query for.
|
|
142
230
|
* @returns Function `invalidateTokenBalances` that invalidates token balances
|
|
143
231
|
* @example
|
|
144
|
-
* const { invalidateTokenBalances } = useInvalidateTokensBalances(
|
|
232
|
+
* const { invalidateTokenBalances } = useInvalidateTokensBalances()
|
|
145
233
|
* (...)
|
|
146
234
|
* await invalidateTokenBalances()
|
|
147
235
|
*/
|
|
148
|
-
export function useInvalidateTokensBalances(
|
|
236
|
+
export function useInvalidateTokensBalances() {
|
|
149
237
|
const queryClient = useQueryClient()
|
|
150
238
|
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
const invalidateTokensBalancesHandler = useCallback(
|
|
154
|
-
() => queryClient.invalidateQueries({ queryKey }),
|
|
155
|
-
[queryClient, queryKey],
|
|
156
|
-
)
|
|
239
|
+
const invalidateTokensBalancesHandler = () =>
|
|
240
|
+
queryClient.invalidateQueries({ queryKey: [TOKEN_BALANCES_QUERY_KEY] })
|
|
157
241
|
|
|
158
242
|
return {
|
|
159
243
|
invalidateTokensBalances: invalidateTokensBalancesHandler,
|
|
@@ -163,23 +247,17 @@ export function useInvalidateTokensBalances(tokens?: MezoChainToken[]) {
|
|
|
163
247
|
/**
|
|
164
248
|
* Hook for resetting current user's token balances. Can be used to reset the
|
|
165
249
|
* balances manually, which forces the data to be re-fetched.
|
|
166
|
-
* @param tokens The list of tokens (as string arrays) for which we want to
|
|
167
|
-
* reset query for.
|
|
168
250
|
* @returns Function `resetTokenBalances` that invalidates token balances
|
|
169
251
|
* @example
|
|
170
|
-
* const { resetTokenBalances } = useResetTokensBalances(
|
|
252
|
+
* const { resetTokenBalances } = useResetTokensBalances()
|
|
171
253
|
* (...)
|
|
172
254
|
* await resetTokenBalances()
|
|
173
255
|
*/
|
|
174
|
-
export function useResetTokensBalances(
|
|
256
|
+
export function useResetTokensBalances() {
|
|
175
257
|
const queryClient = useQueryClient()
|
|
176
258
|
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
const resetTokenBalancesHandler = useCallback(
|
|
180
|
-
() => queryClient.resetQueries({ queryKey }),
|
|
181
|
-
[queryClient, queryKey],
|
|
182
|
-
)
|
|
259
|
+
const resetTokenBalancesHandler = () =>
|
|
260
|
+
queryClient.resetQueries({ queryKey: [TOKEN_BALANCES_QUERY_KEY] })
|
|
183
261
|
|
|
184
262
|
return {
|
|
185
263
|
resetTokenBalances: resetTokenBalancesHandler,
|
|
@@ -5,14 +5,18 @@ import { Address } from "viem"
|
|
|
5
5
|
import { Connector, useAccount } from "wagmi"
|
|
6
6
|
|
|
7
7
|
type UseWalletAccountReturn = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
data: {
|
|
9
|
+
accountAddress?: Address
|
|
10
|
+
walletAddress?: string
|
|
11
|
+
isConnected: boolean
|
|
12
|
+
networkFamily: "bitcoin" | "evm"
|
|
13
|
+
connector?: Connector
|
|
14
|
+
chainId?: number
|
|
15
|
+
}
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
// TODO: Invesitgate race conditions and refactor
|
|
19
|
+
|
|
16
20
|
export default function useWalletAccount(): UseWalletAccountReturn {
|
|
17
21
|
const { address: evmAddress, connector, chainId } = useAccount()
|
|
18
22
|
|
|
@@ -41,11 +45,13 @@ export default function useWalletAccount(): UseWalletAccountReturn {
|
|
|
41
45
|
const { address: btcAddress } = btcData || {}
|
|
42
46
|
|
|
43
47
|
return {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
data: {
|
|
49
|
+
accountAddress: evmAddress,
|
|
50
|
+
walletAddress: btcAddress ?? evmAddress,
|
|
51
|
+
isConnected: networkFamily === "bitcoin" ? !!btcAddress : !!evmAddress,
|
|
52
|
+
networkFamily,
|
|
53
|
+
connector,
|
|
54
|
+
chainId,
|
|
55
|
+
},
|
|
56
|
+
}
|
|
51
57
|
}
|
|
@@ -25,6 +25,8 @@ import xsolvbtcTestnet from "@mezo-org/mezod-contracts/deployments/testnet/mxSol
|
|
|
25
25
|
import musdTestnet from "@mezo-org/musd-contracts/deployments/matsnet/MUSD.json"
|
|
26
26
|
import troveManagerTestnet from "@mezo-org/musd-contracts/deployments/matsnet/TroveManager.json"
|
|
27
27
|
import borrowerOperationsTestnet from "@mezo-org/musd-contracts/deployments/matsnet/BorrowerOperations.json"
|
|
28
|
+
import priceFeed from "@mezo-org/musd-contracts/deployments/mainnet/PriceFeed.json"
|
|
29
|
+
import priceFeedTestnet from "@mezo-org/musd-contracts/deployments/matsnet/PriceFeed.json"
|
|
28
30
|
|
|
29
31
|
import { Abi, Address } from "viem"
|
|
30
32
|
|
|
@@ -41,7 +43,10 @@ export type MezoChainToken =
|
|
|
41
43
|
| "mxSolvBTC"
|
|
42
44
|
| "MUSD"
|
|
43
45
|
|
|
44
|
-
export type MezoBorrowContract =
|
|
46
|
+
export type MezoBorrowContract =
|
|
47
|
+
| "TroveManager"
|
|
48
|
+
| "BorrowerOperations"
|
|
49
|
+
| "PriceFeed"
|
|
45
50
|
|
|
46
51
|
type ContractsMap<K extends string> = Record<
|
|
47
52
|
K,
|
|
@@ -82,11 +87,13 @@ export const mainnetTokenContracts = {
|
|
|
82
87
|
export const mainnetBorrowContracts = {
|
|
83
88
|
TroveManager: troveManagerMainnet,
|
|
84
89
|
BorrowerOperations: borrowerOperationsMainnet,
|
|
90
|
+
PriceFeed: priceFeed,
|
|
85
91
|
} as unknown as ContractsMap<MezoBorrowContract>
|
|
86
92
|
|
|
87
93
|
export const testnetBorrowContracts = {
|
|
88
94
|
TroveManager: troveManagerTestnet,
|
|
89
95
|
BorrowerOperations: borrowerOperationsTestnet,
|
|
96
|
+
PriceFeed: priceFeedTestnet,
|
|
90
97
|
} as unknown as ContractsMap<MezoBorrowContract>
|
|
91
98
|
|
|
92
99
|
export { default as priceOracleContract } from "./priceOracle"
|
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
|
+
})
|