@varla/sdk 1.11.1 → 1.11.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.
- package/AGENTS.md +168 -0
- package/BACKEND.md +94 -0
- package/FRONTEND.md +232 -0
- package/dist/actions/oracleUpdaterRouter.d.ts +24 -2
- package/dist/actions/oracleUpdaterRouter.d.ts.map +1 -1
- package/dist/actions/oracleUpdaterRouter.js +90 -16
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -19,3 +19,171 @@ Published package: **@varla/sdk**
|
|
|
19
19
|
- Actions: `@varla/sdk/actions`
|
|
20
20
|
- Events/indexer: `@varla/sdk/events`
|
|
21
21
|
- Utilities: `@varla/sdk/batch`, `@varla/sdk/format`
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Frontend-oriented view helpers (quick map)
|
|
26
|
+
|
|
27
|
+
> Tip: prefer **subpath imports** so it’s obvious what you’re using:
|
|
28
|
+
>
|
|
29
|
+
> ```ts
|
|
30
|
+
> import * as views from "@varla/sdk/views";
|
|
31
|
+
> import * as actions from "@varla/sdk/actions";
|
|
32
|
+
> ```
|
|
33
|
+
|
|
34
|
+
### Lend page (pool / lenders)
|
|
35
|
+
|
|
36
|
+
- **User supplied amount (current value)** + shares + withdrawable
|
|
37
|
+
- `views.readLenderSnapshot({ pool, user })` →
|
|
38
|
+
`{ shares, assets, maxWithdrawAssets, maxRedeemShares }`
|
|
39
|
+
- Notes:
|
|
40
|
+
- `assets` is the **current underlying value** of the user’s ERC4626 shares (principal + interest).
|
|
41
|
+
- `maxWithdrawAssets` is the **available-to-withdraw right now** (liquidity + reserve aware).
|
|
42
|
+
|
|
43
|
+
- **Available-to-withdraw only**
|
|
44
|
+
- `views.readMaxWithdraw({ pool, user })` → `{ maxWithdrawAssets }`
|
|
45
|
+
|
|
46
|
+
- **Pool share price (assets per share)**
|
|
47
|
+
- `views.readPoolSharePrice({ pool })` → `{ assetsPerShareWad }`
|
|
48
|
+
|
|
49
|
+
- **Pool utilization + rates**
|
|
50
|
+
- `views.readPoolSnapshot({ pool })` or `views.readPoolRates({ pool })`
|
|
51
|
+
|
|
52
|
+
- **Pool safety score**
|
|
53
|
+
- `views.readPoolHealthScore({ pool })` →
|
|
54
|
+
- `{ kind: "no-liquidity" }` when the pool has 0 assets (prevents showing a misleading 100)
|
|
55
|
+
- `{ kind: "ok", utilizationWad, scoreBps }` otherwise
|
|
56
|
+
|
|
57
|
+
### Borrow page (core / borrower risk)
|
|
58
|
+
|
|
59
|
+
- **Account overview (portfolio, debt, HF, max borrow)**
|
|
60
|
+
- `views.readAccountSnapshot({ core, user })`
|
|
61
|
+
- or `views.readBorrowLimits({ core, user })` when you only need limits + HF
|
|
62
|
+
|
|
63
|
+
- **Max LTV vs tier naming (avoid ambiguity)**
|
|
64
|
+
- `views.readTieredLtvConfig({ core })` → `{ tier0, tier1, tier2 }` (maps 1:1 to CONSERVATIVE/MODERATE/RISK)
|
|
65
|
+
- For an actual position, prefer effective LTV:
|
|
66
|
+
- `views.readLtvForPosition({ core, positionId })` → `{ ltvWad }`
|
|
67
|
+
|
|
68
|
+
- **Liquidation threshold / params**
|
|
69
|
+
- `views.readHealthFactor({ core, user })` → `{ healthFactor, canBeLiquidated }`
|
|
70
|
+
- `views.readLiquidationConfig({ core })` and `views.readTierLiquidationConfig({ core, tier })`
|
|
71
|
+
|
|
72
|
+
### Home page / “Top opportunities” (suggested inputs)
|
|
73
|
+
|
|
74
|
+
The SDK can provide raw primitives; **ranking is app-side**:
|
|
75
|
+
- `views.readPoolRates({ pool })` (supplyAPY, utilization)
|
|
76
|
+
- `views.readPoolCaps({ pool })` (capacity constraints)
|
|
77
|
+
- `views.readPoolHealthScore({ pool })` (simple risk signal)
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Not provided by the SDK (by design)
|
|
82
|
+
|
|
83
|
+
- **“Interest accrued / lender earnings” for a user**
|
|
84
|
+
- ERC4626 does not track principal per-user.
|
|
85
|
+
- To show “interest accrued”, you need a cost basis, e.g.:
|
|
86
|
+
- app-side tracking of deposits/withdrawals, or
|
|
87
|
+
- an indexer that reconstructs deposits/withdrawals from events.
|
|
88
|
+
|
|
89
|
+
- **Borrow “net rate”**
|
|
90
|
+
- `borrowRate` and pool `supplyAPY` are available, but “net” is product-specific
|
|
91
|
+
(depends on whether you consider collateral yield, whether user is also a lender, etc.).
|
|
92
|
+
|
|
93
|
+
- **Cooldown period**
|
|
94
|
+
- As of `contracts/VarlaPool.sol` in this repo, there is **no cooldown / withdraw delay** view.
|
|
95
|
+
- If a cooldown is introduced later, we can add `views.readPoolConfig({ pool })`.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## All view helpers (generated)
|
|
100
|
+
|
|
101
|
+
<!-- BEGIN GENERATED:VIEW_HELPERS -->
|
|
102
|
+
<!--
|
|
103
|
+
This section is auto-generated by scripts/sdk-generate-docs.ts.
|
|
104
|
+
Do not edit manually.
|
|
105
|
+
-->
|
|
106
|
+
|
|
107
|
+
- `getInterestRateStrategyFromPool`
|
|
108
|
+
- `hydrateOraclePositionIds`
|
|
109
|
+
- `previewBorrow`
|
|
110
|
+
- `previewRepay`
|
|
111
|
+
- `readAccessManagerBasics`
|
|
112
|
+
- `readAccountPositions`
|
|
113
|
+
- `readAccountPositionsFull`
|
|
114
|
+
- `readAccountSnapshot`
|
|
115
|
+
- `readAdapterInfo`
|
|
116
|
+
- `readBadDebtStatus`
|
|
117
|
+
- `readBorrowLimits`
|
|
118
|
+
- `readBorrowerState`
|
|
119
|
+
- `readBorrowers`
|
|
120
|
+
- `readBorrowersPage`
|
|
121
|
+
- `readCalculateLiquidationBonus`
|
|
122
|
+
- `readCanLiquidate`
|
|
123
|
+
- `readConfiguredPositionIds`
|
|
124
|
+
- `readConvertLiquidatorBasics`
|
|
125
|
+
- `readCoreAddresses`
|
|
126
|
+
- `readCoreGlobalDebt`
|
|
127
|
+
- `readDefaultLtvConfig`
|
|
128
|
+
- `readHasRole`
|
|
129
|
+
- `readHealthFactor`
|
|
130
|
+
- `readInterestRateStrategyBasics`
|
|
131
|
+
- `readLenderSnapshot`
|
|
132
|
+
- `readLiquidationBonusBps`
|
|
133
|
+
- `readLiquidationConfig`
|
|
134
|
+
- `readLiquidationParamsForPosition`
|
|
135
|
+
- `readLiquidatorBasics`
|
|
136
|
+
- `readLiquidity`
|
|
137
|
+
- `readLtvForPosition`
|
|
138
|
+
- `readManyAccountSnapshots`
|
|
139
|
+
- `readManyBorrowLimits`
|
|
140
|
+
- `readManyHasRole`
|
|
141
|
+
- `readManyLiquidationBonusBps`
|
|
142
|
+
- `readManyOraclePositionMeta`
|
|
143
|
+
- `readManyPositionSnapshots`
|
|
144
|
+
- `readManyTargetConfigs`
|
|
145
|
+
- `readManyTargetFunctionRoles`
|
|
146
|
+
- `readMaxPositionsConfig`
|
|
147
|
+
- `readMaxRedeem`
|
|
148
|
+
- `readMaxWithdraw`
|
|
149
|
+
- `readMergeLiquidatorBasics`
|
|
150
|
+
- `readNegRiskMarketPositionIds`
|
|
151
|
+
- `readOracleBasics`
|
|
152
|
+
- `readOracleCollateralStatus`
|
|
153
|
+
- `readOracleConfig`
|
|
154
|
+
- `readOracleFinalizationStatus`
|
|
155
|
+
- `readOracleGuardsStatus`
|
|
156
|
+
- `readOraclePositionMeta`
|
|
157
|
+
- `readOraclePriceData`
|
|
158
|
+
- `readOracleRegistry`
|
|
159
|
+
- `readOracleRegistryPage`
|
|
160
|
+
- `readOracleTiming`
|
|
161
|
+
- `readPoolAccounting`
|
|
162
|
+
- `readPoolCaps`
|
|
163
|
+
- `readPoolCoreAddress`
|
|
164
|
+
- `readPoolDebtState`
|
|
165
|
+
- `readPoolHealthScore`
|
|
166
|
+
- `readPoolRates`
|
|
167
|
+
- `readPoolSharePrice`
|
|
168
|
+
- `readPoolSnapshot`
|
|
169
|
+
- `readPortfolioValue`
|
|
170
|
+
- `readPositionBalance`
|
|
171
|
+
- `readPositionBalances`
|
|
172
|
+
- `readPositionCount`
|
|
173
|
+
- `readPositionLiquidationConfigOverride`
|
|
174
|
+
- `readPositionLtvOverride`
|
|
175
|
+
- `readPositionSnapshot`
|
|
176
|
+
- `readPreviewLiquidation`
|
|
177
|
+
- `readPrice`
|
|
178
|
+
- `readProxyAdminPaused`
|
|
179
|
+
- `readRepayTiming`
|
|
180
|
+
- `readRiskTier`
|
|
181
|
+
- `readRoleSummary`
|
|
182
|
+
- `readSpotPrice`
|
|
183
|
+
- `readSystemSnapshot`
|
|
184
|
+
- `readTargetConfig`
|
|
185
|
+
- `readTierLiquidationConfig`
|
|
186
|
+
- `readTieredLtvConfig`
|
|
187
|
+
- `readTryGetPrice`
|
|
188
|
+
- `readTwap`
|
|
189
|
+
<!-- END GENERATED:VIEW_HELPERS -->
|
package/BACKEND.md
CHANGED
|
@@ -308,3 +308,97 @@ Useful health signals to emit from a backend:
|
|
|
308
308
|
- Treat RPC errors as expected: implement retry/backoff and fallbacks.
|
|
309
309
|
- Keep multicalls bounded (chunking) to avoid RPC provider limits.
|
|
310
310
|
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## All view helpers (generated)
|
|
314
|
+
|
|
315
|
+
<!-- BEGIN GENERATED:VIEW_HELPERS -->
|
|
316
|
+
<!--
|
|
317
|
+
This section is auto-generated by scripts/sdk-generate-docs.ts.
|
|
318
|
+
Do not edit manually.
|
|
319
|
+
-->
|
|
320
|
+
|
|
321
|
+
- `getInterestRateStrategyFromPool`
|
|
322
|
+
- `hydrateOraclePositionIds`
|
|
323
|
+
- `previewBorrow`
|
|
324
|
+
- `previewRepay`
|
|
325
|
+
- `readAccessManagerBasics`
|
|
326
|
+
- `readAccountPositions`
|
|
327
|
+
- `readAccountPositionsFull`
|
|
328
|
+
- `readAccountSnapshot`
|
|
329
|
+
- `readAdapterInfo`
|
|
330
|
+
- `readBadDebtStatus`
|
|
331
|
+
- `readBorrowLimits`
|
|
332
|
+
- `readBorrowerState`
|
|
333
|
+
- `readBorrowers`
|
|
334
|
+
- `readBorrowersPage`
|
|
335
|
+
- `readCalculateLiquidationBonus`
|
|
336
|
+
- `readCanLiquidate`
|
|
337
|
+
- `readConfiguredPositionIds`
|
|
338
|
+
- `readConvertLiquidatorBasics`
|
|
339
|
+
- `readCoreAddresses`
|
|
340
|
+
- `readCoreGlobalDebt`
|
|
341
|
+
- `readDefaultLtvConfig`
|
|
342
|
+
- `readHasRole`
|
|
343
|
+
- `readHealthFactor`
|
|
344
|
+
- `readInterestRateStrategyBasics`
|
|
345
|
+
- `readLenderSnapshot`
|
|
346
|
+
- `readLiquidationBonusBps`
|
|
347
|
+
- `readLiquidationConfig`
|
|
348
|
+
- `readLiquidationParamsForPosition`
|
|
349
|
+
- `readLiquidatorBasics`
|
|
350
|
+
- `readLiquidity`
|
|
351
|
+
- `readLtvForPosition`
|
|
352
|
+
- `readManyAccountSnapshots`
|
|
353
|
+
- `readManyBorrowLimits`
|
|
354
|
+
- `readManyHasRole`
|
|
355
|
+
- `readManyLiquidationBonusBps`
|
|
356
|
+
- `readManyOraclePositionMeta`
|
|
357
|
+
- `readManyPositionSnapshots`
|
|
358
|
+
- `readManyTargetConfigs`
|
|
359
|
+
- `readManyTargetFunctionRoles`
|
|
360
|
+
- `readMaxPositionsConfig`
|
|
361
|
+
- `readMaxRedeem`
|
|
362
|
+
- `readMaxWithdraw`
|
|
363
|
+
- `readMergeLiquidatorBasics`
|
|
364
|
+
- `readNegRiskMarketPositionIds`
|
|
365
|
+
- `readOracleBasics`
|
|
366
|
+
- `readOracleCollateralStatus`
|
|
367
|
+
- `readOracleConfig`
|
|
368
|
+
- `readOracleFinalizationStatus`
|
|
369
|
+
- `readOracleGuardsStatus`
|
|
370
|
+
- `readOraclePositionMeta`
|
|
371
|
+
- `readOraclePriceData`
|
|
372
|
+
- `readOracleRegistry`
|
|
373
|
+
- `readOracleRegistryPage`
|
|
374
|
+
- `readOracleTiming`
|
|
375
|
+
- `readPoolAccounting`
|
|
376
|
+
- `readPoolCaps`
|
|
377
|
+
- `readPoolCoreAddress`
|
|
378
|
+
- `readPoolDebtState`
|
|
379
|
+
- `readPoolHealthScore`
|
|
380
|
+
- `readPoolRates`
|
|
381
|
+
- `readPoolSharePrice`
|
|
382
|
+
- `readPoolSnapshot`
|
|
383
|
+
- `readPortfolioValue`
|
|
384
|
+
- `readPositionBalance`
|
|
385
|
+
- `readPositionBalances`
|
|
386
|
+
- `readPositionCount`
|
|
387
|
+
- `readPositionLiquidationConfigOverride`
|
|
388
|
+
- `readPositionLtvOverride`
|
|
389
|
+
- `readPositionSnapshot`
|
|
390
|
+
- `readPreviewLiquidation`
|
|
391
|
+
- `readPrice`
|
|
392
|
+
- `readProxyAdminPaused`
|
|
393
|
+
- `readRepayTiming`
|
|
394
|
+
- `readRiskTier`
|
|
395
|
+
- `readRoleSummary`
|
|
396
|
+
- `readSpotPrice`
|
|
397
|
+
- `readSystemSnapshot`
|
|
398
|
+
- `readTargetConfig`
|
|
399
|
+
- `readTierLiquidationConfig`
|
|
400
|
+
- `readTieredLtvConfig`
|
|
401
|
+
- `readTryGetPrice`
|
|
402
|
+
- `readTwap`
|
|
403
|
+
<!-- END GENERATED:VIEW_HELPERS -->
|
|
404
|
+
|
package/FRONTEND.md
CHANGED
|
@@ -98,6 +98,144 @@ const snap = await views.readAccountSnapshot({
|
|
|
98
98
|
|
|
99
99
|
---
|
|
100
100
|
|
|
101
|
+
## 3.1) Lend page cookbook (pool / lenders)
|
|
102
|
+
|
|
103
|
+
> Recommended imports:
|
|
104
|
+
>
|
|
105
|
+
> ```ts
|
|
106
|
+
> import * as views from "@varla/sdk/views";
|
|
107
|
+
> ```
|
|
108
|
+
|
|
109
|
+
### User supplied amount (current value)
|
|
110
|
+
|
|
111
|
+
Use `readLenderSnapshot`:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
const lender = await views.readLenderSnapshot({ pool: c.pool, user: userAddress });
|
|
115
|
+
|
|
116
|
+
// lender.assets is the current underlying value of the user’s ERC4626 shares
|
|
117
|
+
// (principal + interest), *not* a tracked principal amount.
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Return shape:
|
|
121
|
+
- `shares`: ERC4626 vault share balance
|
|
122
|
+
- `assets`: `convertToAssets(shares)` (current redeemable underlying)
|
|
123
|
+
|
|
124
|
+
### Available to withdraw (overview chart)
|
|
125
|
+
|
|
126
|
+
If you only need withdrawable amount:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
const { maxWithdrawAssets } = await views.readMaxWithdraw({ pool: c.pool, user: userAddress });
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Or use `readLenderSnapshot` and read `maxWithdrawAssets`.
|
|
133
|
+
|
|
134
|
+
### Pool share price (charting)
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
const { assetsPerShareWad } = await views.readPoolSharePrice({ pool: c.pool });
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Pool rates + utilization
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
const poolRates = await views.readPoolRates({ pool: c.pool });
|
|
144
|
+
// { utilization, borrowRate, supplyAPY, availableLiquidity, maxBorrow }
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Lender earnings / “interest accrued”
|
|
148
|
+
|
|
149
|
+
The SDK does **not** currently provide `readLenderEarnings(pool, user)`.
|
|
150
|
+
|
|
151
|
+
Reason: ERC4626 does not store a per-user principal (cost basis), so “interest accrued”
|
|
152
|
+
cannot be derived purely from the vault without historical data.
|
|
153
|
+
|
|
154
|
+
Recommended approach:
|
|
155
|
+
- Track deposits/withdrawals in your app (or an indexer) to build a cost basis.
|
|
156
|
+
- Compute earnings as (example):
|
|
157
|
+
- `earnings = currentAssets - (sumDeposits - sumWithdrawals)`
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 3.2) Borrow page cookbook (core / borrower risk)
|
|
162
|
+
|
|
163
|
+
### Account overview
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
const snap = await views.readAccountSnapshot({ core: c.core, user: userAddress });
|
|
167
|
+
// { portfolioValue, collateralValue, debt, healthFactor, maxBorrow }
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Max LTV clarification (defaults vs effective)
|
|
171
|
+
|
|
172
|
+
The protocol exposes **default LTV per risk tier**:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
const tiers = await views.readTieredLtvConfig({ core: c.core });
|
|
176
|
+
// { tier0, tier1, tier2 } == { conservative, moderate, risk }
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Important: `tier2`/`risk` is **not universally “the max LTV”**; it’s the default
|
|
180
|
+
for the tier-2 risk category.
|
|
181
|
+
|
|
182
|
+
For a specific collateral position, prefer the **effective** LTV:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
const { ltvWad } = await views.readLtvForPosition({ core: c.core, positionId });
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Liquidation threshold
|
|
189
|
+
|
|
190
|
+
Liquidation eligibility is best represented by health factor:
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
const hf = await views.readHealthFactor({ core: c.core, user: userAddress });
|
|
194
|
+
// { healthFactor, canBeLiquidated }
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
For parameters behind liquidation incentives/fees:
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
const liq = await views.readLiquidationConfig({ core: c.core });
|
|
201
|
+
const liqTier0 = await views.readTierLiquidationConfig({ core: c.core, tier: 0 });
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 3.3) Pool safety score (lend page)
|
|
207
|
+
|
|
208
|
+
If your UI currently does:
|
|
209
|
+
`(1 - utilization) * 100`, it will misleadingly show **100** when the pool has no liquidity.
|
|
210
|
+
|
|
211
|
+
Prefer the SDK helper:
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
const score = await views.readPoolHealthScore({ pool: c.pool });
|
|
215
|
+
|
|
216
|
+
if (score.kind === "no-liquidity") {
|
|
217
|
+
// show "N/A" or "—"
|
|
218
|
+
} else {
|
|
219
|
+
// score.scoreBps is 0..10_000
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Current formula used by the SDK:
|
|
224
|
+
- if `totalAssets == 0` → `{ kind: "no-liquidity" }`
|
|
225
|
+
- else `scoreBps = (1 - utilizationWad) * 10_000` (clamped to [0..10_000])
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 3.4) Home page “top opportunities”
|
|
230
|
+
|
|
231
|
+
The SDK provides primitives, but **ranking is app-side**:
|
|
232
|
+
|
|
233
|
+
- `views.readPoolRates({ pool })` (supply APY, utilization)
|
|
234
|
+
- `views.readPoolCaps({ pool })` (capacity constraints)
|
|
235
|
+
- `views.readPoolHealthScore({ pool })` (simple risk signal)
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
101
239
|
## 4) Writes (simulate-first) with wagmi
|
|
102
240
|
|
|
103
241
|
The SDK write helpers return simulated requests; **you send them with your wallet client**.
|
|
@@ -250,3 +388,97 @@ This keeps UI components clean, and gives you one place to wire:
|
|
|
250
388
|
- analytics
|
|
251
389
|
- receipt confirmations
|
|
252
390
|
- error mapping
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## All view helpers (generated)
|
|
395
|
+
|
|
396
|
+
<!-- BEGIN GENERATED:VIEW_HELPERS -->
|
|
397
|
+
<!--
|
|
398
|
+
This section is auto-generated by scripts/sdk-generate-docs.ts.
|
|
399
|
+
Do not edit manually.
|
|
400
|
+
-->
|
|
401
|
+
|
|
402
|
+
- `getInterestRateStrategyFromPool`
|
|
403
|
+
- `hydrateOraclePositionIds`
|
|
404
|
+
- `previewBorrow`
|
|
405
|
+
- `previewRepay`
|
|
406
|
+
- `readAccessManagerBasics`
|
|
407
|
+
- `readAccountPositions`
|
|
408
|
+
- `readAccountPositionsFull`
|
|
409
|
+
- `readAccountSnapshot`
|
|
410
|
+
- `readAdapterInfo`
|
|
411
|
+
- `readBadDebtStatus`
|
|
412
|
+
- `readBorrowLimits`
|
|
413
|
+
- `readBorrowerState`
|
|
414
|
+
- `readBorrowers`
|
|
415
|
+
- `readBorrowersPage`
|
|
416
|
+
- `readCalculateLiquidationBonus`
|
|
417
|
+
- `readCanLiquidate`
|
|
418
|
+
- `readConfiguredPositionIds`
|
|
419
|
+
- `readConvertLiquidatorBasics`
|
|
420
|
+
- `readCoreAddresses`
|
|
421
|
+
- `readCoreGlobalDebt`
|
|
422
|
+
- `readDefaultLtvConfig`
|
|
423
|
+
- `readHasRole`
|
|
424
|
+
- `readHealthFactor`
|
|
425
|
+
- `readInterestRateStrategyBasics`
|
|
426
|
+
- `readLenderSnapshot`
|
|
427
|
+
- `readLiquidationBonusBps`
|
|
428
|
+
- `readLiquidationConfig`
|
|
429
|
+
- `readLiquidationParamsForPosition`
|
|
430
|
+
- `readLiquidatorBasics`
|
|
431
|
+
- `readLiquidity`
|
|
432
|
+
- `readLtvForPosition`
|
|
433
|
+
- `readManyAccountSnapshots`
|
|
434
|
+
- `readManyBorrowLimits`
|
|
435
|
+
- `readManyHasRole`
|
|
436
|
+
- `readManyLiquidationBonusBps`
|
|
437
|
+
- `readManyOraclePositionMeta`
|
|
438
|
+
- `readManyPositionSnapshots`
|
|
439
|
+
- `readManyTargetConfigs`
|
|
440
|
+
- `readManyTargetFunctionRoles`
|
|
441
|
+
- `readMaxPositionsConfig`
|
|
442
|
+
- `readMaxRedeem`
|
|
443
|
+
- `readMaxWithdraw`
|
|
444
|
+
- `readMergeLiquidatorBasics`
|
|
445
|
+
- `readNegRiskMarketPositionIds`
|
|
446
|
+
- `readOracleBasics`
|
|
447
|
+
- `readOracleCollateralStatus`
|
|
448
|
+
- `readOracleConfig`
|
|
449
|
+
- `readOracleFinalizationStatus`
|
|
450
|
+
- `readOracleGuardsStatus`
|
|
451
|
+
- `readOraclePositionMeta`
|
|
452
|
+
- `readOraclePriceData`
|
|
453
|
+
- `readOracleRegistry`
|
|
454
|
+
- `readOracleRegistryPage`
|
|
455
|
+
- `readOracleTiming`
|
|
456
|
+
- `readPoolAccounting`
|
|
457
|
+
- `readPoolCaps`
|
|
458
|
+
- `readPoolCoreAddress`
|
|
459
|
+
- `readPoolDebtState`
|
|
460
|
+
- `readPoolHealthScore`
|
|
461
|
+
- `readPoolRates`
|
|
462
|
+
- `readPoolSharePrice`
|
|
463
|
+
- `readPoolSnapshot`
|
|
464
|
+
- `readPortfolioValue`
|
|
465
|
+
- `readPositionBalance`
|
|
466
|
+
- `readPositionBalances`
|
|
467
|
+
- `readPositionCount`
|
|
468
|
+
- `readPositionLiquidationConfigOverride`
|
|
469
|
+
- `readPositionLtvOverride`
|
|
470
|
+
- `readPositionSnapshot`
|
|
471
|
+
- `readPreviewLiquidation`
|
|
472
|
+
- `readPrice`
|
|
473
|
+
- `readProxyAdminPaused`
|
|
474
|
+
- `readRepayTiming`
|
|
475
|
+
- `readRiskTier`
|
|
476
|
+
- `readRoleSummary`
|
|
477
|
+
- `readSpotPrice`
|
|
478
|
+
- `readSystemSnapshot`
|
|
479
|
+
- `readTargetConfig`
|
|
480
|
+
- `readTierLiquidationConfig`
|
|
481
|
+
- `readTieredLtvConfig`
|
|
482
|
+
- `readTryGetPrice`
|
|
483
|
+
- `readTwap`
|
|
484
|
+
<!-- END GENERATED:VIEW_HELPERS -->
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Address, Hash } from "viem";
|
|
1
|
+
import type { Address, Hash, Hex } from "viem";
|
|
2
2
|
/**
|
|
3
3
|
* EIP-712 payload builder for OracleUpdaterRouter.
|
|
4
4
|
*
|
|
@@ -51,6 +51,16 @@ export declare const ORACLE_UPDATER_ROUTER_TYPES: {
|
|
|
51
51
|
readonly type: "bytes32";
|
|
52
52
|
}];
|
|
53
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* Hardcoded UPDATE_TYPEHASH from the deployed OracleUpdaterRouter contract.
|
|
56
|
+
*
|
|
57
|
+
* Computed from:
|
|
58
|
+
* keccak256("Update(address oracle,uint256 chainId,address publisher,uint256 nonce,uint256 deadline,bytes32 positionIdsHash,bytes32 priceListHash,bytes32 twapListHash,bytes32 liquidityListHash)")
|
|
59
|
+
*
|
|
60
|
+
* IMPORTANT: This must match the contract's hardcoded UPDATE_TYPEHASH exactly.
|
|
61
|
+
* If the contract is redeployed with a different type hash, this must be updated.
|
|
62
|
+
*/
|
|
63
|
+
export declare const UPDATE_TYPEHASH: Hash;
|
|
54
64
|
/**
|
|
55
65
|
* Convert an update with dynamic arrays into the typed-data "message" shape expected by the router.
|
|
56
66
|
*/
|
|
@@ -65,9 +75,21 @@ export declare function toOracleUpdaterRouterTypedMessage(u: OracleUpdaterRouter
|
|
|
65
75
|
readonly twapListHash: `0x${string}`;
|
|
66
76
|
readonly liquidityListHash: `0x${string}`;
|
|
67
77
|
};
|
|
78
|
+
/**
|
|
79
|
+
* Compute the EIP-712 digest that should be signed.
|
|
80
|
+
* This manually computes the digest to ensure exact match with the contract's hashUpdate().
|
|
81
|
+
*/
|
|
82
|
+
export declare function computeOracleUpdaterDigest(params: {
|
|
83
|
+
routerAddress: Address;
|
|
84
|
+
update: OracleUpdaterRouterUpdate;
|
|
85
|
+
}): Hash;
|
|
68
86
|
export declare function signOracleUpdaterRouterUpdate(params: {
|
|
69
87
|
walletClient: {
|
|
70
|
-
|
|
88
|
+
signMessage: (args: {
|
|
89
|
+
message: {
|
|
90
|
+
raw: Hex;
|
|
91
|
+
};
|
|
92
|
+
}) => Promise<Hash>;
|
|
71
93
|
};
|
|
72
94
|
routerAddress: Address;
|
|
73
95
|
update: OracleUpdaterRouterUpdate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oracleUpdaterRouter.d.ts","sourceRoot":"","sources":["../../src/actions/oracleUpdaterRouter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"oracleUpdaterRouter.d.ts","sourceRoot":"","sources":["../../src/actions/oracleUpdaterRouter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAK/C;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B;;;CAG/B,CAAC;AAEX,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAY9B,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,EAAE,IACwC,CAAC;AAuBvE;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,CAAC,EAAE,yBAAyB;;;;;;;;;;EAY7E;AA+DD;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,yBAAyB,CAAC;CACnC,GAAG,IAAI,CAMP;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,YAAY,EAAE;QACZ,WAAW,EAAE,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE;gBAAE,GAAG,EAAE,GAAG,CAAA;aAAE,CAAA;SAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACjE,CAAC;IACF,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,yBAAyB,CAAC;CACnC,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhB;AAED,wBAAsB,6CAA6C,CAAC,MAAM,EAAE;IAC1E,YAAY,EAAE;QAAE,gBAAgB,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC;IAChE,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,yBAAyB,CAAC;IAClC,SAAS,EAAE,IAAI,CAAC;CACjB,GAAG,OAAO,CAAC,GAAG,CAAC,CAqBf"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Note: explicit .js extension is required for Node ESM resolution.
|
|
2
|
-
import { encodeAbiParameters, keccak256 } from "viem";
|
|
2
|
+
import { concat, encodeAbiParameters, encodePacked, keccak256, toHex } from "viem";
|
|
3
3
|
import { abis } from "../generated.js";
|
|
4
4
|
/**
|
|
5
5
|
* EIP-712 payload builder for OracleUpdaterRouter.
|
|
@@ -25,13 +25,31 @@ export const ORACLE_UPDATER_ROUTER_TYPES = {
|
|
|
25
25
|
{ name: "liquidityListHash", type: "bytes32" },
|
|
26
26
|
],
|
|
27
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Hardcoded UPDATE_TYPEHASH from the deployed OracleUpdaterRouter contract.
|
|
30
|
+
*
|
|
31
|
+
* Computed from:
|
|
32
|
+
* keccak256("Update(address oracle,uint256 chainId,address publisher,uint256 nonce,uint256 deadline,bytes32 positionIdsHash,bytes32 priceListHash,bytes32 twapListHash,bytes32 liquidityListHash)")
|
|
33
|
+
*
|
|
34
|
+
* IMPORTANT: This must match the contract's hardcoded UPDATE_TYPEHASH exactly.
|
|
35
|
+
* If the contract is redeployed with a different type hash, this must be updated.
|
|
36
|
+
*/
|
|
37
|
+
export const UPDATE_TYPEHASH = "0xfb5c9ee2f30c92eeb6fe0049d8ba63d98fcbb57cccd2761e2fd7275ac1bd9bd0";
|
|
38
|
+
/**
|
|
39
|
+
* Hardcoded EIP712Domain type hash.
|
|
40
|
+
* keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
|
|
41
|
+
*/
|
|
42
|
+
const EIP712_DOMAIN_TYPEHASH = "0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f";
|
|
43
|
+
/**
|
|
44
|
+
* Hash a uint256[] array using Solidity's abi.encodePacked semantics.
|
|
45
|
+
* Matches: keccak256(abi.encodePacked(uint256[]))
|
|
46
|
+
*/
|
|
28
47
|
function hashU256Array(xs) {
|
|
29
|
-
// Solidity uses keccak256(abi.encodePacked(uint256[])) for the struct hash.
|
|
30
|
-
// abi.encodePacked(uint256[]) is just tight packing of each uint256 as 32 bytes.
|
|
31
48
|
if (xs.length === 0)
|
|
32
49
|
return keccak256(new Uint8Array([]));
|
|
33
|
-
|
|
34
|
-
|
|
50
|
+
// abi.encodePacked(uint256[]) is just tight packing of each uint256 as 32 bytes
|
|
51
|
+
const packed = encodePacked(xs.map(() => "uint256"), xs);
|
|
52
|
+
return keccak256(packed);
|
|
35
53
|
}
|
|
36
54
|
/**
|
|
37
55
|
* Convert an update with dynamic arrays into the typed-data "message" shape expected by the router.
|
|
@@ -49,18 +67,74 @@ export function toOracleUpdaterRouterTypedMessage(u) {
|
|
|
49
67
|
liquidityListHash: hashU256Array(u.liquidityList),
|
|
50
68
|
};
|
|
51
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Compute the EIP-712 domain separator for the OracleUpdaterRouter.
|
|
72
|
+
*/
|
|
73
|
+
function computeDomainSeparator(chainId, routerAddress) {
|
|
74
|
+
return keccak256(encodeAbiParameters([
|
|
75
|
+
{ type: "bytes32" },
|
|
76
|
+
{ type: "bytes32" },
|
|
77
|
+
{ type: "bytes32" },
|
|
78
|
+
{ type: "uint256" },
|
|
79
|
+
{ type: "address" },
|
|
80
|
+
], [
|
|
81
|
+
EIP712_DOMAIN_TYPEHASH,
|
|
82
|
+
keccak256(toHex(ORACLE_UPDATER_ROUTER_EIP712.name)),
|
|
83
|
+
keccak256(toHex(ORACLE_UPDATER_ROUTER_EIP712.version)),
|
|
84
|
+
chainId,
|
|
85
|
+
routerAddress,
|
|
86
|
+
]));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Compute the struct hash for an Update using the contract's exact UPDATE_TYPEHASH.
|
|
90
|
+
* This bypasses viem's automatic type hash computation to ensure exact match with the contract.
|
|
91
|
+
*/
|
|
92
|
+
function computeStructHash(update) {
|
|
93
|
+
const msg = toOracleUpdaterRouterTypedMessage(update);
|
|
94
|
+
return keccak256(encodeAbiParameters([
|
|
95
|
+
{ type: "bytes32" }, // UPDATE_TYPEHASH
|
|
96
|
+
{ type: "address" }, // oracle
|
|
97
|
+
{ type: "uint256" }, // chainId
|
|
98
|
+
{ type: "address" }, // publisher
|
|
99
|
+
{ type: "uint256" }, // nonce
|
|
100
|
+
{ type: "uint256" }, // deadline
|
|
101
|
+
{ type: "bytes32" }, // positionIdsHash
|
|
102
|
+
{ type: "bytes32" }, // priceListHash
|
|
103
|
+
{ type: "bytes32" }, // twapListHash
|
|
104
|
+
{ type: "bytes32" }, // liquidityListHash
|
|
105
|
+
], [
|
|
106
|
+
UPDATE_TYPEHASH,
|
|
107
|
+
msg.oracle,
|
|
108
|
+
msg.chainId,
|
|
109
|
+
msg.publisher,
|
|
110
|
+
msg.nonce,
|
|
111
|
+
msg.deadline,
|
|
112
|
+
msg.positionIdsHash,
|
|
113
|
+
msg.priceListHash,
|
|
114
|
+
msg.twapListHash,
|
|
115
|
+
msg.liquidityListHash,
|
|
116
|
+
]));
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Compute the EIP-712 digest that should be signed.
|
|
120
|
+
* This manually computes the digest to ensure exact match with the contract's hashUpdate().
|
|
121
|
+
*/
|
|
122
|
+
export function computeOracleUpdaterDigest(params) {
|
|
123
|
+
const domainSeparator = computeDomainSeparator(params.update.chainId, params.routerAddress);
|
|
124
|
+
const structHash = computeStructHash(params.update);
|
|
125
|
+
// EIP-712: "\x19\x01" ++ domainSeparator ++ structHash
|
|
126
|
+
return keccak256(concat(["0x1901", domainSeparator, structHash]));
|
|
127
|
+
}
|
|
52
128
|
export async function signOracleUpdaterRouterUpdate(params) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
message: toOracleUpdaterRouterTypedMessage(params.update),
|
|
63
|
-
}));
|
|
129
|
+
// Manually compute the EIP-712 digest to ensure exact match with contract
|
|
130
|
+
const digest = computeOracleUpdaterDigest({
|
|
131
|
+
routerAddress: params.routerAddress,
|
|
132
|
+
update: params.update,
|
|
133
|
+
});
|
|
134
|
+
// Sign the raw digest (not a personal_sign, just the raw hash)
|
|
135
|
+
return params.walletClient.signMessage({
|
|
136
|
+
message: { raw: digest },
|
|
137
|
+
});
|
|
64
138
|
}
|
|
65
139
|
export async function prepareOracleUpdaterRouterUpdatePricesWithSig(params) {
|
|
66
140
|
return await params.publicClient.simulateContract({
|