@varla/sdk 2.9.0 → 2.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 +66 -8
- package/CHANGELOG.md +17 -0
- package/README.md +73 -0
- package/dist/abi/full/VarlaOracle.d.ts +151 -1
- package/dist/abi/full/VarlaOracle.d.ts.map +1 -1
- package/dist/abi/full/VarlaOracle.js +195 -1
- package/dist/abi/full/VarlaOracle.js.map +1 -1
- package/dist/abi/subsets/VarlaOracle.registry.d.ts +66 -0
- package/dist/abi/subsets/VarlaOracle.registry.d.ts.map +1 -1
- package/dist/abi/subsets/VarlaOracle.registry.js +83 -0
- package/dist/abi/subsets/VarlaOracle.registry.js.map +1 -1
- package/dist/generated.d.ts +217 -1
- package/dist/generated.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/safe.d.ts +108 -0
- package/dist/safe.d.ts.map +1 -0
- package/dist/safe.js +148 -0
- package/dist/safe.js.map +1 -0
- package/dist/views/core.d.ts +90 -0
- package/dist/views/core.d.ts.map +1 -1
- package/dist/views/core.js +110 -0
- package/dist/views/core.js.map +1 -1
- package/package.json +5 -1
- package/src/abi/full/VarlaOracle.ts +195 -1
- package/src/abi/subsets/VarlaOracle.registry.ts +83 -0
- package/src/index.ts +2 -0
- package/src/safe.ts +226 -0
- package/src/views/core.ts +185 -0
package/src/views/core.ts
CHANGED
|
@@ -11,6 +11,191 @@ import { abis } from "../generated.js";
|
|
|
11
11
|
const _WAD = 1_000_000_000_000_000_000n;
|
|
12
12
|
const _E8 = 100_000_000n;
|
|
13
13
|
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Deposit pre-flight (previewCoreDeposit)
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Reason a deposit would be rejected for a specific position.
|
|
20
|
+
*
|
|
21
|
+
* - `"zero-amount"` — caller passed `amount === 0n`.
|
|
22
|
+
* - `"not-configured"` — position has never been configured in the oracle.
|
|
23
|
+
* - `"deposit-not-allowed"` — position is in early-closure window or already resolved.
|
|
24
|
+
* - `"invalid-collateral"` — oracle reports the position as invalid collateral
|
|
25
|
+
* (stale price, low liquidity, manually invalidated, etc.).
|
|
26
|
+
*/
|
|
27
|
+
export type DepositBlockReason =
|
|
28
|
+
| "zero-amount"
|
|
29
|
+
| "not-configured"
|
|
30
|
+
| "deposit-not-allowed"
|
|
31
|
+
| "invalid-collateral";
|
|
32
|
+
|
|
33
|
+
export type PreviewCoreDepositItem = {
|
|
34
|
+
positionId: bigint;
|
|
35
|
+
amount: bigint;
|
|
36
|
+
/** `true` when this individual position passes all pre-flight checks. */
|
|
37
|
+
ok: boolean;
|
|
38
|
+
/** Present only when `ok === false`. */
|
|
39
|
+
reason?: DepositBlockReason;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type PreviewCoreDeposit = {
|
|
43
|
+
/** `true` only when every position passes AND account-level checks pass. */
|
|
44
|
+
canDeposit: boolean;
|
|
45
|
+
/** Per-position results aligned to input order. */
|
|
46
|
+
items: PreviewCoreDepositItem[];
|
|
47
|
+
/** Current deposited position count for the user. */
|
|
48
|
+
currentPositionCount: bigint;
|
|
49
|
+
/** Max positions allowed by Core. */
|
|
50
|
+
maxPositions: bigint;
|
|
51
|
+
/**
|
|
52
|
+
* Whether the deposit would exceed the max-positions limit.
|
|
53
|
+
*
|
|
54
|
+
* Only `true` when depositing would push the count above `maxPositions`.
|
|
55
|
+
* New positions (not already deposited) are counted.
|
|
56
|
+
*/
|
|
57
|
+
wouldExceedMaxPositions: boolean;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Pre-flight check that mirrors VarlaCore.deposit() validation.
|
|
62
|
+
*
|
|
63
|
+
* Frontends should call this **before** `prepareCoreDeposit` to show clear,
|
|
64
|
+
* actionable error messages instead of raw revert data.
|
|
65
|
+
*
|
|
66
|
+
* Checks (per position):
|
|
67
|
+
* 1. `amount > 0`
|
|
68
|
+
* 2. `oracle.isDepositAllowed(positionId)` — blocks inside early-closure window / post-resolution
|
|
69
|
+
* 3. `oracle.isValidCollateral(positionId)` — stale, low-liquidity, or manually invalidated
|
|
70
|
+
*
|
|
71
|
+
* Also enriches with `oracle.isConfigured()` so the frontend can distinguish
|
|
72
|
+
* "not configured" (market not listed) from "early-closure" (market closing soon).
|
|
73
|
+
*
|
|
74
|
+
* Account-level check:
|
|
75
|
+
* - Would the deposit exceed `maxPositions`?
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* import { previewCoreDeposit } from "@varla/sdk/views";
|
|
80
|
+
*
|
|
81
|
+
* const preview = await previewCoreDeposit({
|
|
82
|
+
* oracle, core,
|
|
83
|
+
* user: "0x...",
|
|
84
|
+
* positionIds: [posId],
|
|
85
|
+
* amounts: [amount],
|
|
86
|
+
* });
|
|
87
|
+
*
|
|
88
|
+
* if (!preview.canDeposit) {
|
|
89
|
+
* for (const item of preview.items) {
|
|
90
|
+
* if (!item.ok) console.log(`Position ${item.positionId}: ${item.reason}`);
|
|
91
|
+
* }
|
|
92
|
+
* if (preview.wouldExceedMaxPositions) console.log("Too many positions");
|
|
93
|
+
* }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
// wraps: VarlaOracle.isConfigured,VarlaOracle.isDepositAllowed,VarlaOracle.isValidCollateral,VarlaCore.getPositionCount,VarlaCore.maxPositions,VarlaCore.positionBalances
|
|
97
|
+
export async function previewCoreDeposit(params: {
|
|
98
|
+
oracle: {
|
|
99
|
+
read: {
|
|
100
|
+
isConfigured: (args: readonly [bigint]) => Promise<boolean>;
|
|
101
|
+
isDepositAllowed: (args: readonly [bigint]) => Promise<boolean>;
|
|
102
|
+
isValidCollateral: (args: readonly [bigint]) => Promise<boolean>;
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
core: {
|
|
106
|
+
read: {
|
|
107
|
+
getPositionCount: (args: readonly [Address]) => Promise<bigint>;
|
|
108
|
+
maxPositions: () => Promise<bigint>;
|
|
109
|
+
positionBalances: (args: readonly [Address, bigint]) => Promise<bigint>;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
user: Address;
|
|
113
|
+
positionIds: readonly bigint[];
|
|
114
|
+
amounts: readonly bigint[];
|
|
115
|
+
}): Promise<PreviewCoreDeposit> {
|
|
116
|
+
const { oracle, core, user, positionIds, amounts } = params;
|
|
117
|
+
|
|
118
|
+
if (positionIds.length !== amounts.length) {
|
|
119
|
+
throw new Error("positionIds and amounts must have the same length");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Parallel: oracle checks per-position + account-level reads.
|
|
123
|
+
const [oracleResults, positionCount, maxPositions, existingBalances] = await Promise.all([
|
|
124
|
+
// Per-position oracle checks (all in parallel).
|
|
125
|
+
Promise.all(
|
|
126
|
+
positionIds.map(async (pid) => {
|
|
127
|
+
const [isConfigured, isDepositAllowed, isValidCollateral] = await Promise.all([
|
|
128
|
+
oracle.read.isConfigured([pid]),
|
|
129
|
+
oracle.read.isDepositAllowed([pid]),
|
|
130
|
+
oracle.read.isValidCollateral([pid]),
|
|
131
|
+
]);
|
|
132
|
+
return { isConfigured, isDepositAllowed, isValidCollateral };
|
|
133
|
+
}),
|
|
134
|
+
),
|
|
135
|
+
// Account-level.
|
|
136
|
+
core.read.getPositionCount([user]),
|
|
137
|
+
core.read.maxPositions(),
|
|
138
|
+
// Check which positions user already has deposited (for max-positions calc).
|
|
139
|
+
Promise.all(positionIds.map((pid) => core.read.positionBalances([user, pid]))),
|
|
140
|
+
]);
|
|
141
|
+
|
|
142
|
+
// Build per-position items.
|
|
143
|
+
const items: PreviewCoreDepositItem[] = [];
|
|
144
|
+
let allItemsOk = true;
|
|
145
|
+
|
|
146
|
+
for (let i = 0; i < positionIds.length; i++) {
|
|
147
|
+
const pid = positionIds[i]!;
|
|
148
|
+
const amount = amounts[i]!;
|
|
149
|
+
const orc = oracleResults[i]!;
|
|
150
|
+
|
|
151
|
+
let ok = true;
|
|
152
|
+
let reason: DepositBlockReason | undefined;
|
|
153
|
+
|
|
154
|
+
if (amount === 0n) {
|
|
155
|
+
ok = false;
|
|
156
|
+
reason = "zero-amount";
|
|
157
|
+
} else if (!orc.isConfigured) {
|
|
158
|
+
ok = false;
|
|
159
|
+
reason = "not-configured";
|
|
160
|
+
} else if (!orc.isDepositAllowed) {
|
|
161
|
+
ok = false;
|
|
162
|
+
reason = "deposit-not-allowed";
|
|
163
|
+
} else if (!orc.isValidCollateral) {
|
|
164
|
+
ok = false;
|
|
165
|
+
reason = "invalid-collateral";
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (!ok) allItemsOk = false;
|
|
169
|
+
items.push(
|
|
170
|
+
reason !== undefined
|
|
171
|
+
? { positionId: pid, amount, ok, reason }
|
|
172
|
+
: { positionId: pid, amount, ok },
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Count how many NEW positions this deposit would add.
|
|
177
|
+
const uniqueNewPositionIds = new Set<bigint>();
|
|
178
|
+
for (let i = 0; i < positionIds.length; i++) {
|
|
179
|
+
const pid = positionIds[i]!;
|
|
180
|
+
const existingBal = existingBalances[i]!;
|
|
181
|
+
if (existingBal === 0n) {
|
|
182
|
+
uniqueNewPositionIds.add(pid);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const newCount = positionCount + BigInt(uniqueNewPositionIds.size);
|
|
186
|
+
const wouldExceedMaxPositions = newCount > maxPositions;
|
|
187
|
+
|
|
188
|
+
const canDeposit = allItemsOk && !wouldExceedMaxPositions;
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
canDeposit,
|
|
192
|
+
items,
|
|
193
|
+
currentPositionCount: positionCount,
|
|
194
|
+
maxPositions,
|
|
195
|
+
wouldExceedMaxPositions,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
14
199
|
export type ReadAccountSnapshot = {
|
|
15
200
|
portfolioValue: bigint;
|
|
16
201
|
collateralValue: bigint;
|