@morpho-org/midnight-sdk 1.1.1 → 1.2.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/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/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 +2 -1
- package/lib/cjs/signatures/Tree.js +3 -1
- package/lib/cjs/signatures/TreeUtils.d.ts +2 -2
- package/lib/cjs/signatures/TreeUtils.js +17 -8
- 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/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 +2 -1
- package/lib/esm/signatures/Tree.js +3 -1
- package/lib/esm/signatures/TreeUtils.d.ts +2 -2
- package/lib/esm/signatures/TreeUtils.js +17 -8
- package/package.json +2 -2
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AccrualPosition = exports.Position = void 0;
|
|
4
4
|
const morpho_ts_1 = require("@morpho-org/morpho-ts");
|
|
5
5
|
const errors_js_1 = require("../errors.js");
|
|
6
|
-
const Market_js_1 = require("
|
|
6
|
+
const Market_js_1 = require("../market/Market.js");
|
|
7
7
|
const PositionUtils_js_1 = require("./PositionUtils.js");
|
|
8
8
|
/**
|
|
9
9
|
* Midnight user position as stored by the core contract.
|
|
@@ -13,6 +13,8 @@ const PositionUtils_js_1 = require("./PositionUtils.js");
|
|
|
13
13
|
* import { Position } from "@morpho-org/midnight-sdk";
|
|
14
14
|
*
|
|
15
15
|
* const position = new Position({
|
|
16
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
17
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
16
18
|
* credit: 0n,
|
|
17
19
|
* pendingFee: 0n,
|
|
18
20
|
* lastLossFactor: 0n,
|
|
@@ -25,6 +27,10 @@ const PositionUtils_js_1 = require("./PositionUtils.js");
|
|
|
25
27
|
* ```
|
|
26
28
|
*/
|
|
27
29
|
class Position {
|
|
30
|
+
/** User holding this position. */
|
|
31
|
+
user;
|
|
32
|
+
/** Id of the market on which this position is held. */
|
|
33
|
+
marketId;
|
|
28
34
|
/** User credit. */
|
|
29
35
|
credit;
|
|
30
36
|
/** Pending continuous fee. */
|
|
@@ -40,6 +46,8 @@ class Position {
|
|
|
40
46
|
/** Collateral balances by index. */
|
|
41
47
|
collateral;
|
|
42
48
|
constructor(position) {
|
|
49
|
+
this.user = position.user;
|
|
50
|
+
this.marketId = position.marketId;
|
|
43
51
|
this.credit = BigInt(position.credit);
|
|
44
52
|
this.pendingFee = BigInt(position.pendingFee);
|
|
45
53
|
this.lastLossFactor = BigInt(position.lastLossFactor);
|
|
@@ -57,6 +65,8 @@ class Position {
|
|
|
57
65
|
* import { Position } from "@morpho-org/midnight-sdk";
|
|
58
66
|
*
|
|
59
67
|
* const position = new Position({
|
|
68
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
69
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
60
70
|
* credit: 1_000n,
|
|
61
71
|
* pendingFee: 100n,
|
|
62
72
|
* lastLossFactor: 0n,
|
|
@@ -97,6 +107,7 @@ exports.Position = Position;
|
|
|
97
107
|
*
|
|
98
108
|
* const position = new AccrualPosition(
|
|
99
109
|
* {
|
|
110
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
100
111
|
* credit: 1_000n,
|
|
101
112
|
* pendingFee: 100n,
|
|
102
113
|
* lastLossFactor: 0n,
|
|
@@ -136,11 +147,74 @@ exports.Position = Position;
|
|
|
136
147
|
* ```
|
|
137
148
|
*/
|
|
138
149
|
class AccrualPosition extends Position {
|
|
139
|
-
|
|
140
|
-
market;
|
|
150
|
+
_market;
|
|
141
151
|
constructor(position, market) {
|
|
142
|
-
|
|
143
|
-
|
|
152
|
+
const _market = Market_js_1.Market.from(market);
|
|
153
|
+
super({ ...position, marketId: _market.id });
|
|
154
|
+
this._market = _market;
|
|
155
|
+
}
|
|
156
|
+
/** Hydrated market for this position. */
|
|
157
|
+
get market() {
|
|
158
|
+
return this._market;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Returns the maximum credit units currently withdrawable from this position.
|
|
162
|
+
*
|
|
163
|
+
* The protocol capacity is limited by both the accrued position credit and
|
|
164
|
+
* the market's currently withdrawable liquidity. Default redemption flows may
|
|
165
|
+
* still choose the position face value.
|
|
166
|
+
*
|
|
167
|
+
* @returns Maximum credit units currently withdrawable.
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* import { AccrualPosition } from "@morpho-org/midnight-sdk";
|
|
171
|
+
*
|
|
172
|
+
* const position = new AccrualPosition(
|
|
173
|
+
* {
|
|
174
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
175
|
+
* credit: 1_000n,
|
|
176
|
+
* pendingFee: 100n,
|
|
177
|
+
* lastLossFactor: 0n,
|
|
178
|
+
* lastAccrual: 1_000n,
|
|
179
|
+
* debt: 0n,
|
|
180
|
+
* collateralBitmap: 1n,
|
|
181
|
+
* collateral: [50n],
|
|
182
|
+
* },
|
|
183
|
+
* {
|
|
184
|
+
* params: {
|
|
185
|
+
* chainId: 8453,
|
|
186
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
187
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
188
|
+
* collateralParams: [
|
|
189
|
+
* {
|
|
190
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
191
|
+
* lltv: 770000000000000000n,
|
|
192
|
+
* liquidationCursor: 250000000000000000n,
|
|
193
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
194
|
+
* },
|
|
195
|
+
* ],
|
|
196
|
+
* maturity: 54_000n,
|
|
197
|
+
* rcfThreshold: 0n,
|
|
198
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
199
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
200
|
+
* },
|
|
201
|
+
* totalUnits: 1_000n,
|
|
202
|
+
* lossFactor: 0n,
|
|
203
|
+
* withdrawable: 950n,
|
|
204
|
+
* continuousFeeCredit: 0n,
|
|
205
|
+
* settlementFeeCbps: [1, 2, 3, 4, 5, 6, 7],
|
|
206
|
+
* continuousFee: 10,
|
|
207
|
+
* tickSpacing: 4,
|
|
208
|
+
* },
|
|
209
|
+
* );
|
|
210
|
+
* console.log(position.withdrawable); // 950n
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
get withdrawable() {
|
|
214
|
+
return PositionUtils_js_1.PositionUtils.getWithdrawable({
|
|
215
|
+
position: this,
|
|
216
|
+
market: this.market,
|
|
217
|
+
});
|
|
144
218
|
}
|
|
145
219
|
/**
|
|
146
220
|
* Returns the position collateral balance at an index configured by the market.
|
|
@@ -168,6 +242,7 @@ class AccrualPosition extends Position {
|
|
|
168
242
|
*
|
|
169
243
|
* const position = new AccrualPosition(
|
|
170
244
|
* {
|
|
245
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
171
246
|
* credit: 1_000n,
|
|
172
247
|
* pendingFee: 100n,
|
|
173
248
|
* lastLossFactor: 0n,
|
|
@@ -240,6 +315,7 @@ class AccrualPosition extends Position {
|
|
|
240
315
|
* const collateralToken = "0x0000000000000000000000000000000000007000";
|
|
241
316
|
* const position = new AccrualPosition(
|
|
242
317
|
* {
|
|
318
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
243
319
|
* credit: 1_000n,
|
|
244
320
|
* pendingFee: 100n,
|
|
245
321
|
* lastLossFactor: 0n,
|
|
@@ -309,6 +385,7 @@ class AccrualPosition extends Position {
|
|
|
309
385
|
*
|
|
310
386
|
* const position = new AccrualPosition(
|
|
311
387
|
* {
|
|
388
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
312
389
|
* credit: 1_000n,
|
|
313
390
|
* pendingFee: 100n,
|
|
314
391
|
* lastLossFactor: 0n,
|
|
@@ -380,6 +457,7 @@ class AccrualPosition extends Position {
|
|
|
380
457
|
*
|
|
381
458
|
* const position = new AccrualPosition(
|
|
382
459
|
* {
|
|
460
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
383
461
|
* credit: 1_000n,
|
|
384
462
|
* pendingFee: 100n,
|
|
385
463
|
* 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,
|
|
@@ -12,6 +12,8 @@ const errors_js_1 = require("../errors.js");
|
|
|
12
12
|
*
|
|
13
13
|
* const accrued = PositionUtils.accrueInterest({
|
|
14
14
|
* position: {
|
|
15
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
16
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
15
17
|
* credit: 1_000n,
|
|
16
18
|
* pendingFee: 100n,
|
|
17
19
|
* lastLossFactor: 0n,
|
|
@@ -53,6 +55,27 @@ const errors_js_1 = require("../errors.js");
|
|
|
53
55
|
*/
|
|
54
56
|
var PositionUtils;
|
|
55
57
|
(function (PositionUtils) {
|
|
58
|
+
/**
|
|
59
|
+
* Returns the maximum credit units currently withdrawable by a position.
|
|
60
|
+
*
|
|
61
|
+
* @param params.position - Position whose credit limits the withdrawal.
|
|
62
|
+
* @param params.market - Market whose available liquidity limits the withdrawal.
|
|
63
|
+
* @returns The lower of the position credit and market withdrawable liquidity.
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* import { PositionUtils } from "@morpho-org/midnight-sdk";
|
|
67
|
+
*
|
|
68
|
+
* const withdrawable = PositionUtils.getWithdrawable({
|
|
69
|
+
* position: { credit: 1_000n },
|
|
70
|
+
* market: { withdrawable: 500n },
|
|
71
|
+
* });
|
|
72
|
+
* console.log(withdrawable); // 500n
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
function getWithdrawable(params) {
|
|
76
|
+
return morpho_ts_1.MathLib.min(BigInt(params.position.credit), BigInt(params.market.withdrawable));
|
|
77
|
+
}
|
|
78
|
+
PositionUtils.getWithdrawable = getWithdrawable;
|
|
56
79
|
/**
|
|
57
80
|
* Returns plain Midnight position and market objects accrued like Midnight `updatePositionView`.
|
|
58
81
|
*
|
|
@@ -69,6 +92,8 @@ var PositionUtils;
|
|
|
69
92
|
*
|
|
70
93
|
* const { position, market } = PositionUtils.accrueInterest({
|
|
71
94
|
* position: {
|
|
95
|
+
* user: "0x0000000000000000000000000000000000009000",
|
|
96
|
+
* marketId: "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
72
97
|
* credit: 1_000n,
|
|
73
98
|
* pendingFee: 100n,
|
|
74
99
|
* lastLossFactor: 0n,
|
|
@@ -172,6 +197,8 @@ var PositionUtils;
|
|
|
172
197
|
];
|
|
173
198
|
return {
|
|
174
199
|
position: {
|
|
200
|
+
user: params.position.user,
|
|
201
|
+
marketId: params.position.marketId,
|
|
175
202
|
credit: postSlashCredit - accruedFee,
|
|
176
203
|
pendingFee: postSlashPendingFee - accruedFee,
|
|
177
204
|
lastLossFactor: marketLossFactor,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./Position.js"), exports);
|
|
18
|
+
__exportStar(require("./PositionUtils.js"), exports);
|
|
@@ -18,7 +18,8 @@ function normalizeTree(tree) {
|
|
|
18
18
|
if (isTreeLike(tree)) {
|
|
19
19
|
return tree;
|
|
20
20
|
}
|
|
21
|
-
const
|
|
21
|
+
const entries = Array.isArray(tree) ? tree : [tree];
|
|
22
|
+
const offers = entries.flatMap((entry) => GroupUtils_js_1.GroupUtils.isGroupInput(entry)
|
|
22
23
|
? Group_js_1.Group.from(entry).offers
|
|
23
24
|
: [
|
|
24
25
|
new index_js_1.Offer({
|
|
@@ -118,7 +118,9 @@ class Tree {
|
|
|
118
118
|
* ```
|
|
119
119
|
*/
|
|
120
120
|
static from(tree) {
|
|
121
|
-
|
|
121
|
+
if (tree instanceof Tree)
|
|
122
|
+
return tree;
|
|
123
|
+
return Tree.create(Array.isArray(tree) ? tree : [tree]);
|
|
122
124
|
}
|
|
123
125
|
/**
|
|
124
126
|
* Creates a tree from groups or standalone offers.
|
|
@@ -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
|
*
|
|
@@ -38,6 +38,7 @@ function assertLeafOffers(offers, leafHashes) {
|
|
|
38
38
|
}
|
|
39
39
|
seen.add(leafHash);
|
|
40
40
|
}
|
|
41
|
+
/* v8 ignore next: buildDescriptor rejects empty struct lists before padding; this protects direct internal misuse. */
|
|
41
42
|
if (seen.size === 0) {
|
|
42
43
|
throw new errors_js_1.InvalidTreeError("Tree must not be empty.");
|
|
43
44
|
}
|
|
@@ -121,9 +122,17 @@ var TreeUtils;
|
|
|
121
122
|
async function mempoolValidate(params) {
|
|
122
123
|
let items;
|
|
123
124
|
if (params.ratification == null) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
if ("paddedOffers" in params.tree) {
|
|
126
|
+
items = params.tree.offers.map((offer) => ({
|
|
127
|
+
offer,
|
|
128
|
+
ratifierData: "0x",
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
const entries = Array.isArray(params.tree)
|
|
133
|
+
? params.tree
|
|
134
|
+
: [params.tree];
|
|
135
|
+
const offers = entries.flatMap((entry) => GroupUtils_js_1.GroupUtils.isGroupInput(entry)
|
|
127
136
|
? Group_js_1.Group.from(entry).offers
|
|
128
137
|
: [
|
|
129
138
|
new index_js_1.Offer({
|
|
@@ -131,13 +140,12 @@ var TreeUtils;
|
|
|
131
140
|
group: index_js_1.OfferUtils.groupHash(entry),
|
|
132
141
|
}),
|
|
133
142
|
]);
|
|
134
|
-
if (!("paddedOffers" in params.tree)) {
|
|
135
143
|
buildDescriptor(offers, { preserveStandaloneGroups: true });
|
|
144
|
+
items = offers.map((offer) => ({
|
|
145
|
+
offer,
|
|
146
|
+
ratifierData: "0x",
|
|
147
|
+
}));
|
|
136
148
|
}
|
|
137
|
-
items = offers.map((offer) => ({
|
|
138
|
-
offer,
|
|
139
|
-
ratifierData: "0x",
|
|
140
|
-
}));
|
|
141
149
|
}
|
|
142
150
|
else if (params.ratification.type === "ecrecover") {
|
|
143
151
|
if (params.ratification.signature != null) {
|
|
@@ -262,6 +270,7 @@ var TreeUtils;
|
|
|
262
270
|
const leaves = offerStructs.map(index_js_1.OfferUtils.hashStruct);
|
|
263
271
|
assertLeafOffers(offerStructs, leaves);
|
|
264
272
|
const height = Math.log2(offerStructs.length);
|
|
273
|
+
/* v8 ignore next: exercising this branch would require allocating more than 2^20 offer structs. */
|
|
265
274
|
if (height > 20)
|
|
266
275
|
throw new errors_js_1.InvalidTreeHeightError(height);
|
|
267
276
|
let level = [...leaves];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Address, Client, Hash } from "viem";
|
|
2
|
-
import { AccrualPosition, Position } from "../
|
|
2
|
+
import { AccrualPosition, Position } from "../position/index.js";
|
|
3
3
|
import type { MidnightFetchParams } from "./types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Fetches a Midnight position by id and user.
|
|
@@ -2,7 +2,7 @@ import { getChainAddress } from "@morpho-org/morpho-ts";
|
|
|
2
2
|
import { readContract } from "viem/actions";
|
|
3
3
|
import { midnightAbi } from "../abis.js";
|
|
4
4
|
import { MAX_COLLATERALS } from "../constants.js";
|
|
5
|
-
import { AccrualPosition, Position } from "../
|
|
5
|
+
import { AccrualPosition, Position } from "../position/index.js";
|
|
6
6
|
import { abi as getPositionAbi, code as getPositionCode, } from "../queries/GetPosition.js";
|
|
7
7
|
import { fetchMarket } from "./Market.js";
|
|
8
8
|
import { callParameters, resolveChainId, shouldUseDeployless, } from "./utils.js";
|
|
@@ -60,6 +60,8 @@ export async function fetchPosition(client, params) {
|
|
|
60
60
|
});
|
|
61
61
|
const collateral = position.collateral;
|
|
62
62
|
return new Position({
|
|
63
|
+
user: params.user,
|
|
64
|
+
marketId: params.marketId,
|
|
63
65
|
credit: position.credit,
|
|
64
66
|
pendingFee: position.pendingFee,
|
|
65
67
|
lastLossFactor: position.lastLossFactor,
|
|
@@ -92,6 +94,8 @@ export async function fetchPosition(client, params) {
|
|
|
92
94
|
});
|
|
93
95
|
}));
|
|
94
96
|
return new Position({
|
|
97
|
+
user: params.user,
|
|
98
|
+
marketId: params.marketId,
|
|
95
99
|
credit: position[0],
|
|
96
100
|
pendingFee: position[1],
|
|
97
101
|
lastLossFactor: position[2],
|
package/lib/esm/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./fetch/index.js";
|
|
|
5
5
|
export * from "./market/index.js";
|
|
6
6
|
export * from "./math/index.js";
|
|
7
7
|
export * from "./offers/index.js";
|
|
8
|
+
export * from "./position/index.js";
|
|
8
9
|
export * from "./signatures/index.js";
|
|
9
10
|
/**
|
|
10
11
|
* Namespace for Midnight mempool payload utilities.
|
package/lib/esm/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./fetch/index.js";
|
|
|
5
5
|
export * from "./market/index.js";
|
|
6
6
|
export * from "./math/index.js";
|
|
7
7
|
export * from "./offers/index.js";
|
|
8
|
+
export * from "./position/index.js";
|
|
8
9
|
export * from "./signatures/index.js";
|
|
9
10
|
/**
|
|
10
11
|
* Namespace for Midnight mempool payload utilities.
|
package/lib/esm/market/index.js
CHANGED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { type BigIntish } from "@morpho-org/morpho-ts";
|
|
2
|
+
/** One time-bounded offer leg to convert into a Midnight `Offer.create` input. */
|
|
3
|
+
export interface FixedRateOfferChainLeg {
|
|
4
|
+
/** Spacing-aligned Midnight tick for this offer. */
|
|
5
|
+
readonly tick: bigint;
|
|
6
|
+
/** First timestamp at which the offer leg is active. */
|
|
7
|
+
readonly startTimestamp: bigint;
|
|
8
|
+
/** Last timestamp at which the offer leg is active. */
|
|
9
|
+
readonly expiryTimestamp: bigint;
|
|
10
|
+
}
|
|
11
|
+
/** Parameters shared by lend-only and borrow-only fixed-rate offer-chain builders. */
|
|
12
|
+
export interface BuildFixedRateOfferChainParams {
|
|
13
|
+
/** Target yearly fixed rate as a decimal number, for example `0.05` for 5%. */
|
|
14
|
+
readonly targetRate: number;
|
|
15
|
+
/** Tick spacing enforced by the market. */
|
|
16
|
+
readonly tickSpacing: BigIntish;
|
|
17
|
+
/** Market maturity timestamp in seconds. */
|
|
18
|
+
readonly maturityTimestamp: BigIntish;
|
|
19
|
+
/** First timestamp the chain should cover. */
|
|
20
|
+
readonly chainStartTimestamp: BigIntish;
|
|
21
|
+
/** Latest timestamp the chain may cover. */
|
|
22
|
+
readonly chainEndTimestamp: BigIntish;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Utilities for building time-bounded Midnight offer chains.
|
|
26
|
+
*
|
|
27
|
+
* A Midnight offer has one fixed price, so its displayed yearly rate changes
|
|
28
|
+
* as maturity approaches. The markets app uses these helpers when a maker wants
|
|
29
|
+
* to post, for example, a 5% order for several months: the app builds several
|
|
30
|
+
* adjacent offers sharing the same reserve, each with a different tick and time
|
|
31
|
+
* window, so the order reviews and renders as a stable 5% order across the
|
|
32
|
+
* selected window instead of drifting upward as time passes.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { OfferChainUtils } from "@morpho-org/midnight-sdk";
|
|
37
|
+
*
|
|
38
|
+
* const legs = OfferChainUtils.buildLendFixedRateOfferChain({
|
|
39
|
+
* targetRate: 0.05,
|
|
40
|
+
* tickSpacing: 4n,
|
|
41
|
+
* maturityTimestamp: 1_798_761_600n,
|
|
42
|
+
* chainStartTimestamp: 1_767_225_600n,
|
|
43
|
+
* chainEndTimestamp: 1_791_153_600n,
|
|
44
|
+
* });
|
|
45
|
+
* console.log(legs[0]?.tick);
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare namespace OfferChainUtils {
|
|
49
|
+
/**
|
|
50
|
+
* Maximum fraction of the initial time-to-maturity covered by a fixed-rate offer chain.
|
|
51
|
+
*
|
|
52
|
+
* Use this cap before displaying an expiry picker for a fixed-rate maker
|
|
53
|
+
* order. The last part of the maturity window is intentionally excluded
|
|
54
|
+
* because tiny time changes cause large displayed-rate drift.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { OfferChainUtils } from "@morpho-org/midnight-sdk";
|
|
59
|
+
*
|
|
60
|
+
* console.log(OfferChainUtils.MAX_EXPIRY_TTM_FRACTION);
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
const MAX_EXPIRY_TTM_FRACTION = 0.75;
|
|
64
|
+
/**
|
|
65
|
+
* Builds borrow-side sell-offer legs that approximate one fixed maker rate over time.
|
|
66
|
+
*
|
|
67
|
+
* Use before a make-borrow or supply-collateral-and-make-borrow flow when a
|
|
68
|
+
* borrower wants one displayed fixed borrow rate across a longer window. Map
|
|
69
|
+
* the returned legs to `Offer.create({ buy: false, ... })`, then group and
|
|
70
|
+
* submit them through the maker flow.
|
|
71
|
+
*
|
|
72
|
+
* Borrow chains read their target rate at each leg's expiry edge. If a leg
|
|
73
|
+
* would need to extend past `chainEndTimestamp`, it is dropped rather than
|
|
74
|
+
* clamped so the expiry edge remains the recoverable target-rate edge.
|
|
75
|
+
*
|
|
76
|
+
* @param params - Fixed-rate offer-chain parameters without a side field.
|
|
77
|
+
* @param params.targetRate - Target yearly fixed rate expressed as a decimal number.
|
|
78
|
+
* @param params.tickSpacing - Tick spacing enforced by the market.
|
|
79
|
+
* @param params.maturityTimestamp - Market maturity timestamp in seconds.
|
|
80
|
+
* @param params.chainStartTimestamp - First timestamp the chain should cover.
|
|
81
|
+
* @param params.chainEndTimestamp - Latest timestamp the chain may cover.
|
|
82
|
+
* @returns Borrow-side offer legs that can be mapped to `Offer.create({ buy: false, ... })`.
|
|
83
|
+
* @throws {InvalidOfferParameterError} when an input is invalid or the end timestamp exceeds the supported horizon.
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* import { Offer, OfferChainUtils } from "@morpho-org/midnight-sdk";
|
|
87
|
+
*
|
|
88
|
+
* const legs = OfferChainUtils.buildBorrowFixedRateOfferChain({
|
|
89
|
+
* targetRate: 0.08,
|
|
90
|
+
* tickSpacing: market.tickSpacing,
|
|
91
|
+
* maturityTimestamp: market.params.maturity,
|
|
92
|
+
* chainStartTimestamp: now,
|
|
93
|
+
* chainEndTimestamp: expiry,
|
|
94
|
+
* });
|
|
95
|
+
* const offers = legs.map((leg) =>
|
|
96
|
+
* Offer.create({
|
|
97
|
+
* ...baseOffer,
|
|
98
|
+
* buy: false,
|
|
99
|
+
* tick: leg.tick,
|
|
100
|
+
* start: leg.startTimestamp,
|
|
101
|
+
* expiry: leg.expiryTimestamp,
|
|
102
|
+
* }),
|
|
103
|
+
* );
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
function buildBorrowFixedRateOfferChain(params: BuildFixedRateOfferChainParams): readonly FixedRateOfferChainLeg[];
|
|
107
|
+
/**
|
|
108
|
+
* Builds lend-side buy-offer legs that approximate one fixed maker rate over time.
|
|
109
|
+
*
|
|
110
|
+
* Use before a make-lend flow when a lender wants one displayed fixed lend
|
|
111
|
+
* rate across a longer window. Map the returned legs to
|
|
112
|
+
* `Offer.create({ buy: true, ... })`, then group and submit them through the
|
|
113
|
+
* maker flow.
|
|
114
|
+
*
|
|
115
|
+
* Lend chains read their target rate at each leg's start edge. The first leg
|
|
116
|
+
* may start before `chainStartTimestamp`; clamping that edge would move the
|
|
117
|
+
* recoverable display rate below the maker's target.
|
|
118
|
+
*
|
|
119
|
+
* @param params - Fixed-rate offer-chain parameters without a side field.
|
|
120
|
+
* @param params.targetRate - Target yearly fixed rate expressed as a decimal number.
|
|
121
|
+
* @param params.tickSpacing - Tick spacing enforced by the market.
|
|
122
|
+
* @param params.maturityTimestamp - Market maturity timestamp in seconds.
|
|
123
|
+
* @param params.chainStartTimestamp - First timestamp the chain should cover.
|
|
124
|
+
* @param params.chainEndTimestamp - Latest timestamp the chain may cover.
|
|
125
|
+
* @returns Lend-side offer legs that can be mapped to `Offer.create({ buy: true, ... })`.
|
|
126
|
+
* @throws {InvalidOfferParameterError} when an input is invalid or the end timestamp exceeds the supported horizon.
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* import { Offer, OfferChainUtils } from "@morpho-org/midnight-sdk";
|
|
130
|
+
*
|
|
131
|
+
* const legs = OfferChainUtils.buildLendFixedRateOfferChain({
|
|
132
|
+
* targetRate: 0.05,
|
|
133
|
+
* tickSpacing: market.tickSpacing,
|
|
134
|
+
* maturityTimestamp: market.params.maturity,
|
|
135
|
+
* chainStartTimestamp: now,
|
|
136
|
+
* chainEndTimestamp: expiry,
|
|
137
|
+
* });
|
|
138
|
+
* const offers = legs.map((leg) =>
|
|
139
|
+
* Offer.create({
|
|
140
|
+
* ...baseOffer,
|
|
141
|
+
* buy: true,
|
|
142
|
+
* tick: leg.tick,
|
|
143
|
+
* start: leg.startTimestamp,
|
|
144
|
+
* expiry: leg.expiryTimestamp,
|
|
145
|
+
* }),
|
|
146
|
+
* );
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
function buildLendFixedRateOfferChain(params: BuildFixedRateOfferChainParams): readonly FixedRateOfferChainLeg[];
|
|
150
|
+
/**
|
|
151
|
+
* Returns the latest supported end timestamp for a fixed-rate offer chain.
|
|
152
|
+
*
|
|
153
|
+
* Chains intentionally stop before the final part of the maturity window
|
|
154
|
+
* because rate sensitivity accelerates near maturity and would require too
|
|
155
|
+
* many short-lived offers for a stable maker quote.
|
|
156
|
+
* Call this when constraining a make-offer expiry selector, then pass the
|
|
157
|
+
* selected timestamp to the lend-only or borrow-only chain builder.
|
|
158
|
+
*
|
|
159
|
+
* @param params - Maturity and chain-start timestamps.
|
|
160
|
+
* @param params.maturityTimestamp - Market maturity timestamp in seconds.
|
|
161
|
+
* @param params.chainStartTimestamp - First timestamp the chain should cover.
|
|
162
|
+
* @returns Latest accepted chain end timestamp.
|
|
163
|
+
* @throws {InvalidOfferParameterError} when a timestamp is invalid.
|
|
164
|
+
* @example
|
|
165
|
+
* ```ts
|
|
166
|
+
* import { OfferChainUtils } from "@morpho-org/midnight-sdk";
|
|
167
|
+
*
|
|
168
|
+
* const maxExpiry = OfferChainUtils.getMaxFixedRateOfferChainEndTimestamp({
|
|
169
|
+
* maturityTimestamp: market.params.maturity,
|
|
170
|
+
* chainStartTimestamp: now,
|
|
171
|
+
* });
|
|
172
|
+
* console.log(maxExpiry);
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
function getMaxFixedRateOfferChainEndTimestamp(params: {
|
|
176
|
+
readonly maturityTimestamp: BigIntish;
|
|
177
|
+
readonly chainStartTimestamp: BigIntish;
|
|
178
|
+
}): bigint;
|
|
179
|
+
}
|