@varla/sdk 1.10.12 → 1.11.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.
- package/AGENTS.md +3 -4
- package/BACKEND.md +310 -0
- package/README.md +6 -0
- package/dist/abi/full/OracleUpdaterRouter.d.ts +381 -0
- package/dist/abi/full/OracleUpdaterRouter.d.ts.map +1 -0
- package/dist/abi/full/OracleUpdaterRouter.js +496 -0
- package/dist/abi/full/VarlaOracle.d.ts +112 -0
- package/dist/abi/full/VarlaOracle.d.ts.map +1 -1
- package/dist/abi/full/VarlaOracle.js +147 -0
- package/dist/abi/index.d.ts +1 -0
- package/dist/abi/index.d.ts.map +1 -1
- package/dist/abi/index.js +1 -0
- package/dist/abi/subsets/VarlaOracle.registry.d.ts +64 -0
- package/dist/abi/subsets/VarlaOracle.registry.d.ts.map +1 -1
- package/dist/abi/subsets/VarlaOracle.registry.js +84 -0
- package/dist/actions/admin.d.ts +7 -0
- package/dist/actions/admin.d.ts.map +1 -1
- package/dist/actions/admin.js +12 -0
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +1 -0
- package/dist/actions/oracleUpdaterRouter.d.ts +84 -0
- package/dist/actions/oracleUpdaterRouter.d.ts.map +1 -0
- package/dist/actions/oracleUpdaterRouter.js +86 -0
- package/dist/addresses/bsc.d.ts.map +1 -1
- package/dist/addresses/bsc.js +9 -8
- package/dist/addresses/polygon.d.ts.map +1 -1
- package/dist/addresses/polygon.js +9 -8
- package/dist/batch.d.ts +1 -1
- package/dist/batch.d.ts.map +1 -1
- package/dist/contracts.d.ts +2 -1
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +8 -0
- package/dist/events/oracleRegistrySync.js +1 -1
- package/dist/generated.d.ts +556 -0
- package/dist/generated.d.ts.map +1 -1
- package/dist/generated.js +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/views/oracle.d.ts +12 -0
- package/dist/views/oracle.d.ts.map +1 -1
- package/dist/views/oracle.js +5 -0
- package/package.json +3 -2
package/AGENTS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Published package: **@varla/sdk**
|
|
4
4
|
|
|
5
|
-
## Setup
|
|
5
|
+
## Setup
|
|
6
6
|
- Install: `bun install`
|
|
7
7
|
- Build: `cd packages/sdk && bun run build`
|
|
8
8
|
- Prepack: `cd packages/sdk && bun run prepack`
|
|
@@ -12,11 +12,10 @@ Published package: **@varla/sdk**
|
|
|
12
12
|
- Types: `cd packages/sdk && bun run test:types`
|
|
13
13
|
- Slow RPC (opt-in): `cd packages/sdk && bun run test:rpc:slow`
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Primary exports
|
|
16
16
|
- Addresses: `@varla/sdk/addresses`
|
|
17
17
|
- ABIs: `@varla/sdk/abi`
|
|
18
|
-
-
|
|
19
|
-
- Views: `@varla/sdk` or `@varla/sdk/views`
|
|
18
|
+
- Contracts/bindings + views: `@varla/sdk` or `@varla/sdk/views`
|
|
20
19
|
- Actions: `@varla/sdk/actions`
|
|
21
20
|
- Events/indexer: `@varla/sdk/events`
|
|
22
21
|
- Utilities: `@varla/sdk/batch`, `@varla/sdk/format`
|
package/BACKEND.md
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# Backend integration guide (Node.js services: indexer + oracle updater + ops)
|
|
2
|
+
|
|
3
|
+
This SDK is intentionally **batteries-not-included** for:
|
|
4
|
+
|
|
5
|
+
- RPC configuration (URLs, retries, fallbacks, rate limits)
|
|
6
|
+
- job scheduling / queues
|
|
7
|
+
- persistence (db schemas, migrations)
|
|
8
|
+
- reorg handling strategy (confirmations, replay windows)
|
|
9
|
+
|
|
10
|
+
The SDK *does* provide:
|
|
11
|
+
|
|
12
|
+
- canonical ABIs + deployed addresses
|
|
13
|
+
- typed viem contract bindings (`getVarlaContracts` / `getRequiredVarlaContracts`)
|
|
14
|
+
- read facades (`@varla/sdk/views`) built around multicall + paging
|
|
15
|
+
- simulate-first write helpers (`@varla/sdk/actions`) for safer writes
|
|
16
|
+
- event/indexer helpers (`@varla/sdk/events`) for log syncing
|
|
17
|
+
|
|
18
|
+
This doc shows a recommended setup for **Node.js backend services**, split into common roles:
|
|
19
|
+
|
|
20
|
+
- **Indexer / monitor** (reads + events)
|
|
21
|
+
- **Oracle updater** (offchain prices → onchain updates)
|
|
22
|
+
- **Ops / admin runner** (RBAC + seeding + parameter changes)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 1) RPC + viem client setup (service-side)
|
|
27
|
+
|
|
28
|
+
The SDK does not ship RPC URLs.
|
|
29
|
+
|
|
30
|
+
Recommended:
|
|
31
|
+
- configure explicit RPCs per chain (Polygon/BSC)
|
|
32
|
+
- use `fallback([http(primary), http(secondary)])`
|
|
33
|
+
- add retries/backoff at the transport layer (your code) or via a proxy provider
|
|
34
|
+
|
|
35
|
+
Example `rpc.ts`:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { createPublicClient, fallback, http } from "viem";
|
|
39
|
+
import { polygon, bsc } from "viem/chains";
|
|
40
|
+
|
|
41
|
+
const POLYGON_RPC_URL = process.env.POLYGON_RPC_URL;
|
|
42
|
+
const POLYGON_RPC_URL_BACKUP = process.env.POLYGON_RPC_URL_BACKUP;
|
|
43
|
+
const BSC_RPC_URL = process.env.BSC_RPC_URL;
|
|
44
|
+
const BSC_RPC_URL_BACKUP = process.env.BSC_RPC_URL_BACKUP;
|
|
45
|
+
|
|
46
|
+
if (!POLYGON_RPC_URL) throw new Error("Missing POLYGON_RPC_URL");
|
|
47
|
+
if (!BSC_RPC_URL) throw new Error("Missing BSC_RPC_URL");
|
|
48
|
+
|
|
49
|
+
export const polygonClient = createPublicClient({
|
|
50
|
+
chain: polygon,
|
|
51
|
+
transport: fallback([
|
|
52
|
+
http(POLYGON_RPC_URL),
|
|
53
|
+
...(POLYGON_RPC_URL_BACKUP ? [http(POLYGON_RPC_URL_BACKUP)] : []),
|
|
54
|
+
]),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export const bscClient = createPublicClient({
|
|
58
|
+
chain: bsc,
|
|
59
|
+
transport: fallback([
|
|
60
|
+
http(BSC_RPC_URL),
|
|
61
|
+
...(BSC_RPC_URL_BACKUP ? [http(BSC_RPC_URL_BACKUP)] : []),
|
|
62
|
+
]),
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Notes:
|
|
67
|
+
- You should own your own retry policy (especially for high-volume reads).
|
|
68
|
+
- For “safe finality” reads, prefer waiting N blocks and/or reading with a stable provider.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 2) Getting Varla bindings (typed viem)
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import { getVarlaContracts } from "@varla/sdk";
|
|
76
|
+
import { polygonClient } from "./rpc";
|
|
77
|
+
|
|
78
|
+
const c = getVarlaContracts({ chain: "polygon", client: polygonClient });
|
|
79
|
+
|
|
80
|
+
// Typed reads
|
|
81
|
+
const stats = await c.pool.read.getPoolStats();
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
If your service *requires* certain optional deployments (e.g. adapters, liquidators), use:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { getRequiredVarlaContracts } from "@varla/sdk";
|
|
88
|
+
|
|
89
|
+
const c = getRequiredVarlaContracts({
|
|
90
|
+
chain: "polygon",
|
|
91
|
+
client: polygonClient,
|
|
92
|
+
require: ["liquidator"],
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 3) High-volume reads: views + batching + paging
|
|
99
|
+
|
|
100
|
+
For most backend tasks, prefer SDK view helpers:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import * as views from "@varla/sdk/views";
|
|
104
|
+
|
|
105
|
+
const snap = await views.readSystemSnapshot({ pool: c.pool, core: c.core, oracle: c.oracle });
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Oracle registry (configured positionIds)
|
|
109
|
+
|
|
110
|
+
The oracle can have many configured positionIds. Use paging helpers:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
const page = await views.readOracleRegistryPage({
|
|
114
|
+
oracle: c.oracle,
|
|
115
|
+
client: polygonClient,
|
|
116
|
+
start: 0,
|
|
117
|
+
limit: 500,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
console.log(page.positionIds);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Borrowers list
|
|
124
|
+
|
|
125
|
+
Borrowers are tracked on-chain as a set. Use paging:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
const borrowers = await views.readBorrowersPage({
|
|
129
|
+
core: c.core,
|
|
130
|
+
client: polygonClient,
|
|
131
|
+
start: 0,
|
|
132
|
+
limit: 200,
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 4) Event-driven indexing
|
|
139
|
+
|
|
140
|
+
For indexers, event-driven discovery is often cheaper than full scans.
|
|
141
|
+
|
|
142
|
+
The SDK provides helpers under `@varla/sdk/events` for chunked log fetching and registry sync.
|
|
143
|
+
|
|
144
|
+
Typical pattern:
|
|
145
|
+
|
|
146
|
+
1) pick a block range window (e.g. 50k blocks)
|
|
147
|
+
2) fetch logs in chunks
|
|
148
|
+
3) persist a cursor (last processed block)
|
|
149
|
+
4) on restart, resume from the cursor
|
|
150
|
+
|
|
151
|
+
If you only need the oracle registry (configured positions), use the SDK’s event sync helper
|
|
152
|
+
and then hydrate state via multicall:
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import * as events from "@varla/sdk/events";
|
|
156
|
+
import * as views from "@varla/sdk/views";
|
|
157
|
+
|
|
158
|
+
// 1) discover positionIds from events
|
|
159
|
+
const positionIds = await events.syncOracleRegistryViaEvents({
|
|
160
|
+
oracleAddress: c.oracle.address,
|
|
161
|
+
client: polygonClient,
|
|
162
|
+
fromBlock: 0n,
|
|
163
|
+
toBlock: "latest",
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// 2) hydrate snapshots in multicall batches
|
|
167
|
+
const snaps = await views.readManyPositionSnapshots({
|
|
168
|
+
oracle: { address: c.oracle.address },
|
|
169
|
+
client: polygonClient,
|
|
170
|
+
positionIds,
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Reorg handling:
|
|
175
|
+
- Maintain a **reorg buffer** (e.g. always reprocess last 50–200 blocks).
|
|
176
|
+
- Store both `blockNumber` and `blockHash` if you need strong guarantees.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 5) Writes from a backend: wallet client + simulate-first
|
|
181
|
+
|
|
182
|
+
Backend writes should be explicit and auditable:
|
|
183
|
+
|
|
184
|
+
- hold operator keys securely (HSM/KMS if possible)
|
|
185
|
+
- simulate first to catch reverts
|
|
186
|
+
- send
|
|
187
|
+
- wait for receipts with confirmations
|
|
188
|
+
|
|
189
|
+
Example `wallet.ts`:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import { createWalletClient, http } from "viem";
|
|
193
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
194
|
+
import { polygon } from "viem/chains";
|
|
195
|
+
|
|
196
|
+
const pk = process.env.OPERATOR_PRIVATE_KEY;
|
|
197
|
+
if (!pk) throw new Error("Missing OPERATOR_PRIVATE_KEY");
|
|
198
|
+
|
|
199
|
+
export const operatorAccount = privateKeyToAccount(pk as `0x${string}`);
|
|
200
|
+
|
|
201
|
+
export const polygonWallet = createWalletClient({
|
|
202
|
+
chain: polygon,
|
|
203
|
+
transport: http(process.env.POLYGON_RPC_URL!),
|
|
204
|
+
account: operatorAccount,
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Then use SDK actions:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
import * as actions from "@varla/sdk/actions";
|
|
212
|
+
|
|
213
|
+
const sim = await actions.prepareCoreBorrow({
|
|
214
|
+
publicClient: polygonClient,
|
|
215
|
+
coreAddress: c.core.address,
|
|
216
|
+
account: operatorAccount.address,
|
|
217
|
+
amount: 1_000_000n,
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
const hash = await actions.sendTx({ walletClient: polygonWallet, request: sim.request });
|
|
221
|
+
await polygonClient.waitForTransactionReceipt({ hash, confirmations: 2 });
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## 6) RBAC preflight (AccessManager)
|
|
227
|
+
|
|
228
|
+
The protocol uses OZ `AccessManager`.
|
|
229
|
+
|
|
230
|
+
For admin services, do a preflight check before attempting writes:
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import * as actions from "@varla/sdk/actions";
|
|
234
|
+
|
|
235
|
+
// Example: ensure caller can call `configurePositionsBatch(...)` immediately.
|
|
236
|
+
const selector = actions.selectorFromSignature(actions.ORACLE_SIGS.configurePositionsBatch);
|
|
237
|
+
|
|
238
|
+
await actions.assertCanCallImmediate({
|
|
239
|
+
accessManager: c.accessManager,
|
|
240
|
+
caller: operatorAccount.address,
|
|
241
|
+
target: c.oracle.address,
|
|
242
|
+
selector,
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Tip: if you expect scheduled execution (delays), use the “delayed” flows and build a queue.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 7) Oracle seeding (plan → prepare → execute)
|
|
251
|
+
|
|
252
|
+
The SDK provides **idempotent** seeding planners. Your backend can generate JSON lists
|
|
253
|
+
and then run the seeder.
|
|
254
|
+
|
|
255
|
+
Important: some operations must be done in 2 phases.
|
|
256
|
+
|
|
257
|
+
- `configureOppositePositions(yesPid, noPid)` will revert unless both PIDs are already configured.
|
|
258
|
+
|
|
259
|
+
Therefore:
|
|
260
|
+
1) seed markets/configure positions
|
|
261
|
+
2) seed opposites + negRisk
|
|
262
|
+
|
|
263
|
+
Node convenience helper:
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
import * as actions from "@varla/sdk/actions";
|
|
267
|
+
|
|
268
|
+
const seeded = await actions.seedOracleFromJsonFiles({
|
|
269
|
+
oracle: c.oracle,
|
|
270
|
+
marketsPath: "./markets.polygon.json",
|
|
271
|
+
oppositesPath: "./opposites.polygon.json",
|
|
272
|
+
negRiskPath: "./negrisk.polygon.json",
|
|
273
|
+
prepare: {
|
|
274
|
+
publicClient: polygonClient,
|
|
275
|
+
oracleAddress: c.oracle.address,
|
|
276
|
+
account: operatorAccount.address,
|
|
277
|
+
},
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
console.log(seeded.plan);
|
|
281
|
+
|
|
282
|
+
if ("prepared" in seeded) {
|
|
283
|
+
const hashes = await actions.executeOracleSeedPlan({
|
|
284
|
+
walletClient: polygonWallet,
|
|
285
|
+
prepared: seeded.prepared,
|
|
286
|
+
});
|
|
287
|
+
console.log(hashes);
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## 8) Monitoring / alerting hooks
|
|
294
|
+
|
|
295
|
+
Useful health signals to emit from a backend:
|
|
296
|
+
|
|
297
|
+
- `views.readSystemSnapshot` periodically
|
|
298
|
+
- staleness checks on configured oracle positions
|
|
299
|
+
- borrower health factor checks (paging) and alert on `HF < 1.0`
|
|
300
|
+
- pool utilization + borrow rates
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## 9) Gotchas
|
|
305
|
+
|
|
306
|
+
- **Viem args are arrays**: `contract.read.fn([arg1, arg2])`.
|
|
307
|
+
- Always wait for receipts with confirmations on critical admin writes.
|
|
308
|
+
- Treat RPC errors as expected: implement retry/backoff and fallbacks.
|
|
309
|
+
- Keep multicalls bounded (chunking) to avoid RPC provider limits.
|
|
310
|
+
|
package/README.md
CHANGED
|
@@ -22,6 +22,11 @@ npm i @varla/sdk
|
|
|
22
22
|
|
|
23
23
|
## Usage
|
|
24
24
|
|
|
25
|
+
## Guides
|
|
26
|
+
|
|
27
|
+
- [Frontend integration](./FRONTEND.md)
|
|
28
|
+
- [Backend integration](./BACKEND.md)
|
|
29
|
+
|
|
25
30
|
Frontend (Next.js + RainbowKit + wagmi/viem): see [`FRONTEND.md`](./FRONTEND.md).
|
|
26
31
|
|
|
27
32
|
## Testing (SDK)
|
|
@@ -150,6 +155,7 @@ These are convenience helpers built on top of the contract bindings.
|
|
|
150
155
|
- `readOracleBasics`
|
|
151
156
|
- `readOracleCollateralStatus`
|
|
152
157
|
- `readOracleConfig`
|
|
158
|
+
- `readOracleFinalizationStatus`
|
|
153
159
|
- `readOracleGuardsStatus`
|
|
154
160
|
- `readOraclePositionMeta`
|
|
155
161
|
- `readOraclePriceData`
|