@mezo-org/passport 0.4.0-dev.20 → 0.4.0-dev.21

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.
Files changed (131) hide show
  1. package/README.md +18 -22
  2. package/dist/src/api/portal.d.ts +1 -0
  3. package/dist/src/api/portal.d.ts.map +1 -1
  4. package/dist/src/api/portal.js.map +1 -1
  5. package/dist/src/components/Dropdown/Content.d.ts +16 -2
  6. package/dist/src/components/Dropdown/Content.d.ts.map +1 -1
  7. package/dist/src/components/Dropdown/Content.js +5 -3
  8. package/dist/src/components/Dropdown/Content.js.map +1 -1
  9. package/dist/src/components/Dropdown/Dropdown.d.ts +1 -5
  10. package/dist/src/components/Dropdown/Dropdown.d.ts.map +1 -1
  11. package/dist/src/components/Dropdown/Dropdown.js +7 -6
  12. package/dist/src/components/Dropdown/Dropdown.js.map +1 -1
  13. package/dist/src/components/Dropdown/ListingItem.d.ts +13 -0
  14. package/dist/src/components/Dropdown/ListingItem.d.ts.map +1 -0
  15. package/dist/src/components/Dropdown/ListingItem.js +34 -0
  16. package/dist/src/components/Dropdown/ListingItem.js.map +1 -0
  17. package/dist/src/components/Dropdown/Root/AccountAssetItem.d.ts +11 -0
  18. package/dist/src/components/Dropdown/Root/AccountAssetItem.d.ts.map +1 -0
  19. package/dist/src/components/Dropdown/Root/AccountAssetItem.js +9 -0
  20. package/dist/src/components/Dropdown/Root/AccountAssetItem.js.map +1 -0
  21. package/dist/src/components/Dropdown/Root/AccountBalance.d.ts +2 -1
  22. package/dist/src/components/Dropdown/Root/AccountBalance.d.ts.map +1 -1
  23. package/dist/src/components/Dropdown/Root/AccountBalance.js +7 -8
  24. package/dist/src/components/Dropdown/Root/AccountBalance.js.map +1 -1
  25. package/dist/src/components/Dropdown/Root/AccountOtherAssets.d.ts +9 -0
  26. package/dist/src/components/Dropdown/Root/AccountOtherAssets.d.ts.map +1 -0
  27. package/dist/src/components/Dropdown/Root/AccountOtherAssets.js +47 -0
  28. package/dist/src/components/Dropdown/Root/AccountOtherAssets.js.map +1 -0
  29. package/dist/src/components/Dropdown/Root/Root.d.ts +17 -2
  30. package/dist/src/components/Dropdown/Root/Root.d.ts.map +1 -1
  31. package/dist/src/components/Dropdown/Root/Root.js +15 -22
  32. package/dist/src/components/Dropdown/Root/Root.js.map +1 -1
  33. package/dist/src/components/Dropdown/Root/WalletAddress.js +5 -6
  34. package/dist/src/components/Dropdown/Root/WalletAddress.js.map +1 -1
  35. package/dist/src/components/Dropdown/Root/WelcomeBlock.js +4 -3
  36. package/dist/src/components/Dropdown/Root/WelcomeBlock.js.map +1 -1
  37. package/dist/src/components/Dropdown/TestnetTopBanner.d.ts +3 -0
  38. package/dist/src/components/Dropdown/TestnetTopBanner.d.ts.map +1 -0
  39. package/dist/src/components/Dropdown/TestnetTopBanner.js +14 -0
  40. package/dist/src/components/Dropdown/TestnetTopBanner.js.map +1 -0
  41. package/dist/src/config.js +2 -2
  42. package/dist/src/config.js.map +1 -1
  43. package/dist/src/constants.d.ts +2 -1
  44. package/dist/src/constants.d.ts.map +1 -1
  45. package/dist/src/constants.js +5 -4
  46. package/dist/src/constants.js.map +1 -1
  47. package/dist/src/hooks/index.d.ts +2 -0
  48. package/dist/src/hooks/index.d.ts.map +1 -1
  49. package/dist/src/hooks/index.js +2 -0
  50. package/dist/src/hooks/index.js.map +1 -1
  51. package/dist/src/hooks/useAssetsConversionRates.d.ts +7 -0
  52. package/dist/src/hooks/useAssetsConversionRates.d.ts.map +1 -0
  53. package/dist/src/hooks/{useAssetsUSDConversion.js → useAssetsConversionRates.js} +8 -5
  54. package/dist/src/hooks/useAssetsConversionRates.js.map +1 -0
  55. package/dist/src/hooks/useAuthenticateWithWallet.d.ts.map +1 -1
  56. package/dist/src/hooks/useAuthenticateWithWallet.js +4 -4
  57. package/dist/src/hooks/useAuthenticateWithWallet.js.map +1 -1
  58. package/dist/src/hooks/useBorrowData.d.ts +1418 -0
  59. package/dist/src/hooks/useBorrowData.d.ts.map +1 -0
  60. package/dist/src/hooks/useBorrowData.js +65 -0
  61. package/dist/src/hooks/useBorrowData.js.map +1 -0
  62. package/dist/src/hooks/useDropdownData.d.ts +28 -34
  63. package/dist/src/hooks/useDropdownData.d.ts.map +1 -1
  64. package/dist/src/hooks/useDropdownData.js +48 -65
  65. package/dist/src/hooks/useDropdownData.js.map +1 -1
  66. package/dist/src/hooks/useTokensBalances.d.ts +74 -0
  67. package/dist/src/hooks/useTokensBalances.d.ts.map +1 -0
  68. package/dist/src/hooks/useTokensBalances.js +140 -0
  69. package/dist/src/hooks/useTokensBalances.js.map +1 -0
  70. package/dist/src/hooks/useWalletAccount.d.ts +2 -1
  71. package/dist/src/hooks/useWalletAccount.d.ts.map +1 -1
  72. package/dist/src/hooks/useWalletAccount.js +2 -1
  73. package/dist/src/hooks/useWalletAccount.js.map +1 -1
  74. package/dist/src/lib/contracts/index.d.ts +10 -0
  75. package/dist/src/lib/contracts/index.d.ts.map +1 -0
  76. package/dist/src/lib/contracts/index.js +49 -0
  77. package/dist/src/lib/contracts/index.js.map +1 -0
  78. package/dist/src/lib/contracts/musd.d.ts +107 -0
  79. package/dist/src/lib/contracts/musd.d.ts.map +1 -0
  80. package/dist/src/lib/contracts/musd.js +1070 -0
  81. package/dist/src/lib/contracts/musd.js.map +1 -0
  82. package/dist/src/lib/contracts/troveManager.d.ts +1401 -0
  83. package/dist/src/lib/contracts/troveManager.d.ts.map +1 -0
  84. package/dist/src/lib/contracts/troveManager.js +1820 -0
  85. package/dist/src/lib/contracts/troveManager.js.map +1 -0
  86. package/dist/src/utils/cryptoAssets.d.ts +17 -1
  87. package/dist/src/utils/cryptoAssets.d.ts.map +1 -1
  88. package/dist/src/utils/cryptoAssets.js +88 -30
  89. package/dist/src/utils/cryptoAssets.js.map +1 -1
  90. package/dist/src/utils/cryptoAssets.test.js +47 -30
  91. package/dist/src/utils/cryptoAssets.test.js.map +1 -1
  92. package/dist/src/utils/numbers.d.ts +13 -0
  93. package/dist/src/utils/numbers.d.ts.map +1 -1
  94. package/dist/src/utils/numbers.js +46 -0
  95. package/dist/src/utils/numbers.js.map +1 -1
  96. package/package.json +6 -5
  97. package/src/api/portal.ts +1 -0
  98. package/src/components/Dropdown/Content.tsx +47 -11
  99. package/src/components/Dropdown/Dropdown.tsx +28 -13
  100. package/src/components/Dropdown/ListingItem.tsx +80 -0
  101. package/src/components/Dropdown/README.md +0 -14
  102. package/src/components/Dropdown/Root/AccountAssetItem.tsx +26 -0
  103. package/src/components/Dropdown/Root/AccountBalance.tsx +13 -18
  104. package/src/components/Dropdown/Root/AccountOtherAssets.tsx +63 -0
  105. package/src/components/Dropdown/Root/Root.tsx +59 -53
  106. package/src/components/Dropdown/Root/WalletAddress.tsx +7 -7
  107. package/src/components/Dropdown/Root/WelcomeBlock.tsx +3 -3
  108. package/src/components/Dropdown/TestnetTopBanner.tsx +32 -0
  109. package/src/config.ts +2 -2
  110. package/src/constants.ts +5 -4
  111. package/src/hooks/index.ts +5 -0
  112. package/src/hooks/{useAssetsUSDConversion.ts → useAssetsConversionRates.ts} +8 -7
  113. package/src/hooks/useAuthenticateWithWallet.ts +11 -7
  114. package/src/hooks/useBorrowData.ts +79 -0
  115. package/src/hooks/useDropdownData.ts +64 -123
  116. package/src/hooks/useTokensBalances.ts +187 -0
  117. package/src/hooks/useWalletAccount.ts +4 -2
  118. package/src/lib/contracts/index.ts +75 -0
  119. package/src/lib/contracts/musd.ts +1071 -0
  120. package/src/lib/contracts/troveManager.ts +1819 -0
  121. package/src/utils/cryptoAssets.test.ts +52 -34
  122. package/src/utils/cryptoAssets.ts +114 -34
  123. package/src/utils/numbers.ts +68 -0
  124. package/dist/src/components/Dropdown/Root/AccountAssets.d.ts +0 -13
  125. package/dist/src/components/Dropdown/Root/AccountAssets.d.ts.map +0 -1
  126. package/dist/src/components/Dropdown/Root/AccountAssets.js +0 -43
  127. package/dist/src/components/Dropdown/Root/AccountAssets.js.map +0 -1
  128. package/dist/src/hooks/useAssetsUSDConversion.d.ts +0 -8
  129. package/dist/src/hooks/useAssetsUSDConversion.d.ts.map +0 -1
  130. package/dist/src/hooks/useAssetsUSDConversion.js.map +0 -1
  131. package/src/components/Dropdown/Root/AccountAssets.tsx +0 -108
@@ -4,11 +4,10 @@ import { QUERY_KEYS } from "./constants"
4
4
  import { usePortalApiClient } from "./usePortalApiClient"
5
5
 
6
6
  type AssetsUsdConversion = {
7
- btcUsd: string
8
- ethUsd: string
7
+ usd: Record<"btc" | "eth" | "t", number>
9
8
  }
10
9
 
11
- export function useAssetsUsdConversion(
10
+ export default function useAssetsConversionRates(
12
11
  useQueryOptions: Partial<UseBaseQueryOptions<AssetsUsdConversion>> = {},
13
12
  ) {
14
13
  const portalApiClient = usePortalApiClient()
@@ -16,12 +15,14 @@ export function useAssetsUsdConversion(
16
15
  return useQuery({
17
16
  queryKey: [QUERY_KEYS.ASSETS_USD_CONVERSION],
18
17
  queryFn: async () => {
19
- const { currentUsdPerBtc, currentUsdPerEth } =
18
+ const { currentUsdPerBtc, currentUsdPerEth, currentUsdPerTToken } =
20
19
  await portalApiClient.getPortalStatistics()
21
-
22
20
  return {
23
- btcUsd: currentUsdPerBtc,
24
- ethUsd: currentUsdPerEth,
21
+ usd: {
22
+ btc: Number(currentUsdPerBtc),
23
+ eth: Number(currentUsdPerEth),
24
+ t: Number(currentUsdPerTToken),
25
+ },
25
26
  }
26
27
  },
27
28
  staleTime: 30 * ONE_MINUTE_MS,
@@ -15,27 +15,31 @@ function useAuthenticateWithWallet(
15
15
  "mutationFn" | "mutationKey"
16
16
  > = {},
17
17
  ) {
18
- const { address, chainId, connector, networkFamily } = useWalletAccount()
18
+ const { walletAddress, chainId, connector, networkFamily } =
19
+ useWalletAccount()
19
20
  const { ensureNoSessionAndFetchNonce } = useEnsureNoSessionAndFetchNonce()
20
21
  const { createSessionAsync } = useCreateSession()
21
22
  const { createAccountAsync } = useCreateAccount()
22
23
  const { signMessageAsync } = useSignMessage()
23
24
 
24
- const { refetch: getAccountByAddress } = useGetAccountByAddress(address, {
25
- enabled: false,
26
- retry: false,
27
- })
25
+ const { refetch: getAccountByAddress } = useGetAccountByAddress(
26
+ walletAddress,
27
+ {
28
+ enabled: false,
29
+ retry: false,
30
+ },
31
+ )
28
32
 
29
33
  const { mutate, mutateAsync, ...signInMutationRestParameters } = useMutation({
30
34
  mutationFn: async () => {
31
- if (!address) {
35
+ if (!walletAddress) {
32
36
  throw new Error("Sign in error: Wallet not connected!")
33
37
  }
34
38
 
35
39
  const nonce = await ensureNoSessionAndFetchNonce()
36
40
 
37
41
  const messageResult = createSignInWithWalletMessage(
38
- address,
42
+ walletAddress,
39
43
  nonce,
40
44
  networkFamily,
41
45
  chainId,
@@ -0,0 +1,79 @@
1
+ import { useAccount, useReadContract } from "wagmi"
2
+ import { useCallback } from "react"
3
+ import { useQueryClient } from "@tanstack/react-query"
4
+ import { ONE_MINUTE_MS } from "../utils/time"
5
+ import { troveManagerContract } from "../lib/contracts"
6
+ import { usePassportContext } from "./usePassportContext"
7
+ import { CHAIN_ID } from "../constants"
8
+
9
+ /**
10
+ * Query hook for getting borrow data. Returns collateral and trove debt for the
11
+ * connected account, based on it's evm address.
12
+ * @param queryOptions Query options passed to the underlying `useQuery` hook.
13
+ */
14
+ export function useBorrowData(queryOptions = {}) {
15
+ const { environment = "mainnet" } = usePassportContext()
16
+ const { address } = useAccount()
17
+ return useReadContract({
18
+ abi: troveManagerContract.abi,
19
+ address: troveManagerContract.address[environment],
20
+ functionName: "getEntireDebtAndColl",
21
+ args: [address || "0x"],
22
+ query: {
23
+ enabled: !!address,
24
+ staleTime: 5 * ONE_MINUTE_MS,
25
+ retry: 1,
26
+ select: (data) => {
27
+ if (!data) return undefined
28
+
29
+ const [collateral, principal, interest] = data
30
+ return {
31
+ collateral,
32
+ troveDebt: principal + interest,
33
+ }
34
+ },
35
+ ...queryOptions,
36
+ },
37
+ chainId: CHAIN_ID[environment],
38
+ })
39
+ }
40
+
41
+ /**
42
+ * Hook for for invalidating current user's borrow data. Can be used to
43
+ * invalidate borrow data manually, which forces the data to be re-fetched.
44
+ * @returns Function `invalidateBorrowData` for invalidating the borrow data
45
+ */
46
+ export function useInvalidateBorrowData() {
47
+ const queryClient = useQueryClient()
48
+
49
+ const { queryKey } = useBorrowData()
50
+
51
+ const invalidateBorrowDataHandler = useCallback(
52
+ () => queryClient.invalidateQueries({ queryKey }),
53
+ [queryClient, queryKey],
54
+ )
55
+
56
+ return {
57
+ invalidateBorrowData: invalidateBorrowDataHandler,
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Hook for for resetting current user's borrow data. Can be used to reset
63
+ * borrow data manually, which forces the data to be re-fetched.
64
+ * @returns Function `resetBorrowData` for resetting the borrow data
65
+ */
66
+ export function useResetBorrowData() {
67
+ const queryClient = useQueryClient()
68
+
69
+ const { queryKey } = useBorrowData()
70
+
71
+ const resetBorrowDataHandler = useCallback(
72
+ () => queryClient.resetQueries({ queryKey }),
73
+ [queryClient, queryKey],
74
+ )
75
+
76
+ return {
77
+ resetBorrowData: resetBorrowDataHandler,
78
+ }
79
+ }
@@ -1,160 +1,101 @@
1
- import { useBitcoinAccount } from "@mezo-org/orangekit"
1
+ import { useBalance } from "wagmi"
2
2
  import { useGetCurrentAccount } from "."
3
3
  import {
4
4
  CryptoAssetKey,
5
- getCryptoAsset,
6
5
  isBitcoinLikeCryptoAsset,
7
- isUsdLikeCryptoAsset,
6
+ mapCryptoAssetToDetails,
8
7
  } from "../utils/cryptoAssets"
9
- import {
10
- formatNumberToCompactString,
11
- fromFixedPoint,
12
- fromFixedPointToString,
13
- } from "../utils/numbers"
14
- import { useAssetsUsdConversion } from "./useAssetsUSDConversion"
8
+ import { fromFixedPoint } from "../utils/numbers"
9
+ import useAssetsConversionRates from "./useAssetsConversionRates"
15
10
  import useWalletAccount from "./useWalletAccount"
16
- import { formatUsd } from "../utils/currency"
17
-
18
- /**
19
- * Formats crypto asset to balance details (balance in USD and decimals)
20
- * @param type The type of crypto asset
21
- * @param balance The balance of crypto asset
22
- * @param btcUsdConversionRate The USD conversion rate
23
- * @returns The balance details
24
- */
25
- function formatCryptoAsset(
26
- type: CryptoAssetKey,
27
- balance: bigint,
28
- btcUsdConversionRate: number,
29
- ) {
30
- const { decimals } = getCryptoAsset(type)
31
-
32
- const nativeBalance = fromFixedPoint(balance, decimals)
33
- let balanceInUsd = 0
34
- if (isBitcoinLikeCryptoAsset(type)) {
35
- balanceInUsd = fromFixedPoint(
36
- balance * BigInt(btcUsdConversionRate),
37
- decimals,
38
- )
39
- }
40
- if (isUsdLikeCryptoAsset(type)) {
41
- balanceInUsd = nativeBalance
42
- }
43
-
44
- return {
45
- type,
46
- balance: fromFixedPointToString(
47
- balance,
48
- decimals,
49
- isUsdLikeCryptoAsset(type) ? 2 : 4,
50
- ),
51
- balanceInUsd: formatUsd(balanceInUsd),
52
- }
53
- }
11
+ import { useTokensBalances } from "./useTokensBalances"
12
+ import { useBorrowData } from "./useBorrowData"
54
13
 
55
14
  export type DropdownCryptoAsset<T = CryptoAssetKey> = {
56
15
  type: T
57
16
  balance: bigint
58
17
  }
59
18
 
60
- type DropdownDetailedCryptoAsset = ReturnType<typeof formatCryptoAsset>
61
-
62
- export type DropdownData = {
63
- mezoId: string
64
- accountAddress: string
65
- walletAddress: string
66
- walletType: "bitcoin" | "evm"
67
- totalBalanceInUsd: string
68
- formattedNativeAssets: DropdownDetailedCryptoAsset[]
69
- matsnet: {
70
- mats: string
71
- formattedAssets: DropdownDetailedCryptoAsset[]
72
- }
73
- }
74
-
75
- type UseDropdownDataOptions = {
76
- // This is workaround. It should be read from contracts or fetched from API.
77
- evmNativeAssets?: DropdownCryptoAsset[]
78
- matsnetAssets?: DropdownCryptoAsset[]
79
- }
80
-
81
19
  /**
82
20
  * Aggregates dropdown data for Dropdown component.
83
- * @param options - Options for the dropdown data.
84
- * @param options.evmNativeAssets - Native assets for EVM wallet.
85
- * @param options.matsnetAssets - Matsnet tokens. Rendered as separate section.
86
21
  * @returns Dropdown data.
87
22
  * @dev This hook is for internal use only.
88
23
  */
89
- export default function useDropdownData(
90
- options?: UseDropdownDataOptions,
91
- ): DropdownData | null {
92
- const { evmNativeAssets = [], matsnetAssets = [] } = options || {}
93
-
94
- const { btcBalance } = useBitcoinAccount()
24
+ export default function useDropdownData() {
25
+ const { data: btcBalance } = useBalance()
95
26
  const {
96
- address: walletAddress,
97
- networkFamily,
98
- isConnected,
27
+ walletAddress,
28
+ accountAddress,
29
+ networkFamily: walletType,
99
30
  } = useWalletAccount()
100
31
  const { data: passportAccount } = useGetCurrentAccount()
101
- const { data: assetsUsdConversion } = useAssetsUsdConversion()
102
-
103
- const accountAddress = passportAccount?.linkedAccounts?.find(
104
- (account) => account.type === "wallet",
105
- )?.evmAddress
106
-
107
- if (!walletAddress || !isConnected || !passportAccount || !accountAddress) {
108
- return null
32
+ const { data: assetsConversionRates } = useAssetsConversionRates()
33
+ const { data: tokensBalances } = useTokensBalances()
34
+ const { data: debt } = useBorrowData()
35
+ const mezoId = passportAccount?.mezoId
36
+
37
+ const detailedAssets = Object.fromEntries(
38
+ [
39
+ ["BTC", btcBalance?.value ?? 0n],
40
+ ...Object.entries(tokensBalances ?? {}),
41
+ ].map((asset) => {
42
+ const [type, balance] = asset as [CryptoAssetKey, bigint]
43
+
44
+ let usdConversionRate: number | undefined
45
+ if (isBitcoinLikeCryptoAsset(type))
46
+ usdConversionRate = assetsConversionRates?.usd.btc
47
+ if (type === "mT") {
48
+ usdConversionRate = assetsConversionRates?.usd.t
49
+ }
50
+
51
+ return [
52
+ type,
53
+ mapCryptoAssetToDetails(type, balance, usdConversionRate || 1),
54
+ ]
55
+ }),
56
+ ) as Record<CryptoAssetKey, ReturnType<typeof mapCryptoAssetToDetails>>
57
+
58
+ const assets = {
59
+ btc: detailedAssets.BTC,
60
+ musd: detailedAssets.MUSD,
109
61
  }
110
62
 
111
- const mezoId = passportAccount.mezoId!
112
-
113
- const nativeAssets: DropdownCryptoAsset[] =
114
- networkFamily === "bitcoin"
115
- ? [
116
- {
117
- type: "btc",
118
- balance: BigInt(btcBalance?.total ?? 0),
119
- },
120
- ]
121
- : evmNativeAssets
63
+ const otherAssetsData = Object.values(detailedAssets).filter(
64
+ (asset) => !["BTC", "MUSD"].includes(asset.type),
65
+ )
122
66
 
123
- const btcUsdConversionRate = Number(assetsUsdConversion?.btcUsd ?? 0)
67
+ const otherAssetsCount = otherAssetsData.length
124
68
 
125
- const formattedNativeAssets = nativeAssets.map((asset) =>
126
- formatCryptoAsset(asset.type, asset.balance, btcUsdConversionRate),
69
+ const otherAssetsUsdTotal = otherAssetsData.reduce(
70
+ (sum, { usdBalance }) => sum + usdBalance,
71
+ 0,
127
72
  )
128
73
 
129
- const totalBalanceInUsd = formatUsd(
130
- nativeAssets.reduce((sum, value) => {
131
- const { decimals } = getCryptoAsset(value.type)
132
- return (
133
- sum +
134
- fromFixedPoint(value.balance * BigInt(btcUsdConversionRate), decimals)
135
- )
136
- }, 0),
74
+ const usdTotalBalance = Object.values(detailedAssets).reduce(
75
+ (sum, { usdBalance }) => sum + usdBalance,
76
+ 0,
137
77
  )
138
78
 
139
- const matsBalance = formatNumberToCompactString(
140
- passportAccount.mats.totalMats,
141
- 2,
142
- )
79
+ const matsBalance = passportAccount?.mats.totalMats || 0
143
80
 
144
- const matsnetFormattedAssets = matsnetAssets.map((asset) =>
145
- formatCryptoAsset(asset.type, asset.balance, btcUsdConversionRate),
81
+ const usdCollateral = fromFixedPoint(
82
+ (debt?.collateral ?? 0n) * BigInt(assetsConversionRates?.usd.btc ?? 0),
83
+ 18,
146
84
  )
147
85
 
86
+ const usdTroveDebt = fromFixedPoint(debt?.troveDebt ?? 0n, 18)
87
+
148
88
  return {
149
89
  mezoId,
90
+ matsBalance,
150
91
  accountAddress,
151
92
  walletAddress,
152
- walletType: networkFamily,
153
- totalBalanceInUsd,
154
- formattedNativeAssets,
155
- matsnet: {
156
- mats: matsBalance,
157
- formattedAssets: matsnetFormattedAssets,
158
- },
93
+ walletType,
94
+ usdTotalBalance,
95
+ usdTroveDebt,
96
+ usdCollateral,
97
+ assets,
98
+ otherAssetsCount,
99
+ otherAssetsUsdTotal,
159
100
  }
160
101
  }
@@ -0,0 +1,187 @@
1
+ import { useReadContracts } from "wagmi"
2
+ import { useCallback, useMemo } from "react"
3
+ import { Abi } from "viem"
4
+ import { useQueryClient } from "@tanstack/react-query"
5
+ import { usePassportContext } from "./usePassportContext"
6
+ import {
7
+ mainnetContracts,
8
+ testnetContracts,
9
+ MezoChainToken,
10
+ } from "../lib/contracts"
11
+ import useWalletAccount from "./useWalletAccount"
12
+ import { CHAIN_ID } from "../constants"
13
+
14
+ // Wagmi handles typesafety with ABI const assertions. TypeScript doesn't
15
+ // support importing JSON as const yet so types cannot be inferred from the
16
+ // imported contract. As a workaround there is minimal ABI definition that can
17
+ // be asserted types from.
18
+ // Ref: https://wagmi.sh/core/typescript#const-assert-abis-typed-data
19
+
20
+ const BALANCE_OF_ABI = [
21
+ {
22
+ inputs: [
23
+ {
24
+ internalType: "address",
25
+ name: "account",
26
+ type: "address",
27
+ },
28
+ ],
29
+ name: "balanceOf",
30
+ outputs: [
31
+ {
32
+ internalType: "uint256",
33
+ name: "",
34
+ type: "uint256",
35
+ },
36
+ ],
37
+ stateMutability: "view",
38
+ type: "function",
39
+ },
40
+ ] as const satisfies Abi
41
+
42
+ const BALANCE_TOKENS: MezoChainToken[] = [
43
+ "mcbBTC",
44
+ "mDAI",
45
+ "mFBTC",
46
+ "mSolvBTC",
47
+ "mswBTC",
48
+ "mT",
49
+ "mUSDC",
50
+ "mUSDe",
51
+ "mUSDT",
52
+ "mxSolvBTC",
53
+ "MUSD",
54
+ ]
55
+
56
+ type UseMezoChainTokensBalancesOptions<T> = {
57
+ tokens?: T
58
+ queryOptions?: object
59
+ }
60
+
61
+ /**
62
+ * Hook to get the balance of a list of tokens for the current account
63
+ * @param options.tokens The list of tokens to get the balance for. It will
64
+ * fallback to all tokens if not provided.
65
+ * @param options.queryOptions The query options to pass to the
66
+ * `useReadContracts`
67
+ * @returns Tanstack's `useQuery` returnings with balance of tokens for the
68
+ * current account in form of typesafe object with token names as keys
69
+ * 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
+ * @example
73
+ * const mezoTokensBalance = useTokensBalances({
74
+ * tokens: ["mT", "mxSolvBTC"],
75
+ * })
76
+ * console.log(mezoTokensBalance?.data.mT) // Eg. 0n
77
+ * console.log(Object.keys(mezoTokensBalance?.data)) // ["mT", "mxSolvBTC"]
78
+ */
79
+ export function useTokensBalances<T extends MezoChainToken[]>(
80
+ options: UseMezoChainTokensBalancesOptions<T> = {},
81
+ ) {
82
+ const { environment = "mainnet" } = usePassportContext()
83
+
84
+ const { accountAddress } = useWalletAccount()
85
+
86
+ const contractsMap = useMemo(() => {
87
+ const contracts =
88
+ environment === "mainnet" ? mainnetContracts : testnetContracts
89
+
90
+ const tokenContracts = Object.fromEntries(
91
+ Object.entries(contracts).filter(([key]) =>
92
+ BALANCE_TOKENS.includes(key as MezoChainToken),
93
+ ),
94
+ ) as typeof contracts
95
+
96
+ return tokenContracts
97
+ }, [environment])
98
+
99
+ const { tokens = Object.keys(contractsMap) as T, queryOptions = {} } = options
100
+
101
+ const contracts = useMemo(() => {
102
+ if (!accountAddress) return []
103
+
104
+ return tokens.map((token) => {
105
+ const { address } = contractsMap[token]
106
+
107
+ return {
108
+ address,
109
+ abi: BALANCE_OF_ABI,
110
+ functionName: "balanceOf",
111
+ args: [accountAddress],
112
+ chainId: CHAIN_ID[environment],
113
+ }
114
+ })
115
+ }, [accountAddress, tokens, contractsMap, environment])
116
+
117
+ return useReadContracts({
118
+ contracts,
119
+ query: {
120
+ select: (data) =>
121
+ data.reduce(
122
+ (acc, item) => {
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>,
131
+ ),
132
+ ...queryOptions,
133
+ },
134
+ })
135
+ }
136
+
137
+ /**
138
+ * Hook for invalidating current user's token balances. Can be used to
139
+ * 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
+ * @returns Function `invalidateTokenBalances` that invalidates token balances
143
+ * @example
144
+ * const { invalidateTokenBalances } = useInvalidateTokensBalances(["mT", "mUSD"])
145
+ * (...)
146
+ * await invalidateTokenBalances()
147
+ */
148
+ export function useInvalidateTokensBalances(tokens?: MezoChainToken[]) {
149
+ const queryClient = useQueryClient()
150
+
151
+ const { queryKey } = useTokensBalances({ tokens })
152
+
153
+ const invalidateTokenBalancesHandler = useCallback(
154
+ () => queryClient.invalidateQueries({ queryKey }),
155
+ [queryClient, queryKey],
156
+ )
157
+
158
+ return {
159
+ invalidateTokenBalances: invalidateTokenBalancesHandler,
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Hook for resetting current user's token balances. Can be used to reset the
165
+ * 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
+ * @returns Function `resetTokenBalances` that invalidates token balances
169
+ * @example
170
+ * const { resetTokenBalances } = useResetTokensBalances(["mT", "mUSD"])
171
+ * (...)
172
+ * await resetTokenBalances()
173
+ */
174
+ export function useResetTokensBalances(tokens?: MezoChainToken[]) {
175
+ const queryClient = useQueryClient()
176
+
177
+ const { queryKey } = useTokensBalances({ tokens })
178
+
179
+ const resetTokenBalancesHandler = useCallback(
180
+ () => queryClient.resetQueries({ queryKey }),
181
+ [queryClient, queryKey],
182
+ )
183
+
184
+ return {
185
+ resetTokenBalances: resetTokenBalancesHandler,
186
+ }
187
+ }
@@ -5,7 +5,8 @@ import { Address } from "viem"
5
5
  import { Connector, useAccount } from "wagmi"
6
6
 
7
7
  type UseWalletAccountReturn = {
8
- address?: string | Address
8
+ accountAddress?: string | Address
9
+ walletAddress?: string | Address
9
10
  isConnected: boolean
10
11
  networkFamily: "bitcoin" | "evm"
11
12
  connector?: Connector
@@ -44,7 +45,8 @@ export default function useWalletAccount(): UseWalletAccountReturn {
44
45
  const { address: btcAddress } = btcData || {}
45
46
 
46
47
  return {
47
- address: networkFamily === "bitcoin" ? btcAddress : evmAddress,
48
+ accountAddress: evmAddress,
49
+ walletAddress: btcAddress ?? evmAddress,
48
50
  isConnected: networkFamily === "bitcoin" ? !!btcAddress : !!evmAddress,
49
51
  networkFamily,
50
52
  connector,
@@ -0,0 +1,75 @@
1
+ import cbbtcMainnet from "@mezo-org/mezod-contracts/deployments/mainnet/mcbBTC.json"
2
+ import daiMainnet from "@mezo-org/mezod-contracts/deployments/mainnet/mDAI.json"
3
+ import fbtcMainnet from "@mezo-org/mezod-contracts/deployments/mainnet/mFBTC.json"
4
+ import solvbtcMainnet from "@mezo-org/mezod-contracts/deployments/mainnet/mSolvBTC.json"
5
+ import swbtcMainnet from "@mezo-org/mezod-contracts/deployments/mainnet/mswBTC.json"
6
+ import tMainnet from "@mezo-org/mezod-contracts/deployments/mainnet/mT.json"
7
+ import usdcMainnet from "@mezo-org/mezod-contracts/deployments/mainnet/mUSDC.json"
8
+ import usdeMainnet from "@mezo-org/mezod-contracts/deployments/mainnet/mUSDe.json"
9
+ import usdtMainnet from "@mezo-org/mezod-contracts/deployments/mainnet/mUSDT.json"
10
+ import xsolvbtcMainnet from "@mezo-org/mezod-contracts/deployments/mainnet/mxSolvBTC.json"
11
+
12
+ import cbbtcTestnet from "@mezo-org/mezod-contracts/deployments/testnet/mcbBTC.json"
13
+ import daiTestnet from "@mezo-org/mezod-contracts/deployments/testnet/mDAI.json"
14
+ import fbtcTestnet from "@mezo-org/mezod-contracts/deployments/testnet/mFBTC.json"
15
+ import solvbtcTestnet from "@mezo-org/mezod-contracts/deployments/testnet/mSolvBTC.json"
16
+ import swbtcTestnet from "@mezo-org/mezod-contracts/deployments/testnet/mswBTC.json"
17
+ import tTestnet from "@mezo-org/mezod-contracts/deployments/testnet/mT.json"
18
+ import usdcTestnet from "@mezo-org/mezod-contracts/deployments/testnet/mUSDC.json"
19
+ import usdeTestnet from "@mezo-org/mezod-contracts/deployments/testnet/mUSDe.json"
20
+ import usdtTestnet from "@mezo-org/mezod-contracts/deployments/testnet/mUSDT.json"
21
+ import xsolvbtcTestnet from "@mezo-org/mezod-contracts/deployments/testnet/mxSolvBTC.json"
22
+
23
+ import { Abi, Address } from "viem"
24
+ import { musdTestnet, musdMainnet } from "./musd"
25
+
26
+ export { default as troveManagerContract } from "./troveManager"
27
+
28
+ export type MezoChainToken =
29
+ | "mcbBTC"
30
+ | "mDAI"
31
+ | "mFBTC"
32
+ | "mSolvBTC"
33
+ | "mswBTC"
34
+ | "mT"
35
+ | "mUSDC"
36
+ | "mUSDe"
37
+ | "mUSDT"
38
+ | "mxSolvBTC"
39
+ | "MUSD"
40
+
41
+ type ContractsMap = Record<
42
+ MezoChainToken,
43
+ {
44
+ address: Address
45
+ abi: Abi
46
+ }
47
+ >
48
+
49
+ export const testnetContracts = {
50
+ mcbBTC: cbbtcTestnet,
51
+ mDAI: daiTestnet,
52
+ mFBTC: fbtcTestnet,
53
+ mSolvBTC: solvbtcTestnet,
54
+ mswBTC: swbtcTestnet,
55
+ mT: tTestnet,
56
+ mUSDC: usdcTestnet,
57
+ mUSDe: usdeTestnet,
58
+ mUSDT: usdtTestnet,
59
+ mxSolvBTC: xsolvbtcTestnet,
60
+ MUSD: musdTestnet,
61
+ } as unknown as ContractsMap
62
+
63
+ export const mainnetContracts = {
64
+ mcbBTC: cbbtcMainnet,
65
+ mDAI: daiMainnet,
66
+ mFBTC: fbtcMainnet,
67
+ mSolvBTC: solvbtcMainnet,
68
+ mswBTC: swbtcMainnet,
69
+ mT: tMainnet,
70
+ mUSDC: usdcMainnet,
71
+ mUSDe: usdeMainnet,
72
+ mUSDT: usdtMainnet,
73
+ mxSolvBTC: xsolvbtcMainnet,
74
+ MUSD: musdMainnet,
75
+ } as unknown as ContractsMap