@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,713 @@
1
+ 'use strict';
2
+
3
+ var chunk4VXNJTNQ_cjs = require('./chunk-4VXNJTNQ.cjs');
4
+ var chunkZSWETUGH_cjs = require('./chunk-ZSWETUGH.cjs');
5
+ var chunkCZEDT3MS_cjs = require('./chunk-CZEDT3MS.cjs');
6
+ var viem = require('viem');
7
+
8
+ // src/deployments/31337.json
9
+ var __default = {
10
+ contracts: {
11
+ UPDToken: "0x0000000000000000000000000000000000000000",
12
+ PriceOracle: "0x0000000000000000000000000000000000000000",
13
+ StabilizerNFT: "0x0000000000000000000000000000000000000000",
14
+ OvercollateralizationReporter: "0x0000000000000000000000000000000000000000",
15
+ InsuranceEscrow: "0x0000000000000000000000000000000000000000",
16
+ BridgeEscrow: "0x0000000000000000000000000000000000000000",
17
+ sUPD: "0x0000000000000000000000000000000000000000"
18
+ },
19
+ implementations: {
20
+ PriceOracle: "0x0000000000000000000000000000000000000000",
21
+ StabilizerNFT: "0x0000000000000000000000000000000000000000",
22
+ OvercollateralizationReporter: "0x0000000000000000000000000000000000000000"
23
+ },
24
+ libraries: {
25
+ LinkedListLib: "0x0000000000000000000000000000000000000000",
26
+ CollateralMathLib: "0x0000000000000000000000000000000000000000"
27
+ },
28
+ templates: {
29
+ StabilizerEscrow: "0x0000000000000000000000000000000000000000",
30
+ PositionEscrow: "0x0000000000000000000000000000000000000000"
31
+ },
32
+ external: {
33
+ stETH: "0x0000000000000000000000000000000000000000",
34
+ lido: "0x0000000000000000000000000000000000000000",
35
+ oracleSigner: "0x0000000000000000000000000000000000000000"
36
+ },
37
+ metadata: {
38
+ chainId: 31337,
39
+ deployBlock: 0,
40
+ deployTimestamp: 0,
41
+ deployer: "0x0000000000000000000000000000000000000000"
42
+ }
43
+ };
44
+
45
+ // src/deployments/11155111.json
46
+ var __default2 = {
47
+ contracts: {
48
+ UPDToken: "0x0000000000000000000000000000000000000000",
49
+ PriceOracle: "0x0000000000000000000000000000000000000000",
50
+ StabilizerNFT: "0x0000000000000000000000000000000000000000",
51
+ OvercollateralizationReporter: "0x0000000000000000000000000000000000000000",
52
+ InsuranceEscrow: "0x0000000000000000000000000000000000000000",
53
+ BridgeEscrow: "0x0000000000000000000000000000000000000000",
54
+ sUPD: "0x0000000000000000000000000000000000000000"
55
+ },
56
+ implementations: {
57
+ PriceOracle: "0x0000000000000000000000000000000000000000",
58
+ StabilizerNFT: "0x0000000000000000000000000000000000000000",
59
+ OvercollateralizationReporter: "0x0000000000000000000000000000000000000000"
60
+ },
61
+ libraries: {
62
+ LinkedListLib: "0x0000000000000000000000000000000000000000",
63
+ CollateralMathLib: "0x0000000000000000000000000000000000000000"
64
+ },
65
+ templates: {
66
+ StabilizerEscrow: "0x0000000000000000000000000000000000000000",
67
+ PositionEscrow: "0x0000000000000000000000000000000000000000"
68
+ },
69
+ external: {
70
+ stETH: "0x0000000000000000000000000000000000000000",
71
+ lido: "0x0000000000000000000000000000000000000000",
72
+ oracleSigner: "0x0000000000000000000000000000000000000000"
73
+ },
74
+ metadata: {
75
+ chainId: 11155111,
76
+ deployBlock: 0,
77
+ deployTimestamp: 0,
78
+ deployer: "0x0000000000000000000000000000000000000000"
79
+ }
80
+ };
81
+
82
+ // src/deployments/index.ts
83
+ function parseDeployment(json, chainId) {
84
+ return {
85
+ chainId,
86
+ contracts: {
87
+ UPDToken: json.contracts.UPDToken,
88
+ PriceOracle: json.contracts.PriceOracle,
89
+ StabilizerNFT: json.contracts.StabilizerNFT,
90
+ OvercollateralizationReporter: json.contracts.OvercollateralizationReporter,
91
+ InsuranceEscrow: json.contracts.InsuranceEscrow,
92
+ BridgeEscrow: json.contracts.BridgeEscrow,
93
+ sUPD: json.contracts.sUPD
94
+ },
95
+ implementations: {
96
+ PriceOracle: json.implementations.PriceOracle,
97
+ StabilizerNFT: json.implementations.StabilizerNFT,
98
+ OvercollateralizationReporter: json.implementations.OvercollateralizationReporter
99
+ },
100
+ libraries: {
101
+ LinkedListLib: json.libraries.LinkedListLib,
102
+ CollateralMathLib: json.libraries.CollateralMathLib
103
+ },
104
+ templates: {
105
+ StabilizerEscrow: json.templates.StabilizerEscrow,
106
+ PositionEscrow: json.templates.PositionEscrow
107
+ },
108
+ external: {
109
+ stETH: json.external.stETH,
110
+ lido: json.external.lido,
111
+ oracleSigner: json.external.oracleSigner
112
+ },
113
+ metadata: {
114
+ deployBlock: json.metadata.deployBlock,
115
+ deployTimestamp: json.metadata.deployTimestamp,
116
+ deployer: json.metadata.deployer
117
+ }
118
+ };
119
+ }
120
+ var deployments = {
121
+ 31337: parseDeployment(__default, 31337),
122
+ 11155111: parseDeployment(__default2, 11155111)
123
+ };
124
+ function getDeployment(chainId) {
125
+ return deployments[chainId] ?? null;
126
+ }
127
+ function getDeploymentOrThrow(chainId) {
128
+ const deployment = getDeployment(chainId);
129
+ if (!deployment) {
130
+ throw new Error(
131
+ `No UPD deployment found for chain ${chainId}. Supported chains: ${getSupportedChainIds().join(", ")}`
132
+ );
133
+ }
134
+ return deployment;
135
+ }
136
+ function hasDeployment(chainId) {
137
+ return chainId in deployments;
138
+ }
139
+ function getSupportedChainIds() {
140
+ return Object.keys(deployments).map(Number);
141
+ }
142
+ function getContractAddress(chainId, contractName) {
143
+ const deployment = getDeployment(chainId);
144
+ if (!deployment) return null;
145
+ return deployment.contracts[contractName] ?? null;
146
+ }
147
+
148
+ // src/core/client.ts
149
+ var UPDClient = class {
150
+ config;
151
+ deployment;
152
+ oracle;
153
+ constructor(config) {
154
+ this.config = config;
155
+ this.deployment = getDeploymentOrThrow(config.chainId);
156
+ this.oracle = chunkCZEDT3MS_cjs.createOracleClient({ oracleUrl: config.oracleUrl });
157
+ }
158
+ // ============================================================
159
+ // READ OPERATIONS
160
+ // ============================================================
161
+ /** Get UPD token balance for an address. */
162
+ async getUPDBalance(address) {
163
+ return this.config.publicClient.readContract({
164
+ address: this.deployment.contracts.UPDToken,
165
+ abi: chunkZSWETUGH_cjs.UPD_TOKEN_ABI,
166
+ functionName: "balanceOf",
167
+ args: [address]
168
+ });
169
+ }
170
+ /** Get total UPD supply. */
171
+ async getTotalSupply() {
172
+ return this.config.publicClient.readContract({
173
+ address: this.deployment.contracts.UPDToken,
174
+ abi: chunkZSWETUGH_cjs.UPD_TOKEN_ABI,
175
+ functionName: "totalSupply"
176
+ });
177
+ }
178
+ /** Get system collateral info: total stETH collateral and total UPD supply. */
179
+ async getCollateralInfo() {
180
+ const [totalStEthCollateral, totalUPDSupply] = await Promise.all([
181
+ this.config.publicClient.readContract({
182
+ address: this.deployment.contracts.OvercollateralizationReporter,
183
+ abi: chunkZSWETUGH_cjs.OVERCOLLATERALIZATION_REPORTER_ABI,
184
+ functionName: "totalStEthCollateral"
185
+ }),
186
+ this.getTotalSupply()
187
+ ]);
188
+ return { totalStEthCollateral, totalUPDSupply };
189
+ }
190
+ /** Get details for a specific stabilizer position. */
191
+ async getStabilizerPosition(tokenId) {
192
+ const stabNFT = this.deployment.contracts.StabilizerNFT;
193
+ const [posEscrowAddr, stabEscrowAddr, minRatio] = await Promise.all([
194
+ this.config.publicClient.readContract({
195
+ address: stabNFT,
196
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
197
+ functionName: "positionEscrows",
198
+ args: [tokenId]
199
+ }),
200
+ this.config.publicClient.readContract({
201
+ address: stabNFT,
202
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
203
+ functionName: "stabilizerEscrows",
204
+ args: [tokenId]
205
+ }),
206
+ this.config.publicClient.readContract({
207
+ address: stabNFT,
208
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
209
+ functionName: "minCollateralRatios",
210
+ args: [tokenId]
211
+ })
212
+ ]);
213
+ const [backedUPDAmount, stETHBalance, unallocatedStETH] = await Promise.all([
214
+ this.config.publicClient.readContract({
215
+ address: posEscrowAddr,
216
+ abi: chunkZSWETUGH_cjs.POSITION_ESCROW_ABI,
217
+ functionName: "backedUPDAmount"
218
+ }),
219
+ this.config.publicClient.readContract({
220
+ address: posEscrowAddr,
221
+ abi: chunkZSWETUGH_cjs.POSITION_ESCROW_ABI,
222
+ functionName: "getCurrentStEthBalance"
223
+ }),
224
+ this.config.publicClient.readContract({
225
+ address: stabEscrowAddr,
226
+ abi: chunkZSWETUGH_cjs.STABILIZER_ESCROW_ABI,
227
+ functionName: "unallocatedStETH"
228
+ })
229
+ ]);
230
+ let collateralizationRatio2 = 0n;
231
+ if (backedUPDAmount > 0n && stETHBalance > 0n) {
232
+ collateralizationRatio2 = 0n;
233
+ }
234
+ return {
235
+ tokenId,
236
+ positionEscrowAddress: posEscrowAddr,
237
+ stabilizerEscrowAddress: stabEscrowAddr,
238
+ collateralizationRatio: collateralizationRatio2,
239
+ backedUPDAmount,
240
+ stETHBalance,
241
+ unallocatedStETH,
242
+ minCollateralRatio: minRatio
243
+ };
244
+ }
245
+ // ============================================================
246
+ // WRITE OPERATIONS
247
+ // ============================================================
248
+ /**
249
+ * Mint UPD by sending ETH. Requires walletClient.
250
+ *
251
+ * @example
252
+ * ```ts
253
+ * const attestation = createMockAttestation(2000n * 10n**18n)
254
+ * const hash = await client.mint({
255
+ * to: '0x...',
256
+ * ethAmount: parseEther('1'),
257
+ * priceAttestation: attestation,
258
+ * })
259
+ * ```
260
+ */
261
+ async mint(params) {
262
+ const walletClient = this._requireWallet();
263
+ const { to, ethAmount, priceAttestation } = params;
264
+ return walletClient.writeContract({
265
+ address: this.deployment.contracts.StabilizerNFT,
266
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
267
+ functionName: "mintUPD",
268
+ args: [to, this._toSolidityAttestation(priceAttestation)],
269
+ value: ethAmount,
270
+ chain: walletClient.chain ?? null,
271
+ account: walletClient.account
272
+ });
273
+ }
274
+ /**
275
+ * Burn UPD to receive stETH. Requires walletClient.
276
+ *
277
+ * @example
278
+ * ```ts
279
+ * const attestation = createMockAttestation(2000n * 10n**18n)
280
+ * const hash = await client.burn({
281
+ * updAmount: parseUnits('2000', 18),
282
+ * priceAttestation: attestation,
283
+ * })
284
+ * ```
285
+ */
286
+ async burn(params) {
287
+ const walletClient = this._requireWallet();
288
+ const { updAmount, priceAttestation } = params;
289
+ return walletClient.writeContract({
290
+ address: this.deployment.contracts.StabilizerNFT,
291
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
292
+ functionName: "burnUPD",
293
+ args: [updAmount, this._toSolidityAttestation(priceAttestation)],
294
+ chain: walletClient.chain ?? null,
295
+ account: walletClient.account
296
+ });
297
+ }
298
+ // ============================================================
299
+ // sUPD OPERATIONS
300
+ // ============================================================
301
+ /** Get sUPD contract info: share value, APY, supply, liability. */
302
+ async getSUPDInfo() {
303
+ const supdAddr = this.deployment.contracts.sUPD;
304
+ if (!supdAddr) throw new Error("sUPD not deployed on this chain");
305
+ const [shareValue, annualYieldBps, totalSupply, totalLiabilityUSD] = await Promise.all([
306
+ this.config.publicClient.readContract({
307
+ address: supdAddr,
308
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
309
+ functionName: "currentShareValue"
310
+ }),
311
+ this.config.publicClient.readContract({
312
+ address: supdAddr,
313
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
314
+ functionName: "annualYieldBps"
315
+ }),
316
+ this.config.publicClient.readContract({
317
+ address: supdAddr,
318
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
319
+ functionName: "totalSupply"
320
+ }),
321
+ this.config.publicClient.readContract({
322
+ address: supdAddr,
323
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
324
+ functionName: "totalLiabilityUSD"
325
+ })
326
+ ]);
327
+ return { shareValue, annualYieldBps, totalSupply, totalLiabilityUSD };
328
+ }
329
+ /** Stake UPD to receive sUPD shares. Requires walletClient. */
330
+ async stakeUPD(params) {
331
+ const walletClient = this._requireWallet();
332
+ const supdAddr = this.deployment.contracts.sUPD;
333
+ if (!supdAddr) throw new Error("sUPD not deployed on this chain");
334
+ return walletClient.writeContract({
335
+ address: supdAddr,
336
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
337
+ functionName: "stakeUPD",
338
+ args: [params.updAmount, this._toSolidityAttestation(params.priceAttestation)],
339
+ chain: walletClient.chain ?? null,
340
+ account: walletClient.account
341
+ });
342
+ }
343
+ /** Unstake sUPD shares to receive UPD. Requires walletClient. */
344
+ async unstakeUPD(params) {
345
+ const walletClient = this._requireWallet();
346
+ const supdAddr = this.deployment.contracts.sUPD;
347
+ if (!supdAddr) throw new Error("sUPD not deployed on this chain");
348
+ return walletClient.writeContract({
349
+ address: supdAddr,
350
+ abi: chunkZSWETUGH_cjs.SUPD_ABI,
351
+ functionName: "unstakeToUPD",
352
+ args: [params.shares, this._toSolidityAttestation(params.priceAttestation)],
353
+ chain: walletClient.chain ?? null,
354
+ account: walletClient.account
355
+ });
356
+ }
357
+ // ============================================================
358
+ // CONVENIENCE METHODS
359
+ // ============================================================
360
+ /**
361
+ * Mint UPD by sending ETH, automatically fetching a price attestation from the oracle.
362
+ *
363
+ * @example
364
+ * ```ts
365
+ * const hash = await client.mintWithOracle({
366
+ * to: '0x...',
367
+ * ethAmount: parseEther('1'),
368
+ * })
369
+ * ```
370
+ */
371
+ async mintWithOracle(params) {
372
+ const attestation = await this.oracle.getEthUsdAttestation();
373
+ return this.mint({ ...params, priceAttestation: attestation });
374
+ }
375
+ /**
376
+ * Burn UPD to receive stETH, automatically fetching a price attestation from the oracle.
377
+ *
378
+ * @example
379
+ * ```ts
380
+ * const hash = await client.burnWithOracle({
381
+ * updAmount: parseUnits('2000', 18),
382
+ * })
383
+ * ```
384
+ */
385
+ async burnWithOracle(params) {
386
+ const attestation = await this.oracle.getEthUsdAttestation();
387
+ return this.burn({ ...params, priceAttestation: attestation });
388
+ }
389
+ /**
390
+ * Get system health metrics by combining on-chain collateral data with oracle price.
391
+ *
392
+ * @example
393
+ * ```ts
394
+ * const health = await client.getSystemHealth()
395
+ * console.log(`System ratio: ${health.systemCollateralRatioBps} bps`)
396
+ * console.log(`Healthy: ${health.isHealthy}`)
397
+ * ```
398
+ */
399
+ async getSystemHealth() {
400
+ const [collateral, { price }] = await Promise.all([
401
+ this.getCollateralInfo(),
402
+ this.oracle.getEthUsdPrice()
403
+ ]);
404
+ return chunk4VXNJTNQ_cjs.computeSystemHealth(collateral, price);
405
+ }
406
+ /** Stake UPD, fetching oracle attestation automatically. */
407
+ async stakeUPDWithOracle(params) {
408
+ const attestation = await this.oracle.getEthUsdAttestation();
409
+ return this.stakeUPD({ ...params, priceAttestation: attestation });
410
+ }
411
+ /** Unstake sUPD, fetching oracle attestation automatically. */
412
+ async unstakeUPDWithOracle(params) {
413
+ const attestation = await this.oracle.getEthUsdAttestation();
414
+ return this.unstakeUPD({ ...params, priceAttestation: attestation });
415
+ }
416
+ // ============================================================
417
+ // HELPERS
418
+ // ============================================================
419
+ _requireWallet() {
420
+ if (!this.config.walletClient) {
421
+ throw new Error(
422
+ "UPDClient: walletClient is required for write operations. Pass a walletClient in the config to use mint/burn."
423
+ );
424
+ }
425
+ return this.config.walletClient;
426
+ }
427
+ _toSolidityAttestation(a) {
428
+ return {
429
+ price: a.price,
430
+ decimals: a.decimals,
431
+ dataTimestamp: a.dataTimestamp,
432
+ assetPair: a.assetPair,
433
+ signature: a.signature
434
+ };
435
+ }
436
+ };
437
+ function createUPDClient(config) {
438
+ return new UPDClient(config);
439
+ }
440
+ var EIP3009_DOMAIN_VERSION = "1";
441
+ function randomNonce() {
442
+ const bytes = new Uint8Array(32);
443
+ crypto.getRandomValues(bytes);
444
+ return viem.bytesToHex(bytes);
445
+ }
446
+ function eip3009Domain(tokenAddress, chainId, tokenName) {
447
+ return {
448
+ name: tokenName,
449
+ version: EIP3009_DOMAIN_VERSION,
450
+ chainId,
451
+ verifyingContract: tokenAddress
452
+ };
453
+ }
454
+ async function signTransferAuthorization(params, tokenName = "Universal Private Dollar") {
455
+ const {
456
+ walletClient,
457
+ tokenAddress,
458
+ from,
459
+ to,
460
+ value,
461
+ validAfter = 0n,
462
+ validBefore = BigInt(Math.floor(Date.now() / 1e3) + 3600),
463
+ nonce = randomNonce()
464
+ } = params;
465
+ const chainId = walletClient.chain?.id;
466
+ if (!chainId) throw new Error("walletClient must have a chain configured");
467
+ const signature = await walletClient.signTypedData({
468
+ account: from,
469
+ domain: eip3009Domain(tokenAddress, chainId, tokenName),
470
+ types: {
471
+ TransferWithAuthorization: [
472
+ { name: "from", type: "address" },
473
+ { name: "to", type: "address" },
474
+ { name: "value", type: "uint256" },
475
+ { name: "validAfter", type: "uint256" },
476
+ { name: "validBefore", type: "uint256" },
477
+ { name: "nonce", type: "bytes32" }
478
+ ]
479
+ },
480
+ primaryType: "TransferWithAuthorization",
481
+ message: { from, to, value, validAfter, validBefore, nonce }
482
+ });
483
+ const sigBytes = viem.hexToBytes(signature);
484
+ const r = viem.bytesToHex(sigBytes.slice(0, 32));
485
+ const s = viem.bytesToHex(sigBytes.slice(32, 64));
486
+ const v = sigBytes[64];
487
+ return { from, to, value, validAfter, validBefore, nonce, v, r, s };
488
+ }
489
+ async function signReceiveAuthorization(params, tokenName = "Universal Private Dollar") {
490
+ const {
491
+ walletClient,
492
+ tokenAddress,
493
+ from,
494
+ to,
495
+ value,
496
+ validAfter = 0n,
497
+ validBefore = BigInt(Math.floor(Date.now() / 1e3) + 3600),
498
+ nonce = randomNonce()
499
+ } = params;
500
+ const chainId = walletClient.chain?.id;
501
+ if (!chainId) throw new Error("walletClient must have a chain configured");
502
+ const signature = await walletClient.signTypedData({
503
+ account: from,
504
+ domain: eip3009Domain(tokenAddress, chainId, tokenName),
505
+ types: {
506
+ ReceiveWithAuthorization: [
507
+ { name: "from", type: "address" },
508
+ { name: "to", type: "address" },
509
+ { name: "value", type: "uint256" },
510
+ { name: "validAfter", type: "uint256" },
511
+ { name: "validBefore", type: "uint256" },
512
+ { name: "nonce", type: "bytes32" }
513
+ ]
514
+ },
515
+ primaryType: "ReceiveWithAuthorization",
516
+ message: { from, to, value, validAfter, validBefore, nonce }
517
+ });
518
+ const sigBytes = viem.hexToBytes(signature);
519
+ const r = viem.bytesToHex(sigBytes.slice(0, 32));
520
+ const s = viem.bytesToHex(sigBytes.slice(32, 64));
521
+ const v = sigBytes[64];
522
+ return { from, to, value, validAfter, validBefore, nonce, v, r, s };
523
+ }
524
+ async function signCancelAuthorization(params, tokenName = "Universal Private Dollar") {
525
+ const { walletClient, tokenAddress, authorizer, nonce } = params;
526
+ const chainId = walletClient.chain?.id;
527
+ if (!chainId) throw new Error("walletClient must have a chain configured");
528
+ const signature = await walletClient.signTypedData({
529
+ account: authorizer,
530
+ domain: eip3009Domain(tokenAddress, chainId, tokenName),
531
+ types: {
532
+ CancelAuthorization: [
533
+ { name: "authorizer", type: "address" },
534
+ { name: "nonce", type: "bytes32" }
535
+ ]
536
+ },
537
+ primaryType: "CancelAuthorization",
538
+ message: { authorizer, nonce }
539
+ });
540
+ const sigBytes = viem.hexToBytes(signature);
541
+ const r = viem.bytesToHex(sigBytes.slice(0, 32));
542
+ const s = viem.bytesToHex(sigBytes.slice(32, 64));
543
+ const v = sigBytes[64];
544
+ return { authorizer, nonce, v, r, s };
545
+ }
546
+
547
+ // src/core/verify.ts
548
+ var ERC1967_IMPL_SLOT = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
549
+ async function verifyDeployment(publicClient, deployment) {
550
+ const checks = [];
551
+ await _verifyBytecode(publicClient, checks, "UPDToken", deployment.contracts.UPDToken);
552
+ await _verifyBytecode(publicClient, checks, "PriceOracle", deployment.contracts.PriceOracle);
553
+ await _verifyBytecode(publicClient, checks, "StabilizerNFT", deployment.contracts.StabilizerNFT);
554
+ await _verifyBytecode(publicClient, checks, "Reporter", deployment.contracts.OvercollateralizationReporter);
555
+ await _verifyBytecode(publicClient, checks, "InsuranceEscrow", deployment.contracts.InsuranceEscrow);
556
+ await _verifyProxyImpl(publicClient, checks, "PriceOracle", deployment.contracts.PriceOracle, deployment.implementations.PriceOracle);
557
+ await _verifyProxyImpl(publicClient, checks, "StabilizerNFT", deployment.contracts.StabilizerNFT, deployment.implementations.StabilizerNFT);
558
+ await _verifyProxyImpl(publicClient, checks, "Reporter", deployment.contracts.OvercollateralizationReporter, deployment.implementations.OvercollateralizationReporter);
559
+ await _verifyStabilizerNFTStorage(publicClient, checks, deployment);
560
+ await _verifyReporterStorage(publicClient, checks, deployment);
561
+ await _verifyRole(
562
+ publicClient,
563
+ checks,
564
+ "UPDToken MINTER_ROLE -> StabilizerNFT",
565
+ deployment.contracts.UPDToken,
566
+ chunkZSWETUGH_cjs.UPD_TOKEN_ABI,
567
+ "0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6",
568
+ // keccak256("MINTER_ROLE")
569
+ deployment.contracts.StabilizerNFT
570
+ );
571
+ await _verifyRole(
572
+ publicClient,
573
+ checks,
574
+ "UPDToken BURNER_ROLE -> StabilizerNFT",
575
+ deployment.contracts.UPDToken,
576
+ chunkZSWETUGH_cjs.UPD_TOKEN_ABI,
577
+ "0x3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848",
578
+ // keccak256("BURNER_ROLE")
579
+ deployment.contracts.StabilizerNFT
580
+ );
581
+ const passed = checks.filter((c) => c.passed).length;
582
+ const failed = checks.filter((c) => !c.passed).length;
583
+ return {
584
+ chainId: deployment.chainId,
585
+ checks,
586
+ passed,
587
+ failed,
588
+ allPassed: failed === 0
589
+ };
590
+ }
591
+ async function _verifyBytecode(client, checks, name, address) {
592
+ try {
593
+ const code = await client.getCode({ address });
594
+ const exists = code !== void 0 && code !== "0x" && code.length > 2;
595
+ checks.push({ name: `${name} bytecode exists`, passed: exists });
596
+ } catch {
597
+ checks.push({ name: `${name} bytecode exists`, passed: false });
598
+ }
599
+ }
600
+ async function _verifyProxyImpl(client, checks, name, proxyAddress, expectedImpl) {
601
+ try {
602
+ const implSlot = await client.getStorageAt({
603
+ address: proxyAddress,
604
+ slot: ERC1967_IMPL_SLOT
605
+ });
606
+ const actualImpl = ("0x" + (implSlot ?? "0x").slice(26)).toLowerCase();
607
+ const expected = expectedImpl.toLowerCase();
608
+ checks.push({
609
+ name: `${name} proxy -> impl`,
610
+ passed: actualImpl === expected,
611
+ expected: expectedImpl,
612
+ actual: actualImpl
613
+ });
614
+ } catch {
615
+ checks.push({ name: `${name} proxy -> impl`, passed: false, expected: expectedImpl });
616
+ }
617
+ }
618
+ async function _verifyStabilizerNFTStorage(client, checks, d) {
619
+ try {
620
+ const nft = d.contracts.StabilizerNFT;
621
+ const updToken = await client.readContract({
622
+ address: nft,
623
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
624
+ functionName: "updToken"
625
+ });
626
+ checks.push({
627
+ name: "StabilizerNFT.updToken",
628
+ passed: updToken.toLowerCase() === d.contracts.UPDToken.toLowerCase(),
629
+ expected: d.contracts.UPDToken,
630
+ actual: updToken
631
+ });
632
+ const oracle = await client.readContract({
633
+ address: nft,
634
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
635
+ functionName: "oracle"
636
+ });
637
+ checks.push({
638
+ name: "StabilizerNFT.oracle",
639
+ passed: oracle.toLowerCase() === d.contracts.PriceOracle.toLowerCase(),
640
+ expected: d.contracts.PriceOracle,
641
+ actual: oracle
642
+ });
643
+ const stETH = await client.readContract({
644
+ address: nft,
645
+ abi: chunkZSWETUGH_cjs.STABILIZER_NFT_ABI,
646
+ functionName: "stETH"
647
+ });
648
+ checks.push({
649
+ name: "StabilizerNFT.stETH",
650
+ passed: stETH.toLowerCase() === d.external.stETH.toLowerCase(),
651
+ expected: d.external.stETH,
652
+ actual: stETH
653
+ });
654
+ } catch {
655
+ checks.push({ name: "StabilizerNFT storage", passed: false });
656
+ }
657
+ }
658
+ async function _verifyReporterStorage(client, checks, d) {
659
+ try {
660
+ const reporter = d.contracts.OvercollateralizationReporter;
661
+ const stabNFT = await client.readContract({
662
+ address: reporter,
663
+ abi: chunkZSWETUGH_cjs.OVERCOLLATERALIZATION_REPORTER_ABI,
664
+ functionName: "stabilizerNFTContract"
665
+ });
666
+ checks.push({
667
+ name: "Reporter.stabilizerNFT",
668
+ passed: stabNFT.toLowerCase() === d.contracts.StabilizerNFT.toLowerCase(),
669
+ expected: d.contracts.StabilizerNFT,
670
+ actual: stabNFT
671
+ });
672
+ const updToken = await client.readContract({
673
+ address: reporter,
674
+ abi: chunkZSWETUGH_cjs.OVERCOLLATERALIZATION_REPORTER_ABI,
675
+ functionName: "updToken"
676
+ });
677
+ checks.push({
678
+ name: "Reporter.updToken",
679
+ passed: updToken.toLowerCase() === d.contracts.UPDToken.toLowerCase(),
680
+ expected: d.contracts.UPDToken,
681
+ actual: updToken
682
+ });
683
+ } catch {
684
+ checks.push({ name: "Reporter storage", passed: false });
685
+ }
686
+ }
687
+ async function _verifyRole(client, checks, name, contractAddress, abi, roleHash, account) {
688
+ try {
689
+ const hasRole = await client.readContract({
690
+ address: contractAddress,
691
+ abi,
692
+ functionName: "hasRole",
693
+ args: [roleHash, account]
694
+ });
695
+ checks.push({ name, passed: hasRole });
696
+ } catch {
697
+ checks.push({ name, passed: false });
698
+ }
699
+ }
700
+
701
+ exports.UPDClient = UPDClient;
702
+ exports.createUPDClient = createUPDClient;
703
+ exports.getContractAddress = getContractAddress;
704
+ exports.getDeployment = getDeployment;
705
+ exports.getDeploymentOrThrow = getDeploymentOrThrow;
706
+ exports.getSupportedChainIds = getSupportedChainIds;
707
+ exports.hasDeployment = hasDeployment;
708
+ exports.signCancelAuthorization = signCancelAuthorization;
709
+ exports.signReceiveAuthorization = signReceiveAuthorization;
710
+ exports.signTransferAuthorization = signTransferAuthorization;
711
+ exports.verifyDeployment = verifyDeployment;
712
+ //# sourceMappingURL=chunk-WRPVPA7E.cjs.map
713
+ //# sourceMappingURL=chunk-WRPVPA7E.cjs.map