@morpho-org/midnight-sdk 0.1.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/README.md +252 -0
- package/lib/cjs/abis.d.ts +3170 -0
- package/lib/cjs/abis.js +4073 -0
- package/lib/cjs/api/MidnightApi.d.ts +532 -0
- package/lib/cjs/api/MidnightApi.js +713 -0
- package/lib/cjs/api/helpers.d.ts +20 -0
- package/lib/cjs/api/helpers.js +189 -0
- package/lib/cjs/api/index.d.ts +2 -0
- package/lib/cjs/api/index.js +21 -0
- package/lib/cjs/api/types.d.ts +453 -0
- package/lib/cjs/api/types.js +2 -0
- package/lib/cjs/constants.d.ts +168 -0
- package/lib/cjs/constants.js +187 -0
- package/lib/cjs/errors.d.ts +253 -0
- package/lib/cjs/errors.js +309 -0
- package/lib/cjs/fetch/Market.d.ts +65 -0
- package/lib/cjs/fetch/Market.js +117 -0
- package/lib/cjs/fetch/Offer.d.ts +74 -0
- package/lib/cjs/fetch/Offer.js +119 -0
- package/lib/cjs/fetch/Position.d.ts +85 -0
- package/lib/cjs/fetch/Position.js +148 -0
- package/lib/cjs/fetch/Ratifier.d.ts +38 -0
- package/lib/cjs/fetch/Ratifier.js +57 -0
- package/lib/cjs/fetch/index.d.ts +5 -0
- package/lib/cjs/fetch/index.js +21 -0
- package/lib/cjs/fetch/types.d.ts +57 -0
- package/lib/cjs/fetch/types.js +2 -0
- package/lib/cjs/fetch/utils.d.ts +8 -0
- package/lib/cjs/fetch/utils.js +18 -0
- package/lib/cjs/index.d.ts +18 -0
- package/lib/cjs/index.js +57 -0
- package/lib/cjs/market/Market.d.ts +613 -0
- package/lib/cjs/market/Market.js +503 -0
- package/lib/cjs/market/MarketUtils.d.ts +189 -0
- package/lib/cjs/market/MarketUtils.js +303 -0
- package/lib/cjs/market/Position.d.ts +424 -0
- package/lib/cjs/market/Position.js +425 -0
- package/lib/cjs/market/PositionUtils.d.ts +115 -0
- package/lib/cjs/market/PositionUtils.js +194 -0
- package/lib/cjs/market/index.d.ts +4 -0
- package/lib/cjs/market/index.js +20 -0
- package/lib/cjs/math/ConsumableUnitsLib.d.ts +57 -0
- package/lib/cjs/math/ConsumableUnitsLib.js +77 -0
- package/lib/cjs/math/TakeAmountsLib.d.ts +175 -0
- package/lib/cjs/math/TakeAmountsLib.js +199 -0
- package/lib/cjs/math/TickLib.d.ts +200 -0
- package/lib/cjs/math/TickLib.js +272 -0
- package/lib/cjs/math/index.d.ts +3 -0
- package/lib/cjs/math/index.js +19 -0
- package/lib/cjs/offers/Offer.d.ts +534 -0
- package/lib/cjs/offers/Offer.js +343 -0
- package/lib/cjs/offers/OfferUtils.d.ts +565 -0
- package/lib/cjs/offers/OfferUtils.js +659 -0
- package/lib/cjs/offers/index.d.ts +2 -0
- package/lib/cjs/offers/index.js +18 -0
- package/lib/cjs/package.json +1 -0
- package/lib/cjs/queries/GetPosition.d.ts +55 -0
- package/lib/cjs/queries/GetPosition.js +74 -0
- package/lib/cjs/queries/index.d.ts +1 -0
- package/lib/cjs/queries/index.js +37 -0
- package/lib/cjs/signatures/EcrecoverRatifierUtils.d.ts +733 -0
- package/lib/cjs/signatures/EcrecoverRatifierUtils.js +618 -0
- package/lib/cjs/signatures/Group.d.ts +178 -0
- package/lib/cjs/signatures/Group.js +193 -0
- package/lib/cjs/signatures/GroupUtils.d.ts +191 -0
- package/lib/cjs/signatures/GroupUtils.js +127 -0
- package/lib/cjs/signatures/Payload.d.ts +283 -0
- package/lib/cjs/signatures/Payload.js +570 -0
- package/lib/cjs/signatures/RatifierUtils.d.ts +109 -0
- package/lib/cjs/signatures/RatifierUtils.js +76 -0
- package/lib/cjs/signatures/SetterRatifierUtils.d.ts +243 -0
- package/lib/cjs/signatures/SetterRatifierUtils.js +217 -0
- package/lib/cjs/signatures/Tree.d.ts +241 -0
- package/lib/cjs/signatures/Tree.js +263 -0
- package/lib/cjs/signatures/TreeUtils.d.ts +573 -0
- package/lib/cjs/signatures/TreeUtils.js +461 -0
- package/lib/cjs/signatures/index.d.ts +7 -0
- package/lib/cjs/signatures/index.js +23 -0
- package/lib/esm/abis.d.ts +3170 -0
- package/lib/esm/abis.js +4070 -0
- package/lib/esm/api/MidnightApi.d.ts +532 -0
- package/lib/esm/api/MidnightApi.js +709 -0
- package/lib/esm/api/helpers.d.ts +20 -0
- package/lib/esm/api/helpers.js +180 -0
- package/lib/esm/api/index.d.ts +2 -0
- package/lib/esm/api/index.js +2 -0
- package/lib/esm/api/types.d.ts +453 -0
- package/lib/esm/api/types.js +1 -0
- package/lib/esm/constants.d.ts +168 -0
- package/lib/esm/constants.js +184 -0
- package/lib/esm/errors.d.ts +253 -0
- package/lib/esm/errors.js +291 -0
- package/lib/esm/fetch/Market.d.ts +65 -0
- package/lib/esm/fetch/Market.js +113 -0
- package/lib/esm/fetch/Offer.d.ts +74 -0
- package/lib/esm/fetch/Offer.js +116 -0
- package/lib/esm/fetch/Position.d.ts +85 -0
- package/lib/esm/fetch/Position.js +144 -0
- package/lib/esm/fetch/Ratifier.d.ts +38 -0
- package/lib/esm/fetch/Ratifier.js +54 -0
- package/lib/esm/fetch/index.d.ts +5 -0
- package/lib/esm/fetch/index.js +5 -0
- package/lib/esm/fetch/types.d.ts +57 -0
- package/lib/esm/fetch/types.js +1 -0
- package/lib/esm/fetch/utils.d.ts +8 -0
- package/lib/esm/fetch/utils.js +12 -0
- package/lib/esm/index.d.ts +18 -0
- package/lib/esm/index.js +18 -0
- package/lib/esm/market/Market.d.ts +613 -0
- package/lib/esm/market/Market.js +498 -0
- package/lib/esm/market/MarketUtils.d.ts +189 -0
- package/lib/esm/market/MarketUtils.js +300 -0
- package/lib/esm/market/Position.d.ts +424 -0
- package/lib/esm/market/Position.js +420 -0
- package/lib/esm/market/PositionUtils.d.ts +115 -0
- package/lib/esm/market/PositionUtils.js +191 -0
- package/lib/esm/market/index.d.ts +4 -0
- package/lib/esm/market/index.js +4 -0
- package/lib/esm/math/ConsumableUnitsLib.d.ts +57 -0
- package/lib/esm/math/ConsumableUnitsLib.js +74 -0
- package/lib/esm/math/TakeAmountsLib.d.ts +175 -0
- package/lib/esm/math/TakeAmountsLib.js +196 -0
- package/lib/esm/math/TickLib.d.ts +200 -0
- package/lib/esm/math/TickLib.js +269 -0
- package/lib/esm/math/index.d.ts +3 -0
- package/lib/esm/math/index.js +3 -0
- package/lib/esm/offers/Offer.d.ts +534 -0
- package/lib/esm/offers/Offer.js +339 -0
- package/lib/esm/offers/OfferUtils.d.ts +565 -0
- package/lib/esm/offers/OfferUtils.js +656 -0
- package/lib/esm/offers/index.d.ts +2 -0
- package/lib/esm/offers/index.js +2 -0
- package/lib/esm/package.json +1 -0
- package/lib/esm/queries/GetPosition.d.ts +55 -0
- package/lib/esm/queries/GetPosition.js +71 -0
- package/lib/esm/queries/index.d.ts +1 -0
- package/lib/esm/queries/index.js +1 -0
- package/lib/esm/signatures/EcrecoverRatifierUtils.d.ts +733 -0
- package/lib/esm/signatures/EcrecoverRatifierUtils.js +615 -0
- package/lib/esm/signatures/Group.d.ts +178 -0
- package/lib/esm/signatures/Group.js +189 -0
- package/lib/esm/signatures/GroupUtils.d.ts +191 -0
- package/lib/esm/signatures/GroupUtils.js +124 -0
- package/lib/esm/signatures/Payload.d.ts +283 -0
- package/lib/esm/signatures/Payload.js +564 -0
- package/lib/esm/signatures/RatifierUtils.d.ts +109 -0
- package/lib/esm/signatures/RatifierUtils.js +73 -0
- package/lib/esm/signatures/SetterRatifierUtils.d.ts +243 -0
- package/lib/esm/signatures/SetterRatifierUtils.js +214 -0
- package/lib/esm/signatures/Tree.d.ts +241 -0
- package/lib/esm/signatures/Tree.js +259 -0
- package/lib/esm/signatures/TreeUtils.d.ts +573 -0
- package/lib/esm/signatures/TreeUtils.js +458 -0
- package/lib/esm/signatures/index.d.ts +7 -0
- package/lib/esm/signatures/index.js +7 -0
- package/package.json +69 -0
- package/src/index.ts +19 -0
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Market = exports.MarketParams = void 0;
|
|
4
|
+
const morpho_ts_1 = require("@morpho-org/morpho-ts");
|
|
5
|
+
const errors_js_1 = require("../errors.js");
|
|
6
|
+
const MarketUtils_js_1 = require("./MarketUtils.js");
|
|
7
|
+
/**
|
|
8
|
+
* Immutable Midnight market configuration.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { MarketParams } from "@morpho-org/midnight-sdk";
|
|
13
|
+
*
|
|
14
|
+
* const params = new MarketParams({
|
|
15
|
+
* loanToken: "0x0000000000000000000000000000000000000001",
|
|
16
|
+
* collateralParams: [
|
|
17
|
+
* {
|
|
18
|
+
* token: "0x0000000000000000000000000000000000000002",
|
|
19
|
+
* lltv: 770000000000000000n,
|
|
20
|
+
* maxLif: 1061007957559681697n,
|
|
21
|
+
* oracle: "0x0000000000000000000000000000000000000003",
|
|
22
|
+
* },
|
|
23
|
+
* ],
|
|
24
|
+
* maturity: 1n,
|
|
25
|
+
* rcfThreshold: 0n,
|
|
26
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
27
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
28
|
+
* });
|
|
29
|
+
* console.log(params.loanToken);
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
class MarketParams {
|
|
33
|
+
/** Loan token address. */
|
|
34
|
+
loanToken;
|
|
35
|
+
/** Collateral definitions sorted by token. */
|
|
36
|
+
collateralParams;
|
|
37
|
+
/** Market maturity timestamp. */
|
|
38
|
+
maturity;
|
|
39
|
+
/** Recovery close factor threshold. */
|
|
40
|
+
rcfThreshold;
|
|
41
|
+
/** Entry gate address. */
|
|
42
|
+
enterGate;
|
|
43
|
+
/** Liquidator gate address. */
|
|
44
|
+
liquidatorGate;
|
|
45
|
+
/**
|
|
46
|
+
* Creates normalized market params.
|
|
47
|
+
*
|
|
48
|
+
* @param params - Market params to normalize.
|
|
49
|
+
* @throws {InvalidMarketParameterError} when the collateral list is empty, contains duplicate tokens, or has LLTV outside `[0, WAD]`.
|
|
50
|
+
*/
|
|
51
|
+
constructor(params) {
|
|
52
|
+
this.loanToken = params.loanToken;
|
|
53
|
+
const collateralParams = params.collateralParams.map(MarketUtils_js_1.MarketUtils.toCollateralParams);
|
|
54
|
+
if (collateralParams.length === 0) {
|
|
55
|
+
throw new errors_js_1.InvalidMarketParameterError({
|
|
56
|
+
parameter: "collateralParams",
|
|
57
|
+
value: params.collateralParams.length,
|
|
58
|
+
instruction: "Provide at least one collateral.",
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const seenCollateralTokens = new Set();
|
|
62
|
+
for (const collateral of collateralParams) {
|
|
63
|
+
if (collateral.lltv < 0n || collateral.lltv > morpho_ts_1.MathLib.WAD) {
|
|
64
|
+
throw new errors_js_1.InvalidMarketParameterError({
|
|
65
|
+
parameter: "collateralParams.lltv",
|
|
66
|
+
value: collateral.lltv,
|
|
67
|
+
instruction: "Use an LLTV between 0 and WAD.",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const token = collateral.token.toLowerCase();
|
|
71
|
+
if (seenCollateralTokens.has(token)) {
|
|
72
|
+
throw new errors_js_1.InvalidMarketParameterError({
|
|
73
|
+
parameter: "collateralParams",
|
|
74
|
+
value: collateral.token,
|
|
75
|
+
instruction: "Use each collateral token at most once.",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
seenCollateralTokens.add(token);
|
|
79
|
+
}
|
|
80
|
+
this.collateralParams = collateralParams.sort((a, b) => a.token.toLowerCase() < b.token.toLowerCase() ? -1 : 1);
|
|
81
|
+
this.maturity = BigInt(params.maturity);
|
|
82
|
+
this.rcfThreshold = BigInt(params.rcfThreshold);
|
|
83
|
+
this.enterGate = params.enterGate;
|
|
84
|
+
this.liquidatorGate = params.liquidatorGate;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns market params from a params object or hydrated market.
|
|
88
|
+
*
|
|
89
|
+
* Use at boundaries that accept either a standalone market config or a full
|
|
90
|
+
* market object. Existing `MarketParams` instances are returned as-is.
|
|
91
|
+
*
|
|
92
|
+
* @param market - Market params or hydrated market.
|
|
93
|
+
* @returns Market params instance.
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* import { MarketParams } from "@morpho-org/midnight-sdk";
|
|
97
|
+
*
|
|
98
|
+
* const params = MarketParams.from({
|
|
99
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
100
|
+
* collateralParams: [
|
|
101
|
+
* {
|
|
102
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
103
|
+
* lltv: 770000000000000000n,
|
|
104
|
+
* maxLif: 1061007957559681697n,
|
|
105
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
106
|
+
* },
|
|
107
|
+
* ],
|
|
108
|
+
* maturity: 54_000n,
|
|
109
|
+
* rcfThreshold: 0n,
|
|
110
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
111
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
112
|
+
* });
|
|
113
|
+
* console.log(params.loanToken);
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
static from(market) {
|
|
117
|
+
if ("params" in market)
|
|
118
|
+
return MarketParams.from(market.params);
|
|
119
|
+
return market instanceof MarketParams ? market : new MarketParams(market);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.MarketParams = MarketParams;
|
|
123
|
+
/**
|
|
124
|
+
* Hydrated Midnight market configuration plus state.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* import { registerCustomAddresses } from "@morpho-org/morpho-ts";
|
|
129
|
+
* import { Market } from "@morpho-org/midnight-sdk";
|
|
130
|
+
*
|
|
131
|
+
* registerCustomAddresses({
|
|
132
|
+
* addresses: {
|
|
133
|
+
* 31337: {
|
|
134
|
+
* morpho: "0x0000000000000000000000000000000000000001",
|
|
135
|
+
* bundler3: {
|
|
136
|
+
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
137
|
+
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
138
|
+
* },
|
|
139
|
+
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
140
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
141
|
+
* },
|
|
142
|
+
* },
|
|
143
|
+
* });
|
|
144
|
+
*
|
|
145
|
+
* const market = new Market({
|
|
146
|
+
* chainId: 31337,
|
|
147
|
+
* params: {
|
|
148
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
149
|
+
* collateralParams: [
|
|
150
|
+
* {
|
|
151
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
152
|
+
* lltv: 770000000000000000n,
|
|
153
|
+
* maxLif: 1061007957559681697n,
|
|
154
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
155
|
+
* },
|
|
156
|
+
* ],
|
|
157
|
+
* maturity: 54_000n,
|
|
158
|
+
* rcfThreshold: 0n,
|
|
159
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
160
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
161
|
+
* },
|
|
162
|
+
* totalUnits: 1_000n,
|
|
163
|
+
* lossFactor: 0n,
|
|
164
|
+
* withdrawable: 500n,
|
|
165
|
+
* continuousFeeCredit: 0n,
|
|
166
|
+
* settlementFeeCbps: [1, 2, 3, 4, 5, 6, 7],
|
|
167
|
+
* continuousFee: 10,
|
|
168
|
+
* tickSpacing: 4,
|
|
169
|
+
* });
|
|
170
|
+
* console.log(market.timeToMaturity(0n));
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
class Market {
|
|
174
|
+
/** Market id. */
|
|
175
|
+
id;
|
|
176
|
+
/** EIP-155 chain id used to derive the market id. */
|
|
177
|
+
chainId;
|
|
178
|
+
/** Immutable market configuration. */
|
|
179
|
+
params;
|
|
180
|
+
/** Total market units. */
|
|
181
|
+
totalUnits;
|
|
182
|
+
/** Current loss factor. */
|
|
183
|
+
lossFactor;
|
|
184
|
+
/** Withdrawable assets. */
|
|
185
|
+
withdrawable;
|
|
186
|
+
/** Continuous-fee credit. */
|
|
187
|
+
continuousFeeCredit;
|
|
188
|
+
/** Seven settlement-fee cbp buckets. */
|
|
189
|
+
settlementFeeCbps;
|
|
190
|
+
/** Continuous fee per second. */
|
|
191
|
+
continuousFee;
|
|
192
|
+
/** Market tick spacing. */
|
|
193
|
+
tickSpacing;
|
|
194
|
+
constructor(market) {
|
|
195
|
+
this.chainId = BigInt(market.chainId);
|
|
196
|
+
this.params = MarketParams.from(market.params);
|
|
197
|
+
this.id = MarketUtils_js_1.MarketUtils.toId({ market: this.params, chainId: this.chainId });
|
|
198
|
+
this.totalUnits = BigInt(market.totalUnits);
|
|
199
|
+
this.lossFactor = BigInt(market.lossFactor);
|
|
200
|
+
this.withdrawable = BigInt(market.withdrawable);
|
|
201
|
+
this.continuousFeeCredit = BigInt(market.continuousFeeCredit);
|
|
202
|
+
this.settlementFeeCbps = [...market.settlementFeeCbps];
|
|
203
|
+
this.continuousFee = market.continuousFee;
|
|
204
|
+
this.tickSpacing = market.tickSpacing;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Returns the non-negative time remaining before maturity.
|
|
208
|
+
*
|
|
209
|
+
* @param timestamp - Timestamp to compare.
|
|
210
|
+
* @returns Seconds until maturity, floored to zero.
|
|
211
|
+
* @throws {NegativeValueError} when `timestamp` is negative.
|
|
212
|
+
* @example
|
|
213
|
+
* ```ts
|
|
214
|
+
* import { registerCustomAddresses } from "@morpho-org/morpho-ts";
|
|
215
|
+
* import { Market } from "@morpho-org/midnight-sdk";
|
|
216
|
+
*
|
|
217
|
+
* registerCustomAddresses({
|
|
218
|
+
* addresses: {
|
|
219
|
+
* 31337: {
|
|
220
|
+
* morpho: "0x0000000000000000000000000000000000000001",
|
|
221
|
+
* bundler3: {
|
|
222
|
+
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
223
|
+
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
224
|
+
* },
|
|
225
|
+
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
226
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
227
|
+
* },
|
|
228
|
+
* },
|
|
229
|
+
* });
|
|
230
|
+
*
|
|
231
|
+
* const market = new Market({
|
|
232
|
+
* chainId: 31337,
|
|
233
|
+
* params: {
|
|
234
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
235
|
+
* collateralParams: [
|
|
236
|
+
* {
|
|
237
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
238
|
+
* lltv: 770000000000000000n,
|
|
239
|
+
* maxLif: 1061007957559681697n,
|
|
240
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
241
|
+
* },
|
|
242
|
+
* ],
|
|
243
|
+
* maturity: 54_000n,
|
|
244
|
+
* rcfThreshold: 0n,
|
|
245
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
246
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
247
|
+
* },
|
|
248
|
+
* totalUnits: 1_000n,
|
|
249
|
+
* lossFactor: 0n,
|
|
250
|
+
* withdrawable: 500n,
|
|
251
|
+
* continuousFeeCredit: 0n,
|
|
252
|
+
* settlementFeeCbps: [1, 2, 3, 4, 5, 6, 7],
|
|
253
|
+
* continuousFee: 10,
|
|
254
|
+
* tickSpacing: 4,
|
|
255
|
+
* });
|
|
256
|
+
* console.log(market.timeToMaturity(0n));
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
timeToMaturity(timestamp) {
|
|
260
|
+
const normalizedTimestamp = BigInt(timestamp);
|
|
261
|
+
(0, morpho_ts_1.assertNonNegative)("timestamp", normalizedTimestamp);
|
|
262
|
+
return normalizedTimestamp >= this.params.maturity
|
|
263
|
+
? 0n
|
|
264
|
+
: this.params.maturity - normalizedTimestamp;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Computes the settlement fee for a time to maturity from the hydrated market state.
|
|
268
|
+
*
|
|
269
|
+
* @param timeToMaturity - Seconds until maturity.
|
|
270
|
+
* @returns WAD-scaled settlement fee.
|
|
271
|
+
* @throws {NegativeValueError} when `timeToMaturity` is negative.
|
|
272
|
+
* @example
|
|
273
|
+
* ```ts
|
|
274
|
+
* import { registerCustomAddresses } from "@morpho-org/morpho-ts";
|
|
275
|
+
* import { Market } from "@morpho-org/midnight-sdk";
|
|
276
|
+
*
|
|
277
|
+
* registerCustomAddresses({
|
|
278
|
+
* addresses: {
|
|
279
|
+
* 31337: {
|
|
280
|
+
* morpho: "0x0000000000000000000000000000000000000001",
|
|
281
|
+
* bundler3: {
|
|
282
|
+
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
283
|
+
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
284
|
+
* },
|
|
285
|
+
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
286
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
287
|
+
* },
|
|
288
|
+
* },
|
|
289
|
+
* });
|
|
290
|
+
*
|
|
291
|
+
* const market = new Market({
|
|
292
|
+
* chainId: 31337,
|
|
293
|
+
* params: {
|
|
294
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
295
|
+
* collateralParams: [
|
|
296
|
+
* {
|
|
297
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
298
|
+
* lltv: 770000000000000000n,
|
|
299
|
+
* maxLif: 1061007957559681697n,
|
|
300
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
301
|
+
* },
|
|
302
|
+
* ],
|
|
303
|
+
* maturity: 54_000n,
|
|
304
|
+
* rcfThreshold: 0n,
|
|
305
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
306
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
307
|
+
* },
|
|
308
|
+
* totalUnits: 1_000n,
|
|
309
|
+
* lossFactor: 0n,
|
|
310
|
+
* withdrawable: 500n,
|
|
311
|
+
* continuousFeeCredit: 0n,
|
|
312
|
+
* settlementFeeCbps: [1, 2, 3, 4, 5, 6, 7],
|
|
313
|
+
* continuousFee: 10,
|
|
314
|
+
* tickSpacing: 4,
|
|
315
|
+
* });
|
|
316
|
+
* console.log(market.getSettlementFee(0n));
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
319
|
+
getSettlementFee(timeToMaturity) {
|
|
320
|
+
return MarketUtils_js_1.MarketUtils.getSettlementFee({
|
|
321
|
+
settlementFeeCbps: this.settlementFeeCbps,
|
|
322
|
+
timeToMaturity,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Returns collateral params by numeric index.
|
|
327
|
+
*
|
|
328
|
+
* @param index - Collateral index.
|
|
329
|
+
* @returns Collateral params, or undefined when the index is not configured.
|
|
330
|
+
* @example
|
|
331
|
+
* ```ts
|
|
332
|
+
* import { registerCustomAddresses } from "@morpho-org/morpho-ts";
|
|
333
|
+
* import { Market } from "@morpho-org/midnight-sdk";
|
|
334
|
+
*
|
|
335
|
+
* registerCustomAddresses({
|
|
336
|
+
* addresses: {
|
|
337
|
+
* 31337: {
|
|
338
|
+
* morpho: "0x0000000000000000000000000000000000000001",
|
|
339
|
+
* bundler3: {
|
|
340
|
+
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
341
|
+
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
342
|
+
* },
|
|
343
|
+
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
344
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
345
|
+
* },
|
|
346
|
+
* },
|
|
347
|
+
* });
|
|
348
|
+
*
|
|
349
|
+
* const market = new Market({
|
|
350
|
+
* chainId: 31337,
|
|
351
|
+
* params: {
|
|
352
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
353
|
+
* collateralParams: [
|
|
354
|
+
* {
|
|
355
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
356
|
+
* lltv: 770000000000000000n,
|
|
357
|
+
* maxLif: 1061007957559681697n,
|
|
358
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
359
|
+
* },
|
|
360
|
+
* ],
|
|
361
|
+
* maturity: 54_000n,
|
|
362
|
+
* rcfThreshold: 0n,
|
|
363
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
364
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
365
|
+
* },
|
|
366
|
+
* totalUnits: 1_000n,
|
|
367
|
+
* lossFactor: 0n,
|
|
368
|
+
* withdrawable: 500n,
|
|
369
|
+
* continuousFeeCredit: 0n,
|
|
370
|
+
* settlementFeeCbps: [1, 2, 3, 4, 5, 6, 7],
|
|
371
|
+
* continuousFee: 10,
|
|
372
|
+
* tickSpacing: 4,
|
|
373
|
+
* });
|
|
374
|
+
* const params = market.getCollateralParamsByIndex(0);
|
|
375
|
+
* console.log(params?.token);
|
|
376
|
+
* ```
|
|
377
|
+
*/
|
|
378
|
+
getCollateralParamsByIndex(index) {
|
|
379
|
+
const normalizedIndex = BigInt(index);
|
|
380
|
+
if (normalizedIndex < 0n ||
|
|
381
|
+
normalizedIndex > BigInt(Number.MAX_SAFE_INTEGER))
|
|
382
|
+
return undefined;
|
|
383
|
+
return this.params.collateralParams[Number(normalizedIndex)];
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Returns the configured collateral index for a token.
|
|
387
|
+
*
|
|
388
|
+
* @param token - Collateral token address.
|
|
389
|
+
* @returns Collateral index, or undefined when the token is not configured.
|
|
390
|
+
* @example
|
|
391
|
+
* ```ts
|
|
392
|
+
* import { registerCustomAddresses } from "@morpho-org/morpho-ts";
|
|
393
|
+
* import { Market } from "@morpho-org/midnight-sdk";
|
|
394
|
+
*
|
|
395
|
+
* registerCustomAddresses({
|
|
396
|
+
* addresses: {
|
|
397
|
+
* 31337: {
|
|
398
|
+
* morpho: "0x0000000000000000000000000000000000000001",
|
|
399
|
+
* bundler3: {
|
|
400
|
+
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
401
|
+
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
402
|
+
* },
|
|
403
|
+
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
404
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
405
|
+
* },
|
|
406
|
+
* },
|
|
407
|
+
* });
|
|
408
|
+
*
|
|
409
|
+
* const collateralToken = "0x0000000000000000000000000000000000007000";
|
|
410
|
+
* const market = new Market({
|
|
411
|
+
* chainId: 31337,
|
|
412
|
+
* params: {
|
|
413
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
414
|
+
* collateralParams: [
|
|
415
|
+
* {
|
|
416
|
+
* token: collateralToken,
|
|
417
|
+
* lltv: 770000000000000000n,
|
|
418
|
+
* maxLif: 1061007957559681697n,
|
|
419
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
420
|
+
* },
|
|
421
|
+
* ],
|
|
422
|
+
* maturity: 54_000n,
|
|
423
|
+
* rcfThreshold: 0n,
|
|
424
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
425
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
426
|
+
* },
|
|
427
|
+
* totalUnits: 1_000n,
|
|
428
|
+
* lossFactor: 0n,
|
|
429
|
+
* withdrawable: 500n,
|
|
430
|
+
* continuousFeeCredit: 0n,
|
|
431
|
+
* settlementFeeCbps: [1, 2, 3, 4, 5, 6, 7],
|
|
432
|
+
* continuousFee: 10,
|
|
433
|
+
* tickSpacing: 4,
|
|
434
|
+
* });
|
|
435
|
+
* const index = market.getCollateralIndexByToken(collateralToken);
|
|
436
|
+
* console.log(index);
|
|
437
|
+
* ```
|
|
438
|
+
*/
|
|
439
|
+
getCollateralIndexByToken(token) {
|
|
440
|
+
const expectedToken = token.toLowerCase();
|
|
441
|
+
const index = this.params.collateralParams.findIndex((params) => params.token.toLowerCase() === expectedToken);
|
|
442
|
+
return index === -1 ? undefined : index;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Returns collateral params by token address.
|
|
446
|
+
*
|
|
447
|
+
* @param token - Collateral token address.
|
|
448
|
+
* @returns Collateral params, or undefined when the token is not configured.
|
|
449
|
+
* @example
|
|
450
|
+
* ```ts
|
|
451
|
+
* import { registerCustomAddresses } from "@morpho-org/morpho-ts";
|
|
452
|
+
* import { Market } from "@morpho-org/midnight-sdk";
|
|
453
|
+
*
|
|
454
|
+
* registerCustomAddresses({
|
|
455
|
+
* addresses: {
|
|
456
|
+
* 31337: {
|
|
457
|
+
* morpho: "0x0000000000000000000000000000000000000001",
|
|
458
|
+
* bundler3: {
|
|
459
|
+
* bundler3: "0x0000000000000000000000000000000000000002",
|
|
460
|
+
* generalAdapter1: "0x0000000000000000000000000000000000000003",
|
|
461
|
+
* },
|
|
462
|
+
* adaptiveCurveIrm: "0x0000000000000000000000000000000000000004",
|
|
463
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
464
|
+
* },
|
|
465
|
+
* },
|
|
466
|
+
* });
|
|
467
|
+
*
|
|
468
|
+
* const collateralToken = "0x0000000000000000000000000000000000007000";
|
|
469
|
+
* const market = new Market({
|
|
470
|
+
* chainId: 31337,
|
|
471
|
+
* params: {
|
|
472
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
473
|
+
* collateralParams: [
|
|
474
|
+
* {
|
|
475
|
+
* token: collateralToken,
|
|
476
|
+
* lltv: 770000000000000000n,
|
|
477
|
+
* maxLif: 1061007957559681697n,
|
|
478
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
479
|
+
* },
|
|
480
|
+
* ],
|
|
481
|
+
* maturity: 54_000n,
|
|
482
|
+
* rcfThreshold: 0n,
|
|
483
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
484
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
485
|
+
* },
|
|
486
|
+
* totalUnits: 1_000n,
|
|
487
|
+
* lossFactor: 0n,
|
|
488
|
+
* withdrawable: 500n,
|
|
489
|
+
* continuousFeeCredit: 0n,
|
|
490
|
+
* settlementFeeCbps: [1, 2, 3, 4, 5, 6, 7],
|
|
491
|
+
* continuousFee: 10,
|
|
492
|
+
* tickSpacing: 4,
|
|
493
|
+
* });
|
|
494
|
+
* const params = market.getCollateralParamsByToken(collateralToken);
|
|
495
|
+
* console.log(params?.lltv);
|
|
496
|
+
* ```
|
|
497
|
+
*/
|
|
498
|
+
getCollateralParamsByToken(token) {
|
|
499
|
+
const index = this.getCollateralIndexByToken(token);
|
|
500
|
+
return index == null ? undefined : this.params.collateralParams[index];
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
exports.Market = Market;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { type BigIntish } from "@morpho-org/morpho-ts";
|
|
2
|
+
import { type CollateralParams, type ICollateralParams, type MarketInput, MarketParams, type SettlementFeeCbps } from "./Market.js";
|
|
3
|
+
type CollateralParamsInput = ICollateralParams | CollateralParams;
|
|
4
|
+
/**
|
|
5
|
+
* Domain helpers for Midnight markets.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { MarketUtils } from "@morpho-org/midnight-sdk";
|
|
10
|
+
*
|
|
11
|
+
* console.log(typeof MarketUtils.hash);
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare namespace MarketUtils {
|
|
15
|
+
/**
|
|
16
|
+
* Converts collateral params from a plain input or ABI tuple.
|
|
17
|
+
*
|
|
18
|
+
* @param params.token - Collateral token address.
|
|
19
|
+
* @param params.lltv - WAD-scaled liquidation loan-to-value.
|
|
20
|
+
* @param params.maxLif - WAD-scaled maximum liquidation incentive factor.
|
|
21
|
+
* @param params.oracle - Oracle address used to price this collateral.
|
|
22
|
+
* @returns Collateral params with bigint fields.
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { MarketUtils } from "@morpho-org/midnight-sdk";
|
|
26
|
+
*
|
|
27
|
+
* const collateral = MarketUtils.toCollateralParams({
|
|
28
|
+
* token: "0x0000000000000000000000000000000000000001",
|
|
29
|
+
* lltv: 770000000000000000n,
|
|
30
|
+
* maxLif: 1061007957559681697n,
|
|
31
|
+
* oracle: "0x0000000000000000000000000000000000000002",
|
|
32
|
+
* });
|
|
33
|
+
* console.log(collateral.maxLif);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
function toCollateralParams(params: CollateralParamsInput): CollateralParams;
|
|
37
|
+
/**
|
|
38
|
+
* Converts market params into the tuple object expected by viem ABI encoders.
|
|
39
|
+
*
|
|
40
|
+
* @param market - Market params or hydrated market.
|
|
41
|
+
* @returns ABI-compatible market params.
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { MarketUtils } from "@morpho-org/midnight-sdk";
|
|
45
|
+
*
|
|
46
|
+
* const struct = MarketUtils.toStruct({
|
|
47
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
48
|
+
* collateralParams: [
|
|
49
|
+
* {
|
|
50
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
51
|
+
* lltv: 770000000000000000n,
|
|
52
|
+
* maxLif: 1061007957559681697n,
|
|
53
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
54
|
+
* },
|
|
55
|
+
* ],
|
|
56
|
+
* maturity: 54_000n,
|
|
57
|
+
* rcfThreshold: 0n,
|
|
58
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
59
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
60
|
+
* });
|
|
61
|
+
* console.log(struct.maturity);
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
function toStruct(market: MarketInput): MarketParams;
|
|
65
|
+
/**
|
|
66
|
+
* Returns the liquidation incentive factor for an LLTV and liquidation cursor.
|
|
67
|
+
*
|
|
68
|
+
* @param input - WAD-scaled LLTV or collateral params carrying an LLTV.
|
|
69
|
+
* @param cursor - WAD-scaled liquidation cursor, usually `LIQUIDATION_CURSOR_LOW` or `LIQUIDATION_CURSOR_HIGH`.
|
|
70
|
+
* @returns WAD-scaled liquidation incentive factor.
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* import { LIQUIDATION_CURSOR_LOW, MarketUtils } from "@morpho-org/midnight-sdk";
|
|
74
|
+
*
|
|
75
|
+
* const liquidationIncentiveFactor = MarketUtils.getLiquidationIncentiveFactor(
|
|
76
|
+
* 770000000000000000n,
|
|
77
|
+
* LIQUIDATION_CURSOR_LOW,
|
|
78
|
+
* );
|
|
79
|
+
* console.log(liquidationIncentiveFactor);
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
function getLiquidationIncentiveFactor(input: BigIntish | Pick<CollateralParamsInput, "lltv">, cursor: BigIntish): bigint;
|
|
83
|
+
/**
|
|
84
|
+
* Computes the Midnight settlement fee from market cbp buckets and time to maturity.
|
|
85
|
+
*
|
|
86
|
+
* This mirrors Midnight `settlementFee`: cbp buckets are scaled by {@link CBP},
|
|
87
|
+
* values are linearly interpolated between {@link SETTLEMENT_FEE_BREAKPOINTS},
|
|
88
|
+
* and any time to maturity at or above 360 days uses the last bucket.
|
|
89
|
+
*
|
|
90
|
+
* @param params.settlementFeeCbps - Seven settlement-fee centibip buckets from the market state.
|
|
91
|
+
* @param params.timeToMaturity - Seconds until market maturity.
|
|
92
|
+
* @returns WAD-scaled settlement fee.
|
|
93
|
+
* @throws {NegativeValueError} when `timeToMaturity` is negative.
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* import { MarketUtils } from "@morpho-org/midnight-sdk";
|
|
97
|
+
*
|
|
98
|
+
* const fee = MarketUtils.getSettlementFee({
|
|
99
|
+
* settlementFeeCbps: [1, 2, 3, 4, 5, 6, 7],
|
|
100
|
+
* timeToMaturity: 12n * 60n * 60n,
|
|
101
|
+
* });
|
|
102
|
+
* console.log(fee);
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
function getSettlementFee(params: {
|
|
106
|
+
readonly settlementFeeCbps: SettlementFeeCbps;
|
|
107
|
+
readonly timeToMaturity: BigIntish;
|
|
108
|
+
}): bigint;
|
|
109
|
+
/**
|
|
110
|
+
* Computes the HashLib market params struct hash.
|
|
111
|
+
*
|
|
112
|
+
* Hashing canonicalizes non-empty collateral params by token order and
|
|
113
|
+
* preserves the protocol-zero empty market used for tree padding. It does
|
|
114
|
+
* not validate every market creation rule. Use {@link MarketParams} when
|
|
115
|
+
* constructing user-facing market params.
|
|
116
|
+
*
|
|
117
|
+
* @param market - Market to hash.
|
|
118
|
+
* @returns EIP-712 market struct hash.
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* import { MarketUtils } from "@morpho-org/midnight-sdk";
|
|
122
|
+
*
|
|
123
|
+
* const hash = MarketUtils.hash({
|
|
124
|
+
* loanToken: "0x0000000000000000000000000000000000000001",
|
|
125
|
+
* collateralParams: [
|
|
126
|
+
* {
|
|
127
|
+
* token: "0x0000000000000000000000000000000000000002",
|
|
128
|
+
* lltv: 770000000000000000n,
|
|
129
|
+
* maxLif: 1061007957559681697n,
|
|
130
|
+
* oracle: "0x0000000000000000000000000000000000000003",
|
|
131
|
+
* },
|
|
132
|
+
* ],
|
|
133
|
+
* maturity: 1n,
|
|
134
|
+
* rcfThreshold: 0n,
|
|
135
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
136
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
137
|
+
* });
|
|
138
|
+
* console.log(hash);
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
function hash(market: MarketInput): `0x${string}`;
|
|
142
|
+
/**
|
|
143
|
+
* Computes the Midnight id for a market using `IdLib.toId`.
|
|
144
|
+
*
|
|
145
|
+
* @param params.market - Market to hash.
|
|
146
|
+
* @param params.chainId - EIP-155 chain id used to resolve the core Midnight address from the registry.
|
|
147
|
+
* @returns Market id.
|
|
148
|
+
* @throws {UnsupportedChainIdError} when no address registry exists for `chainId`.
|
|
149
|
+
* @throws {UnknownAddressError} when the registry has no Midnight address for `chainId`.
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* import { ChainId, registerCustomAddresses } from "@morpho-org/morpho-ts";
|
|
153
|
+
* import { MarketUtils } from "@morpho-org/midnight-sdk";
|
|
154
|
+
*
|
|
155
|
+
* registerCustomAddresses({
|
|
156
|
+
* addresses: {
|
|
157
|
+
* [ChainId.BaseMainnet]: {
|
|
158
|
+
* midnight: "0x0000000000000000000000000000000000000001",
|
|
159
|
+
* },
|
|
160
|
+
* },
|
|
161
|
+
* });
|
|
162
|
+
*
|
|
163
|
+
* const id = MarketUtils.toId({
|
|
164
|
+
* market: {
|
|
165
|
+
* loanToken: "0x0000000000000000000000000000000000000001",
|
|
166
|
+
* collateralParams: [
|
|
167
|
+
* {
|
|
168
|
+
* token: "0x0000000000000000000000000000000000000002",
|
|
169
|
+
* lltv: 770000000000000000n,
|
|
170
|
+
* maxLif: 1061007957559681697n,
|
|
171
|
+
* oracle: "0x0000000000000000000000000000000000000003",
|
|
172
|
+
* },
|
|
173
|
+
* ],
|
|
174
|
+
* maturity: 1n,
|
|
175
|
+
* rcfThreshold: 0n,
|
|
176
|
+
* enterGate: "0x0000000000000000000000000000000000000000",
|
|
177
|
+
* liquidatorGate: "0x0000000000000000000000000000000000000000",
|
|
178
|
+
* },
|
|
179
|
+
* chainId: ChainId.BaseMainnet,
|
|
180
|
+
* });
|
|
181
|
+
* console.log(id);
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
function toId(params: {
|
|
185
|
+
readonly market: MarketInput;
|
|
186
|
+
readonly chainId: BigIntish;
|
|
187
|
+
}): `0x${string}`;
|
|
188
|
+
}
|
|
189
|
+
export {};
|