@mezo-org/passport 0.4.0-dev.9 → 0.5.0

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 (300) hide show
  1. package/README.md +18 -22
  2. package/dist/src/api/auth.d.ts +7 -3
  3. package/dist/src/api/auth.d.ts.map +1 -1
  4. package/dist/src/api/auth.js +3 -1
  5. package/dist/src/api/auth.js.map +1 -1
  6. package/dist/src/api/client.d.ts +4 -1
  7. package/dist/src/api/client.d.ts.map +1 -1
  8. package/dist/src/api/client.js +9 -2
  9. package/dist/src/api/client.js.map +1 -1
  10. package/dist/src/api/portal.d.ts +3 -9
  11. package/dist/src/api/portal.d.ts.map +1 -1
  12. package/dist/src/api/portal.js +8 -5
  13. package/dist/src/api/portal.js.map +1 -1
  14. package/dist/src/components/Dropdown/ConnectedTrigger.d.ts +2 -1
  15. package/dist/src/components/Dropdown/ConnectedTrigger.d.ts.map +1 -1
  16. package/dist/src/components/Dropdown/ConnectedTrigger.js +29 -20
  17. package/dist/src/components/Dropdown/ConnectedTrigger.js.map +1 -1
  18. package/dist/src/components/Dropdown/Content.d.ts +4 -5
  19. package/dist/src/components/Dropdown/Content.d.ts.map +1 -1
  20. package/dist/src/components/Dropdown/Content.js +19 -61
  21. package/dist/src/components/Dropdown/Content.js.map +1 -1
  22. package/dist/src/components/Dropdown/DisconnectedTrigger.d.ts.map +1 -1
  23. package/dist/src/components/Dropdown/DisconnectedTrigger.js +2 -2
  24. package/dist/src/components/Dropdown/DisconnectedTrigger.js.map +1 -1
  25. package/dist/src/components/Dropdown/Dropdown.d.ts +9 -6
  26. package/dist/src/components/Dropdown/Dropdown.d.ts.map +1 -1
  27. package/dist/src/components/Dropdown/Dropdown.js +10 -10
  28. package/dist/src/components/Dropdown/Dropdown.js.map +1 -1
  29. package/dist/src/components/Dropdown/ListingItem.d.ts +14 -0
  30. package/dist/src/components/Dropdown/ListingItem.d.ts.map +1 -0
  31. package/dist/src/components/Dropdown/ListingItem.js +42 -0
  32. package/dist/src/components/Dropdown/ListingItem.js.map +1 -0
  33. package/dist/src/components/Dropdown/NestedViewLayout.d.ts +8 -0
  34. package/dist/src/components/Dropdown/NestedViewLayout.d.ts.map +1 -0
  35. package/dist/src/components/Dropdown/NestedViewLayout.js +32 -0
  36. package/dist/src/components/Dropdown/NestedViewLayout.js.map +1 -0
  37. package/dist/src/components/Dropdown/Receive/Receive.d.ts +4 -0
  38. package/dist/src/components/Dropdown/Receive/Receive.d.ts.map +1 -0
  39. package/dist/src/components/Dropdown/Receive/Receive.js +64 -0
  40. package/dist/src/components/Dropdown/Receive/Receive.js.map +1 -0
  41. package/dist/src/components/Dropdown/Root/AccountAddressActions.d.ts +4 -0
  42. package/dist/src/components/Dropdown/Root/AccountAddressActions.d.ts.map +1 -0
  43. package/dist/src/components/Dropdown/Root/AccountAddressActions.js +49 -0
  44. package/dist/src/components/Dropdown/Root/AccountAddressActions.js.map +1 -0
  45. package/dist/src/components/Dropdown/Root/AccountBalance.d.ts +6 -0
  46. package/dist/src/components/Dropdown/Root/AccountBalance.d.ts.map +1 -0
  47. package/dist/src/components/Dropdown/Root/AccountBalance.js +31 -0
  48. package/dist/src/components/Dropdown/Root/AccountBalance.js.map +1 -0
  49. package/dist/src/components/Dropdown/Root/AccountBtcListing.d.ts +6 -0
  50. package/dist/src/components/Dropdown/Root/AccountBtcListing.d.ts.map +1 -0
  51. package/dist/src/components/Dropdown/Root/AccountBtcListing.js +27 -0
  52. package/dist/src/components/Dropdown/Root/AccountBtcListing.js.map +1 -0
  53. package/dist/src/components/Dropdown/Root/AccountError.d.ts +8 -0
  54. package/dist/src/components/Dropdown/Root/AccountError.d.ts.map +1 -0
  55. package/dist/src/components/Dropdown/Root/AccountError.js +17 -0
  56. package/dist/src/components/Dropdown/Root/AccountError.js.map +1 -0
  57. package/dist/src/components/Dropdown/Root/AccountMusdListing.d.ts +4 -0
  58. package/dist/src/components/Dropdown/Root/AccountMusdListing.d.ts.map +1 -0
  59. package/dist/src/components/Dropdown/Root/AccountMusdListing.js +21 -0
  60. package/dist/src/components/Dropdown/Root/AccountMusdListing.js.map +1 -0
  61. package/dist/src/components/Dropdown/Root/AccountOtherAssets.d.ts +8 -0
  62. package/dist/src/components/Dropdown/Root/AccountOtherAssets.d.ts.map +1 -0
  63. package/dist/src/components/Dropdown/Root/AccountOtherAssets.js +43 -0
  64. package/dist/src/components/Dropdown/Root/AccountOtherAssets.js.map +1 -0
  65. package/dist/src/components/Dropdown/Root/Root.d.ts +8 -0
  66. package/dist/src/components/Dropdown/Root/Root.d.ts.map +1 -0
  67. package/dist/src/components/Dropdown/Root/Root.js +45 -0
  68. package/dist/src/components/Dropdown/Root/Root.js.map +1 -0
  69. package/dist/src/components/Dropdown/Root/WalletAddress.d.ts +4 -0
  70. package/dist/src/components/Dropdown/Root/WalletAddress.d.ts.map +1 -0
  71. package/dist/src/components/Dropdown/Root/WalletAddress.js +66 -0
  72. package/dist/src/components/Dropdown/Root/WalletAddress.js.map +1 -0
  73. package/dist/src/components/Dropdown/Root/WelcomeBlock.d.ts +6 -0
  74. package/dist/src/components/Dropdown/Root/WelcomeBlock.d.ts.map +1 -0
  75. package/dist/src/components/Dropdown/Root/WelcomeBlock.js +88 -0
  76. package/dist/src/components/Dropdown/Root/WelcomeBlock.js.map +1 -0
  77. package/dist/src/components/Dropdown/SlotNumber.d.ts +19 -0
  78. package/dist/src/components/Dropdown/SlotNumber.d.ts.map +1 -0
  79. package/dist/src/components/Dropdown/SlotNumber.js +67 -0
  80. package/dist/src/components/Dropdown/SlotNumber.js.map +1 -0
  81. package/dist/src/components/Dropdown/TestnetTopBanner.d.ts +3 -0
  82. package/dist/src/components/Dropdown/TestnetTopBanner.d.ts.map +1 -0
  83. package/dist/src/components/Dropdown/TestnetTopBanner.js +14 -0
  84. package/dist/src/components/Dropdown/TestnetTopBanner.js.map +1 -0
  85. package/dist/src/config.d.ts +19 -5
  86. package/dist/src/config.d.ts.map +1 -1
  87. package/dist/src/config.js +58 -14
  88. package/dist/src/config.js.map +1 -1
  89. package/dist/src/constants.d.ts +11 -3
  90. package/dist/src/constants.d.ts.map +1 -1
  91. package/dist/src/constants.js +12 -4
  92. package/dist/src/constants.js.map +1 -1
  93. package/dist/src/hooks/index.d.ts +4 -0
  94. package/dist/src/hooks/index.d.ts.map +1 -1
  95. package/dist/src/hooks/index.js +4 -0
  96. package/dist/src/hooks/index.js.map +1 -1
  97. package/dist/src/hooks/useAssetsConversionRates.d.ts +18 -0
  98. package/dist/src/hooks/useAssetsConversionRates.d.ts.map +1 -0
  99. package/dist/src/hooks/useAssetsConversionRates.js +67 -0
  100. package/dist/src/hooks/useAssetsConversionRates.js.map +1 -0
  101. package/dist/src/hooks/useAuthenticateWithWallet.d.ts +13 -13
  102. package/dist/src/hooks/useAuthenticateWithWallet.d.ts.map +1 -1
  103. package/dist/src/hooks/useAuthenticateWithWallet.js +9 -8
  104. package/dist/src/hooks/useAuthenticateWithWallet.js.map +1 -1
  105. package/dist/src/hooks/useBorrowData.d.ts +108 -0
  106. package/dist/src/hooks/useBorrowData.d.ts.map +1 -0
  107. package/dist/src/hooks/useBorrowData.js +201 -0
  108. package/dist/src/hooks/useBorrowData.js.map +1 -0
  109. package/dist/src/hooks/useCreateAccount.d.ts.map +1 -1
  110. package/dist/src/hooks/useCreateAccount.js +22 -1
  111. package/dist/src/hooks/useCreateAccount.js.map +1 -1
  112. package/dist/src/hooks/useGetCurrentAccount.d.ts.map +1 -1
  113. package/dist/src/hooks/useGetCurrentAccount.js +4 -6
  114. package/dist/src/hooks/useGetCurrentAccount.js.map +1 -1
  115. package/dist/src/hooks/useLinkAccount.d.ts +19 -13
  116. package/dist/src/hooks/useLinkAccount.d.ts.map +1 -1
  117. package/dist/src/hooks/useLinkAccount.js +20 -1
  118. package/dist/src/hooks/useLinkAccount.js.map +1 -1
  119. package/dist/src/hooks/useRefreshPassport.d.ts +19 -0
  120. package/dist/src/hooks/useRefreshPassport.d.ts.map +1 -0
  121. package/dist/src/hooks/useRefreshPassport.js +44 -0
  122. package/dist/src/hooks/useRefreshPassport.js.map +1 -0
  123. package/dist/src/hooks/useSignInWithWallet.d.ts +13 -13
  124. package/dist/src/hooks/useSignInWithWallet.d.ts.map +1 -1
  125. package/dist/src/hooks/useSignUpWithWallet.d.ts +13 -13
  126. package/dist/src/hooks/useSignUpWithWallet.d.ts.map +1 -1
  127. package/dist/src/hooks/useTokensBalances.d.ts +75 -0
  128. package/dist/src/hooks/useTokensBalances.d.ts.map +1 -0
  129. package/dist/src/hooks/useTokensBalances.js +181 -0
  130. package/dist/src/hooks/useTokensBalances.js.map +1 -0
  131. package/dist/src/hooks/useValidateMezoId.d.ts +8 -0
  132. package/dist/src/hooks/useValidateMezoId.d.ts.map +1 -0
  133. package/dist/src/hooks/useValidateMezoId.js +24 -0
  134. package/dist/src/hooks/useValidateMezoId.js.map +1 -0
  135. package/dist/src/hooks/useWalletAccount.d.ts +2 -1
  136. package/dist/src/hooks/useWalletAccount.d.ts.map +1 -1
  137. package/dist/src/hooks/useWalletAccount.js +20 -15
  138. package/dist/src/hooks/useWalletAccount.js.map +1 -1
  139. package/dist/src/hooks/useWatchTransferEvents.d.ts +5 -0
  140. package/dist/src/hooks/useWatchTransferEvents.d.ts.map +1 -0
  141. package/dist/src/hooks/useWatchTransferEvents.js +63 -0
  142. package/dist/src/hooks/useWatchTransferEvents.js.map +1 -0
  143. package/dist/src/index.d.ts +2 -1
  144. package/dist/src/index.d.ts.map +1 -1
  145. package/dist/src/index.js +2 -1
  146. package/dist/src/index.js.map +1 -1
  147. package/dist/src/lib/contracts/index.d.ts +13 -0
  148. package/dist/src/lib/contracts/index.d.ts.map +1 -0
  149. package/dist/src/lib/contracts/index.js +66 -0
  150. package/dist/src/lib/contracts/index.js.map +1 -0
  151. package/dist/src/lib/contracts/priceOracle.d.ts +43 -0
  152. package/dist/src/lib/contracts/priceOracle.d.ts.map +1 -0
  153. package/dist/src/lib/contracts/priceOracle.js +52 -0
  154. package/dist/src/lib/contracts/priceOracle.js.map +1 -0
  155. package/dist/src/provider.d.ts +7 -1
  156. package/dist/src/provider.d.ts.map +1 -1
  157. package/dist/src/provider.js +4 -1
  158. package/dist/src/provider.js.map +1 -1
  159. package/dist/src/stores/dropdownStore.d.ts +12 -0
  160. package/dist/src/stores/dropdownStore.d.ts.map +1 -0
  161. package/dist/src/stores/dropdownStore.js +13 -0
  162. package/dist/src/stores/dropdownStore.js.map +1 -0
  163. package/dist/src/utils/address.d.ts +1 -1
  164. package/dist/src/utils/address.d.ts.map +1 -1
  165. package/dist/src/utils/address.js +2 -0
  166. package/dist/src/utils/address.js.map +1 -1
  167. package/dist/src/utils/address.test.js +8 -5
  168. package/dist/src/utils/address.test.js.map +1 -1
  169. package/dist/src/utils/assets.d.ts +145 -0
  170. package/dist/src/utils/assets.d.ts.map +1 -0
  171. package/dist/src/utils/assets.js +100 -0
  172. package/dist/src/utils/assets.js.map +1 -0
  173. package/dist/src/utils/assets.test.d.ts +2 -0
  174. package/dist/src/utils/assets.test.d.ts.map +1 -0
  175. package/dist/src/utils/assets.test.js +46 -0
  176. package/dist/src/utils/assets.test.js.map +1 -0
  177. package/dist/src/utils/currency.d.ts +13 -2
  178. package/dist/src/utils/currency.d.ts.map +1 -1
  179. package/dist/src/utils/currency.js +22 -8
  180. package/dist/src/utils/currency.js.map +1 -1
  181. package/dist/src/utils/currency.test.js +44 -1
  182. package/dist/src/utils/currency.test.js.map +1 -1
  183. package/dist/src/utils/mezoId.d.ts +7 -0
  184. package/dist/src/utils/mezoId.d.ts.map +1 -0
  185. package/dist/src/utils/mezoId.js +41 -0
  186. package/dist/src/utils/mezoId.js.map +1 -0
  187. package/dist/src/utils/numbers.d.ts +15 -33
  188. package/dist/src/utils/numbers.d.ts.map +1 -1
  189. package/dist/src/utils/numbers.js +26 -70
  190. package/dist/src/utils/numbers.js.map +1 -1
  191. package/dist/src/utils/numbers.test.js +46 -42
  192. package/dist/src/utils/numbers.test.js.map +1 -1
  193. package/dist/src/utils/siww.d.ts +1 -0
  194. package/dist/src/utils/siww.d.ts.map +1 -1
  195. package/dist/src/utils/siww.js +50 -12
  196. package/dist/src/utils/siww.js.map +1 -1
  197. package/dist/src/utils/wagmi.d.ts +3 -0
  198. package/dist/src/utils/wagmi.d.ts.map +1 -0
  199. package/dist/src/utils/wagmi.js +7 -0
  200. package/dist/src/utils/wagmi.js.map +1 -0
  201. package/dist/src/wallet/index.d.ts +1 -1
  202. package/dist/src/wallet/index.d.ts.map +1 -1
  203. package/dist/src/wallet/index.js +1 -1
  204. package/dist/src/wallet/index.js.map +1 -1
  205. package/package.json +11 -8
  206. package/src/api/auth.ts +8 -4
  207. package/src/api/client.ts +11 -2
  208. package/src/api/portal.ts +11 -14
  209. package/src/components/Dropdown/ConnectedTrigger.tsx +52 -32
  210. package/src/components/Dropdown/Content.tsx +26 -121
  211. package/src/components/Dropdown/DisconnectedTrigger.tsx +2 -1
  212. package/src/components/Dropdown/Dropdown.tsx +29 -17
  213. package/src/components/Dropdown/ListingItem.tsx +176 -0
  214. package/src/components/Dropdown/NestedViewLayout.tsx +87 -0
  215. package/src/components/Dropdown/README.md +10 -18
  216. package/src/components/Dropdown/Receive/Receive.tsx +144 -0
  217. package/src/components/Dropdown/Root/AccountAddressActions.tsx +99 -0
  218. package/src/components/Dropdown/Root/AccountBalance.tsx +68 -0
  219. package/src/components/Dropdown/Root/AccountBtcListing.tsx +52 -0
  220. package/src/components/Dropdown/Root/AccountError.tsx +34 -0
  221. package/src/components/Dropdown/Root/AccountMusdListing.tsx +45 -0
  222. package/src/components/Dropdown/Root/AccountOtherAssets.tsx +85 -0
  223. package/src/components/Dropdown/Root/Root.tsx +77 -0
  224. package/src/components/Dropdown/Root/WalletAddress.tsx +123 -0
  225. package/src/components/Dropdown/Root/WelcomeBlock.tsx +173 -0
  226. package/src/components/Dropdown/SlotNumber.tsx +131 -0
  227. package/src/components/Dropdown/TestnetTopBanner.tsx +32 -0
  228. package/src/config.ts +88 -20
  229. package/src/constants.ts +12 -4
  230. package/src/hooks/index.ts +7 -0
  231. package/src/hooks/useAssetsConversionRates.ts +79 -0
  232. package/src/hooks/useAuthenticateWithWallet.ts +30 -14
  233. package/src/hooks/useBorrowData.ts +246 -0
  234. package/src/hooks/useCreateAccount.ts +29 -2
  235. package/src/hooks/useGetCurrentAccount.ts +5 -7
  236. package/src/hooks/useLinkAccount.ts +37 -4
  237. package/src/hooks/useRefreshPassport.ts +56 -0
  238. package/src/hooks/useSignInWithWallet.ts +2 -2
  239. package/src/hooks/useSignUpWithWallet.ts +2 -2
  240. package/src/hooks/useTokensBalances.ts +265 -0
  241. package/src/hooks/useValidateMezoId.ts +31 -0
  242. package/src/hooks/useWalletAccount.ts +32 -20
  243. package/src/hooks/useWatchTransferEvents.ts +74 -0
  244. package/src/index.ts +12 -1
  245. package/src/lib/contracts/index.ts +99 -0
  246. package/src/lib/contracts/priceOracle.ts +53 -0
  247. package/src/provider.ts +11 -3
  248. package/src/stores/dropdownStore.ts +20 -0
  249. package/src/utils/address.test.ts +10 -6
  250. package/src/utils/address.ts +5 -3
  251. package/src/utils/assets.test.ts +57 -0
  252. package/src/utils/assets.ts +103 -0
  253. package/src/utils/currency.test.ts +77 -1
  254. package/src/utils/currency.ts +35 -9
  255. package/src/utils/mezoId.ts +51 -0
  256. package/src/utils/numbers.test.ts +49 -42
  257. package/src/utils/numbers.ts +33 -95
  258. package/src/utils/siww.ts +71 -16
  259. package/src/utils/wagmi.ts +12 -0
  260. package/src/wallet/index.ts +3 -2
  261. package/dist/src/components/Dropdown/AccountAddress.d.ts +0 -8
  262. package/dist/src/components/Dropdown/AccountAddress.d.ts.map +0 -1
  263. package/dist/src/components/Dropdown/AccountAddress.js +0 -58
  264. package/dist/src/components/Dropdown/AccountAddress.js.map +0 -1
  265. package/dist/src/components/Dropdown/AccountAssets.d.ts +0 -14
  266. package/dist/src/components/Dropdown/AccountAssets.d.ts.map +0 -1
  267. package/dist/src/components/Dropdown/AccountAssets.js +0 -44
  268. package/dist/src/components/Dropdown/AccountAssets.js.map +0 -1
  269. package/dist/src/components/Dropdown/AccountBalance.d.ts +0 -7
  270. package/dist/src/components/Dropdown/AccountBalance.d.ts.map +0 -1
  271. package/dist/src/components/Dropdown/AccountBalance.js +0 -18
  272. package/dist/src/components/Dropdown/AccountBalance.js.map +0 -1
  273. package/dist/src/components/Dropdown/WelcomeBlock.d.ts +0 -8
  274. package/dist/src/components/Dropdown/WelcomeBlock.d.ts.map +0 -1
  275. package/dist/src/components/Dropdown/WelcomeBlock.js +0 -44
  276. package/dist/src/components/Dropdown/WelcomeBlock.js.map +0 -1
  277. package/dist/src/hooks/useAssetsUSDConversion.d.ts +0 -8
  278. package/dist/src/hooks/useAssetsUSDConversion.d.ts.map +0 -1
  279. package/dist/src/hooks/useAssetsUSDConversion.js +0 -21
  280. package/dist/src/hooks/useAssetsUSDConversion.js.map +0 -1
  281. package/dist/src/hooks/useDropdownData.d.ts +0 -44
  282. package/dist/src/hooks/useDropdownData.d.ts.map +0 -1
  283. package/dist/src/hooks/useDropdownData.js +0 -73
  284. package/dist/src/hooks/useDropdownData.js.map +0 -1
  285. package/dist/src/utils/cryptoAssets.d.ts +0 -28
  286. package/dist/src/utils/cryptoAssets.d.ts.map +0 -1
  287. package/dist/src/utils/cryptoAssets.js +0 -73
  288. package/dist/src/utils/cryptoAssets.js.map +0 -1
  289. package/dist/src/utils/cryptoAssets.test.d.ts +0 -2
  290. package/dist/src/utils/cryptoAssets.test.d.ts.map +0 -1
  291. package/dist/src/utils/cryptoAssets.test.js +0 -49
  292. package/dist/src/utils/cryptoAssets.test.js.map +0 -1
  293. package/src/components/Dropdown/AccountAddress.tsx +0 -111
  294. package/src/components/Dropdown/AccountAssets.tsx +0 -110
  295. package/src/components/Dropdown/AccountBalance.tsx +0 -38
  296. package/src/components/Dropdown/WelcomeBlock.tsx +0 -92
  297. package/src/hooks/useAssetsUSDConversion.ts +0 -31
  298. package/src/hooks/useDropdownData.ts +0 -130
  299. package/src/utils/cryptoAssets.test.ts +0 -59
  300. package/src/utils/cryptoAssets.ts +0 -93
@@ -0,0 +1,79 @@
1
+ import { useQuery } from "@tanstack/react-query"
2
+ import { useConfig } from "wagmi"
3
+ import { readContract } from "wagmi/actions"
4
+ import { parseUnits } from "viem"
5
+ import { ONE_SECOND_MS } from "../utils/time"
6
+ import { usePortalApiClient } from "./usePortalApiClient"
7
+ import { priceOracleContract } from "../lib/contracts"
8
+ import { CHAIN_ID } from "../constants"
9
+ import { usePassportContext } from "./usePassportContext"
10
+ import { normalizePrecision } from "../utils/numbers"
11
+
12
+ export const CONVERSION_RATE_DECIMALS = 18
13
+
14
+ // If the oracle has not been updated in at least 60 seconds, it is stale.
15
+ const MAX_PRICE_DELAY = 60 * ONE_SECOND_MS
16
+
17
+ export const QUERY_KEY = "passport.assetsConversionRates"
18
+
19
+ /**
20
+ * Hook to fetch assets conversion rates.
21
+ * @see https://github.com/mezo-org/musd/blob/f0b2030315f0d8b0fc11a9fc778856fe4673051f/solidity/contracts/PriceFeed.sol
22
+ * @returns {}.data.{}.price - The latest asset price.
23
+ * @returns {}.data.{}.digits - The latest asset price digits.
24
+ * @returns {}.isPending - Whether the request is pending.
25
+ * @returns {}.isError - Whether there was an error fetching the price.
26
+ */
27
+ export function useAssetsConversionRates() {
28
+ const portalApiClient = usePortalApiClient()
29
+ const { environment = "mainnet" } = usePassportContext()
30
+ const config = useConfig()
31
+
32
+ return useQuery({
33
+ queryKey: [QUERY_KEY],
34
+ queryFn: async () =>
35
+ Promise.all([
36
+ portalApiClient.getPortalStatistics(),
37
+ readContract(config, {
38
+ ...priceOracleContract,
39
+ functionName: "latestRoundData",
40
+ chainId: CHAIN_ID[environment],
41
+ }),
42
+ ]),
43
+ select: ([portalStatistics, btcPriceData]) => {
44
+ const tTokenConversionRate = portalStatistics.currentUsdPerTToken
45
+ const [, btcConversionRate] = btcPriceData
46
+
47
+ const tPrice = parseUnits(tTokenConversionRate, CONVERSION_RATE_DECIMALS)
48
+ const btcPrice = normalizePrecision(
49
+ btcConversionRate,
50
+ CONVERSION_RATE_DECIMALS,
51
+ )
52
+
53
+ return {
54
+ rates: {
55
+ mT: tPrice,
56
+ BTC: btcPrice,
57
+ },
58
+ decimals: CONVERSION_RATE_DECIMALS,
59
+ }
60
+ },
61
+ refetchInterval: ({ state }) => {
62
+ if (!state.data) return MAX_PRICE_DELAY
63
+
64
+ const [, btcPriceData] = state.data
65
+ const [, , , updatedAt] = btcPriceData
66
+
67
+ if (!updatedAt) return MAX_PRICE_DELAY
68
+
69
+ const age = Date.now() - Number(updatedAt) * 1000
70
+
71
+ return age > MAX_PRICE_DELAY
72
+ ? // If the data is stale, we want to refetch as soon as possible, but
73
+ // not faster than once per second, to avoid excessive requests.
74
+ // Math.max ensures the interval is at least 1 second.
75
+ Math.max(ONE_SECOND_MS, MAX_PRICE_DELAY - age)
76
+ : MAX_PRICE_DELAY - age
77
+ },
78
+ })
79
+ }
@@ -1,9 +1,16 @@
1
1
  import { useSignMessage } from "wagmi"
2
- import { MutationOptions, useMutation } from "@tanstack/react-query"
2
+ import {
3
+ DefaultError,
4
+ MutationOptions,
5
+ useMutation,
6
+ } from "@tanstack/react-query"
3
7
  import { useCreateAccount } from "./useCreateAccount"
4
8
  import { useCreateSession } from "./useCreateSession"
5
9
  import { useEnsureNoSessionAndFetchNonce } from "./useEnsureNoSessionAndFetchNonce"
6
- import { createSignInWithWalletMessage } from "../utils/siww"
10
+ import {
11
+ createSignInWithWalletMessage,
12
+ verifyDomainInSignInWithWalletMessage,
13
+ } from "../utils/siww"
7
14
  import { useGetAccountByAddress } from "./useGetAccountByAddress"
8
15
  import type { Session } from "../api"
9
16
  import useWalletAccount from "./useWalletAccount"
@@ -11,40 +18,49 @@ import useWalletAccount from "./useWalletAccount"
11
18
  function useAuthenticateWithWallet(
12
19
  shouldCreateAccount = false,
13
20
  mutationOptions: Omit<
14
- MutationOptions<Session>,
21
+ MutationOptions<Session, DefaultError, number | void>,
15
22
  "mutationFn" | "mutationKey"
16
23
  > = {},
17
24
  ) {
18
- const { address, chainId, connector, networkFamily } = useWalletAccount()
25
+ const walletAccount = useWalletAccount()
19
26
  const { ensureNoSessionAndFetchNonce } = useEnsureNoSessionAndFetchNonce()
20
27
  const { createSessionAsync } = useCreateSession()
21
28
  const { createAccountAsync } = useCreateAccount()
22
29
  const { signMessageAsync } = useSignMessage()
23
30
 
24
- const { refetch: getAccountByAddress } = useGetAccountByAddress(address, {
25
- enabled: false,
26
- retry: false,
27
- })
31
+ const { refetch: getAccountByAddress } = useGetAccountByAddress(
32
+ walletAccount.walletAddress,
33
+ {
34
+ enabled: false,
35
+ retry: false,
36
+ },
37
+ )
28
38
 
29
39
  const { mutate, mutateAsync, ...signInMutationRestParameters } = useMutation({
30
- mutationFn: async () => {
31
- if (!address) {
40
+ mutationFn: async (chainId?: number | void) => {
41
+ if (!walletAccount.walletAddress) {
32
42
  throw new Error("Sign in error: Wallet not connected!")
33
43
  }
34
44
 
35
45
  const nonce = await ensureNoSessionAndFetchNonce()
36
46
 
37
47
  const messageResult = createSignInWithWalletMessage(
38
- address,
48
+ walletAccount.walletAddress,
39
49
  nonce,
40
- networkFamily,
41
- chainId,
50
+ walletAccount.networkFamily!,
51
+ chainId ?? walletAccount.chainId,
42
52
  )
43
53
  const signatureResult = await signMessageAsync({
44
54
  message: messageResult,
45
- connector,
55
+ connector: walletAccount.connector,
46
56
  })
47
57
 
58
+ await verifyDomainInSignInWithWalletMessage(
59
+ messageResult,
60
+ signatureResult,
61
+ nonce,
62
+ )
63
+
48
64
  if (shouldCreateAccount) {
49
65
  const getAccountByAddressResult = await getAccountByAddress()
50
66
 
@@ -0,0 +1,246 @@
1
+ import { useReadContracts } from "wagmi"
2
+ import { useCallback, useMemo } from "react"
3
+ import { useQueryClient } from "@tanstack/react-query"
4
+ import { formatUnits } from "viem"
5
+ import { ONE_MINUTE_MS } from "../utils/time"
6
+ import {
7
+ mainnetBorrowContracts,
8
+ testnetBorrowContracts,
9
+ } from "../lib/contracts"
10
+ import { usePassportContext } from "./usePassportContext"
11
+ import { CHAIN_ID } from "../constants"
12
+ import { bigIntMax, normalizePrecision } from "../utils/numbers"
13
+ import useWalletAccount from "./useWalletAccount"
14
+ import { getAsset } from "../utils/assets"
15
+ import { convertToUsd } from "../utils/currency"
16
+
17
+ const DEBT_AND_COLL_PRECISION = 18
18
+
19
+ // Wagmi handles typesafety with ABI const assertions. TypeScript doesn't
20
+ // support importing JSON as const yet so types cannot be inferred from the
21
+ // imported contract. As a workaround there is minimal ABI definition that can
22
+ // be asserted types from.
23
+ // Ref: https://wagmi.sh/core/typescript#const-assert-abis-typed-data
24
+
25
+ const TROVE_MANAGER_ABI = [
26
+ {
27
+ inputs: [
28
+ {
29
+ internalType: "address",
30
+ name: "_borrower",
31
+ type: "address",
32
+ },
33
+ ],
34
+ name: "getEntireDebtAndColl",
35
+ outputs: [
36
+ {
37
+ internalType: "uint256",
38
+ name: "coll",
39
+ type: "uint256",
40
+ },
41
+ {
42
+ internalType: "uint256",
43
+ name: "principal",
44
+ type: "uint256",
45
+ },
46
+ {
47
+ internalType: "uint256",
48
+ name: "interest",
49
+ type: "uint256",
50
+ },
51
+ {
52
+ internalType: "uint256",
53
+ name: "pendingCollateral",
54
+ type: "uint256",
55
+ },
56
+ {
57
+ internalType: "uint256",
58
+ name: "pendingPrincipal",
59
+ type: "uint256",
60
+ },
61
+ {
62
+ internalType: "uint256",
63
+ name: "pendingInterest",
64
+ type: "uint256",
65
+ },
66
+ ],
67
+ stateMutability: "view",
68
+ type: "function",
69
+ },
70
+ ] as const
71
+
72
+ const BORROWER_OPERATIONS_ABI = [
73
+ {
74
+ inputs: [],
75
+ name: "MUSD_GAS_COMPENSATION",
76
+ outputs: [
77
+ {
78
+ internalType: "uint256",
79
+ name: "",
80
+ type: "uint256",
81
+ },
82
+ ],
83
+ stateMutability: "view",
84
+ type: "function",
85
+ },
86
+ ] as const
87
+
88
+ const PRICE_FEED_ABI = [
89
+ {
90
+ inputs: [],
91
+ name: "fetchPrice",
92
+ outputs: [
93
+ {
94
+ internalType: "uint256",
95
+ name: "",
96
+ type: "uint256",
97
+ },
98
+ ],
99
+ stateMutability: "view",
100
+ type: "function",
101
+ },
102
+ ] as const
103
+
104
+ /**
105
+ * Query hook for getting borrow data. Returns collateral and trove debt for the
106
+ * connected account, based on it's evm address.
107
+ * @param queryOptions Query options passed to the underlying `useQuery` hook.
108
+ */
109
+ export function useBorrowData(queryOptions = {}) {
110
+ const { environment = "mainnet" } = usePassportContext()
111
+ const walletAccount = useWalletAccount()
112
+
113
+ const contractAddress = useMemo(() => {
114
+ if (environment === "mainnet") {
115
+ return {
116
+ troveManager: mainnetBorrowContracts.TroveManager.address,
117
+ borrowerOperations: mainnetBorrowContracts.BorrowerOperations.address,
118
+ priceFeed: mainnetBorrowContracts.PriceFeed.address,
119
+ }
120
+ }
121
+ return {
122
+ troveManager: testnetBorrowContracts.TroveManager.address,
123
+ borrowerOperations: testnetBorrowContracts.BorrowerOperations.address,
124
+ priceFeed: testnetBorrowContracts.PriceFeed.address,
125
+ }
126
+ }, [environment])
127
+
128
+ const chainId = CHAIN_ID[environment]
129
+
130
+ return useReadContracts({
131
+ contracts: [
132
+ {
133
+ abi: TROVE_MANAGER_ABI,
134
+ address: contractAddress.troveManager,
135
+ functionName: "getEntireDebtAndColl",
136
+ args: walletAccount.accountAddress
137
+ ? [walletAccount.accountAddress]
138
+ : ["0x" as `0x${string}}`],
139
+ chainId,
140
+ },
141
+ {
142
+ abi: BORROWER_OPERATIONS_ABI,
143
+ address: contractAddress.borrowerOperations,
144
+ functionName: "MUSD_GAS_COMPENSATION",
145
+ chainId,
146
+ },
147
+ {
148
+ abi: PRICE_FEED_ABI,
149
+ address: contractAddress.priceFeed,
150
+ functionName: "fetchPrice",
151
+ chainId,
152
+ },
153
+ ],
154
+ query: {
155
+ enabled: !!walletAccount.accountAddress,
156
+ staleTime: 5 * ONE_MINUTE_MS,
157
+ retry: 1,
158
+ select: (data) => {
159
+ if (!data || data.some((item) => !item.result))
160
+ throw new Error("No borrow data available")
161
+
162
+ const [rawCollateral, principal, interest] = data[0].result!
163
+ const gasCompensation = data[1].result!
164
+ const collateralPrice = data[2].result!
165
+
166
+ const btcDetails = getAsset("BTC")
167
+
168
+ const collateral = {
169
+ value: rawCollateral,
170
+ decimals: btcDetails.decimals,
171
+ symbol: btcDetails.symbol,
172
+ formatted: formatUnits(rawCollateral, DEBT_AND_COLL_PRECISION),
173
+ usd: convertToUsd(
174
+ rawCollateral,
175
+ DEBT_AND_COLL_PRECISION,
176
+ collateralPrice,
177
+ DEBT_AND_COLL_PRECISION,
178
+ ),
179
+ }
180
+
181
+ const debtInUsdValue = bigIntMax(
182
+ normalizePrecision(
183
+ principal + interest - gasCompensation,
184
+ DEBT_AND_COLL_PRECISION,
185
+ ),
186
+ 0n, // Ensure that debt is not negative
187
+ )
188
+ const formattedDebtInUsd = formatUnits(
189
+ debtInUsdValue,
190
+ DEBT_AND_COLL_PRECISION,
191
+ )
192
+
193
+ const debtInUsd = {
194
+ value: debtInUsdValue,
195
+ formatted: formattedDebtInUsd,
196
+ }
197
+
198
+ return {
199
+ collateral,
200
+ debtInUsd,
201
+ }
202
+ },
203
+ ...queryOptions,
204
+ },
205
+ })
206
+ }
207
+
208
+ /**
209
+ * Hook for for invalidating current user's borrow data. Can be used to
210
+ * invalidate borrow data manually, which forces the data to be re-fetched.
211
+ * @returns Function `invalidateBorrowData` for invalidating the borrow data
212
+ */
213
+ export function useInvalidateBorrowData() {
214
+ const queryClient = useQueryClient()
215
+
216
+ const { queryKey } = useBorrowData()
217
+
218
+ const invalidateBorrowDataHandler = useCallback(
219
+ () => queryClient.invalidateQueries({ queryKey }),
220
+ [queryClient, queryKey],
221
+ )
222
+
223
+ return {
224
+ invalidateBorrowData: invalidateBorrowDataHandler,
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Hook for for resetting current user's borrow data. Can be used to reset
230
+ * borrow data manually, which forces the data to be re-fetched.
231
+ * @returns Function `resetBorrowData` for resetting the borrow data
232
+ */
233
+ export function useResetBorrowData() {
234
+ const queryClient = useQueryClient()
235
+
236
+ const { queryKey } = useBorrowData()
237
+
238
+ const resetBorrowDataHandler = useCallback(
239
+ () => queryClient.resetQueries({ queryKey }),
240
+ [queryClient, queryKey],
241
+ )
242
+
243
+ return {
244
+ resetBorrowData: resetBorrowDataHandler,
245
+ }
246
+ }
@@ -7,6 +7,8 @@ import {
7
7
  import { useAuthApiClient } from "./useAuthApiClient"
8
8
  import { QUERY_KEYS } from "./constants"
9
9
  import type { CreateAccountRequest, CreateAccountResponse } from "../api"
10
+ import useWalletAccount from "./useWalletAccount"
11
+ import { getBitcoinPublicKeyFromConnector } from "../utils/wagmi"
10
12
 
11
13
  export function useCreateAccount(
12
14
  mutationOptions: Omit<
@@ -16,12 +18,37 @@ export function useCreateAccount(
16
18
  ) {
17
19
  const queryClient = useQueryClient()
18
20
  const authApiClient = useAuthApiClient()
21
+ const walletAccount = useWalletAccount()
19
22
 
20
23
  const { onSuccess: customOnSuccess, ...restMutationOptions } = mutationOptions
21
24
 
22
25
  const { mutate, mutateAsync, ...rest } = useMutation({
23
- mutationFn: (createAccountRequest: CreateAccountRequest) =>
24
- authApiClient.createAccount(createAccountRequest),
26
+ mutationFn: async (
27
+ createAccountMutationFnParameters: CreateAccountRequest,
28
+ ) => {
29
+ if (createAccountMutationFnParameters.type === "wallet") {
30
+ if (!walletAccount?.connector) {
31
+ throw new Error("Connector not defined.")
32
+ }
33
+
34
+ const bitcoinPublicKey = await getBitcoinPublicKeyFromConnector(
35
+ walletAccount.connector,
36
+ )
37
+
38
+ // Creating bitcoin mezo account
39
+ if (bitcoinPublicKey) {
40
+ return authApiClient.createAccount({
41
+ ...createAccountMutationFnParameters,
42
+ bitcoinPublicKey,
43
+ })
44
+ }
45
+ }
46
+
47
+ // Creating evm mezo account
48
+ return authApiClient.createAccount({
49
+ ...createAccountMutationFnParameters,
50
+ })
51
+ },
25
52
  onSuccess: (data, variables, context) => {
26
53
  queryClient.resetQueries({
27
54
  queryKey: [QUERY_KEYS.ACCOUNT],
@@ -24,16 +24,15 @@ export function useGetCurrentAccount(
24
24
  queryKey: [QUERY_KEYS.ACCOUNT, QUERY_KEYS.CURRENT],
25
25
  queryFn: async () => {
26
26
  const currentAccount = await authApiClient.getCurrentAccount()
27
+ if (!currentAccount) {
28
+ throw new Error("No current account found")
29
+ }
30
+
27
31
  const linkedWallets = currentAccount?.linkedAccounts?.filter(
28
32
  (account) => account.type === "wallet",
29
33
  )
30
34
  if (!linkedWallets || linkedWallets.length === 0) {
31
- return {
32
- ...currentAccount,
33
- mats: {
34
- totalMats: 0,
35
- },
36
- }
35
+ throw new Error("No linked wallets found for the current account")
37
36
  }
38
37
 
39
38
  const addresses = linkedWallets.map(
@@ -42,7 +41,6 @@ export function useGetCurrentAccount(
42
41
  const mats = await Promise.all(
43
42
  addresses.map((address) => portalApiClient.getPortalMats(address)),
44
43
  )
45
-
46
44
  const totalMats = mats.reduce(
47
45
  (sumMats, currentMats) => sumMats + currentMats.totalMats,
48
46
  0,
@@ -5,23 +5,56 @@ import {
5
5
  DefaultError,
6
6
  } from "@tanstack/react-query"
7
7
  import { useAuthApiClient } from "./useAuthApiClient"
8
- import type { LinkAccountRequest, LinkAccountResponse } from "../api"
8
+ import type { LinkAccountResponse, SignatureData } from "../api"
9
9
  import { QUERY_KEYS } from "./constants"
10
+ import useWalletAccount from "./useWalletAccount"
11
+ import { getBitcoinPublicKeyFromConnector } from "../utils/wagmi"
12
+
13
+ type LinkAccountMutationFnParameters =
14
+ | ({ type: "wallet" } & SignatureData)
15
+ | { type: "discord" }
10
16
 
11
17
  export function useLinkAccount(
12
18
  mutationOptions: Omit<
13
- MutationOptions<LinkAccountResponse, DefaultError, LinkAccountRequest>,
19
+ MutationOptions<
20
+ LinkAccountResponse,
21
+ DefaultError,
22
+ LinkAccountMutationFnParameters
23
+ >,
14
24
  "mutationFn" | "mutationKey"
15
25
  > = {},
16
26
  ) {
17
27
  const queryClient = useQueryClient()
18
28
  const authApiClient = useAuthApiClient()
29
+ const walletAccount = useWalletAccount()
19
30
 
20
31
  const { onSuccess: customOnSuccess, ...restMutationOptions } = mutationOptions
21
32
 
22
33
  const { mutate, mutateAsync, ...rest } = useMutation({
23
- mutationFn: (linkAccountRequest: LinkAccountRequest) =>
24
- authApiClient.linkAccount(linkAccountRequest),
34
+ mutationFn: async (
35
+ linkAccountMutationFnParameters: LinkAccountMutationFnParameters,
36
+ ) => {
37
+ if (linkAccountMutationFnParameters.type === "wallet") {
38
+ if (!walletAccount?.connector) {
39
+ throw new Error("Connector not defined.")
40
+ }
41
+
42
+ const bitcoinPublicKey = await getBitcoinPublicKeyFromConnector(
43
+ walletAccount.connector,
44
+ )
45
+
46
+ // Linking bitcoin account
47
+ if (bitcoinPublicKey) {
48
+ return authApiClient.linkAccount({
49
+ ...linkAccountMutationFnParameters,
50
+ bitcoinPublicKey,
51
+ })
52
+ }
53
+ }
54
+
55
+ // Linking any other account like wallet evm address account or discord
56
+ return authApiClient.linkAccount(linkAccountMutationFnParameters)
57
+ },
25
58
  onSuccess: (data, variables, context) => {
26
59
  queryClient.resetQueries({ queryKey: [QUERY_KEYS.ACCOUNT] })
27
60
  if (customOnSuccess) customOnSuccess(data, variables, context)
@@ -0,0 +1,56 @@
1
+ import { useQueryClient } from "@tanstack/react-query"
2
+ import { useCallback } from "react"
3
+ import { useAccount, useBalance } from "wagmi"
4
+ import { QUERY_KEYS } from "./constants"
5
+ import { useInvalidateBorrowData } from "./useBorrowData"
6
+ import { useInvalidateTokensBalances } from "./useTokensBalances"
7
+
8
+ /**
9
+ * Hook to refresh the passport using query invalidation mechanism.
10
+ * By calling the refresh function, the latest data will be refetched as soon as possible.
11
+ *
12
+ * @example
13
+ * const { refreshCurrentAccount, refreshUsdConversion } = useRefreshPassport()
14
+ *
15
+ * // Call this function to refresh the current account
16
+ * const handlerefreshCurrentAccount = async () => {
17
+ * await refreshCurrentAccount()
18
+ * }
19
+ */
20
+ export function useRefreshPassport() {
21
+ const { address } = useAccount()
22
+ const queryClient = useQueryClient()
23
+ const { invalidateBorrowData } = useInvalidateBorrowData()
24
+ const { invalidateTokensBalances } = useInvalidateTokensBalances()
25
+ const { queryKey: nativeTokenQueryKey } = useBalance({ address })
26
+
27
+ const refreshCurrentAccount = useCallback(
28
+ () =>
29
+ queryClient.invalidateQueries({
30
+ queryKey: [QUERY_KEYS.ACCOUNT, QUERY_KEYS.CURRENT],
31
+ }),
32
+ [queryClient],
33
+ )
34
+
35
+ const refreshUsdConversion = useCallback(
36
+ () =>
37
+ queryClient.invalidateQueries({
38
+ queryKey: [QUERY_KEYS.ASSETS_USD_CONVERSION],
39
+ }),
40
+ [queryClient],
41
+ )
42
+
43
+ const refreshTokensBalances = useCallback(async () => {
44
+ await queryClient.invalidateQueries({
45
+ queryKey: nativeTokenQueryKey,
46
+ })
47
+ await invalidateTokensBalances()
48
+ }, [queryClient, nativeTokenQueryKey, invalidateTokensBalances])
49
+
50
+ return {
51
+ refreshCurrentAccount,
52
+ refreshUsdConversion,
53
+ refreshBorrowData: invalidateBorrowData,
54
+ refreshTokensBalances,
55
+ }
56
+ }
@@ -1,10 +1,10 @@
1
- import { MutationOptions } from "@tanstack/react-query"
1
+ import { DefaultError, MutationOptions } from "@tanstack/react-query"
2
2
  import { useAuthenticateWithWallet } from "./useAuthenticateWithWallet"
3
3
  import type { Session } from "../api"
4
4
 
5
5
  function useSignInWithWallet(
6
6
  mutationOptions: Omit<
7
- MutationOptions<Session>,
7
+ MutationOptions<Session, DefaultError, number | void>,
8
8
  "mutationFn" | "mutationKey"
9
9
  > = {},
10
10
  ) {
@@ -1,10 +1,10 @@
1
- import { MutationOptions } from "@tanstack/react-query"
1
+ import { DefaultError, MutationOptions } from "@tanstack/react-query"
2
2
  import { useAuthenticateWithWallet } from "./useAuthenticateWithWallet"
3
3
  import type { Session } from "../api"
4
4
 
5
5
  function useSignUpWithWallet(
6
6
  mutationOptions: Omit<
7
- MutationOptions<Session>,
7
+ MutationOptions<Session, DefaultError, number | void>,
8
8
  "mutationFn" | "mutationKey"
9
9
  > = {},
10
10
  ) {