@permissionless-technologies/upd-sdk 0.1.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 (68) hide show
  1. package/README.md +172 -0
  2. package/dist/chunk-4RBWWS2X.js +6616 -0
  3. package/dist/chunk-4RBWWS2X.js.map +1 -0
  4. package/dist/chunk-4VXNJTNQ.cjs +58 -0
  5. package/dist/chunk-4VXNJTNQ.cjs.map +1 -0
  6. package/dist/chunk-5NNXIJE4.js +16 -0
  7. package/dist/chunk-5NNXIJE4.js.map +1 -0
  8. package/dist/chunk-63FIKV36.js +49 -0
  9. package/dist/chunk-63FIKV36.js.map +1 -0
  10. package/dist/chunk-CZEDT3MS.cjs +62 -0
  11. package/dist/chunk-CZEDT3MS.cjs.map +1 -0
  12. package/dist/chunk-DF34ON56.cjs +18 -0
  13. package/dist/chunk-DF34ON56.cjs.map +1 -0
  14. package/dist/chunk-DJBU2OEB.js +57 -0
  15. package/dist/chunk-DJBU2OEB.js.map +1 -0
  16. package/dist/chunk-LNGWRYGY.js +3 -0
  17. package/dist/chunk-LNGWRYGY.js.map +1 -0
  18. package/dist/chunk-POBNO37G.cjs +4 -0
  19. package/dist/chunk-POBNO37G.cjs.map +1 -0
  20. package/dist/chunk-R64I3LAO.js +701 -0
  21. package/dist/chunk-R64I3LAO.js.map +1 -0
  22. package/dist/chunk-RIRT4JX6.js +1808 -0
  23. package/dist/chunk-RIRT4JX6.js.map +1 -0
  24. package/dist/chunk-WRPVPA7E.cjs +713 -0
  25. package/dist/chunk-WRPVPA7E.cjs.map +1 -0
  26. package/dist/chunk-ZDAHLZWC.cjs +1812 -0
  27. package/dist/chunk-ZDAHLZWC.cjs.map +1 -0
  28. package/dist/chunk-ZSWETUGH.cjs +6623 -0
  29. package/dist/chunk-ZSWETUGH.cjs.map +1 -0
  30. package/dist/constants-Bk2bGYfX.d.ts +64 -0
  31. package/dist/constants-BlOP_9dy.d.cts +64 -0
  32. package/dist/contracts/index.cjs +45 -0
  33. package/dist/contracts/index.cjs.map +1 -0
  34. package/dist/contracts/index.d.cts +6559 -0
  35. package/dist/contracts/index.d.ts +6559 -0
  36. package/dist/contracts/index.js +4 -0
  37. package/dist/contracts/index.js.map +1 -0
  38. package/dist/core/index.cjs +76 -0
  39. package/dist/core/index.cjs.map +1 -0
  40. package/dist/core/index.d.cts +5 -0
  41. package/dist/core/index.d.ts +5 -0
  42. package/dist/core/index.js +7 -0
  43. package/dist/core/index.js.map +1 -0
  44. package/dist/health-BUb4ItNt.d.ts +46 -0
  45. package/dist/health-DPxBqH7b.d.cts +46 -0
  46. package/dist/index-XNClksom.d.ts +415 -0
  47. package/dist/index-yRBqVOHV.d.cts +415 -0
  48. package/dist/index.cjs +138 -0
  49. package/dist/index.cjs.map +1 -0
  50. package/dist/index.d.cts +7 -0
  51. package/dist/index.d.ts +7 -0
  52. package/dist/index.js +9 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/oracle/index.cjs +30 -0
  55. package/dist/oracle/index.cjs.map +1 -0
  56. package/dist/oracle/index.d.cts +41 -0
  57. package/dist/oracle/index.d.ts +41 -0
  58. package/dist/oracle/index.js +5 -0
  59. package/dist/oracle/index.js.map +1 -0
  60. package/dist/react/index.cjs +383 -0
  61. package/dist/react/index.cjs.map +1 -0
  62. package/dist/react/index.d.cts +339 -0
  63. package/dist/react/index.d.ts +339 -0
  64. package/dist/react/index.js +370 -0
  65. package/dist/react/index.js.map +1 -0
  66. package/dist/types-DySv82My.d.cts +70 -0
  67. package/dist/types-DySv82My.d.ts +70 -0
  68. package/package.json +93 -0
@@ -0,0 +1,41 @@
1
+ import { a as OracleClientConfig, O as OracleClient } from '../constants-Bk2bGYfX.js';
2
+ export { D as DEFAULT_ORACLE_URL, b as DEFAULT_TIMEOUT, E as ETH_USD_ASSET_PAIR, d as OracleResponse, c as createMockAttestation } from '../constants-Bk2bGYfX.js';
3
+ import '../types-DySv82My.js';
4
+ import 'viem';
5
+
6
+ /**
7
+ * Oracle HTTP Client — Fetches signed price attestations from an oracle service.
8
+ *
9
+ * The oracle service returns signed ETH/USD prices in the exact format
10
+ * that PriceOracle.sol expects. The client deserializes the response
11
+ * into a PriceAttestationQuery that can be passed directly to
12
+ * UPDClient.mint() or UPDClient.burn().
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { createOracleClient } from '@permissionless-technologies/upd-sdk/oracle'
17
+ *
18
+ * const oracle = createOracleClient()
19
+ * const attestation = await oracle.getEthUsdAttestation()
20
+ *
21
+ * // Pass directly to mint
22
+ * await updClient.mint({ to: '0x...', ethAmount: parseEther('1'), priceAttestation: attestation })
23
+ * ```
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * // Custom oracle URL (e.g. local development)
28
+ * const oracle = createOracleClient({ oracleUrl: 'http://localhost:3000' })
29
+ * const { price } = await oracle.getEthUsdPrice()
30
+ * ```
31
+ */
32
+
33
+ /**
34
+ * Create an oracle client that fetches signed price attestations.
35
+ *
36
+ * @param config - Optional configuration (URL, timeout, custom fetch)
37
+ * @returns An OracleClient instance
38
+ */
39
+ declare function createOracleClient(config?: OracleClientConfig): OracleClient;
40
+
41
+ export { OracleClient, OracleClientConfig, createOracleClient };
@@ -0,0 +1,5 @@
1
+ import '../chunk-LNGWRYGY.js';
2
+ export { createMockAttestation } from '../chunk-5NNXIJE4.js';
3
+ export { DEFAULT_ORACLE_URL, DEFAULT_TIMEOUT, ETH_USD_ASSET_PAIR, createOracleClient } from '../chunk-DJBU2OEB.js';
4
+ //# sourceMappingURL=index.js.map
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,383 @@
1
+ 'use strict';
2
+
3
+ require('../chunk-ZDAHLZWC.cjs');
4
+ var chunk4VXNJTNQ_cjs = require('../chunk-4VXNJTNQ.cjs');
5
+ var chunkZSWETUGH_cjs = require('../chunk-ZSWETUGH.cjs');
6
+ var chunkCZEDT3MS_cjs = require('../chunk-CZEDT3MS.cjs');
7
+ var wagmi = require('wagmi');
8
+ var reactQuery = require('@tanstack/react-query');
9
+ var react = require('react');
10
+
11
+ function useUPD(config) {
12
+ const { tokenAddress, userAddress } = config;
13
+ const { data: balance, isLoading: balanceLoading } = wagmi.useReadContract({
14
+ address: tokenAddress,
15
+ abi: chunkZSWETUGH_cjs.UPD_TOKEN_ABI,
16
+ functionName: "balanceOf",
17
+ args: userAddress ? [userAddress] : void 0,
18
+ query: { enabled: !!userAddress }
19
+ });
20
+ const { data: totalSupply, isLoading: supplyLoading } = wagmi.useReadContract({
21
+ address: tokenAddress,
22
+ abi: chunkZSWETUGH_cjs.UPD_TOKEN_ABI,
23
+ functionName: "totalSupply"
24
+ });
25
+ return {
26
+ balance,
27
+ totalSupply,
28
+ isLoading: balanceLoading || supplyLoading
29
+ };
30
+ }
31
+ function useCollateral(config) {
32
+ const { reporterAddress, tokenAddress } = config;
33
+ const { data: totalStEthCollateral, isLoading: collateralLoading } = wagmi.useReadContract({
34
+ address: reporterAddress,
35
+ abi: chunkZSWETUGH_cjs.OVERCOLLATERALIZATION_REPORTER_ABI,
36
+ functionName: "totalStEthCollateral"
37
+ });
38
+ const { data: totalUPDSupply, isLoading: supplyLoading } = wagmi.useReadContract({
39
+ address: tokenAddress,
40
+ abi: chunkZSWETUGH_cjs.UPD_TOKEN_ABI,
41
+ functionName: "totalSupply"
42
+ });
43
+ return {
44
+ totalStEthCollateral,
45
+ totalUPDSupply,
46
+ isLoading: collateralLoading || supplyLoading
47
+ };
48
+ }
49
+ function useStabilizer(config) {
50
+ const { stabilizerNFTAddress, tokenId } = config;
51
+ const { data: positionEscrow, isLoading: posLoading } = wagmi.useReadContract({
52
+ address: stabilizerNFTAddress,
53
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
54
+ functionName: "positionEscrows",
55
+ args: tokenId !== void 0 ? [tokenId] : void 0,
56
+ query: { enabled: tokenId !== void 0 }
57
+ });
58
+ const { data: stabilizerEscrow, isLoading: stabLoading } = wagmi.useReadContract({
59
+ address: stabilizerNFTAddress,
60
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
61
+ functionName: "stabilizerEscrows",
62
+ args: tokenId !== void 0 ? [tokenId] : void 0,
63
+ query: { enabled: tokenId !== void 0 }
64
+ });
65
+ return {
66
+ positionEscrowAddress: positionEscrow,
67
+ stabilizerEscrowAddress: stabilizerEscrow,
68
+ isLoading: posLoading || stabLoading
69
+ };
70
+ }
71
+ function formatUsdPrice(price) {
72
+ if (price === void 0) return "--";
73
+ const priceFloat = Number(price) / 1e18;
74
+ return new Intl.NumberFormat("en-US", {
75
+ style: "currency",
76
+ currency: "USD",
77
+ minimumFractionDigits: 2,
78
+ maximumFractionDigits: 2
79
+ }).format(priceFloat);
80
+ }
81
+ function useEthUsdPrice(config) {
82
+ const oracleUrl = config?.oracleUrl;
83
+ const refetchInterval = config?.refetchInterval ?? 1e4;
84
+ const enabled = config?.enabled ?? true;
85
+ const oracle = chunkCZEDT3MS_cjs.createOracleClient({ oracleUrl });
86
+ const { data, isLoading, error, refetch } = reactQuery.useQuery({
87
+ queryKey: ["upd-oracle-eth-usd", oracleUrl],
88
+ queryFn: () => oracle.getEthUsdAttestation(),
89
+ refetchInterval,
90
+ enabled,
91
+ staleTime: 5e3
92
+ });
93
+ return {
94
+ price: data?.price,
95
+ priceFormatted: formatUsdPrice(data?.price),
96
+ attestation: data,
97
+ isLoading,
98
+ error,
99
+ refetch: () => {
100
+ refetch();
101
+ }
102
+ };
103
+ }
104
+ function useMintQuote(ethAmount, config) {
105
+ const { price, isLoading } = useEthUsdPrice({
106
+ ...config,
107
+ enabled: ethAmount > 0n && (config?.enabled ?? true)
108
+ });
109
+ const updAmount = react.useMemo(() => {
110
+ if (price === void 0 || ethAmount === 0n) return void 0;
111
+ return chunk4VXNJTNQ_cjs.quoteMintUPD(ethAmount, price);
112
+ }, [ethAmount, price]);
113
+ return {
114
+ updAmount,
115
+ ethUsdPrice: price,
116
+ isLoading
117
+ };
118
+ }
119
+ function useBurnQuote(updAmount, config) {
120
+ const { price, isLoading } = useEthUsdPrice({
121
+ ...config,
122
+ enabled: updAmount > 0n && (config?.enabled ?? true)
123
+ });
124
+ const stEthAmount = react.useMemo(() => {
125
+ if (price === void 0 || updAmount === 0n) return void 0;
126
+ return chunk4VXNJTNQ_cjs.quoteBurnUPD(updAmount, price);
127
+ }, [updAmount, price]);
128
+ return {
129
+ stEthAmount,
130
+ ethUsdPrice: price,
131
+ isLoading
132
+ };
133
+ }
134
+ function useMintUPD(config) {
135
+ const { stabilizerNFTAddress } = config;
136
+ const {
137
+ writeContract,
138
+ data: txHash,
139
+ isPending,
140
+ error: writeError,
141
+ reset
142
+ } = wagmi.useWriteContract();
143
+ const {
144
+ isLoading: isConfirming,
145
+ isSuccess: isConfirmed
146
+ } = wagmi.useWaitForTransactionReceipt({
147
+ hash: txHash
148
+ });
149
+ function mint(params) {
150
+ writeContract({
151
+ address: stabilizerNFTAddress,
152
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
153
+ functionName: "mintUPD",
154
+ args: [
155
+ params.to,
156
+ {
157
+ price: params.attestation.price,
158
+ decimals: params.attestation.decimals,
159
+ dataTimestamp: params.attestation.dataTimestamp,
160
+ assetPair: params.attestation.assetPair,
161
+ signature: params.attestation.signature
162
+ }
163
+ ],
164
+ value: params.ethAmount
165
+ });
166
+ }
167
+ return {
168
+ mint,
169
+ isPending,
170
+ txHash,
171
+ isConfirming,
172
+ isConfirmed,
173
+ error: writeError,
174
+ reset
175
+ };
176
+ }
177
+ function useBurnUPD(config) {
178
+ const { stabilizerNFTAddress } = config;
179
+ const {
180
+ writeContract,
181
+ data: txHash,
182
+ isPending,
183
+ error: writeError,
184
+ reset
185
+ } = wagmi.useWriteContract();
186
+ const {
187
+ isLoading: isConfirming,
188
+ isSuccess: isConfirmed
189
+ } = wagmi.useWaitForTransactionReceipt({
190
+ hash: txHash
191
+ });
192
+ function burn(params) {
193
+ writeContract({
194
+ address: stabilizerNFTAddress,
195
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
196
+ functionName: "burnUPD",
197
+ args: [
198
+ params.updAmount,
199
+ {
200
+ price: params.attestation.price,
201
+ decimals: params.attestation.decimals,
202
+ dataTimestamp: params.attestation.dataTimestamp,
203
+ assetPair: params.attestation.assetPair,
204
+ signature: params.attestation.signature
205
+ }
206
+ ]
207
+ });
208
+ }
209
+ return {
210
+ burn,
211
+ isPending,
212
+ txHash,
213
+ isConfirming,
214
+ isConfirmed,
215
+ error: writeError,
216
+ reset
217
+ };
218
+ }
219
+ function useSystemHealth(config) {
220
+ const collateralConfig = {
221
+ reporterAddress: config.reporterAddress,
222
+ tokenAddress: config.tokenAddress
223
+ };
224
+ const priceConfig = {
225
+ oracleUrl: config.oracleUrl
226
+ };
227
+ const {
228
+ totalStEthCollateral,
229
+ totalUPDSupply,
230
+ isLoading: collateralLoading
231
+ } = useCollateral(collateralConfig);
232
+ const {
233
+ price: ethUsdPrice,
234
+ isLoading: priceLoading
235
+ } = useEthUsdPrice(priceConfig);
236
+ const health = react.useMemo(() => {
237
+ if (totalStEthCollateral === void 0 || totalUPDSupply === void 0 || ethUsdPrice === void 0) {
238
+ return void 0;
239
+ }
240
+ return chunk4VXNJTNQ_cjs.computeSystemHealth(
241
+ { totalStEthCollateral, totalUPDSupply },
242
+ ethUsdPrice,
243
+ config.minRatioBps
244
+ );
245
+ }, [totalStEthCollateral, totalUPDSupply, ethUsdPrice, config.minRatioBps]);
246
+ return {
247
+ health,
248
+ isLoading: collateralLoading || priceLoading
249
+ };
250
+ }
251
+ function useSUPD(config) {
252
+ const { supdAddress, userAddress } = config;
253
+ const { data: balance, isLoading: balLoading } = wagmi.useReadContract({
254
+ address: supdAddress,
255
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
256
+ functionName: "balanceOf",
257
+ args: userAddress ? [userAddress] : void 0,
258
+ query: { enabled: !!userAddress }
259
+ });
260
+ const { data: totalSupply, isLoading: supplyLoading } = wagmi.useReadContract({
261
+ address: supdAddress,
262
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
263
+ functionName: "totalSupply"
264
+ });
265
+ const { data: shareValue, isLoading: svLoading } = wagmi.useReadContract({
266
+ address: supdAddress,
267
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
268
+ functionName: "currentShareValue"
269
+ });
270
+ const { data: annualYieldBps, isLoading: apyLoading } = wagmi.useReadContract({
271
+ address: supdAddress,
272
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
273
+ functionName: "annualYieldBps"
274
+ });
275
+ const { data: totalLiabilityUSD, isLoading: liabLoading } = wagmi.useReadContract({
276
+ address: supdAddress,
277
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
278
+ functionName: "totalLiabilityUSD"
279
+ });
280
+ return {
281
+ balance,
282
+ totalSupply,
283
+ shareValue,
284
+ annualYieldBps,
285
+ totalLiabilityUSD,
286
+ isLoading: balLoading || supplyLoading || svLoading || apyLoading || liabLoading
287
+ };
288
+ }
289
+ function useStakeUPD(config) {
290
+ const { supdAddress } = config;
291
+ const {
292
+ writeContract,
293
+ data: txHash,
294
+ isPending,
295
+ error: writeError,
296
+ reset
297
+ } = wagmi.useWriteContract();
298
+ const {
299
+ isLoading: isConfirming,
300
+ isSuccess: isConfirmed
301
+ } = wagmi.useWaitForTransactionReceipt({ hash: txHash });
302
+ function stake(params) {
303
+ writeContract({
304
+ address: supdAddress,
305
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
306
+ functionName: "stakeUPD",
307
+ args: [
308
+ params.updAmount,
309
+ {
310
+ price: params.attestation.price,
311
+ decimals: params.attestation.decimals,
312
+ dataTimestamp: params.attestation.dataTimestamp,
313
+ assetPair: params.attestation.assetPair,
314
+ signature: params.attestation.signature
315
+ }
316
+ ]
317
+ });
318
+ }
319
+ return {
320
+ stake,
321
+ isPending,
322
+ txHash,
323
+ isConfirming,
324
+ isConfirmed,
325
+ error: writeError,
326
+ reset
327
+ };
328
+ }
329
+ function useUnstakeUPD(config) {
330
+ const { supdAddress } = config;
331
+ const {
332
+ writeContract,
333
+ data: txHash,
334
+ isPending,
335
+ error: writeError,
336
+ reset
337
+ } = wagmi.useWriteContract();
338
+ const {
339
+ isLoading: isConfirming,
340
+ isSuccess: isConfirmed
341
+ } = wagmi.useWaitForTransactionReceipt({ hash: txHash });
342
+ function unstake(params) {
343
+ writeContract({
344
+ address: supdAddress,
345
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
346
+ functionName: "unstakeToUPD",
347
+ args: [
348
+ params.shares,
349
+ {
350
+ price: params.attestation.price,
351
+ decimals: params.attestation.decimals,
352
+ dataTimestamp: params.attestation.dataTimestamp,
353
+ assetPair: params.attestation.assetPair,
354
+ signature: params.attestation.signature
355
+ }
356
+ ]
357
+ });
358
+ }
359
+ return {
360
+ unstake,
361
+ isPending,
362
+ txHash,
363
+ isConfirming,
364
+ isConfirmed,
365
+ error: writeError,
366
+ reset
367
+ };
368
+ }
369
+
370
+ exports.useBurnQuote = useBurnQuote;
371
+ exports.useBurnUPD = useBurnUPD;
372
+ exports.useCollateral = useCollateral;
373
+ exports.useEthUsdPrice = useEthUsdPrice;
374
+ exports.useMintQuote = useMintQuote;
375
+ exports.useMintUPD = useMintUPD;
376
+ exports.useSUPD = useSUPD;
377
+ exports.useStabilizer = useStabilizer;
378
+ exports.useStakeUPD = useStakeUPD;
379
+ exports.useSystemHealth = useSystemHealth;
380
+ exports.useUPD = useUPD;
381
+ exports.useUnstakeUPD = useUnstakeUPD;
382
+ //# sourceMappingURL=index.cjs.map
383
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/react/use-upd.ts","../../src/react/use-collateral.ts","../../src/react/use-stabilizer.ts","../../src/react/use-eth-usd-price.ts","../../src/react/use-mint-quote.ts","../../src/react/use-burn-quote.ts","../../src/react/use-mint-upd.ts","../../src/react/use-burn-upd.ts","../../src/react/use-system-health.ts","../../src/react/use-supd.ts","../../src/react/use-stake-upd.ts","../../src/react/use-unstake-upd.ts"],"names":["useReadContract","UPD_TOKEN_ABI","OVERCOLLATERALIZATION_REPORTER_ABI","STABILIZER_NFT_ABI","createOracleClient","useQuery","useMemo","quoteMintUPD","quoteBurnUPD","useWriteContract","useWaitForTransactionReceipt","computeSystemHealth","SUPD_ABI"],"mappings":"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","file":"index.cjs","sourcesContent":["import { useReadContract } from 'wagmi'\nimport type { Address } from 'viem'\nimport { UPD_TOKEN_ABI } from '../contracts/index.js'\n\nexport interface UseUPDConfig {\n tokenAddress: Address\n userAddress?: Address\n}\n\nexport interface UseUPDReturn {\n balance: bigint | undefined\n totalSupply: bigint | undefined\n isLoading: boolean\n}\n\nexport function useUPD(config: UseUPDConfig): UseUPDReturn {\n const { tokenAddress, userAddress } = config\n\n const { data: balance, isLoading: balanceLoading } = useReadContract({\n address: tokenAddress,\n abi: UPD_TOKEN_ABI,\n functionName: 'balanceOf',\n args: userAddress ? [userAddress] : undefined,\n query: { enabled: !!userAddress },\n })\n\n const { data: totalSupply, isLoading: supplyLoading } = useReadContract({\n address: tokenAddress,\n abi: UPD_TOKEN_ABI,\n functionName: 'totalSupply',\n })\n\n return {\n balance: balance as bigint | undefined,\n totalSupply: totalSupply as bigint | undefined,\n isLoading: balanceLoading || supplyLoading,\n }\n}\n","import { useReadContract } from 'wagmi'\nimport type { Address } from 'viem'\nimport { OVERCOLLATERALIZATION_REPORTER_ABI } from '../contracts/index.js'\nimport { UPD_TOKEN_ABI } from '../contracts/index.js'\n\nexport interface UseCollateralConfig {\n reporterAddress: Address\n tokenAddress: Address\n}\n\nexport interface UseCollateralReturn {\n totalStEthCollateral: bigint | undefined\n totalUPDSupply: bigint | undefined\n isLoading: boolean\n}\n\nexport function useCollateral(config: UseCollateralConfig): UseCollateralReturn {\n const { reporterAddress, tokenAddress } = config\n\n const { data: totalStEthCollateral, isLoading: collateralLoading } =\n useReadContract({\n address: reporterAddress,\n abi: OVERCOLLATERALIZATION_REPORTER_ABI,\n functionName: 'totalStEthCollateral',\n })\n\n const { data: totalUPDSupply, isLoading: supplyLoading } = useReadContract({\n address: tokenAddress,\n abi: UPD_TOKEN_ABI,\n functionName: 'totalSupply',\n })\n\n return {\n totalStEthCollateral: totalStEthCollateral as bigint | undefined,\n totalUPDSupply: totalUPDSupply as bigint | undefined,\n isLoading: collateralLoading || supplyLoading,\n }\n}\n","import { useReadContract } from 'wagmi'\nimport type { Address } from 'viem'\nimport { STABILIZER_NFT_ABI } from '../contracts/index.js'\n\nexport interface UseStabilizerConfig {\n stabilizerNFTAddress: Address\n tokenId?: bigint\n}\n\nexport interface UseStabilizerReturn {\n positionEscrowAddress: Address | undefined\n stabilizerEscrowAddress: Address | undefined\n isLoading: boolean\n}\n\nexport function useStabilizer(\n config: UseStabilizerConfig,\n): UseStabilizerReturn {\n const { stabilizerNFTAddress, tokenId } = config\n\n const { data: positionEscrow, isLoading: posLoading } = useReadContract({\n address: stabilizerNFTAddress,\n abi: STABILIZER_NFT_ABI,\n functionName: 'positionEscrows',\n args: tokenId !== undefined ? [tokenId] : undefined,\n query: { enabled: tokenId !== undefined },\n })\n\n const { data: stabilizerEscrow, isLoading: stabLoading } = useReadContract({\n address: stabilizerNFTAddress,\n abi: STABILIZER_NFT_ABI,\n functionName: 'stabilizerEscrows',\n args: tokenId !== undefined ? [tokenId] : undefined,\n query: { enabled: tokenId !== undefined },\n })\n\n return {\n positionEscrowAddress: positionEscrow as Address | undefined,\n stabilizerEscrowAddress: stabilizerEscrow as Address | undefined,\n isLoading: posLoading || stabLoading,\n }\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { createOracleClient } from '../oracle/client.js'\nimport type { PriceAttestationQuery } from '../core/types.js'\n\nexport interface UseEthUsdPriceConfig {\n /** Oracle service URL. Defaults to oracle.upd.io. */\n oracleUrl?: string\n /** Refetch interval in milliseconds. Defaults to 10000 (10s). */\n refetchInterval?: number\n /** Whether to enable the query. Defaults to true. */\n enabled?: boolean\n}\n\nexport interface UseEthUsdPriceReturn {\n /** Raw price in 18 decimals (e.g. 2000e18 = $2000). */\n price: bigint | undefined\n /** Human-readable formatted price string (e.g. \"$2,000.00\"). */\n priceFormatted: string\n /** Full signed attestation, ready to pass to mint/burn. */\n attestation: PriceAttestationQuery | undefined\n /** Whether the initial fetch is loading. */\n isLoading: boolean\n /** Error from the most recent fetch, if any. */\n error: Error | null\n /** Manually trigger a refetch. */\n refetch: () => void\n}\n\nfunction formatUsdPrice(price: bigint | undefined): string {\n if (price === undefined) return '--'\n const priceFloat = Number(price) / 1e18\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(priceFloat)\n}\n\nexport function useEthUsdPrice(config?: UseEthUsdPriceConfig): UseEthUsdPriceReturn {\n const oracleUrl = config?.oracleUrl\n const refetchInterval = config?.refetchInterval ?? 10_000\n const enabled = config?.enabled ?? true\n\n const oracle = createOracleClient({ oracleUrl })\n\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: ['upd-oracle-eth-usd', oracleUrl],\n queryFn: () => oracle.getEthUsdAttestation(),\n refetchInterval,\n enabled,\n staleTime: 5_000,\n })\n\n return {\n price: data?.price,\n priceFormatted: formatUsdPrice(data?.price),\n attestation: data,\n isLoading,\n error: error as Error | null,\n refetch: () => { refetch() },\n }\n}\n","import { useMemo } from 'react'\nimport { useEthUsdPrice, type UseEthUsdPriceConfig } from './use-eth-usd-price.js'\nimport { quoteMintUPD } from '../core/quote.js'\n\nexport interface UseMintQuoteConfig extends UseEthUsdPriceConfig {}\n\nexport interface UseMintQuoteReturn {\n /** Expected UPD amount for the given ETH input (18 decimals). */\n updAmount: bigint | undefined\n /** Current ETH/USD price used for the quote (18 decimals). */\n ethUsdPrice: bigint | undefined\n /** Whether the price is still loading. */\n isLoading: boolean\n}\n\n/**\n * Real-time mint quote hook — composes oracle price + pure math.\n *\n * @param ethAmount - ETH amount to quote (in wei). Pass 0n to disable.\n * @param config - Optional oracle configuration.\n *\n * @example\n * ```tsx\n * const { updAmount, isLoading } = useMintQuote(parseEther('1'))\n * // updAmount ≈ 2000e18 (at $2000/ETH)\n * ```\n */\nexport function useMintQuote(\n ethAmount: bigint,\n config?: UseMintQuoteConfig,\n): UseMintQuoteReturn {\n const { price, isLoading } = useEthUsdPrice({\n ...config,\n enabled: ethAmount > 0n && (config?.enabled ?? true),\n })\n\n const updAmount = useMemo(() => {\n if (price === undefined || ethAmount === 0n) return undefined\n return quoteMintUPD(ethAmount, price)\n }, [ethAmount, price])\n\n return {\n updAmount,\n ethUsdPrice: price,\n isLoading,\n }\n}\n","import { useMemo } from 'react'\nimport { useEthUsdPrice, type UseEthUsdPriceConfig } from './use-eth-usd-price.js'\nimport { quoteBurnUPD } from '../core/quote.js'\n\nexport interface UseBurnQuoteConfig extends UseEthUsdPriceConfig {}\n\nexport interface UseBurnQuoteReturn {\n /** Expected stETH amount for the given UPD input (in wei). */\n stEthAmount: bigint | undefined\n /** Current ETH/USD price used for the quote (18 decimals). */\n ethUsdPrice: bigint | undefined\n /** Whether the price is still loading. */\n isLoading: boolean\n}\n\n/**\n * Real-time burn quote hook — composes oracle price + pure math.\n *\n * @param updAmount - UPD amount to quote (18 decimals). Pass 0n to disable.\n * @param config - Optional oracle configuration.\n *\n * @example\n * ```tsx\n * const { stEthAmount, isLoading } = useBurnQuote(parseUnits('2000', 18))\n * // stEthAmount ≈ 1e18 (at $2000/ETH)\n * ```\n */\nexport function useBurnQuote(\n updAmount: bigint,\n config?: UseBurnQuoteConfig,\n): UseBurnQuoteReturn {\n const { price, isLoading } = useEthUsdPrice({\n ...config,\n enabled: updAmount > 0n && (config?.enabled ?? true),\n })\n\n const stEthAmount = useMemo(() => {\n if (price === undefined || updAmount === 0n) return undefined\n return quoteBurnUPD(updAmount, price)\n }, [updAmount, price])\n\n return {\n stEthAmount,\n ethUsdPrice: price,\n isLoading,\n }\n}\n","import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi'\nimport type { Address, Hash } from 'viem'\nimport type { PriceAttestationQuery } from '../core/types.js'\nimport { STABILIZER_NFT_ABI } from '../contracts/index.js'\n\nexport interface UseMintUPDConfig {\n /** Address of the StabilizerNFT contract. */\n stabilizerNFTAddress: Address\n}\n\nexport interface UseMintUPDReturn {\n /** Execute the mint transaction. */\n mint: (params: {\n to: Address\n ethAmount: bigint\n attestation: PriceAttestationQuery\n }) => void\n /** Whether the transaction is being sent. */\n isPending: boolean\n /** Transaction hash once submitted. */\n txHash: Hash | undefined\n /** Whether we're waiting for confirmation. */\n isConfirming: boolean\n /** Whether the transaction is confirmed. */\n isConfirmed: boolean\n /** Error from the transaction, if any. */\n error: Error | null\n /** Reset the mutation state. */\n reset: () => void\n}\n\n/**\n * Write hook for minting UPD by depositing ETH.\n *\n * @example\n * ```tsx\n * const { mint, isPending, isConfirmed, error } = useMintUPD({\n * stabilizerNFTAddress: deployment.contracts.StabilizerNFT,\n * })\n *\n * // Use with useEthUsdPrice to get attestation\n * const { attestation } = useEthUsdPrice()\n *\n * <button onClick={() => mint({ to: userAddress, ethAmount: parseEther('1'), attestation })}>\n * Mint UPD\n * </button>\n * ```\n */\nexport function useMintUPD(config: UseMintUPDConfig): UseMintUPDReturn {\n const { stabilizerNFTAddress } = config\n\n const {\n writeContract,\n data: txHash,\n isPending,\n error: writeError,\n reset,\n } = useWriteContract()\n\n const {\n isLoading: isConfirming,\n isSuccess: isConfirmed,\n } = useWaitForTransactionReceipt({\n hash: txHash,\n })\n\n function mint(params: {\n to: Address\n ethAmount: bigint\n attestation: PriceAttestationQuery\n }) {\n writeContract({\n address: stabilizerNFTAddress,\n abi: STABILIZER_NFT_ABI,\n functionName: 'mintUPD',\n args: [\n params.to,\n {\n price: params.attestation.price,\n decimals: params.attestation.decimals,\n dataTimestamp: params.attestation.dataTimestamp,\n assetPair: params.attestation.assetPair,\n signature: params.attestation.signature,\n },\n ],\n value: params.ethAmount,\n })\n }\n\n return {\n mint,\n isPending,\n txHash,\n isConfirming,\n isConfirmed,\n error: writeError as Error | null,\n reset,\n }\n}\n","import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi'\nimport type { Address, Hash } from 'viem'\nimport type { PriceAttestationQuery } from '../core/types.js'\nimport { STABILIZER_NFT_ABI } from '../contracts/index.js'\n\nexport interface UseBurnUPDConfig {\n /** Address of the StabilizerNFT contract. */\n stabilizerNFTAddress: Address\n}\n\nexport interface UseBurnUPDReturn {\n /** Execute the burn transaction. */\n burn: (params: {\n updAmount: bigint\n attestation: PriceAttestationQuery\n }) => void\n /** Whether the transaction is being sent. */\n isPending: boolean\n /** Transaction hash once submitted. */\n txHash: Hash | undefined\n /** Whether we're waiting for confirmation. */\n isConfirming: boolean\n /** Whether the transaction is confirmed. */\n isConfirmed: boolean\n /** Error from the transaction, if any. */\n error: Error | null\n /** Reset the mutation state. */\n reset: () => void\n}\n\n/**\n * Write hook for burning UPD to receive stETH.\n *\n * @example\n * ```tsx\n * const { burn, isPending, isConfirmed } = useBurnUPD({\n * stabilizerNFTAddress: deployment.contracts.StabilizerNFT,\n * })\n *\n * const { attestation } = useEthUsdPrice()\n *\n * <button onClick={() => burn({ updAmount: parseUnits('1000', 18), attestation })}>\n * Burn 1000 UPD\n * </button>\n * ```\n */\nexport function useBurnUPD(config: UseBurnUPDConfig): UseBurnUPDReturn {\n const { stabilizerNFTAddress } = config\n\n const {\n writeContract,\n data: txHash,\n isPending,\n error: writeError,\n reset,\n } = useWriteContract()\n\n const {\n isLoading: isConfirming,\n isSuccess: isConfirmed,\n } = useWaitForTransactionReceipt({\n hash: txHash,\n })\n\n function burn(params: {\n updAmount: bigint\n attestation: PriceAttestationQuery\n }) {\n writeContract({\n address: stabilizerNFTAddress,\n abi: STABILIZER_NFT_ABI,\n functionName: 'burnUPD',\n args: [\n params.updAmount,\n {\n price: params.attestation.price,\n decimals: params.attestation.decimals,\n dataTimestamp: params.attestation.dataTimestamp,\n assetPair: params.attestation.assetPair,\n signature: params.attestation.signature,\n },\n ],\n })\n }\n\n return {\n burn,\n isPending,\n txHash,\n isConfirming,\n isConfirmed,\n error: writeError as Error | null,\n reset,\n }\n}\n","import { useMemo } from 'react'\nimport type { Address } from 'viem'\nimport { useCollateral, type UseCollateralConfig } from './use-collateral.js'\nimport { useEthUsdPrice, type UseEthUsdPriceConfig } from './use-eth-usd-price.js'\nimport { computeSystemHealth, type SystemHealth } from '../core/health.js'\n\nexport interface UseSystemHealthConfig {\n /** Address of the OvercollateralizationReporter contract. */\n reporterAddress: Address\n /** Address of the UPD token. */\n tokenAddress: Address\n /** Oracle service URL. */\n oracleUrl?: string\n /** Minimum collateral ratio in basis points (default: 12500 = 125%). */\n minRatioBps?: bigint\n}\n\nexport interface UseSystemHealthReturn {\n /** Computed system health metrics, or undefined if still loading. */\n health: SystemHealth | undefined\n /** Whether any underlying data is still loading. */\n isLoading: boolean\n}\n\n/**\n * System health hook — composes useCollateral + useEthUsdPrice + computeSystemHealth.\n *\n * @example\n * ```tsx\n * const { health, isLoading } = useSystemHealth({\n * reporterAddress: deployment.contracts.OvercollateralizationReporter,\n * tokenAddress: deployment.contracts.UPDToken,\n * })\n *\n * if (health && !health.isHealthy) {\n * return <Alert>System undercollateralized: {health.systemCollateralRatioBps} bps</Alert>\n * }\n * ```\n */\nexport function useSystemHealth(config: UseSystemHealthConfig): UseSystemHealthReturn {\n const collateralConfig: UseCollateralConfig = {\n reporterAddress: config.reporterAddress,\n tokenAddress: config.tokenAddress,\n }\n\n const priceConfig: UseEthUsdPriceConfig = {\n oracleUrl: config.oracleUrl,\n }\n\n const {\n totalStEthCollateral,\n totalUPDSupply,\n isLoading: collateralLoading,\n } = useCollateral(collateralConfig)\n\n const {\n price: ethUsdPrice,\n isLoading: priceLoading,\n } = useEthUsdPrice(priceConfig)\n\n const health = useMemo(() => {\n if (\n totalStEthCollateral === undefined ||\n totalUPDSupply === undefined ||\n ethUsdPrice === undefined\n ) {\n return undefined\n }\n\n return computeSystemHealth(\n { totalStEthCollateral, totalUPDSupply },\n ethUsdPrice,\n config.minRatioBps,\n )\n }, [totalStEthCollateral, totalUPDSupply, ethUsdPrice, config.minRatioBps])\n\n return {\n health,\n isLoading: collateralLoading || priceLoading,\n }\n}\n","import { useReadContract } from 'wagmi'\nimport type { Address } from 'viem'\nimport { SUPD_ABI } from '../contracts/index.js'\n\nexport interface UseSUPDConfig {\n /** Address of the sUPD contract. */\n supdAddress: Address\n /** User address to read balance for (optional). */\n userAddress?: Address\n}\n\nexport interface UseSUPDReturn {\n /** User's sUPD balance (18 decimals). */\n balance: bigint | undefined\n /** Total sUPD shares outstanding. */\n totalSupply: bigint | undefined\n /** Current share value with accrued yield (18 decimals). */\n shareValue: bigint | undefined\n /** Annual yield in basis points (e.g. 800 = 8%). */\n annualYieldBps: bigint | undefined\n /** Total USD liability of all outstanding sUPD. */\n totalLiabilityUSD: bigint | undefined\n /** Whether any read is still loading. */\n isLoading: boolean\n}\n\n/**\n * Read hook for sUPD — share value, APY, balances, and total liability.\n *\n * @example\n * ```tsx\n * const { balance, shareValue, annualYieldBps, isLoading } = useSUPD({\n * supdAddress: deployment.contracts.sUPD,\n * userAddress: account.address,\n * })\n * ```\n */\nexport function useSUPD(config: UseSUPDConfig): UseSUPDReturn {\n const { supdAddress, userAddress } = config\n\n const { data: balance, isLoading: balLoading } = useReadContract({\n address: supdAddress,\n abi: SUPD_ABI,\n functionName: 'balanceOf',\n args: userAddress ? [userAddress] : undefined,\n query: { enabled: !!userAddress },\n })\n\n const { data: totalSupply, isLoading: supplyLoading } = useReadContract({\n address: supdAddress,\n abi: SUPD_ABI,\n functionName: 'totalSupply',\n })\n\n const { data: shareValue, isLoading: svLoading } = useReadContract({\n address: supdAddress,\n abi: SUPD_ABI,\n functionName: 'currentShareValue',\n })\n\n const { data: annualYieldBps, isLoading: apyLoading } = useReadContract({\n address: supdAddress,\n abi: SUPD_ABI,\n functionName: 'annualYieldBps',\n })\n\n const { data: totalLiabilityUSD, isLoading: liabLoading } = useReadContract({\n address: supdAddress,\n abi: SUPD_ABI,\n functionName: 'totalLiabilityUSD',\n })\n\n return {\n balance: balance as bigint | undefined,\n totalSupply: totalSupply as bigint | undefined,\n shareValue: shareValue as bigint | undefined,\n annualYieldBps: annualYieldBps as bigint | undefined,\n totalLiabilityUSD: totalLiabilityUSD as bigint | undefined,\n isLoading: balLoading || supplyLoading || svLoading || apyLoading || liabLoading,\n }\n}\n","import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi'\nimport type { Address, Hash } from 'viem'\nimport type { PriceAttestationQuery } from '../core/types.js'\nimport { SUPD_ABI } from '../contracts/index.js'\n\nexport interface UseStakeUPDConfig {\n /** Address of the sUPD contract. */\n supdAddress: Address\n}\n\nexport interface UseStakeUPDReturn {\n /** Execute the stake transaction. User must approve UPD transfer to sUPD first. */\n stake: (params: {\n updAmount: bigint\n attestation: PriceAttestationQuery\n }) => void\n isPending: boolean\n txHash: Hash | undefined\n isConfirming: boolean\n isConfirmed: boolean\n error: Error | null\n reset: () => void\n}\n\n/**\n * Write hook for staking UPD → sUPD.\n *\n * Note: The user must first approve the sUPD contract to spend their UPD tokens\n * (via UPDToken.approve or EIP-3009 transferWithAuthorization).\n *\n * @example\n * ```tsx\n * const { stake, isPending } = useStakeUPD({\n * supdAddress: deployment.contracts.sUPD,\n * })\n *\n * const { attestation } = useEthUsdPrice()\n *\n * <button onClick={() => stake({ updAmount: parseUnits('1000', 18), attestation })}>\n * Stake 1000 UPD\n * </button>\n * ```\n */\nexport function useStakeUPD(config: UseStakeUPDConfig): UseStakeUPDReturn {\n const { supdAddress } = config\n\n const {\n writeContract,\n data: txHash,\n isPending,\n error: writeError,\n reset,\n } = useWriteContract()\n\n const {\n isLoading: isConfirming,\n isSuccess: isConfirmed,\n } = useWaitForTransactionReceipt({ hash: txHash })\n\n function stake(params: {\n updAmount: bigint\n attestation: PriceAttestationQuery\n }) {\n writeContract({\n address: supdAddress,\n abi: SUPD_ABI,\n functionName: 'stakeUPD',\n args: [\n params.updAmount,\n {\n price: params.attestation.price,\n decimals: params.attestation.decimals,\n dataTimestamp: params.attestation.dataTimestamp,\n assetPair: params.attestation.assetPair,\n signature: params.attestation.signature,\n },\n ],\n })\n }\n\n return {\n stake,\n isPending,\n txHash,\n isConfirming,\n isConfirmed,\n error: writeError as Error | null,\n reset,\n }\n}\n","import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi'\nimport type { Address, Hash } from 'viem'\nimport type { PriceAttestationQuery } from '../core/types.js'\nimport { SUPD_ABI } from '../contracts/index.js'\n\nexport interface UseUnstakeUPDConfig {\n /** Address of the sUPD contract. */\n supdAddress: Address\n}\n\nexport interface UseUnstakeUPDReturn {\n /** Execute the unstake transaction (unstakeToUPD — full redemption). */\n unstake: (params: {\n shares: bigint\n attestation: PriceAttestationQuery\n }) => void\n isPending: boolean\n txHash: Hash | undefined\n isConfirming: boolean\n isConfirmed: boolean\n error: Error | null\n reset: () => void\n}\n\n/**\n * Write hook for unstaking sUPD → UPD.\n *\n * Calls `unstakeToUPD(shares, priceQuery)` which gathers stETH from sUPD's\n * stabilizer escrows and mints fresh UPD to the caller.\n *\n * For advanced unstake variants (pro-rata, queued, with-extra-UPD), use the\n * contract ABI directly.\n *\n * @example\n * ```tsx\n * const { unstake, isPending } = useUnstakeUPD({\n * supdAddress: deployment.contracts.sUPD,\n * })\n *\n * const { attestation } = useEthUsdPrice()\n *\n * <button onClick={() => unstake({ shares: myShares, attestation })}>\n * Unstake\n * </button>\n * ```\n */\nexport function useUnstakeUPD(config: UseUnstakeUPDConfig): UseUnstakeUPDReturn {\n const { supdAddress } = config\n\n const {\n writeContract,\n data: txHash,\n isPending,\n error: writeError,\n reset,\n } = useWriteContract()\n\n const {\n isLoading: isConfirming,\n isSuccess: isConfirmed,\n } = useWaitForTransactionReceipt({ hash: txHash })\n\n function unstake(params: {\n shares: bigint\n attestation: PriceAttestationQuery\n }) {\n writeContract({\n address: supdAddress,\n abi: SUPD_ABI,\n functionName: 'unstakeToUPD',\n args: [\n params.shares,\n {\n price: params.attestation.price,\n decimals: params.attestation.decimals,\n dataTimestamp: params.attestation.dataTimestamp,\n assetPair: params.attestation.assetPair,\n signature: params.attestation.signature,\n },\n ],\n })\n }\n\n return {\n unstake,\n isPending,\n txHash,\n isConfirming,\n isConfirmed,\n error: writeError as Error | null,\n reset,\n }\n}\n"]}