@sudobility/heavymath_ui 0.0.3

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 (201) hide show
  1. package/dist/components/dealer/DealerNFTList.d.ts +6 -0
  2. package/dist/components/dealer/DealerNFTList.d.ts.map +1 -0
  3. package/dist/components/dealer/DealerNFTList.js +46 -0
  4. package/dist/components/dealer/DealerNFTList.js.map +1 -0
  5. package/dist/components/dealer/DealerNFTSelector.d.ts +8 -0
  6. package/dist/components/dealer/DealerNFTSelector.d.ts.map +1 -0
  7. package/dist/components/dealer/DealerNFTSelector.js +10 -0
  8. package/dist/components/dealer/DealerNFTSelector.js.map +1 -0
  9. package/dist/components/dealer/UpcomingGamesWidget.d.ts +8 -0
  10. package/dist/components/dealer/UpcomingGamesWidget.d.ts.map +1 -0
  11. package/dist/components/dealer/UpcomingGamesWidget.js +68 -0
  12. package/dist/components/dealer/UpcomingGamesWidget.js.map +1 -0
  13. package/dist/components/icons/index.d.ts +2 -0
  14. package/dist/components/icons/index.d.ts.map +1 -0
  15. package/dist/components/icons/index.js +2 -0
  16. package/dist/components/icons/index.js.map +1 -0
  17. package/dist/components/market/GameMarketsSection.d.ts +16 -0
  18. package/dist/components/market/GameMarketsSection.d.ts.map +1 -0
  19. package/dist/components/market/GameMarketsSection.js +18 -0
  20. package/dist/components/market/GameMarketsSection.js.map +1 -0
  21. package/dist/components/market/InlineCreateMarketForm.d.ts +17 -0
  22. package/dist/components/market/InlineCreateMarketForm.d.ts.map +1 -0
  23. package/dist/components/market/InlineCreateMarketForm.js +274 -0
  24. package/dist/components/market/InlineCreateMarketForm.js.map +1 -0
  25. package/dist/components/market/LeagueMarketsSection.d.ts +16 -0
  26. package/dist/components/market/LeagueMarketsSection.d.ts.map +1 -0
  27. package/dist/components/market/LeagueMarketsSection.js +15 -0
  28. package/dist/components/market/LeagueMarketsSection.js.map +1 -0
  29. package/dist/components/market/MarketCard.d.ts +8 -0
  30. package/dist/components/market/MarketCard.d.ts.map +1 -0
  31. package/dist/components/market/MarketCard.js +30 -0
  32. package/dist/components/market/MarketCard.js.map +1 -0
  33. package/dist/components/market/MarketList.d.ts +9 -0
  34. package/dist/components/market/MarketList.d.ts.map +1 -0
  35. package/dist/components/market/MarketList.js +17 -0
  36. package/dist/components/market/MarketList.js.map +1 -0
  37. package/dist/components/market/MarketStatusBadge.d.ts +8 -0
  38. package/dist/components/market/MarketStatusBadge.d.ts.map +1 -0
  39. package/dist/components/market/MarketStatusBadge.js +31 -0
  40. package/dist/components/market/MarketStatusBadge.js.map +1 -0
  41. package/dist/components/market/PredictionSlider.d.ts +11 -0
  42. package/dist/components/market/PredictionSlider.d.ts.map +1 -0
  43. package/dist/components/market/PredictionSlider.js +55 -0
  44. package/dist/components/market/PredictionSlider.js.map +1 -0
  45. package/dist/components/market/SportPredictionCard.d.ts +15 -0
  46. package/dist/components/market/SportPredictionCard.d.ts.map +1 -0
  47. package/dist/components/market/SportPredictionCard.js +92 -0
  48. package/dist/components/market/SportPredictionCard.js.map +1 -0
  49. package/dist/components/market/TeamMarketsSection.d.ts +17 -0
  50. package/dist/components/market/TeamMarketsSection.d.ts.map +1 -0
  51. package/dist/components/market/TeamMarketsSection.js +8 -0
  52. package/dist/components/market/TeamMarketsSection.js.map +1 -0
  53. package/dist/components/market/TeamTournamentMarketForm.d.ts +19 -0
  54. package/dist/components/market/TeamTournamentMarketForm.d.ts.map +1 -0
  55. package/dist/components/market/TeamTournamentMarketForm.js +92 -0
  56. package/dist/components/market/TeamTournamentMarketForm.js.map +1 -0
  57. package/dist/components/market/TournamentMarketForm.d.ts +19 -0
  58. package/dist/components/market/TournamentMarketForm.d.ts.map +1 -0
  59. package/dist/components/market/TournamentMarketForm.js +86 -0
  60. package/dist/components/market/TournamentMarketForm.js.map +1 -0
  61. package/dist/components/market/index.d.ts +12 -0
  62. package/dist/components/market/index.d.ts.map +1 -0
  63. package/dist/components/market/index.js +12 -0
  64. package/dist/components/market/index.js.map +1 -0
  65. package/dist/components/sports/SeasonSelector.d.ts +10 -0
  66. package/dist/components/sports/SeasonSelector.d.ts.map +1 -0
  67. package/dist/components/sports/SeasonSelector.js +13 -0
  68. package/dist/components/sports/SeasonSelector.js.map +1 -0
  69. package/dist/components/ui/AnimatedCollapse.d.ts +9 -0
  70. package/dist/components/ui/AnimatedCollapse.d.ts.map +1 -0
  71. package/dist/components/ui/AnimatedCollapse.js +8 -0
  72. package/dist/components/ui/AnimatedCollapse.js.map +1 -0
  73. package/dist/components/ui/FavoriteStar.d.ts +13 -0
  74. package/dist/components/ui/FavoriteStar.d.ts.map +1 -0
  75. package/dist/components/ui/FavoriteStar.js +47 -0
  76. package/dist/components/ui/FavoriteStar.js.map +1 -0
  77. package/dist/components/wallet/ConnectedWalletMenu.d.ts +16 -0
  78. package/dist/components/wallet/ConnectedWalletMenu.d.ts.map +1 -0
  79. package/dist/components/wallet/ConnectedWalletMenu.js +131 -0
  80. package/dist/components/wallet/ConnectedWalletMenu.js.map +1 -0
  81. package/dist/components/wallet/DealerRoute.d.ts +6 -0
  82. package/dist/components/wallet/DealerRoute.d.ts.map +1 -0
  83. package/dist/components/wallet/DealerRoute.js +20 -0
  84. package/dist/components/wallet/DealerRoute.js.map +1 -0
  85. package/dist/components/wallet/ProtectedRoute.d.ts +8 -0
  86. package/dist/components/wallet/ProtectedRoute.d.ts.map +1 -0
  87. package/dist/components/wallet/ProtectedRoute.js +17 -0
  88. package/dist/components/wallet/ProtectedRoute.js.map +1 -0
  89. package/dist/components/wallet/WalletConnectionModal.d.ts +7 -0
  90. package/dist/components/wallet/WalletConnectionModal.d.ts.map +1 -0
  91. package/dist/components/wallet/WalletConnectionModal.js +334 -0
  92. package/dist/components/wallet/WalletConnectionModal.js.map +1 -0
  93. package/dist/config/app.d.ts +24 -0
  94. package/dist/config/app.d.ts.map +1 -0
  95. package/dist/config/app.js +18 -0
  96. package/dist/config/app.js.map +1 -0
  97. package/dist/config/chains.d.ts +1070 -0
  98. package/dist/config/chains.d.ts.map +1 -0
  99. package/dist/config/chains.js +28 -0
  100. package/dist/config/chains.js.map +1 -0
  101. package/dist/config/contracts.d.ts +15 -0
  102. package/dist/config/contracts.d.ts.map +1 -0
  103. package/dist/config/contracts.js +62 -0
  104. package/dist/config/contracts.js.map +1 -0
  105. package/dist/config/sportCodes.d.ts +58 -0
  106. package/dist/config/sportCodes.d.ts.map +1 -0
  107. package/dist/config/sportCodes.js +78 -0
  108. package/dist/config/sportCodes.js.map +1 -0
  109. package/dist/context/IndexerContext.d.ts +34 -0
  110. package/dist/context/IndexerContext.d.ts.map +1 -0
  111. package/dist/context/IndexerContext.js +40 -0
  112. package/dist/context/IndexerContext.js.map +1 -0
  113. package/dist/context/WalletAuthContext.d.ts +26 -0
  114. package/dist/context/WalletAuthContext.d.ts.map +1 -0
  115. package/dist/context/WalletAuthContext.js +148 -0
  116. package/dist/context/WalletAuthContext.js.map +1 -0
  117. package/dist/hooks/index.d.ts +13 -0
  118. package/dist/hooks/index.d.ts.map +1 -0
  119. package/dist/hooks/index.js +13 -0
  120. package/dist/hooks/index.js.map +1 -0
  121. package/dist/hooks/useContractWithToast.d.ts +1348 -0
  122. package/dist/hooks/useContractWithToast.d.ts.map +1 -0
  123. package/dist/hooks/useContractWithToast.js +395 -0
  124. package/dist/hooks/useContractWithToast.js.map +1 -0
  125. package/dist/hooks/useDealerNFT.d.ts +71 -0
  126. package/dist/hooks/useDealerNFT.d.ts.map +1 -0
  127. package/dist/hooks/useDealerNFT.js +127 -0
  128. package/dist/hooks/useDealerNFT.js.map +1 -0
  129. package/dist/hooks/useDealerPermission.d.ts +11 -0
  130. package/dist/hooks/useDealerPermission.d.ts.map +1 -0
  131. package/dist/hooks/useDealerPermission.js +48 -0
  132. package/dist/hooks/useDealerPermission.js.map +1 -0
  133. package/dist/hooks/useFilteredSportsData.d.ts +20 -0
  134. package/dist/hooks/useFilteredSportsData.d.ts.map +1 -0
  135. package/dist/hooks/useFilteredSportsData.js +52 -0
  136. package/dist/hooks/useFilteredSportsData.js.map +1 -0
  137. package/dist/hooks/useGameMarkets.d.ts +23 -0
  138. package/dist/hooks/useGameMarkets.d.ts.map +1 -0
  139. package/dist/hooks/useGameMarkets.js +50 -0
  140. package/dist/hooks/useGameMarkets.js.map +1 -0
  141. package/dist/hooks/useLeagueMarkets.d.ts +11 -0
  142. package/dist/hooks/useLeagueMarkets.d.ts.map +1 -0
  143. package/dist/hooks/useLeagueMarkets.js +38 -0
  144. package/dist/hooks/useLeagueMarkets.js.map +1 -0
  145. package/dist/hooks/useMarketContract.d.ts +219 -0
  146. package/dist/hooks/useMarketContract.d.ts.map +1 -0
  147. package/dist/hooks/useMarketContract.js +790 -0
  148. package/dist/hooks/useMarketContract.js.map +1 -0
  149. package/dist/hooks/useToastActions.d.ts +13 -0
  150. package/dist/hooks/useToastActions.d.ts.map +1 -0
  151. package/dist/hooks/useToastActions.js +40 -0
  152. package/dist/hooks/useToastActions.js.map +1 -0
  153. package/dist/index.d.ts +43 -0
  154. package/dist/index.d.ts.map +1 -0
  155. package/dist/index.js +47 -0
  156. package/dist/index.js.map +1 -0
  157. package/dist/lib/evmClient.d.ts +299 -0
  158. package/dist/lib/evmClient.d.ts.map +1 -0
  159. package/dist/lib/evmClient.js +691 -0
  160. package/dist/lib/evmClient.js.map +1 -0
  161. package/dist/types/auth.d.ts +44 -0
  162. package/dist/types/auth.d.ts.map +1 -0
  163. package/dist/types/auth.js +17 -0
  164. package/dist/types/auth.js.map +1 -0
  165. package/dist/types/dealer.d.ts +59 -0
  166. package/dist/types/dealer.d.ts.map +1 -0
  167. package/dist/types/dealer.js +31 -0
  168. package/dist/types/dealer.js.map +1 -0
  169. package/dist/types/market.d.ts +79 -0
  170. package/dist/types/market.d.ts.map +1 -0
  171. package/dist/types/market.js +47 -0
  172. package/dist/types/market.js.map +1 -0
  173. package/dist/utils/conditionData.d.ts +8 -0
  174. package/dist/utils/conditionData.d.ts.map +1 -0
  175. package/dist/utils/conditionData.js +7 -0
  176. package/dist/utils/conditionData.js.map +1 -0
  177. package/dist/utils/datetime.d.ts +3 -0
  178. package/dist/utils/datetime.d.ts.map +1 -0
  179. package/dist/utils/datetime.js +13 -0
  180. package/dist/utils/datetime.js.map +1 -0
  181. package/dist/utils/format.d.ts +79 -0
  182. package/dist/utils/format.d.ts.map +1 -0
  183. package/dist/utils/format.js +144 -0
  184. package/dist/utils/format.js.map +1 -0
  185. package/dist/utils/marketDisplay.d.ts +28 -0
  186. package/dist/utils/marketDisplay.d.ts.map +1 -0
  187. package/dist/utils/marketDisplay.js +45 -0
  188. package/dist/utils/marketDisplay.js.map +1 -0
  189. package/dist/utils/marketId.d.ts +8 -0
  190. package/dist/utils/marketId.d.ts.map +1 -0
  191. package/dist/utils/marketId.js +12 -0
  192. package/dist/utils/marketId.js.map +1 -0
  193. package/dist/utils/oracleId.d.ts +33 -0
  194. package/dist/utils/oracleId.d.ts.map +1 -0
  195. package/dist/utils/oracleId.js +62 -0
  196. package/dist/utils/oracleId.js.map +1 -0
  197. package/dist/utils/sportsSeason.d.ts +10 -0
  198. package/dist/utils/sportsSeason.d.ts.map +1 -0
  199. package/dist/utils/sportsSeason.js +39 -0
  200. package/dist/utils/sportsSeason.js.map +1 -0
  201. package/package.json +85 -0
@@ -0,0 +1,790 @@
1
+ import { useMemo } from 'react';
2
+ import { usePublicClient, useConfig } from 'wagmi';
3
+ import { getPublicClient, getWalletClient, switchChain } from 'wagmi/actions';
4
+ import { useMutation, useQuery, useQueryClient, } from '@tanstack/react-query';
5
+ import { EVMPredictionClient } from '../lib/evmClient';
6
+ import { getContractAddress } from '../config/contracts';
7
+ import { getAppConfig } from '../config/app';
8
+ /**
9
+ * Invalidate query keys immediately and again after delays to account for
10
+ * indexer processing time. The on-chain tx confirms before the indexer
11
+ * picks up the event, so the first refetch often returns stale data.
12
+ */
13
+ function invalidateWithRetry(queryClient, queryKeys) {
14
+ const invalidate = () => {
15
+ for (const queryKey of queryKeys) {
16
+ queryClient.invalidateQueries({ queryKey });
17
+ }
18
+ };
19
+ const delays = [0, 5000, 12000, 20000, 30000];
20
+ for (const delay of delays) {
21
+ if (delay === 0) {
22
+ invalidate();
23
+ }
24
+ else {
25
+ setTimeout(invalidate, delay);
26
+ }
27
+ }
28
+ }
29
+ /**
30
+ * @fileoverview Contract interaction hooks
31
+ * @description React hooks that wrap EVMPredictionClient operations with wagmi wallet state.
32
+ * Each hook manages its own wallet/public client references via wagmi hooks and
33
+ * delegates to a singleton EVMPredictionClient per chain.
34
+ */
35
+ /** Singleton EVMPredictionClient cache keyed by chain ID */
36
+ const clientCache = new Map();
37
+ /**
38
+ * Get or create a singleton EVMPredictionClient for the given chain.
39
+ *
40
+ * @param chainId - The EVM chain ID
41
+ * @returns The client instance, or null if contracts are not deployed on this chain
42
+ */
43
+ function getClient(chainId) {
44
+ const cached = clientCache.get(chainId);
45
+ if (cached)
46
+ return cached;
47
+ const predictionMarket = getContractAddress(chainId, 'predictionMarket');
48
+ const usdc = getContractAddress(chainId, 'usdc');
49
+ if (!predictionMarket ||
50
+ predictionMarket === '0x0000000000000000000000000000000000000000') {
51
+ return null;
52
+ }
53
+ const client = new EVMPredictionClient({
54
+ predictionMarket,
55
+ stakeToken: usdc,
56
+ });
57
+ clientCache.set(chainId, client);
58
+ return client;
59
+ }
60
+ /**
61
+ * Get wallet and public clients, auto-switching chain if needed.
62
+ */
63
+ async function getClients(config, chainId) {
64
+ const walletClient = await getWalletClient(config);
65
+ if (walletClient.chain?.id !== chainId) {
66
+ await switchChain(config, { chainId });
67
+ }
68
+ return {
69
+ walletClient: await getWalletClient(config),
70
+ publicClient: getPublicClient(config, { chainId }),
71
+ };
72
+ }
73
+ /**
74
+ * Hook to get the EVM prediction client for the current chain.
75
+ *
76
+ * @returns The EVMPredictionClient for the current chain, or null if contracts are unavailable
77
+ */
78
+ export function useEVMClient() {
79
+ const chainId = getAppConfig().defaultChainId;
80
+ return useMemo(() => {
81
+ if (!chainId)
82
+ return null;
83
+ return getClient(chainId);
84
+ }, [chainId]);
85
+ }
86
+ /**
87
+ * Hook to place a prediction on a market.
88
+ * Auto-handles USDC allowance approval before the prediction transaction.
89
+ *
90
+ * @returns TanStack mutation for placing predictions
91
+ */
92
+ export function usePlacePrediction() {
93
+ const config = useConfig();
94
+ const chainId = getAppConfig().defaultChainId;
95
+ const client = useEVMClient();
96
+ const queryClient = useQueryClient();
97
+ return useMutation({
98
+ mutationFn: async ({ marketId, percentage, amount, }) => {
99
+ const { walletClient, publicClient } = await getClients(config, chainId);
100
+ if (!client || !walletClient || !publicClient) {
101
+ throw new Error('Client not available');
102
+ }
103
+ const result = await client.placePrediction({
104
+ walletClient,
105
+ publicClient,
106
+ chain: publicClient.chain,
107
+ }, marketId, percentage, amount);
108
+ return result;
109
+ },
110
+ onSuccess: () => {
111
+ invalidateWithRetry(queryClient, [
112
+ ['heavymath', 'markets'],
113
+ ['heavymath', 'market'],
114
+ ['heavymath', 'market-predictions'],
115
+ ['heavymath', 'predictions'],
116
+ ]);
117
+ },
118
+ meta: {
119
+ chainId,
120
+ },
121
+ });
122
+ }
123
+ /**
124
+ * Hook to update an existing prediction on a market.
125
+ * Auto-handles USDC allowance approval for additional stake amounts.
126
+ *
127
+ * @returns TanStack mutation for updating predictions
128
+ */
129
+ export function useUpdatePrediction() {
130
+ const config = useConfig();
131
+ const chainId = getAppConfig().defaultChainId;
132
+ const client = useEVMClient();
133
+ const queryClient = useQueryClient();
134
+ return useMutation({
135
+ mutationFn: async ({ marketId, newPercentage, additionalAmount, }) => {
136
+ const { walletClient, publicClient } = await getClients(config, chainId);
137
+ if (!client || !walletClient || !publicClient) {
138
+ throw new Error('Client not available');
139
+ }
140
+ const result = await client.updatePrediction({
141
+ walletClient,
142
+ publicClient,
143
+ chain: publicClient.chain,
144
+ }, marketId, newPercentage, additionalAmount);
145
+ return result;
146
+ },
147
+ onSuccess: () => {
148
+ invalidateWithRetry(queryClient, [
149
+ ['heavymath', 'markets'],
150
+ ['heavymath', 'market'],
151
+ ['heavymath', 'market-predictions'],
152
+ ['heavymath', 'predictions'],
153
+ ]);
154
+ },
155
+ meta: {
156
+ chainId,
157
+ },
158
+ });
159
+ }
160
+ /**
161
+ * Hook to withdraw a prediction from a market (before deadline).
162
+ *
163
+ * @returns TanStack mutation for withdrawing predictions
164
+ */
165
+ export function useWithdrawPrediction() {
166
+ const config = useConfig();
167
+ const chainId = getAppConfig().defaultChainId;
168
+ const client = useEVMClient();
169
+ const queryClient = useQueryClient();
170
+ return useMutation({
171
+ mutationFn: async ({ marketId }) => {
172
+ const { walletClient, publicClient } = await getClients(config, chainId);
173
+ if (!client || !walletClient || !publicClient) {
174
+ throw new Error('Client not available');
175
+ }
176
+ const result = await client.withdrawPrediction({
177
+ walletClient,
178
+ publicClient,
179
+ chain: publicClient.chain,
180
+ }, marketId);
181
+ return result;
182
+ },
183
+ onSuccess: () => {
184
+ invalidateWithRetry(queryClient, [
185
+ ['heavymath', 'markets'],
186
+ ['heavymath', 'market'],
187
+ ['heavymath', 'market-predictions'],
188
+ ['heavymath', 'predictions'],
189
+ ]);
190
+ },
191
+ meta: {
192
+ chainId,
193
+ },
194
+ });
195
+ }
196
+ /**
197
+ * Hook to claim winnings from a resolved market.
198
+ *
199
+ * @returns TanStack mutation for claiming winnings
200
+ */
201
+ export function useClaimWinnings() {
202
+ const config = useConfig();
203
+ const chainId = getAppConfig().defaultChainId;
204
+ const client = useEVMClient();
205
+ const queryClient = useQueryClient();
206
+ return useMutation({
207
+ mutationFn: async ({ marketId }) => {
208
+ const { walletClient, publicClient } = await getClients(config, chainId);
209
+ if (!client || !walletClient || !publicClient) {
210
+ throw new Error('Client not available');
211
+ }
212
+ const result = await client.claimWinnings({
213
+ walletClient,
214
+ publicClient,
215
+ chain: publicClient.chain,
216
+ }, marketId);
217
+ return result;
218
+ },
219
+ onSuccess: () => {
220
+ invalidateWithRetry(queryClient, [
221
+ ['heavymath', 'predictions'],
222
+ ['heavymath', 'market'],
223
+ ['heavymath', 'withdrawals'],
224
+ ]);
225
+ },
226
+ meta: {
227
+ chainId,
228
+ },
229
+ });
230
+ }
231
+ /**
232
+ * Hook to claim a refund from a cancelled or abandoned market.
233
+ *
234
+ * @returns TanStack mutation for claiming refunds
235
+ */
236
+ export function useClaimRefund() {
237
+ const config = useConfig();
238
+ const chainId = getAppConfig().defaultChainId;
239
+ const client = useEVMClient();
240
+ const queryClient = useQueryClient();
241
+ return useMutation({
242
+ mutationFn: async ({ marketId }) => {
243
+ const { walletClient, publicClient } = await getClients(config, chainId);
244
+ if (!client || !walletClient || !publicClient) {
245
+ throw new Error('Client not available');
246
+ }
247
+ const result = await client.claimRefund({
248
+ walletClient,
249
+ publicClient,
250
+ chain: publicClient.chain,
251
+ }, marketId);
252
+ return result;
253
+ },
254
+ onSuccess: () => {
255
+ invalidateWithRetry(queryClient, [
256
+ ['heavymath', 'predictions'],
257
+ ['heavymath', 'market'],
258
+ ]);
259
+ },
260
+ meta: {
261
+ chainId,
262
+ },
263
+ });
264
+ }
265
+ /**
266
+ * Hook to read on-chain market data from the smart contract.
267
+ *
268
+ * @param marketId - The market ID to query, or undefined to skip
269
+ * @returns TanStack query result with market state data
270
+ */
271
+ export function useOnChainMarket(marketId) {
272
+ const publicClient = usePublicClient();
273
+ const chainId = getAppConfig().defaultChainId;
274
+ const client = useEVMClient();
275
+ return useQuery({
276
+ queryKey: ['onChainMarket', chainId, marketId?.toString()],
277
+ queryFn: async () => {
278
+ if (!client || !publicClient || marketId === undefined) {
279
+ return null;
280
+ }
281
+ return client.getMarket(publicClient, marketId);
282
+ },
283
+ enabled: !!client && !!publicClient && marketId !== undefined,
284
+ });
285
+ }
286
+ /**
287
+ * Hook to read on-chain prediction data for a specific user and market.
288
+ *
289
+ * @param marketId - The market ID to query, or undefined to skip
290
+ * @param account - The user's wallet address, or undefined to skip
291
+ * @returns TanStack query result with prediction data (amount, percentage, placedAt, claimed)
292
+ */
293
+ export function useOnChainPrediction(marketId, account) {
294
+ const publicClient = usePublicClient();
295
+ const chainId = getAppConfig().defaultChainId;
296
+ const client = useEVMClient();
297
+ return useQuery({
298
+ queryKey: ['onChainPrediction', chainId, marketId?.toString(), account],
299
+ queryFn: async () => {
300
+ if (!client || !publicClient || marketId === undefined || !account) {
301
+ return null;
302
+ }
303
+ return client.getPrediction(publicClient, marketId, account);
304
+ },
305
+ enabled: !!client && !!publicClient && marketId !== undefined && !!account,
306
+ });
307
+ }
308
+ /**
309
+ * Hook to lock a market after its deadline.
310
+ * Calculates market split and enables partial refunds for the overweight side.
311
+ * Anyone can call this after the market deadline.
312
+ *
313
+ * @returns TanStack mutation for locking markets
314
+ */
315
+ export function useLockMarket() {
316
+ const config = useConfig();
317
+ const chainId = getAppConfig().defaultChainId;
318
+ const client = useEVMClient();
319
+ const queryClient = useQueryClient();
320
+ return useMutation({
321
+ mutationFn: async ({ marketId }) => {
322
+ const { walletClient, publicClient } = await getClients(config, chainId);
323
+ if (!client || !walletClient || !publicClient) {
324
+ throw new Error('Client not available');
325
+ }
326
+ const result = await client.lockMarket({
327
+ walletClient,
328
+ publicClient,
329
+ chain: publicClient.chain,
330
+ }, marketId);
331
+ return result;
332
+ },
333
+ onSuccess: () => {
334
+ invalidateWithRetry(queryClient, [
335
+ ['heavymath', 'markets'],
336
+ ['heavymath', 'market'],
337
+ ['onChainMarket'],
338
+ ]);
339
+ },
340
+ meta: {
341
+ chainId,
342
+ },
343
+ });
344
+ }
345
+ /**
346
+ * Hook to claim a partial refund from a locked market.
347
+ * Available to bettors on the overweight side after market is locked.
348
+ *
349
+ * @returns TanStack mutation for claiming lock refunds
350
+ */
351
+ export function useClaimLockRefund() {
352
+ const config = useConfig();
353
+ const chainId = getAppConfig().defaultChainId;
354
+ const client = useEVMClient();
355
+ const queryClient = useQueryClient();
356
+ return useMutation({
357
+ mutationFn: async ({ marketId }) => {
358
+ const { walletClient, publicClient } = await getClients(config, chainId);
359
+ if (!client || !walletClient || !publicClient) {
360
+ throw new Error('Client not available');
361
+ }
362
+ const result = await client.claimLockRefund({
363
+ walletClient,
364
+ publicClient,
365
+ chain: publicClient.chain,
366
+ }, marketId);
367
+ return result;
368
+ },
369
+ onSuccess: () => {
370
+ invalidateWithRetry(queryClient, [
371
+ ['heavymath', 'predictions'],
372
+ ['heavymath', 'market'],
373
+ ['onChainMarket'],
374
+ ]);
375
+ },
376
+ meta: {
377
+ chainId,
378
+ },
379
+ });
380
+ }
381
+ /**
382
+ * Hook to read the lock refund amount for the current user on a market.
383
+ *
384
+ * @param marketId - The market ID to query, or undefined to skip
385
+ * @param account - The user's wallet address, or undefined to skip
386
+ * @returns TanStack query result with refund amount
387
+ */
388
+ export function useLockRefundAmount(marketId, account) {
389
+ const publicClient = usePublicClient();
390
+ const chainId = getAppConfig().defaultChainId;
391
+ const client = useEVMClient();
392
+ return useQuery({
393
+ queryKey: ['lockRefundAmount', chainId, marketId?.toString(), account],
394
+ queryFn: async () => {
395
+ if (!client || !publicClient || marketId === undefined || !account) {
396
+ return 0n;
397
+ }
398
+ return client.getLockRefundAmount(publicClient, marketId, account);
399
+ },
400
+ enabled: !!client && !!publicClient && marketId !== undefined && !!account,
401
+ });
402
+ }
403
+ /**
404
+ * Hook to read the lock split boundaries for a locked market.
405
+ * Returns negativePercentage and positivePercentage which define the under/over boundary.
406
+ *
407
+ * @param marketId - The market ID to query, or undefined to skip
408
+ * @returns TanStack query result with split boundary data
409
+ */
410
+ export function useMarketSplit(marketId) {
411
+ const publicClient = usePublicClient();
412
+ const chainId = getAppConfig().defaultChainId;
413
+ const client = useEVMClient();
414
+ return useQuery({
415
+ queryKey: ['marketSplit', chainId, marketId?.toString()],
416
+ queryFn: async () => {
417
+ if (!client || !publicClient || marketId === undefined) {
418
+ return null;
419
+ }
420
+ return client.getLockRefundsSplit(publicClient, marketId);
421
+ },
422
+ enabled: !!client && !!publicClient && marketId !== undefined,
423
+ });
424
+ }
425
+ /**
426
+ * Hook to read the contract's testMode flag.
427
+ * When true, markets can be locked/resolved without waiting for the deadline.
428
+ *
429
+ * @returns TanStack query result with boolean testMode value
430
+ */
431
+ export function useTestMode() {
432
+ const publicClient = usePublicClient();
433
+ const chainId = getAppConfig().defaultChainId;
434
+ const client = useEVMClient();
435
+ return useQuery({
436
+ queryKey: ['testMode', chainId],
437
+ queryFn: async () => {
438
+ if (!client || !publicClient) {
439
+ return false;
440
+ }
441
+ return client.getTestMode(publicClient);
442
+ },
443
+ enabled: !!client && !!publicClient,
444
+ staleTime: 60000, // cache for 1 minute — rarely changes
445
+ });
446
+ }
447
+ /** Minimal ABI for reading PredictionMarket.owner() (from OwnableUpgradeable) */
448
+ const OWNER_ABI = [
449
+ {
450
+ name: 'owner',
451
+ type: 'function',
452
+ stateMutability: 'view',
453
+ inputs: [],
454
+ outputs: [{ name: '', type: 'address' }],
455
+ },
456
+ ];
457
+ /**
458
+ * Hook to read the PredictionMarket contract owner address.
459
+ * Used to gate admin-only UI (e.g., Chainlink configuration).
460
+ *
461
+ * @returns TanStack query result with the owner address
462
+ */
463
+ export function useContractOwner() {
464
+ const config = useConfig();
465
+ const chainId = getAppConfig().defaultChainId;
466
+ const predictionMarketAddress = getContractAddress(chainId, 'predictionMarket');
467
+ const query = useQuery({
468
+ queryKey: ['contractOwner', chainId],
469
+ queryFn: async () => {
470
+ if (!predictionMarketAddress)
471
+ return null;
472
+ if (predictionMarketAddress === '0x0000000000000000000000000000000000000000')
473
+ return null;
474
+ const publicClient = getPublicClient(config, { chainId });
475
+ if (!publicClient)
476
+ return null;
477
+ const result = await publicClient.readContract({
478
+ address: predictionMarketAddress,
479
+ abi: OWNER_ABI,
480
+ functionName: 'owner',
481
+ });
482
+ console.log('[useContractOwner] owner:', result, 'chain:', chainId, 'contract:', predictionMarketAddress);
483
+ return result;
484
+ },
485
+ enabled: !!predictionMarketAddress,
486
+ staleTime: 300000,
487
+ });
488
+ if (query.error) {
489
+ console.error('[useContractOwner] error:', query.error);
490
+ }
491
+ return query;
492
+ }
493
+ /** Minimal ABI for reading OracleResolver.pendingResolution(uint256) */
494
+ const PENDING_RESOLUTION_ABI = [
495
+ {
496
+ name: 'pendingResolution',
497
+ type: 'function',
498
+ stateMutability: 'view',
499
+ inputs: [{ name: 'marketId', type: 'uint256' }],
500
+ outputs: [{ name: '', type: 'bool' }],
501
+ },
502
+ ];
503
+ /**
504
+ * Hook to check whether a Chainlink oracle resolution request is pending
505
+ * for a given market. Reads `pendingResolution(marketId)` from the
506
+ * OracleResolver contract.
507
+ *
508
+ * Polls every 10 seconds while the result is `true` (waiting for callback),
509
+ * and stops polling once it flips to `false`.
510
+ *
511
+ * @param marketId - The on-chain market ID (bigint), or undefined to skip
512
+ * @returns TanStack query result with boolean (true = request in flight)
513
+ */
514
+ export function usePendingResolution(marketId) {
515
+ const publicClient = usePublicClient();
516
+ const chainId = getAppConfig().defaultChainId;
517
+ const oracleResolverAddress = getContractAddress(chainId, 'oracleResolver');
518
+ return useQuery({
519
+ queryKey: ['pendingResolution', chainId, marketId?.toString()],
520
+ queryFn: async () => {
521
+ if (!publicClient || marketId === undefined || !oracleResolverAddress) {
522
+ return false;
523
+ }
524
+ // Skip if oracle resolver is the zero address (not deployed)
525
+ if (oracleResolverAddress === '0x0000000000000000000000000000000000000000') {
526
+ return false;
527
+ }
528
+ const result = await publicClient.readContract({
529
+ address: oracleResolverAddress,
530
+ abi: PENDING_RESOLUTION_ABI,
531
+ functionName: 'pendingResolution',
532
+ args: [marketId],
533
+ });
534
+ return result;
535
+ },
536
+ enabled: !!publicClient && marketId !== undefined && !!oracleResolverAddress,
537
+ // Poll every 10s while pending, stop when not pending
538
+ refetchInterval: query => (query.state.data === true ? 10000 : false),
539
+ });
540
+ }
541
+ /**
542
+ * Hook to create a new prediction market (dealer only).
543
+ *
544
+ * @returns TanStack mutation for creating markets
545
+ */
546
+ export function useCreateMarket() {
547
+ const config = useConfig();
548
+ const chainId = getAppConfig().defaultChainId;
549
+ const client = useEVMClient();
550
+ const queryClient = useQueryClient();
551
+ return useMutation({
552
+ mutationFn: async ({ tokenId, category, subCategory, deadline, description, oracleId, conditionData, }) => {
553
+ const { walletClient, publicClient } = await getClients(config, chainId);
554
+ if (!client || !walletClient || !publicClient) {
555
+ throw new Error('Client not available');
556
+ }
557
+ const result = await client.createMarket({
558
+ walletClient,
559
+ publicClient,
560
+ chain: publicClient.chain,
561
+ }, {
562
+ tokenId,
563
+ category,
564
+ subCategory,
565
+ deadline,
566
+ description,
567
+ oracleId,
568
+ conditionData,
569
+ });
570
+ return result;
571
+ },
572
+ onSuccess: () => {
573
+ invalidateWithRetry(queryClient, [
574
+ ['heavymath', 'markets'],
575
+ ['heavymath', 'dealer'],
576
+ ]);
577
+ },
578
+ meta: {
579
+ chainId,
580
+ },
581
+ });
582
+ }
583
+ /**
584
+ * Hook to resolve a market with a manual resolution value (dealer only).
585
+ *
586
+ * @returns TanStack mutation for resolving markets
587
+ */
588
+ export function useResolveMarket() {
589
+ const config = useConfig();
590
+ const chainId = getAppConfig().defaultChainId;
591
+ const client = useEVMClient();
592
+ const queryClient = useQueryClient();
593
+ return useMutation({
594
+ mutationFn: async ({ marketId, positiveOutcome, }) => {
595
+ const { walletClient, publicClient } = await getClients(config, chainId);
596
+ if (!client || !walletClient || !publicClient) {
597
+ throw new Error('Client not available');
598
+ }
599
+ const result = await client.resolveMarket({
600
+ walletClient,
601
+ publicClient,
602
+ chain: publicClient.chain,
603
+ }, marketId, positiveOutcome);
604
+ return result;
605
+ },
606
+ onSuccess: () => {
607
+ invalidateWithRetry(queryClient, [
608
+ ['heavymath', 'markets'],
609
+ ['heavymath', 'market'],
610
+ ['heavymath', 'market-history'],
611
+ ]);
612
+ },
613
+ meta: {
614
+ chainId,
615
+ },
616
+ });
617
+ }
618
+ /**
619
+ * Hook to resolve a market using oracle data (anyone can call after deadline).
620
+ *
621
+ * @returns TanStack mutation for oracle-based resolution
622
+ */
623
+ export function useResolveMarketWithOracle() {
624
+ const config = useConfig();
625
+ const chainId = getAppConfig().defaultChainId;
626
+ const client = useEVMClient();
627
+ const queryClient = useQueryClient();
628
+ return useMutation({
629
+ mutationFn: async ({ marketId }) => {
630
+ const { walletClient, publicClient } = await getClients(config, chainId);
631
+ if (!client || !walletClient || !publicClient) {
632
+ throw new Error('Client not available');
633
+ }
634
+ const result = await client.resolveMarketWithOracle({
635
+ walletClient,
636
+ publicClient,
637
+ chain: publicClient.chain,
638
+ }, marketId);
639
+ return result;
640
+ },
641
+ onSuccess: () => {
642
+ invalidateWithRetry(queryClient, [
643
+ ['heavymath', 'markets'],
644
+ ['heavymath', 'market'],
645
+ ['heavymath', 'market-history'],
646
+ ]);
647
+ },
648
+ meta: {
649
+ chainId,
650
+ },
651
+ });
652
+ }
653
+ /**
654
+ * Hook to request oracle resolution via Chainlink (step 1 of 2).
655
+ * Anyone can call. Sends a Chainlink request to fetch the game result.
656
+ *
657
+ * @returns TanStack mutation for requesting oracle resolution
658
+ */
659
+ export function useRequestOracleResolution() {
660
+ const config = useConfig();
661
+ const chainId = getAppConfig().defaultChainId;
662
+ const client = useEVMClient();
663
+ const queryClient = useQueryClient();
664
+ return useMutation({
665
+ mutationFn: async ({ marketId }) => {
666
+ const { walletClient, publicClient } = await getClients(config, chainId);
667
+ if (!client || !walletClient || !publicClient) {
668
+ throw new Error('Client not available');
669
+ }
670
+ const result = await client.requestOracleResolution({
671
+ walletClient,
672
+ publicClient,
673
+ chain: publicClient.chain,
674
+ }, marketId);
675
+ return result;
676
+ },
677
+ onSuccess: () => {
678
+ invalidateWithRetry(queryClient, [['heavymath', 'oracle-requests']]);
679
+ },
680
+ meta: {
681
+ chainId,
682
+ },
683
+ });
684
+ }
685
+ /**
686
+ * Hook to complete oracle resolution after Chainlink callback (step 2 of 2).
687
+ * Anyone can call after the Chainlink callback has delivered the result.
688
+ *
689
+ * @returns TanStack mutation for completing oracle resolution
690
+ */
691
+ export function useCompleteOracleResolution() {
692
+ const config = useConfig();
693
+ const chainId = getAppConfig().defaultChainId;
694
+ const client = useEVMClient();
695
+ const queryClient = useQueryClient();
696
+ return useMutation({
697
+ mutationFn: async ({ marketId }) => {
698
+ const { walletClient, publicClient } = await getClients(config, chainId);
699
+ if (!client || !walletClient || !publicClient) {
700
+ throw new Error('Client not available');
701
+ }
702
+ const result = await client.completeOracleResolution({
703
+ walletClient,
704
+ publicClient,
705
+ chain: publicClient.chain,
706
+ }, marketId);
707
+ return result;
708
+ },
709
+ onSuccess: () => {
710
+ invalidateWithRetry(queryClient, [
711
+ ['heavymath', 'markets'],
712
+ ['heavymath', 'market'],
713
+ ['heavymath', 'market-history'],
714
+ ]);
715
+ },
716
+ meta: {
717
+ chainId,
718
+ },
719
+ });
720
+ }
721
+ /**
722
+ * Hook to cancel a market (dealer only).
723
+ *
724
+ * @returns TanStack mutation for cancelling markets
725
+ */
726
+ export function useCancelMarket() {
727
+ const config = useConfig();
728
+ const chainId = getAppConfig().defaultChainId;
729
+ const client = useEVMClient();
730
+ const queryClient = useQueryClient();
731
+ return useMutation({
732
+ mutationFn: async ({ marketId }) => {
733
+ const { walletClient, publicClient } = await getClients(config, chainId);
734
+ if (!client || !walletClient || !publicClient) {
735
+ throw new Error('Client not available');
736
+ }
737
+ const result = await client.cancelMarket({
738
+ walletClient,
739
+ publicClient,
740
+ chain: publicClient.chain,
741
+ }, marketId);
742
+ return result;
743
+ },
744
+ onSuccess: () => {
745
+ invalidateWithRetry(queryClient, [
746
+ ['heavymath', 'markets'],
747
+ ['heavymath', 'market'],
748
+ ['heavymath', 'market-history'],
749
+ ]);
750
+ },
751
+ meta: {
752
+ chainId,
753
+ },
754
+ });
755
+ }
756
+ /**
757
+ * Hook to withdraw accumulated dealer fees from a resolved market (dealer only).
758
+ *
759
+ * @returns TanStack mutation for withdrawing dealer fees
760
+ */
761
+ export function useWithdrawDealerFees() {
762
+ const config = useConfig();
763
+ const chainId = getAppConfig().defaultChainId;
764
+ const client = useEVMClient();
765
+ const queryClient = useQueryClient();
766
+ return useMutation({
767
+ mutationFn: async ({ marketId }) => {
768
+ const { walletClient, publicClient } = await getClients(config, chainId);
769
+ if (!client || !walletClient || !publicClient) {
770
+ throw new Error('Client not available');
771
+ }
772
+ const result = await client.withdrawDealerFees({
773
+ walletClient,
774
+ publicClient,
775
+ chain: publicClient.chain,
776
+ }, marketId);
777
+ return result;
778
+ },
779
+ onSuccess: () => {
780
+ invalidateWithRetry(queryClient, [
781
+ ['heavymath', 'withdrawals'],
782
+ ['heavymath', 'market'],
783
+ ]);
784
+ },
785
+ meta: {
786
+ chainId,
787
+ },
788
+ });
789
+ }
790
+ //# sourceMappingURL=useMarketContract.js.map