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

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 (263) hide show
  1. package/dist/src/api/auth.d.ts +57 -52
  2. package/dist/src/api/auth.d.ts.map +1 -1
  3. package/dist/src/api/auth.js +22 -53
  4. package/dist/src/api/auth.js.map +1 -1
  5. package/dist/src/api/client.d.ts +24 -0
  6. package/dist/src/api/client.d.ts.map +1 -0
  7. package/dist/src/api/client.js +54 -0
  8. package/dist/src/api/client.js.map +1 -0
  9. package/dist/src/api/fetch-error.d.ts +5 -0
  10. package/dist/src/api/fetch-error.d.ts.map +1 -0
  11. package/dist/src/api/fetch-error.js +8 -0
  12. package/dist/src/api/fetch-error.js.map +1 -0
  13. package/dist/src/api/index.d.ts +3 -0
  14. package/dist/src/api/index.d.ts.map +1 -0
  15. package/dist/src/api/index.js +3 -0
  16. package/dist/src/api/index.js.map +1 -0
  17. package/dist/src/api/portal.d.ts +32 -0
  18. package/dist/src/api/portal.d.ts.map +1 -0
  19. package/dist/src/api/portal.js +23 -0
  20. package/dist/src/api/portal.js.map +1 -0
  21. package/dist/src/assets/DefaultAvatar.d.ts +5 -0
  22. package/dist/src/assets/DefaultAvatar.d.ts.map +1 -0
  23. package/dist/src/assets/DefaultAvatar.js +21 -0
  24. package/dist/src/assets/DefaultAvatar.js.map +1 -0
  25. package/dist/src/components/Dropdown/ConnectedTrigger.d.ts +8 -0
  26. package/dist/src/components/Dropdown/ConnectedTrigger.d.ts.map +1 -0
  27. package/dist/src/components/Dropdown/ConnectedTrigger.js +39 -0
  28. package/dist/src/components/Dropdown/ConnectedTrigger.js.map +1 -0
  29. package/dist/src/components/Dropdown/Content.d.ts +9 -0
  30. package/dist/src/components/Dropdown/Content.d.ts.map +1 -0
  31. package/dist/src/components/Dropdown/Content.js +25 -0
  32. package/dist/src/components/Dropdown/Content.js.map +1 -0
  33. package/dist/src/components/Dropdown/DisconnectedTrigger.d.ts +7 -0
  34. package/dist/src/components/Dropdown/DisconnectedTrigger.d.ts.map +1 -0
  35. package/dist/src/components/Dropdown/DisconnectedTrigger.js +13 -0
  36. package/dist/src/components/Dropdown/DisconnectedTrigger.js.map +1 -0
  37. package/dist/src/components/Dropdown/Dropdown.d.ts +27 -0
  38. package/dist/src/components/Dropdown/Dropdown.d.ts.map +1 -0
  39. package/dist/src/components/Dropdown/Dropdown.js +64 -0
  40. package/dist/src/components/Dropdown/Dropdown.js.map +1 -0
  41. package/dist/src/components/Dropdown/NestedViewLayout.d.ts +7 -0
  42. package/dist/src/components/Dropdown/NestedViewLayout.d.ts.map +1 -0
  43. package/dist/src/components/Dropdown/NestedViewLayout.js +34 -0
  44. package/dist/src/components/Dropdown/NestedViewLayout.js.map +1 -0
  45. package/dist/src/components/Dropdown/Receive/Receive.d.ts +7 -0
  46. package/dist/src/components/Dropdown/Receive/Receive.d.ts.map +1 -0
  47. package/dist/src/components/Dropdown/Receive/Receive.js +53 -0
  48. package/dist/src/components/Dropdown/Receive/Receive.js.map +1 -0
  49. package/dist/src/components/Dropdown/Root/AccountAddressActions.d.ts +7 -0
  50. package/dist/src/components/Dropdown/Root/AccountAddressActions.d.ts.map +1 -0
  51. package/dist/src/components/Dropdown/Root/AccountAddressActions.js +48 -0
  52. package/dist/src/components/Dropdown/Root/AccountAddressActions.js.map +1 -0
  53. package/dist/src/components/Dropdown/Root/AccountAssets.d.ts +13 -0
  54. package/dist/src/components/Dropdown/Root/AccountAssets.d.ts.map +1 -0
  55. package/dist/src/components/Dropdown/Root/AccountAssets.js +43 -0
  56. package/dist/src/components/Dropdown/Root/AccountAssets.js.map +1 -0
  57. package/dist/src/components/Dropdown/Root/AccountBalance.d.ts +7 -0
  58. package/dist/src/components/Dropdown/Root/AccountBalance.d.ts.map +1 -0
  59. package/dist/src/components/Dropdown/Root/AccountBalance.js +16 -0
  60. package/dist/src/components/Dropdown/Root/AccountBalance.js.map +1 -0
  61. package/dist/src/components/Dropdown/Root/Root.d.ts +8 -0
  62. package/dist/src/components/Dropdown/Root/Root.d.ts.map +1 -0
  63. package/dist/src/components/Dropdown/Root/Root.js +64 -0
  64. package/dist/src/components/Dropdown/Root/Root.js.map +1 -0
  65. package/dist/src/components/Dropdown/Root/WalletAddress.d.ts +8 -0
  66. package/dist/src/components/Dropdown/Root/WalletAddress.d.ts.map +1 -0
  67. package/dist/src/components/Dropdown/Root/WalletAddress.js +65 -0
  68. package/dist/src/components/Dropdown/Root/WalletAddress.js.map +1 -0
  69. package/dist/src/components/Dropdown/Root/WelcomeBlock.d.ts +8 -0
  70. package/dist/src/components/Dropdown/Root/WelcomeBlock.d.ts.map +1 -0
  71. package/dist/src/components/Dropdown/Root/WelcomeBlock.js +43 -0
  72. package/dist/src/components/Dropdown/Root/WelcomeBlock.js.map +1 -0
  73. package/dist/src/components/Dropdown/index.d.ts +3 -0
  74. package/dist/src/components/Dropdown/index.d.ts.map +1 -0
  75. package/dist/src/components/Dropdown/index.js +2 -0
  76. package/dist/src/components/Dropdown/index.js.map +1 -0
  77. package/dist/src/components/index.d.ts +2 -0
  78. package/dist/src/components/index.d.ts.map +1 -0
  79. package/dist/src/components/index.js +2 -0
  80. package/dist/src/components/index.js.map +1 -0
  81. package/dist/src/hooks/constants.d.ts +3 -3
  82. package/dist/src/hooks/constants.js +4 -4
  83. package/dist/src/hooks/constants.js.map +1 -1
  84. package/dist/src/hooks/index.d.ts +2 -4
  85. package/dist/src/hooks/index.d.ts.map +1 -1
  86. package/dist/src/hooks/index.js +2 -4
  87. package/dist/src/hooks/index.js.map +1 -1
  88. package/dist/src/hooks/useAssetsUSDConversion.d.ts +8 -0
  89. package/dist/src/hooks/useAssetsUSDConversion.d.ts.map +1 -0
  90. package/dist/src/hooks/useAssetsUSDConversion.js +21 -0
  91. package/dist/src/hooks/useAssetsUSDConversion.js.map +1 -0
  92. package/dist/src/hooks/useAuthApiClient.d.ts +1 -1
  93. package/dist/src/hooks/useAuthApiClient.d.ts.map +1 -1
  94. package/dist/src/hooks/useAuthenticateWithWallet.d.ts +73 -0
  95. package/dist/src/hooks/useAuthenticateWithWallet.d.ts.map +1 -0
  96. package/dist/src/hooks/useAuthenticateWithWallet.js +69 -0
  97. package/dist/src/hooks/useAuthenticateWithWallet.js.map +1 -0
  98. package/dist/src/hooks/useCreateAccount.d.ts +41 -137
  99. package/dist/src/hooks/useCreateAccount.d.ts.map +1 -1
  100. package/dist/src/hooks/useCreateAccount.js +8 -10
  101. package/dist/src/hooks/useCreateAccount.js.map +1 -1
  102. package/dist/src/hooks/useCreateSession.d.ts +12 -182
  103. package/dist/src/hooks/useCreateSession.d.ts.map +1 -1
  104. package/dist/src/hooks/useCreateSession.js +12 -18
  105. package/dist/src/hooks/useCreateSession.js.map +1 -1
  106. package/dist/src/hooks/useDropdownData.d.ts +45 -0
  107. package/dist/src/hooks/useDropdownData.d.ts.map +1 -0
  108. package/dist/src/hooks/useDropdownData.js +80 -0
  109. package/dist/src/hooks/useDropdownData.js.map +1 -0
  110. package/dist/src/hooks/useEnsureNoSessionAndFetchNonce.d.ts +5 -0
  111. package/dist/src/hooks/useEnsureNoSessionAndFetchNonce.d.ts.map +1 -0
  112. package/dist/src/hooks/useEnsureNoSessionAndFetchNonce.js +34 -0
  113. package/dist/src/hooks/useEnsureNoSessionAndFetchNonce.js.map +1 -0
  114. package/dist/src/hooks/useGetAccountByAddress.d.ts +3 -5
  115. package/dist/src/hooks/useGetAccountByAddress.d.ts.map +1 -1
  116. package/dist/src/hooks/useGetAccountByAddress.js +3 -4
  117. package/dist/src/hooks/useGetAccountByAddress.js.map +1 -1
  118. package/dist/src/hooks/useGetAccountByMezoId.d.ts +3 -5
  119. package/dist/src/hooks/useGetAccountByMezoId.d.ts.map +1 -1
  120. package/dist/src/hooks/useGetAccountByMezoId.js +3 -4
  121. package/dist/src/hooks/useGetAccountByMezoId.js.map +1 -1
  122. package/dist/src/hooks/useGetCurrentAccount.d.ts +14 -8
  123. package/dist/src/hooks/useGetCurrentAccount.d.ts.map +1 -1
  124. package/dist/src/hooks/useGetCurrentAccount.js +28 -6
  125. package/dist/src/hooks/useGetCurrentAccount.js.map +1 -1
  126. package/dist/src/hooks/useGetSession.d.ts +3 -20
  127. package/dist/src/hooks/useGetSession.d.ts.map +1 -1
  128. package/dist/src/hooks/useGetSession.js +2 -2
  129. package/dist/src/hooks/useGetSession.js.map +1 -1
  130. package/dist/src/hooks/useLinkAccount.d.ts +15 -121
  131. package/dist/src/hooks/useLinkAccount.d.ts.map +1 -1
  132. package/dist/src/hooks/useLinkAccount.js +8 -21
  133. package/dist/src/hooks/useLinkAccount.js.map +1 -1
  134. package/dist/src/hooks/usePortalApiClient.d.ts +2 -0
  135. package/dist/src/hooks/usePortalApiClient.d.ts.map +1 -0
  136. package/dist/src/hooks/usePortalApiClient.js +6 -0
  137. package/dist/src/hooks/usePortalApiClient.js.map +1 -0
  138. package/dist/src/hooks/useRefreshPassport.d.ts +17 -0
  139. package/dist/src/hooks/useRefreshPassport.d.ts.map +1 -0
  140. package/dist/src/hooks/useRefreshPassport.js +29 -0
  141. package/dist/src/hooks/useRefreshPassport.js.map +1 -0
  142. package/dist/src/hooks/useSignInWithDiscord.d.ts +12 -181
  143. package/dist/src/hooks/useSignInWithDiscord.d.ts.map +1 -1
  144. package/dist/src/hooks/useSignInWithDiscord.js +11 -22
  145. package/dist/src/hooks/useSignInWithDiscord.js.map +1 -1
  146. package/dist/src/hooks/useSignInWithWallet.d.ts +12 -181
  147. package/dist/src/hooks/useSignInWithWallet.d.ts.map +1 -1
  148. package/dist/src/hooks/useSignInWithWallet.js +6 -44
  149. package/dist/src/hooks/useSignInWithWallet.js.map +1 -1
  150. package/dist/src/hooks/useSignOut.d.ts +12 -28
  151. package/dist/src/hooks/useSignOut.d.ts.map +1 -1
  152. package/dist/src/hooks/useSignOut.js +11 -6
  153. package/dist/src/hooks/useSignOut.js.map +1 -1
  154. package/dist/src/hooks/useSignUpWithWallet.d.ts +73 -0
  155. package/dist/src/hooks/useSignUpWithWallet.d.ts.map +1 -0
  156. package/dist/src/hooks/useSignUpWithWallet.js +11 -0
  157. package/dist/src/hooks/useSignUpWithWallet.js.map +1 -0
  158. package/dist/src/hooks/useUpdateMezoId.d.ts +30 -82
  159. package/dist/src/hooks/useUpdateMezoId.d.ts.map +1 -1
  160. package/dist/src/hooks/useUpdateMezoId.js +8 -12
  161. package/dist/src/hooks/useUpdateMezoId.js.map +1 -1
  162. package/dist/src/hooks/useWalletAccount.d.ts +12 -0
  163. package/dist/src/hooks/useWalletAccount.d.ts.map +1 -0
  164. package/dist/src/hooks/useWalletAccount.js +28 -0
  165. package/dist/src/hooks/useWalletAccount.js.map +1 -0
  166. package/dist/src/index.d.ts +1 -0
  167. package/dist/src/index.d.ts.map +1 -1
  168. package/dist/src/index.js +1 -0
  169. package/dist/src/index.js.map +1 -1
  170. package/dist/src/provider.d.ts +10 -13
  171. package/dist/src/provider.d.ts.map +1 -1
  172. package/dist/src/provider.js +11 -20
  173. package/dist/src/provider.js.map +1 -1
  174. package/dist/src/stores/dropdownStore.d.ts +12 -0
  175. package/dist/src/stores/dropdownStore.d.ts.map +1 -0
  176. package/dist/src/stores/dropdownStore.js +13 -0
  177. package/dist/src/stores/dropdownStore.js.map +1 -0
  178. package/dist/src/utils/address.d.ts +15 -0
  179. package/dist/src/utils/address.d.ts.map +1 -0
  180. package/dist/src/utils/address.js +37 -0
  181. package/dist/src/utils/address.js.map +1 -0
  182. package/dist/src/utils/address.test.d.ts +2 -0
  183. package/dist/src/utils/address.test.d.ts.map +1 -0
  184. package/dist/src/utils/address.test.js +40 -0
  185. package/dist/src/utils/address.test.js.map +1 -0
  186. package/dist/src/utils/cryptoAssets.d.ts +28 -0
  187. package/dist/src/utils/cryptoAssets.d.ts.map +1 -0
  188. package/dist/src/utils/cryptoAssets.js +73 -0
  189. package/dist/src/utils/cryptoAssets.js.map +1 -0
  190. package/dist/src/utils/cryptoAssets.test.d.ts +2 -0
  191. package/dist/src/utils/cryptoAssets.test.d.ts.map +1 -0
  192. package/dist/src/utils/cryptoAssets.test.js +50 -0
  193. package/dist/src/utils/cryptoAssets.test.js.map +1 -0
  194. package/dist/src/utils/currency.d.ts +14 -0
  195. package/dist/src/utils/currency.d.ts.map +1 -0
  196. package/dist/src/utils/currency.js +27 -0
  197. package/dist/src/utils/currency.js.map +1 -0
  198. package/dist/src/utils/currency.test.d.ts +2 -0
  199. package/dist/src/utils/currency.test.d.ts.map +1 -0
  200. package/dist/src/utils/currency.test.js +34 -0
  201. package/dist/src/utils/currency.test.js.map +1 -0
  202. package/dist/src/utils/numbers.d.ts +45 -0
  203. package/dist/src/utils/numbers.d.ts.map +1 -0
  204. package/dist/src/utils/numbers.js +86 -0
  205. package/dist/src/utils/numbers.js.map +1 -0
  206. package/dist/src/utils/numbers.test.d.ts +2 -0
  207. package/dist/src/utils/numbers.test.d.ts.map +1 -0
  208. package/dist/src/utils/numbers.test.js +170 -0
  209. package/dist/src/utils/numbers.test.js.map +1 -0
  210. package/package.json +10 -4
  211. package/src/api/auth.ts +104 -129
  212. package/src/api/client.ts +78 -0
  213. package/src/api/fetch-error.ts +8 -0
  214. package/src/api/index.ts +2 -0
  215. package/src/api/portal.ts +56 -0
  216. package/src/assets/DefaultAvatar.tsx +74 -0
  217. package/src/components/Dropdown/ConnectedTrigger.tsx +76 -0
  218. package/src/components/Dropdown/Content.tsx +62 -0
  219. package/src/components/Dropdown/DisconnectedTrigger.tsx +36 -0
  220. package/src/components/Dropdown/Dropdown.tsx +124 -0
  221. package/src/components/Dropdown/NestedViewLayout.tsx +75 -0
  222. package/src/components/Dropdown/README.md +55 -0
  223. package/src/components/Dropdown/Receive/Receive.tsx +119 -0
  224. package/src/components/Dropdown/Root/AccountAddressActions.tsx +101 -0
  225. package/src/components/Dropdown/Root/AccountAssets.tsx +108 -0
  226. package/src/components/Dropdown/Root/AccountBalance.tsx +35 -0
  227. package/src/components/Dropdown/Root/Root.tsx +141 -0
  228. package/src/components/Dropdown/Root/WalletAddress.tsx +128 -0
  229. package/src/components/Dropdown/Root/WelcomeBlock.tsx +91 -0
  230. package/src/components/Dropdown/index.ts +2 -0
  231. package/src/components/index.ts +1 -0
  232. package/src/hooks/constants.ts +4 -4
  233. package/src/hooks/index.ts +2 -4
  234. package/src/hooks/useAssetsUSDConversion.ts +31 -0
  235. package/src/hooks/useAuthenticateWithWallet.ts +98 -0
  236. package/src/hooks/useCreateAccount.ts +20 -11
  237. package/src/hooks/useCreateSession.ts +24 -18
  238. package/src/hooks/useDropdownData.ts +160 -0
  239. package/src/hooks/useEnsureNoSessionAndFetchNonce.ts +46 -0
  240. package/src/hooks/useGetAccountByAddress.ts +11 -5
  241. package/src/hooks/useGetAccountByMezoId.ts +11 -5
  242. package/src/hooks/useGetCurrentAccount.ts +53 -7
  243. package/src/hooks/useGetSession.ts +10 -3
  244. package/src/hooks/useLinkAccount.ts +19 -31
  245. package/src/hooks/usePortalApiClient.ts +6 -0
  246. package/src/hooks/useRefreshPassport.ts +40 -0
  247. package/src/hooks/useSignInWithDiscord.ts +19 -28
  248. package/src/hooks/useSignInWithWallet.ts +14 -55
  249. package/src/hooks/useSignOut.ts +22 -6
  250. package/src/hooks/useSignUpWithWallet.ts +21 -0
  251. package/src/hooks/useUpdateMezoId.ts +20 -12
  252. package/src/hooks/useWalletAccount.ts +53 -0
  253. package/src/index.ts +1 -0
  254. package/src/provider.ts +30 -37
  255. package/src/stores/dropdownStore.ts +20 -0
  256. package/src/utils/address.test.ts +48 -0
  257. package/src/utils/address.ts +45 -0
  258. package/src/utils/cryptoAssets.test.ts +61 -0
  259. package/src/utils/cryptoAssets.ts +93 -0
  260. package/src/utils/currency.test.ts +38 -0
  261. package/src/utils/currency.ts +32 -0
  262. package/src/utils/numbers.test.ts +220 -0
  263. package/src/utils/numbers.ts +120 -0
@@ -0,0 +1,160 @@
1
+ import { useBitcoinAccount } from "@mezo-org/orangekit"
2
+ import { useGetCurrentAccount } from "."
3
+ import {
4
+ CryptoAssetKey,
5
+ getCryptoAsset,
6
+ isBitcoinLikeCryptoAsset,
7
+ isUsdLikeCryptoAsset,
8
+ } from "../utils/cryptoAssets"
9
+ import {
10
+ formatNumberToCompactString,
11
+ fromFixedPoint,
12
+ fromFixedPointToString,
13
+ } from "../utils/numbers"
14
+ import { useAssetsUsdConversion } from "./useAssetsUSDConversion"
15
+ 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
+ }
54
+
55
+ export type DropdownCryptoAsset<T = CryptoAssetKey> = {
56
+ type: T
57
+ balance: bigint
58
+ }
59
+
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
+ /**
82
+ * 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
+ * @returns Dropdown data.
87
+ * @dev This hook is for internal use only.
88
+ */
89
+ export default function useDropdownData(
90
+ options?: UseDropdownDataOptions,
91
+ ): DropdownData | null {
92
+ const { evmNativeAssets = [], matsnetAssets = [] } = options || {}
93
+
94
+ const { btcBalance } = useBitcoinAccount()
95
+ const {
96
+ address: walletAddress,
97
+ networkFamily,
98
+ isConnected,
99
+ } = useWalletAccount()
100
+ 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
109
+ }
110
+
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
122
+
123
+ const btcUsdConversionRate = Number(assetsUsdConversion?.btcUsd ?? 0)
124
+
125
+ const formattedNativeAssets = nativeAssets.map((asset) =>
126
+ formatCryptoAsset(asset.type, asset.balance, btcUsdConversionRate),
127
+ )
128
+
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),
137
+ )
138
+
139
+ const matsBalance = formatNumberToCompactString(
140
+ passportAccount.mats.totalMats,
141
+ 2,
142
+ )
143
+
144
+ const matsnetFormattedAssets = matsnetAssets.map((asset) =>
145
+ formatCryptoAsset(asset.type, asset.balance, btcUsdConversionRate),
146
+ )
147
+
148
+ return {
149
+ mezoId,
150
+ accountAddress,
151
+ walletAddress,
152
+ walletType: networkFamily,
153
+ totalBalanceInUsd,
154
+ formattedNativeAssets,
155
+ matsnet: {
156
+ mats: matsBalance,
157
+ formattedAssets: matsnetFormattedAssets,
158
+ },
159
+ }
160
+ }
@@ -0,0 +1,46 @@
1
+ import { useCallback } from "react"
2
+ import { useGetSession } from "./useGetSession"
3
+ import { useSignOut } from "./useSignOut"
4
+
5
+ function useEnsureNoSessionAndFetchNonce() {
6
+ const { refetch: getSession } = useGetSession(undefined, {
7
+ enabled: false,
8
+ retry: false,
9
+ })
10
+ const { signOutAsync } = useSignOut()
11
+
12
+ const getAndValidateSession = useCallback(async () => {
13
+ const getSessionResult = await getSession()
14
+
15
+ // TODO: We should create a separate endpoint that will always return nonce
16
+ if (getSessionResult.error) {
17
+ throw new Error(
18
+ `Sign in error: Failed to fetch the current session: ${getSessionResult.error}`,
19
+ )
20
+ }
21
+ if (!getSessionResult.data) {
22
+ throw new Error(
23
+ "Sign in error: Failed to fetch the current session; no data returned.",
24
+ )
25
+ }
26
+
27
+ return getSessionResult.data
28
+ }, [getSession])
29
+
30
+ const ensureNoSessionAndFetchNonce = useCallback(async () => {
31
+ let getSessionResult = await getAndValidateSession()
32
+
33
+ if (!("nonce" in getSessionResult)) {
34
+ // If there is active session we are terminating it
35
+ await signOutAsync()
36
+ // Because we've signed out we can assume nonce will be returned here
37
+ getSessionResult = (await getAndValidateSession()) as { nonce: string }
38
+ }
39
+
40
+ return getSessionResult.nonce
41
+ }, [getAndValidateSession, signOutAsync])
42
+
43
+ return { ensureNoSessionAndFetchNonce }
44
+ }
45
+
46
+ export { useEnsureNoSessionAndFetchNonce }
@@ -1,19 +1,25 @@
1
- import { useQuery, skipToken } from "@tanstack/react-query"
1
+ import { useQuery, skipToken, UseBaseQueryOptions } from "@tanstack/react-query"
2
2
  import { useAuthApiClient } from "./useAuthApiClient"
3
3
  import { QUERY_KEYS } from "./constants"
4
4
  import { ONE_MINUTE_MS } from "../utils/time"
5
+ import type { GetAccountByMezoIdOrAddressResponse } from "../api"
5
6
 
6
- export function useGetAccountByAddress(address?: string, useQueryOptions = {}) {
7
+ export function useGetAccountByAddress(
8
+ address?: string,
9
+ queryOptions: Omit<
10
+ UseBaseQueryOptions<GetAccountByMezoIdOrAddressResponse | null>,
11
+ "queryKey" | "queryFn"
12
+ > = {},
13
+ ) {
7
14
  const authApiClient = useAuthApiClient()
8
15
 
9
16
  return useQuery({
10
- queryKey: [QUERY_KEYS.ACCOUNT_BY_ADDRESS, address],
17
+ queryKey: [QUERY_KEYS.ACCOUNT, address],
11
18
  queryFn: address
12
19
  ? () => authApiClient.getAccountByMezoIdOrAddress(address)
13
20
  : skipToken,
14
21
  staleTime: ONE_MINUTE_MS,
15
22
  retry: 1,
16
- enabled: !!address,
17
- ...useQueryOptions,
23
+ ...queryOptions,
18
24
  })
19
25
  }
@@ -1,19 +1,25 @@
1
- import { useQuery, skipToken } from "@tanstack/react-query"
1
+ import { useQuery, skipToken, UseBaseQueryOptions } from "@tanstack/react-query"
2
2
  import { useAuthApiClient } from "./useAuthApiClient"
3
3
  import { QUERY_KEYS } from "./constants"
4
4
  import { ONE_MINUTE_MS } from "../utils/time"
5
+ import type { GetAccountByMezoIdOrAddressResponse } from "../api"
5
6
 
6
- export function useGetAccountByMezoId(mezoId?: string, useQueryOptions = {}) {
7
+ export function useGetAccountByMezoId(
8
+ mezoId?: string,
9
+ queryOptions: Omit<
10
+ UseBaseQueryOptions<GetAccountByMezoIdOrAddressResponse | null>,
11
+ "queryKey" | "queryFn"
12
+ > = {},
13
+ ) {
7
14
  const authApiClient = useAuthApiClient()
8
15
 
9
16
  return useQuery({
10
- queryKey: [QUERY_KEYS.ACCOUNT_BY_MEZO_ID, mezoId],
17
+ queryKey: [QUERY_KEYS.ACCOUNT, mezoId],
11
18
  queryFn: mezoId
12
19
  ? () => authApiClient.getAccountByMezoIdOrAddress(mezoId)
13
20
  : skipToken,
14
21
  staleTime: ONE_MINUTE_MS,
15
22
  retry: 1,
16
- enabled: !!mezoId,
17
- ...useQueryOptions,
23
+ ...queryOptions,
18
24
  })
19
25
  }
@@ -1,16 +1,62 @@
1
- import { useQuery } from "@tanstack/react-query"
2
- import { useAuthApiClient } from "./useAuthApiClient"
3
- import { QUERY_KEYS } from "./constants"
1
+ import { UseBaseQueryOptions, useQuery } from "@tanstack/react-query"
4
2
  import { ONE_MINUTE_MS } from "../utils/time"
3
+ import { QUERY_KEYS } from "./constants"
4
+ import { useAuthApiClient } from "./useAuthApiClient"
5
+ import { usePortalApiClient } from "./usePortalApiClient"
6
+ import type { GetCurrentAccountResponse } from "../api"
5
7
 
6
- export function useGetCurrentAccount(useQueryOptions = {}) {
8
+ type GetCurrentAccountResponseWithMats = GetCurrentAccountResponse & {
9
+ mats: {
10
+ totalMats: number
11
+ }
12
+ }
13
+
14
+ export function useGetCurrentAccount(
15
+ queryOptions: Omit<
16
+ UseBaseQueryOptions<GetCurrentAccountResponseWithMats>,
17
+ "queryKey" | "queryFn"
18
+ > = {},
19
+ ) {
7
20
  const authApiClient = useAuthApiClient()
21
+ const portalApiClient = usePortalApiClient()
8
22
 
9
23
  return useQuery({
10
- queryKey: [QUERY_KEYS.CURRENT_ACCOUNT],
11
- queryFn: () => authApiClient.getCurrentAccount(),
24
+ queryKey: [QUERY_KEYS.ACCOUNT, QUERY_KEYS.CURRENT],
25
+ queryFn: async () => {
26
+ const currentAccount = await authApiClient.getCurrentAccount()
27
+ const linkedWallets = currentAccount?.linkedAccounts?.filter(
28
+ (account) => account.type === "wallet",
29
+ )
30
+ if (!linkedWallets || linkedWallets.length === 0) {
31
+ return {
32
+ ...currentAccount,
33
+ mats: {
34
+ totalMats: 0,
35
+ },
36
+ }
37
+ }
38
+
39
+ const addresses = linkedWallets.map(
40
+ (account) => account.btcAddress || account.evmAddress,
41
+ )
42
+ const mats = await Promise.all(
43
+ addresses.map((address) => portalApiClient.getPortalMats(address)),
44
+ )
45
+
46
+ const totalMats = mats.reduce(
47
+ (sumMats, currentMats) => sumMats + currentMats.totalMats,
48
+ 0,
49
+ )
50
+
51
+ return {
52
+ ...currentAccount,
53
+ mats: {
54
+ totalMats,
55
+ },
56
+ }
57
+ },
12
58
  staleTime: ONE_MINUTE_MS,
13
59
  retry: 1,
14
- ...useQueryOptions,
60
+ ...queryOptions,
15
61
  })
16
62
  }
@@ -1,15 +1,22 @@
1
- import { useQuery } from "@tanstack/react-query"
1
+ import { useQuery, UseBaseQueryOptions } from "@tanstack/react-query"
2
2
  import { useAuthApiClient } from "./useAuthApiClient"
3
3
  import { QUERY_KEYS } from "./constants"
4
4
  import { ONE_MINUTE_MS } from "../utils/time"
5
+ import type { GetSessionResponse } from "../api"
5
6
 
6
- export function useGetSession(code?: string, useQueryOptions = {}) {
7
+ export function useGetSession(
8
+ code?: string,
9
+ queryOptions: Omit<
10
+ UseBaseQueryOptions<GetSessionResponse>,
11
+ "queryKey" | "queryFn"
12
+ > = {},
13
+ ) {
7
14
  const authApiClient = useAuthApiClient()
8
15
  return useQuery({
9
16
  queryKey: [QUERY_KEYS.SESSION, code],
10
17
  queryFn: () => authApiClient.getSession(code),
11
18
  staleTime: ONE_MINUTE_MS,
12
19
  retry: 1,
13
- ...useQueryOptions,
20
+ ...queryOptions,
14
21
  })
15
22
  }
@@ -1,44 +1,32 @@
1
- import { useQueryClient, useMutation } from "@tanstack/react-query"
1
+ import {
2
+ useQueryClient,
3
+ useMutation,
4
+ MutationOptions,
5
+ DefaultError,
6
+ } from "@tanstack/react-query"
2
7
  import { useAuthApiClient } from "./useAuthApiClient"
3
- import { LinkAccountRequest } from "../api/auth"
8
+ import type { LinkAccountRequest, LinkAccountResponse } from "../api"
4
9
  import { QUERY_KEYS } from "./constants"
5
10
 
6
- export function useLinkAccount(useMutationOptions = {}) {
11
+ export function useLinkAccount(
12
+ mutationOptions: Omit<
13
+ MutationOptions<LinkAccountResponse, DefaultError, LinkAccountRequest>,
14
+ "mutationFn" | "mutationKey"
15
+ > = {},
16
+ ) {
7
17
  const queryClient = useQueryClient()
8
18
  const authApiClient = useAuthApiClient()
9
19
 
20
+ const { onSuccess: customOnSuccess, ...restMutationOptions } = mutationOptions
21
+
10
22
  const { mutate, mutateAsync, ...rest } = useMutation({
11
23
  mutationFn: (linkAccountRequest: LinkAccountRequest) =>
12
24
  authApiClient.linkAccount(linkAccountRequest),
13
- onSuccess: (data) => {
14
- if ("user_metadata" in data) {
15
- if (data.user_metadata.mezoId) {
16
- queryClient.setQueryData(
17
- [QUERY_KEYS.ACCOUNT_BY_MEZO_ID, data.user_metadata.mezoId],
18
- data,
19
- )
20
- }
21
-
22
- queryClient.setQueryData(
23
- [QUERY_KEYS.ACCOUNT_BY_ADDRESS, data.user_metadata.btcAddress],
24
- data,
25
- )
26
- queryClient.setQueryData(
27
- [QUERY_KEYS.ACCOUNT_BY_ADDRESS, data.user_metadata.evmAddress],
28
- data,
29
- )
30
- } else {
31
- queryClient.resetQueries({
32
- queryKey: [QUERY_KEYS.ACCOUNT_BY_MEZO_ID],
33
- exact: false,
34
- })
35
- queryClient.resetQueries({
36
- queryKey: [QUERY_KEYS.ACCOUNT_BY_ADDRESS],
37
- exact: false,
38
- })
39
- }
25
+ onSuccess: (data, variables, context) => {
26
+ queryClient.resetQueries({ queryKey: [QUERY_KEYS.ACCOUNT] })
27
+ if (customOnSuccess) customOnSuccess(data, variables, context)
40
28
  },
41
- ...useMutationOptions,
29
+ ...restMutationOptions,
42
30
  })
43
31
 
44
32
  return { linkAccount: mutate, linkAccountAsync: mutateAsync, ...rest }
@@ -0,0 +1,6 @@
1
+ import { usePassportContext } from "./usePassportContext"
2
+
3
+ export function usePortalApiClient() {
4
+ const { portalApiClient } = usePassportContext()
5
+ return portalApiClient
6
+ }
@@ -0,0 +1,40 @@
1
+ import { useQueryClient } from "@tanstack/react-query"
2
+ import { useCallback } from "react"
3
+ import { QUERY_KEYS } from "./constants"
4
+
5
+ /**
6
+ * Hook to refresh the passport using query invalidation mechanism.
7
+ * By calling the refresh function, the latest data will be refetched as soon as possible.
8
+ *
9
+ * @example
10
+ * const { refreshCurrentAccount, refreshUsdConversion } = useRefreshPassport()
11
+ *
12
+ * // Call this function to refresh the current account
13
+ * const handlerefreshCurrentAccount = async () => {
14
+ * await refreshCurrentAccount()
15
+ * }
16
+ */
17
+ export function useRefreshPassport() {
18
+ const queryClient = useQueryClient()
19
+
20
+ const refreshCurrentAccount = useCallback(
21
+ () =>
22
+ queryClient.invalidateQueries({
23
+ queryKey: [QUERY_KEYS.ACCOUNT, QUERY_KEYS.CURRENT],
24
+ }),
25
+ [queryClient],
26
+ )
27
+
28
+ const refreshUsdConversion = useCallback(
29
+ () =>
30
+ queryClient.invalidateQueries({
31
+ queryKey: [QUERY_KEYS.ASSETS_USD_CONVERSION],
32
+ }),
33
+ [queryClient],
34
+ )
35
+
36
+ return {
37
+ refreshCurrentAccount,
38
+ refreshUsdConversion,
39
+ }
40
+ }
@@ -1,42 +1,33 @@
1
- import { useAccount } from "wagmi"
2
- import { useMutation } from "@tanstack/react-query"
3
- import { useGetSession } from "./useGetSession"
1
+ import { MutationOptions, useMutation } from "@tanstack/react-query"
4
2
  import { useCreateSession } from "./useCreateSession"
3
+ import { useEnsureNoSessionAndFetchNonce } from "./useEnsureNoSessionAndFetchNonce"
4
+ import type { AuthenticationProviderRedirectResponse } from "../api"
5
5
 
6
- function useSignInWithDiscord() {
7
- const { address } = useAccount()
8
- const { refetch: getSession } = useGetSession(undefined, {
9
- enabled: false,
10
- })
6
+ function useSignInWithDiscord(
7
+ mutationOptions: Omit<
8
+ MutationOptions<AuthenticationProviderRedirectResponse>,
9
+ "mutationFn" | "mutationKey"
10
+ > = {},
11
+ ) {
12
+ const { ensureNoSessionAndFetchNonce } = useEnsureNoSessionAndFetchNonce()
11
13
  const { createSessionAsync } = useCreateSession()
12
14
 
13
15
  const { mutate, mutateAsync, ...signInMutationRestParameters } = useMutation({
14
- mutationFn: async () => {
15
- if (!address) {
16
- throw new Error("Sign in error: User not connected!")
17
- }
18
-
19
- const getSessionResult = await getSession()
20
-
21
- // TODO: We should create a separate endpoint that will always return nonce
22
- if (!getSessionResult.data || !("nonce" in getSessionResult.data)) {
23
- if (getSessionResult.error) {
24
- throw new Error(`Sign in error: ${getSessionResult.error}`)
25
- }
26
- throw new Error(
27
- "Sign in error: Nonce not available! Remove the session first.",
28
- )
29
- }
16
+ mutationFn: async (): Promise<AuthenticationProviderRedirectResponse> => {
17
+ await ensureNoSessionAndFetchNonce()
30
18
 
31
- return createSessionAsync({
19
+ return (await createSessionAsync({
32
20
  type: "discord",
33
- })
21
+ })) as AuthenticationProviderRedirectResponse
22
+ // ^ By passing type: "discord" we know for sure the return type is
23
+ // AuthenticationProviderRedirectResponse
34
24
  },
25
+ ...mutationOptions,
35
26
  })
36
27
 
37
28
  return {
38
- signIn: mutate,
39
- signInAsync: mutateAsync,
29
+ signInWithDiscord: mutate,
30
+ signInWithDiscordAsync: mutateAsync,
40
31
  ...signInMutationRestParameters,
41
32
  }
42
33
  }
@@ -1,61 +1,20 @@
1
- import { useAccount, useSignMessage } from "wagmi"
2
- import { useBitcoinAccount } from "@mezo-org/orangekit"
3
- import { useMutation } from "@tanstack/react-query"
4
- import { useGetSession } from "./useGetSession"
5
- import { useCreateSession } from "./useCreateSession"
6
- import { createSignInWithWalletMessage } from "../utils/siww"
1
+ import { MutationOptions } from "@tanstack/react-query"
2
+ import { useAuthenticateWithWallet } from "./useAuthenticateWithWallet"
3
+ import type { Session } from "../api"
7
4
 
8
- function useSignInWithWallet() {
9
- console.log("use sign int with wallet broooo")
10
- const { chainId, address, connector } = useAccount()
11
- const { btcAddress } = useBitcoinAccount()
12
- const { refetch: getSession } = useGetSession(undefined, {
13
- enabled: false,
14
- })
15
- const { createSessionAsync } = useCreateSession()
16
- const { signMessageAsync } = useSignMessage()
17
-
18
- const { mutate, mutateAsync, ...signInMutationRestParameters } = useMutation({
19
- mutationFn: async () => {
20
- if (!address) {
21
- throw new Error("Sign in error: User not connected!")
22
- }
23
-
24
- const getSessionResult = await getSession()
25
-
26
- // TODO: We should create a separate endpoint that will always return nonce
27
- if (!getSessionResult.data || !("nonce" in getSessionResult.data)) {
28
- if (getSessionResult.error) {
29
- throw new Error(`Sign in error: ${getSessionResult.error}`)
30
- }
31
- throw new Error(
32
- "Sign in error: Nonce not available! Remove the session first.",
33
- )
34
- }
35
-
36
- const networkFamily = btcAddress ? "bitcoin" : "evm"
37
- const messageResult = createSignInWithWalletMessage(
38
- btcAddress ? btcAddress! : address!,
39
- getSessionResult.data.nonce,
40
- networkFamily,
41
- chainId,
42
- )
43
- const signatureResult = await signMessageAsync({
44
- message: messageResult,
45
- connector,
46
- })
47
- return createSessionAsync({
48
- type: "wallet",
49
- message: messageResult,
50
- signature: signatureResult,
51
- })
52
- },
53
- })
5
+ function useSignInWithWallet(
6
+ mutationOptions: Omit<
7
+ MutationOptions<Session>,
8
+ "mutationFn" | "mutationKey"
9
+ > = {},
10
+ ) {
11
+ const { authenticateWithWallet, authenticateWithWalletAsync, ...rest } =
12
+ useAuthenticateWithWallet(false, mutationOptions)
54
13
 
55
14
  return {
56
- signIn: mutate,
57
- signInAsync: mutateAsync,
58
- ...signInMutationRestParameters,
15
+ signInWithWallet: authenticateWithWallet,
16
+ signInWithWalletAsync: authenticateWithWalletAsync,
17
+ ...rest,
59
18
  }
60
19
  }
61
20
 
@@ -1,18 +1,34 @@
1
- import { useMutation, useQueryClient } from "@tanstack/react-query"
1
+ import {
2
+ MutationOptions,
3
+ useMutation,
4
+ useQueryClient,
5
+ } from "@tanstack/react-query"
2
6
  import { useAuthApiClient } from "./useAuthApiClient"
3
7
  import { QUERY_KEYS } from "./constants"
8
+ import type { DeleteSessionResponse } from "../api"
4
9
 
5
- export function useSignOut(useMutationOptions = {}) {
10
+ export function useSignOut(
11
+ mutationOptions: Omit<
12
+ MutationOptions<DeleteSessionResponse>,
13
+ "mutationFn" | "mutationKey"
14
+ > = {},
15
+ ) {
6
16
  const queryClient = useQueryClient()
7
17
  const authApiClient = useAuthApiClient()
8
18
 
19
+ const { onSuccess: customOnSuccess, ...restMutationOptions } = mutationOptions
20
+
9
21
  const { mutate, mutateAsync, ...rest } = useMutation({
10
22
  mutationFn: () => authApiClient.deleteSession(),
11
- onSuccess: () => {
12
- queryClient.resetQueries({ queryKey: [QUERY_KEYS.SESSION], exact: false })
13
- queryClient.resetQueries({ queryKey: [QUERY_KEYS.CURRENT_ACCOUNT] })
23
+ onSuccess: (data, variables, context) => {
24
+ queryClient.resetQueries({ queryKey: [QUERY_KEYS.SESSION] })
25
+ queryClient.resetQueries({
26
+ queryKey: [QUERY_KEYS.ACCOUNT, QUERY_KEYS.CURRENT],
27
+ })
28
+
29
+ if (customOnSuccess) customOnSuccess(data, variables, context)
14
30
  },
15
- ...useMutationOptions,
31
+ ...restMutationOptions,
16
32
  })
17
33
 
18
34
  return { signOut: mutate, signOutAsync: mutateAsync, ...rest }
@@ -0,0 +1,21 @@
1
+ import { MutationOptions } from "@tanstack/react-query"
2
+ import { useAuthenticateWithWallet } from "./useAuthenticateWithWallet"
3
+ import type { Session } from "../api"
4
+
5
+ function useSignUpWithWallet(
6
+ mutationOptions: Omit<
7
+ MutationOptions<Session>,
8
+ "mutationFn" | "mutationKey"
9
+ > = {},
10
+ ) {
11
+ const { authenticateWithWallet, authenticateWithWalletAsync, ...rest } =
12
+ useAuthenticateWithWallet(true, mutationOptions)
13
+
14
+ return {
15
+ signUpWithWallet: authenticateWithWallet,
16
+ signUpWithWalletAsync: authenticateWithWalletAsync,
17
+ ...rest,
18
+ }
19
+ }
20
+
21
+ export { useSignUpWithWallet }