@morpho-org/midnight-sdk 1.1.1 → 1.2.1
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/lib/cjs/api/helpers.js +2 -4
- package/lib/cjs/api/version.generated.d.ts +2 -0
- package/lib/cjs/api/version.generated.js +6 -0
- package/lib/cjs/fetch/Position.d.ts +1 -1
- package/lib/cjs/fetch/Position.js +5 -1
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/market/index.d.ts +0 -2
- package/lib/cjs/market/index.js +0 -2
- package/lib/cjs/offers/Offer.d.ts +14 -10
- package/lib/cjs/offers/Offer.js +11 -7
- package/lib/cjs/offers/OfferChainUtils.d.ts +179 -0
- package/lib/cjs/offers/OfferChainUtils.js +446 -0
- package/lib/cjs/offers/index.d.ts +1 -0
- package/lib/cjs/offers/index.js +1 -0
- package/lib/cjs/{market → position}/Position.d.ts +83 -6
- package/lib/cjs/{market → position}/Position.js +83 -5
- package/lib/{esm/market → cjs/position}/PositionUtils.d.ts +26 -1
- package/lib/cjs/{market → position}/PositionUtils.js +27 -0
- package/lib/cjs/position/index.d.ts +2 -0
- package/lib/cjs/position/index.js +18 -0
- package/lib/cjs/signatures/RatifierUtils.js +4 -5
- package/lib/cjs/signatures/Tree.d.ts +3 -2
- package/lib/cjs/signatures/Tree.js +7 -4
- package/lib/cjs/signatures/TreeUtils.d.ts +4 -7
- package/lib/cjs/signatures/TreeUtils.js +22 -16
- package/lib/esm/api/helpers.js +1 -3
- package/lib/esm/api/version.generated.d.ts +2 -0
- package/lib/esm/api/version.generated.js +3 -0
- package/lib/esm/fetch/Position.d.ts +1 -1
- package/lib/esm/fetch/Position.js +5 -1
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/market/index.d.ts +0 -2
- package/lib/esm/market/index.js +0 -2
- package/lib/esm/offers/Offer.d.ts +14 -10
- package/lib/esm/offers/Offer.js +12 -8
- package/lib/esm/offers/OfferChainUtils.d.ts +179 -0
- package/lib/esm/offers/OfferChainUtils.js +443 -0
- package/lib/esm/offers/index.d.ts +1 -0
- package/lib/esm/offers/index.js +1 -0
- package/lib/esm/{market → position}/Position.d.ts +83 -6
- package/lib/esm/{market → position}/Position.js +83 -5
- package/lib/{cjs/market → esm/position}/PositionUtils.d.ts +26 -1
- package/lib/esm/{market → position}/PositionUtils.js +27 -0
- package/lib/esm/position/index.d.ts +2 -0
- package/lib/esm/position/index.js +2 -0
- package/lib/esm/signatures/RatifierUtils.js +5 -6
- package/lib/esm/signatures/Tree.d.ts +3 -2
- package/lib/esm/signatures/Tree.js +8 -5
- package/lib/esm/signatures/TreeUtils.d.ts +4 -7
- package/lib/esm/signatures/TreeUtils.js +22 -16
- package/package.json +4 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type BigIntish } from "@morpho-org/morpho-ts";
|
|
2
|
-
import type { Address } from "viem";
|
|
3
|
-
import { type IMarket, Market } from "
|
|
2
|
+
import type { Address, Hash } from "viem";
|
|
3
|
+
import { type IMarket, Market } from "../market/Market.js";
|
|
4
4
|
/**
|
|
5
5
|
* Plain input accepted by {@link Position}.
|
|
6
6
|
*
|
|
@@ -9,6 +9,8 @@ import { type IMarket, Market } from "./Market.js";
|
|
|
9
9
|
* import type { IPosition } from "@morpho-org/midnight-sdk";
|
|
10
10
|
*
|
|
11
11
|
* const position: IPosition = {
|
|
12
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
13
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
12
14
|
* credit: 0n,
|
|
13
15
|
* pendingFee: 0n,
|
|
14
16
|
* lastLossFactor: 0n,
|
|
@@ -20,6 +22,10 @@ import { type IMarket, Market } from "./Market.js";
|
|
|
20
22
|
* ```
|
|
21
23
|
*/
|
|
22
24
|
export interface IPosition {
|
|
25
|
+
/** User holding this position. */
|
|
26
|
+
readonly user: Address;
|
|
27
|
+
/** Id of the market on which this position is held. */
|
|
28
|
+
readonly marketId: Hash;
|
|
23
29
|
/** User credit. */
|
|
24
30
|
readonly credit: BigIntish;
|
|
25
31
|
/** Pending continuous fee. */
|
|
@@ -43,6 +49,8 @@ export interface IPosition {
|
|
|
43
49
|
* import { Position } from "@morpho-org/midnight-sdk";
|
|
44
50
|
*
|
|
45
51
|
* const position = new Position({
|
|
52
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
53
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
46
54
|
* credit: 0n,
|
|
47
55
|
* pendingFee: 0n,
|
|
48
56
|
* lastLossFactor: 0n,
|
|
@@ -54,7 +62,11 @@ export interface IPosition {
|
|
|
54
62
|
* console.log(position.debt);
|
|
55
63
|
* ```
|
|
56
64
|
*/
|
|
57
|
-
export declare class Position {
|
|
65
|
+
export declare class Position implements IPosition {
|
|
66
|
+
/** User holding this position. */
|
|
67
|
+
readonly user: Address;
|
|
68
|
+
/** Id of the market on which this position is held. */
|
|
69
|
+
readonly marketId: Hash;
|
|
58
70
|
/** User credit. */
|
|
59
71
|
readonly credit: bigint;
|
|
60
72
|
/** Pending continuous fee. */
|
|
@@ -79,6 +91,8 @@ export declare class Position {
|
|
|
79
91
|
* import { Position } from "@morpho-org/midnight-sdk";
|
|
80
92
|
*
|
|
81
93
|
* const position = new Position({
|
|
94
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
95
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
82
96
|
* credit: 1_000n,
|
|
83
97
|
* pendingFee: 100n,
|
|
84
98
|
* lastLossFactor: 0n,
|
|
@@ -92,6 +106,9 @@ export declare class Position {
|
|
|
92
106
|
*/
|
|
93
107
|
get faceValue(): bigint;
|
|
94
108
|
}
|
|
109
|
+
/** Plain input shape for a Midnight position paired with hydrated market state. */
|
|
110
|
+
export interface IAccrualPosition extends Omit<IPosition, "marketId"> {
|
|
111
|
+
}
|
|
95
112
|
/**
|
|
96
113
|
* Midnight position paired with its hydrated market.
|
|
97
114
|
*
|
|
@@ -116,6 +133,7 @@ export declare class Position {
|
|
|
116
133
|
*
|
|
117
134
|
* const position = new AccrualPosition(
|
|
118
135
|
* {
|
|
136
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
119
137
|
* credit: 1_000n,
|
|
120
138
|
* pendingFee: 100n,
|
|
121
139
|
* lastLossFactor: 0n,
|
|
@@ -154,10 +172,65 @@ export declare class Position {
|
|
|
154
172
|
* console.log(position.market.id);
|
|
155
173
|
* ```
|
|
156
174
|
*/
|
|
157
|
-
export declare class AccrualPosition extends Position {
|
|
175
|
+
export declare class AccrualPosition extends Position implements IAccrualPosition {
|
|
176
|
+
protected readonly _market: Market;
|
|
177
|
+
constructor(position: IAccrualPosition, market: IMarket | Market);
|
|
158
178
|
/** Hydrated market for this position. */
|
|
159
|
-
|
|
160
|
-
|
|
179
|
+
get market(): Market;
|
|
180
|
+
/**
|
|
181
|
+
* Returns the maximum credit units currently withdrawable from this position.
|
|
182
|
+
*
|
|
183
|
+
* The protocol capacity is limited by both the accrued position credit and
|
|
184
|
+
* the market's currently withdrawable liquidity. Default redemption flows may
|
|
185
|
+
* still choose the position face value.
|
|
186
|
+
*
|
|
187
|
+
* @returns Maximum credit units currently withdrawable.
|
|
188
|
+
* @example
|
|
189
|
+
* ```ts
|
|
190
|
+
* import { AccrualPosition } from "@morpho-org/midnight-sdk";
|
|
191
|
+
*
|
|
192
|
+
* const position = new AccrualPosition(
|
|
193
|
+
* {
|
|
194
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
195
|
+
* credit: 1_000n,
|
|
196
|
+
* pendingFee: 100n,
|
|
197
|
+
* lastLossFactor: 0n,
|
|
198
|
+
* lastAccrual: 1_000n,
|
|
199
|
+
* debt: 0n,
|
|
200
|
+
* collateralBitmap: 1n,
|
|
201
|
+
* collateral: [50n],
|
|
202
|
+
* },
|
|
203
|
+
* {
|
|
204
|
+
* params: {
|
|
205
|
+
* chainId: 8453,
|
|
206
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
207
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
208
|
+
* collateralParams: [
|
|
209
|
+
* {
|
|
210
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
211
|
+
* lltv: 770000000000000000n,
|
|
212
|
+
* liquidationCursor: 250000000000000000n,
|
|
213
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
214
|
+
* },
|
|
215
|
+
* ],
|
|
216
|
+
* maturity: 54_000n,
|
|
217
|
+
* rcfThreshold: 0n,
|
|
218
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
219
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
220
|
+
* },
|
|
221
|
+
* totalUnits: 1_000n,
|
|
222
|
+
* lossFactor: 0n,
|
|
223
|
+
* withdrawable: 950n,
|
|
224
|
+
* continuousFeeCredit: 0n,
|
|
225
|
+
* settlementFeeCbps: [1, 2, 3, 4, 5, 6, 7],
|
|
226
|
+
* continuousFee: 10,
|
|
227
|
+
* tickSpacing: 4,
|
|
228
|
+
* },
|
|
229
|
+
* );
|
|
230
|
+
* console.log(position.withdrawable); // 950n
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
get withdrawable(): bigint;
|
|
161
234
|
/**
|
|
162
235
|
* Returns the position collateral balance at an index configured by the market.
|
|
163
236
|
*
|
|
@@ -184,6 +257,7 @@ export declare class AccrualPosition extends Position {
|
|
|
184
257
|
*
|
|
185
258
|
* const position = new AccrualPosition(
|
|
186
259
|
* {
|
|
260
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
187
261
|
* credit: 1_000n,
|
|
188
262
|
* pendingFee: 100n,
|
|
189
263
|
* lastLossFactor: 0n,
|
|
@@ -251,6 +325,7 @@ export declare class AccrualPosition extends Position {
|
|
|
251
325
|
* const collateralToken = "0x0000000000000000000000000000000000007000";
|
|
252
326
|
* const position = new AccrualPosition(
|
|
253
327
|
* {
|
|
328
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
254
329
|
* credit: 1_000n,
|
|
255
330
|
* pendingFee: 100n,
|
|
256
331
|
* lastLossFactor: 0n,
|
|
@@ -317,6 +392,7 @@ export declare class AccrualPosition extends Position {
|
|
|
317
392
|
*
|
|
318
393
|
* const position = new AccrualPosition(
|
|
319
394
|
* {
|
|
395
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
320
396
|
* credit: 1_000n,
|
|
321
397
|
* pendingFee: 100n,
|
|
322
398
|
* lastLossFactor: 0n,
|
|
@@ -386,6 +462,7 @@ export declare class AccrualPosition extends Position {
|
|
|
386
462
|
*
|
|
387
463
|
* const position = new AccrualPosition(
|
|
388
464
|
* {
|
|
465
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
389
466
|
* credit: 1_000n,
|
|
390
467
|
* pendingFee: 100n,
|
|
391
468
|
* lastLossFactor: 0n,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _try, MathLib } from "@morpho-org/morpho-ts";
|
|
2
2
|
import { UnknownCollateralIndexError } from "../errors.js";
|
|
3
|
-
import { Market } from "
|
|
3
|
+
import { Market } from "../market/Market.js";
|
|
4
4
|
import { PositionUtils } from "./PositionUtils.js";
|
|
5
5
|
/**
|
|
6
6
|
* Midnight user position as stored by the core contract.
|
|
@@ -10,6 +10,8 @@ import { PositionUtils } from "./PositionUtils.js";
|
|
|
10
10
|
* import { Position } from "@morpho-org/midnight-sdk";
|
|
11
11
|
*
|
|
12
12
|
* const position = new Position({
|
|
13
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
14
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
13
15
|
* credit: 0n,
|
|
14
16
|
* pendingFee: 0n,
|
|
15
17
|
* lastLossFactor: 0n,
|
|
@@ -22,6 +24,10 @@ import { PositionUtils } from "./PositionUtils.js";
|
|
|
22
24
|
* ```
|
|
23
25
|
*/
|
|
24
26
|
export class Position {
|
|
27
|
+
/** User holding this position. */
|
|
28
|
+
user;
|
|
29
|
+
/** Id of the market on which this position is held. */
|
|
30
|
+
marketId;
|
|
25
31
|
/** User credit. */
|
|
26
32
|
credit;
|
|
27
33
|
/** Pending continuous fee. */
|
|
@@ -37,6 +43,8 @@ export class Position {
|
|
|
37
43
|
/** Collateral balances by index. */
|
|
38
44
|
collateral;
|
|
39
45
|
constructor(position) {
|
|
46
|
+
this.user = position.user;
|
|
47
|
+
this.marketId = position.marketId;
|
|
40
48
|
this.credit = BigInt(position.credit);
|
|
41
49
|
this.pendingFee = BigInt(position.pendingFee);
|
|
42
50
|
this.lastLossFactor = BigInt(position.lastLossFactor);
|
|
@@ -54,6 +62,8 @@ export class Position {
|
|
|
54
62
|
* import { Position } from "@morpho-org/midnight-sdk";
|
|
55
63
|
*
|
|
56
64
|
* const position = new Position({
|
|
65
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
66
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
57
67
|
* credit: 1_000n,
|
|
58
68
|
* pendingFee: 100n,
|
|
59
69
|
* lastLossFactor: 0n,
|
|
@@ -93,6 +103,7 @@ export class Position {
|
|
|
93
103
|
*
|
|
94
104
|
* const position = new AccrualPosition(
|
|
95
105
|
* {
|
|
106
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
96
107
|
* credit: 1_000n,
|
|
97
108
|
* pendingFee: 100n,
|
|
98
109
|
* lastLossFactor: 0n,
|
|
@@ -132,11 +143,74 @@ export class Position {
|
|
|
132
143
|
* ```
|
|
133
144
|
*/
|
|
134
145
|
export class AccrualPosition extends Position {
|
|
135
|
-
|
|
136
|
-
market;
|
|
146
|
+
_market;
|
|
137
147
|
constructor(position, market) {
|
|
138
|
-
|
|
139
|
-
|
|
148
|
+
const _market = Market.from(market);
|
|
149
|
+
super({ ...position, marketId: _market.id });
|
|
150
|
+
this._market = _market;
|
|
151
|
+
}
|
|
152
|
+
/** Hydrated market for this position. */
|
|
153
|
+
get market() {
|
|
154
|
+
return this._market;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Returns the maximum credit units currently withdrawable from this position.
|
|
158
|
+
*
|
|
159
|
+
* The protocol capacity is limited by both the accrued position credit and
|
|
160
|
+
* the market's currently withdrawable liquidity. Default redemption flows may
|
|
161
|
+
* still choose the position face value.
|
|
162
|
+
*
|
|
163
|
+
* @returns Maximum credit units currently withdrawable.
|
|
164
|
+
* @example
|
|
165
|
+
* ```ts
|
|
166
|
+
* import { AccrualPosition } from "@morpho-org/midnight-sdk";
|
|
167
|
+
*
|
|
168
|
+
* const position = new AccrualPosition(
|
|
169
|
+
* {
|
|
170
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
171
|
+
* credit: 1_000n,
|
|
172
|
+
* pendingFee: 100n,
|
|
173
|
+
* lastLossFactor: 0n,
|
|
174
|
+
* lastAccrual: 1_000n,
|
|
175
|
+
* debt: 0n,
|
|
176
|
+
* collateralBitmap: 1n,
|
|
177
|
+
* collateral: [50n],
|
|
178
|
+
* },
|
|
179
|
+
* {
|
|
180
|
+
* params: {
|
|
181
|
+
* chainId: 8453,
|
|
182
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
183
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
184
|
+
* collateralParams: [
|
|
185
|
+
* {
|
|
186
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
187
|
+
* lltv: 770000000000000000n,
|
|
188
|
+
* liquidationCursor: 250000000000000000n,
|
|
189
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
190
|
+
* },
|
|
191
|
+
* ],
|
|
192
|
+
* maturity: 54_000n,
|
|
193
|
+
* rcfThreshold: 0n,
|
|
194
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
195
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
196
|
+
* },
|
|
197
|
+
* totalUnits: 1_000n,
|
|
198
|
+
* lossFactor: 0n,
|
|
199
|
+
* withdrawable: 950n,
|
|
200
|
+
* continuousFeeCredit: 0n,
|
|
201
|
+
* settlementFeeCbps: [1, 2, 3, 4, 5, 6, 7],
|
|
202
|
+
* continuousFee: 10,
|
|
203
|
+
* tickSpacing: 4,
|
|
204
|
+
* },
|
|
205
|
+
* );
|
|
206
|
+
* console.log(position.withdrawable); // 950n
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
get withdrawable() {
|
|
210
|
+
return PositionUtils.getWithdrawable({
|
|
211
|
+
position: this,
|
|
212
|
+
market: this.market,
|
|
213
|
+
});
|
|
140
214
|
}
|
|
141
215
|
/**
|
|
142
216
|
* Returns the position collateral balance at an index configured by the market.
|
|
@@ -164,6 +238,7 @@ export class AccrualPosition extends Position {
|
|
|
164
238
|
*
|
|
165
239
|
* const position = new AccrualPosition(
|
|
166
240
|
* {
|
|
241
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
167
242
|
* credit: 1_000n,
|
|
168
243
|
* pendingFee: 100n,
|
|
169
244
|
* lastLossFactor: 0n,
|
|
@@ -236,6 +311,7 @@ export class AccrualPosition extends Position {
|
|
|
236
311
|
* const collateralToken = "0x0000000000000000000000000000000000007000";
|
|
237
312
|
* const position = new AccrualPosition(
|
|
238
313
|
* {
|
|
314
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
239
315
|
* credit: 1_000n,
|
|
240
316
|
* pendingFee: 100n,
|
|
241
317
|
* lastLossFactor: 0n,
|
|
@@ -305,6 +381,7 @@ export class AccrualPosition extends Position {
|
|
|
305
381
|
*
|
|
306
382
|
* const position = new AccrualPosition(
|
|
307
383
|
* {
|
|
384
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
308
385
|
* credit: 1_000n,
|
|
309
386
|
* pendingFee: 100n,
|
|
310
387
|
* lastLossFactor: 0n,
|
|
@@ -376,6 +453,7 @@ export class AccrualPosition extends Position {
|
|
|
376
453
|
*
|
|
377
454
|
* const position = new AccrualPosition(
|
|
378
455
|
* {
|
|
456
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
379
457
|
* credit: 1_000n,
|
|
380
458
|
* pendingFee: 100n,
|
|
381
459
|
* lastLossFactor: 0n,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type BigIntish } from "@morpho-org/morpho-ts";
|
|
2
|
-
import type { IMarket } from "
|
|
2
|
+
import type { IMarket } from "../market/Market.js";
|
|
3
3
|
import type { IPosition } from "./Position.js";
|
|
4
4
|
/**
|
|
5
5
|
* Domain helpers for Midnight positions.
|
|
@@ -10,6 +10,8 @@ import type { IPosition } from "./Position.js";
|
|
|
10
10
|
*
|
|
11
11
|
* const accrued = PositionUtils.accrueInterest({
|
|
12
12
|
* position: {
|
|
13
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
14
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
13
15
|
* credit: 1_000n,
|
|
14
16
|
* pendingFee: 100n,
|
|
15
17
|
* lastLossFactor: 0n,
|
|
@@ -50,6 +52,27 @@ import type { IPosition } from "./Position.js";
|
|
|
50
52
|
* ```
|
|
51
53
|
*/
|
|
52
54
|
export declare namespace PositionUtils {
|
|
55
|
+
/**
|
|
56
|
+
* Returns the maximum credit units currently withdrawable by a position.
|
|
57
|
+
*
|
|
58
|
+
* @param params.position - Position whose credit limits the withdrawal.
|
|
59
|
+
* @param params.market - Market whose available liquidity limits the withdrawal.
|
|
60
|
+
* @returns The lower of the position credit and market withdrawable liquidity.
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { PositionUtils } from "@morpho-org/midnight-sdk";
|
|
64
|
+
*
|
|
65
|
+
* const withdrawable = PositionUtils.getWithdrawable({
|
|
66
|
+
* position: { credit: 1_000n },
|
|
67
|
+
* market: { withdrawable: 500n },
|
|
68
|
+
* });
|
|
69
|
+
* console.log(withdrawable); // 500n
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
function getWithdrawable(params: {
|
|
73
|
+
readonly position: Pick<IPosition, "credit">;
|
|
74
|
+
readonly market: Pick<IMarket, "withdrawable">;
|
|
75
|
+
}): bigint;
|
|
53
76
|
/**
|
|
54
77
|
* Returns plain Midnight position and market objects accrued like Midnight `updatePositionView`.
|
|
55
78
|
*
|
|
@@ -66,6 +89,8 @@ export declare namespace PositionUtils {
|
|
|
66
89
|
*
|
|
67
90
|
* const { position, market } = PositionUtils.accrueInterest({
|
|
68
91
|
* position: {
|
|
92
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
93
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
69
94
|
* credit: 1_000n,
|
|
70
95
|
* pendingFee: 100n,
|
|
71
96
|
* lastLossFactor: 0n,
|
|
@@ -9,6 +9,8 @@ import { InvalidPositionAccrualStateError, InvalidPositionAccrualTimestampError,
|
|
|
9
9
|
*
|
|
10
10
|
* const accrued = PositionUtils.accrueInterest({
|
|
11
11
|
* position: {
|
|
12
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
13
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
12
14
|
* credit: 1_000n,
|
|
13
15
|
* pendingFee: 100n,
|
|
14
16
|
* lastLossFactor: 0n,
|
|
@@ -50,6 +52,27 @@ import { InvalidPositionAccrualStateError, InvalidPositionAccrualTimestampError,
|
|
|
50
52
|
*/
|
|
51
53
|
export var PositionUtils;
|
|
52
54
|
(function (PositionUtils) {
|
|
55
|
+
/**
|
|
56
|
+
* Returns the maximum credit units currently withdrawable by a position.
|
|
57
|
+
*
|
|
58
|
+
* @param params.position - Position whose credit limits the withdrawal.
|
|
59
|
+
* @param params.market - Market whose available liquidity limits the withdrawal.
|
|
60
|
+
* @returns The lower of the position credit and market withdrawable liquidity.
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { PositionUtils } from "@morpho-org/midnight-sdk";
|
|
64
|
+
*
|
|
65
|
+
* const withdrawable = PositionUtils.getWithdrawable({
|
|
66
|
+
* position: { credit: 1_000n },
|
|
67
|
+
* market: { withdrawable: 500n },
|
|
68
|
+
* });
|
|
69
|
+
* console.log(withdrawable); // 500n
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
function getWithdrawable(params) {
|
|
73
|
+
return MathLib.min(BigInt(params.position.credit), BigInt(params.market.withdrawable));
|
|
74
|
+
}
|
|
75
|
+
PositionUtils.getWithdrawable = getWithdrawable;
|
|
53
76
|
/**
|
|
54
77
|
* Returns plain Midnight position and market objects accrued like Midnight `updatePositionView`.
|
|
55
78
|
*
|
|
@@ -66,6 +89,8 @@ export var PositionUtils;
|
|
|
66
89
|
*
|
|
67
90
|
* const { position, market } = PositionUtils.accrueInterest({
|
|
68
91
|
* position: {
|
|
92
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
93
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
69
94
|
* credit: 1_000n,
|
|
70
95
|
* pendingFee: 100n,
|
|
71
96
|
* lastLossFactor: 0n,
|
|
@@ -169,6 +194,8 @@ export var PositionUtils;
|
|
|
169
194
|
];
|
|
170
195
|
return {
|
|
171
196
|
position: {
|
|
197
|
+
user: params.position.user,
|
|
198
|
+
marketId: params.position.marketId,
|
|
172
199
|
credit: postSlashCredit - accruedFee,
|
|
173
200
|
pendingFee: postSlashPendingFee - accruedFee,
|
|
174
201
|
lastLossFactor: marketLossFactor,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InvalidTreeError } from "../errors.js";
|
|
2
|
-
import { Offer
|
|
2
|
+
import { Offer } from "../offers/index.js";
|
|
3
3
|
import { Group } from "./Group.js";
|
|
4
4
|
import { GroupUtils } from "./GroupUtils.js";
|
|
5
5
|
import { TreeUtils } from "./TreeUtils.js";
|
|
@@ -15,17 +15,16 @@ function normalizeTree(tree) {
|
|
|
15
15
|
if (isTreeLike(tree)) {
|
|
16
16
|
return tree;
|
|
17
17
|
}
|
|
18
|
-
const
|
|
18
|
+
const entries = Array.isArray(tree) ? tree : [tree];
|
|
19
|
+
const offers = entries.flatMap((entry) => GroupUtils.isGroupInput(entry)
|
|
19
20
|
? Group.from(entry).offers
|
|
20
21
|
: [
|
|
21
22
|
new Offer({
|
|
22
23
|
...Offer.from(entry),
|
|
23
|
-
group:
|
|
24
|
+
group: GroupUtils.hash([entry]),
|
|
24
25
|
}),
|
|
25
26
|
]);
|
|
26
|
-
const descriptor = TreeUtils.buildDescriptor(
|
|
27
|
-
preserveStandaloneGroups: true,
|
|
28
|
-
});
|
|
27
|
+
const descriptor = TreeUtils.buildDescriptor(entries);
|
|
29
28
|
return {
|
|
30
29
|
offers,
|
|
31
30
|
paddedOffers: descriptor.offers,
|
|
@@ -108,8 +108,9 @@ export declare class Tree {
|
|
|
108
108
|
*
|
|
109
109
|
* Use after `Offer.create` and optional `Group.create`, before
|
|
110
110
|
* `Tree.mempoolValidate`, `EcrecoverRatifierUtils.ratify`, or
|
|
111
|
-
* `SetterRatifierUtils.ratify`. Groups are flattened
|
|
112
|
-
* offer
|
|
111
|
+
* `SetterRatifierUtils.ratify`. Groups are flattened, and every standalone
|
|
112
|
+
* offer is normalized as a singleton group using the router-compatible group
|
|
113
|
+
* id algorithm.
|
|
113
114
|
*
|
|
114
115
|
* @param params - Groups or standalone offers in leaf order.
|
|
115
116
|
* @returns Tree instance.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Offer
|
|
1
|
+
import { Offer } from "../offers/index.js";
|
|
2
2
|
import { Group } from "./Group.js";
|
|
3
3
|
import { GroupUtils } from "./GroupUtils.js";
|
|
4
4
|
import { TreeUtils, } from "./TreeUtils.js";
|
|
@@ -60,7 +60,7 @@ export class Tree {
|
|
|
60
60
|
: [
|
|
61
61
|
new Offer({
|
|
62
62
|
...Offer.from(entry),
|
|
63
|
-
group:
|
|
63
|
+
group: GroupUtils.hash([entry]),
|
|
64
64
|
}),
|
|
65
65
|
]);
|
|
66
66
|
const descriptor = TreeUtils.buildDescriptor(params);
|
|
@@ -115,15 +115,18 @@ export class Tree {
|
|
|
115
115
|
* ```
|
|
116
116
|
*/
|
|
117
117
|
static from(tree) {
|
|
118
|
-
|
|
118
|
+
if (tree instanceof Tree)
|
|
119
|
+
return tree;
|
|
120
|
+
return Tree.create(Array.isArray(tree) ? tree : [tree]);
|
|
119
121
|
}
|
|
120
122
|
/**
|
|
121
123
|
* Creates a tree from groups or standalone offers.
|
|
122
124
|
*
|
|
123
125
|
* Use after `Offer.create` and optional `Group.create`, before
|
|
124
126
|
* `Tree.mempoolValidate`, `EcrecoverRatifierUtils.ratify`, or
|
|
125
|
-
* `SetterRatifierUtils.ratify`. Groups are flattened
|
|
126
|
-
* offer
|
|
127
|
+
* `SetterRatifierUtils.ratify`. Groups are flattened, and every standalone
|
|
128
|
+
* offer is normalized as a singleton group using the router-compatible group
|
|
129
|
+
* id algorithm.
|
|
127
130
|
*
|
|
128
131
|
* @param params - Groups or standalone offers in leaf order.
|
|
129
132
|
* @returns Tree instance.
|
|
@@ -188,7 +188,7 @@ export type TreeCreateParams = readonly GroupInput[];
|
|
|
188
188
|
* console.log(tree);
|
|
189
189
|
* ```
|
|
190
190
|
*/
|
|
191
|
-
export type TreeInput = Tree | TreeCreateParams;
|
|
191
|
+
export type TreeInput = Tree | TreeCreateParams | GroupInput;
|
|
192
192
|
/**
|
|
193
193
|
* Tree-shaped data required by ratifier helpers.
|
|
194
194
|
*
|
|
@@ -284,7 +284,7 @@ export interface TreeLike {
|
|
|
284
284
|
* console.log(tree);
|
|
285
285
|
* ```
|
|
286
286
|
*/
|
|
287
|
-
export type RatifierTreeInput = TreeLike |
|
|
287
|
+
export type RatifierTreeInput = TreeLike | TreeInput;
|
|
288
288
|
/**
|
|
289
289
|
* Optional ratification inputs for {@link Tree.mempoolValidate}.
|
|
290
290
|
*
|
|
@@ -489,12 +489,11 @@ export declare namespace TreeUtils {
|
|
|
489
489
|
* Use after `Group.create` or standalone `Offer.create` when you need the
|
|
490
490
|
* padded leaves for custom signing, root approval, or proof construction.
|
|
491
491
|
* Groups are encoded with their derived shared group id, and standalone
|
|
492
|
-
* offers are encoded with
|
|
492
|
+
* offers are encoded as singleton groups with the same algorithm.
|
|
493
493
|
* `Tree.create` calls this internally and is the simpler API for most
|
|
494
494
|
* make-side code.
|
|
495
495
|
*
|
|
496
496
|
* @param entries - Groups or standalone offers in leaf order.
|
|
497
|
-
* @param options.preserveStandaloneGroups - Whether standalone offer group ids should be preserved instead of normalized.
|
|
498
497
|
* @returns Tree descriptor.
|
|
499
498
|
* @throws {InvalidTreeError} when the offer count is empty, all padding, or duplicated.
|
|
500
499
|
* @throws {InvalidTreeHeightError} when the padded tree exceeds supported ratifier typehashes.
|
|
@@ -532,9 +531,7 @@ export declare namespace TreeUtils {
|
|
|
532
531
|
* console.log(tree.root);
|
|
533
532
|
* ```
|
|
534
533
|
*/
|
|
535
|
-
function buildDescriptor(entries: TreeCreateParams
|
|
536
|
-
readonly preserveStandaloneGroups?: boolean;
|
|
537
|
-
}): TreeDescriptor;
|
|
534
|
+
function buildDescriptor(entries: TreeCreateParams): TreeDescriptor;
|
|
538
535
|
/**
|
|
539
536
|
* Builds only the tree root.
|
|
540
537
|
*
|
|
@@ -35,6 +35,7 @@ function assertLeafOffers(offers, leafHashes) {
|
|
|
35
35
|
}
|
|
36
36
|
seen.add(leafHash);
|
|
37
37
|
}
|
|
38
|
+
/* v8 ignore next: buildDescriptor rejects empty struct lists before padding; this protects direct internal misuse. */
|
|
38
39
|
if (seen.size === 0) {
|
|
39
40
|
throw new InvalidTreeError("Tree must not be empty.");
|
|
40
41
|
}
|
|
@@ -118,23 +119,30 @@ export var TreeUtils;
|
|
|
118
119
|
async function mempoolValidate(params) {
|
|
119
120
|
let items;
|
|
120
121
|
if (params.ratification == null) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
if ("paddedOffers" in params.tree) {
|
|
123
|
+
items = params.tree.offers.map((offer) => ({
|
|
124
|
+
offer,
|
|
125
|
+
ratifierData: "0x",
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const entries = Array.isArray(params.tree)
|
|
130
|
+
? params.tree
|
|
131
|
+
: [params.tree];
|
|
132
|
+
const offers = entries.flatMap((entry) => GroupUtils.isGroupInput(entry)
|
|
124
133
|
? Group.from(entry).offers
|
|
125
134
|
: [
|
|
126
135
|
new Offer({
|
|
127
136
|
...Offer.from(entry),
|
|
128
|
-
group:
|
|
137
|
+
group: GroupUtils.hash([entry]),
|
|
129
138
|
}),
|
|
130
139
|
]);
|
|
131
|
-
|
|
132
|
-
|
|
140
|
+
buildDescriptor(entries);
|
|
141
|
+
items = offers.map((offer) => ({
|
|
142
|
+
offer,
|
|
143
|
+
ratifierData: "0x",
|
|
144
|
+
}));
|
|
133
145
|
}
|
|
134
|
-
items = offers.map((offer) => ({
|
|
135
|
-
offer,
|
|
136
|
-
ratifierData: "0x",
|
|
137
|
-
}));
|
|
138
146
|
}
|
|
139
147
|
else if (params.ratification.type === "ecrecover") {
|
|
140
148
|
if (params.ratification.signature != null) {
|
|
@@ -198,12 +206,11 @@ export var TreeUtils;
|
|
|
198
206
|
* Use after `Group.create` or standalone `Offer.create` when you need the
|
|
199
207
|
* padded leaves for custom signing, root approval, or proof construction.
|
|
200
208
|
* Groups are encoded with their derived shared group id, and standalone
|
|
201
|
-
* offers are encoded with
|
|
209
|
+
* offers are encoded as singleton groups with the same algorithm.
|
|
202
210
|
* `Tree.create` calls this internally and is the simpler API for most
|
|
203
211
|
* make-side code.
|
|
204
212
|
*
|
|
205
213
|
* @param entries - Groups or standalone offers in leaf order.
|
|
206
|
-
* @param options.preserveStandaloneGroups - Whether standalone offer group ids should be preserved instead of normalized.
|
|
207
214
|
* @returns Tree descriptor.
|
|
208
215
|
* @throws {InvalidTreeError} when the offer count is empty, all padding, or duplicated.
|
|
209
216
|
* @throws {InvalidTreeHeightError} when the padded tree exceeds supported ratifier typehashes.
|
|
@@ -241,15 +248,13 @@ export var TreeUtils;
|
|
|
241
248
|
* console.log(tree.root);
|
|
242
249
|
* ```
|
|
243
250
|
*/
|
|
244
|
-
function buildDescriptor(entries
|
|
251
|
+
function buildDescriptor(entries) {
|
|
245
252
|
const structs = entries.flatMap((entry) => GroupUtils.isGroupInput(entry)
|
|
246
253
|
? GroupUtils.toStructs(entry)
|
|
247
254
|
: [
|
|
248
255
|
OfferUtils.toStruct({
|
|
249
256
|
offer: entry,
|
|
250
|
-
group:
|
|
251
|
-
? undefined
|
|
252
|
-
: OfferUtils.groupHash(entry),
|
|
257
|
+
group: GroupUtils.hash([entry]),
|
|
253
258
|
}),
|
|
254
259
|
]);
|
|
255
260
|
if (structs.length === 0) {
|
|
@@ -259,6 +264,7 @@ export var TreeUtils;
|
|
|
259
264
|
const leaves = offerStructs.map(OfferUtils.hashStruct);
|
|
260
265
|
assertLeafOffers(offerStructs, leaves);
|
|
261
266
|
const height = Math.log2(offerStructs.length);
|
|
267
|
+
/* v8 ignore next: exercising this branch would require allocating more than 2^20 offer structs. */
|
|
262
268
|
if (height > 20)
|
|
263
269
|
throw new InvalidTreeHeightError(height);
|
|
264
270
|
let level = [...leaves];
|