@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
package/README.md
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# @morpho-org/midnight-sdk
|
|
2
|
+
|
|
3
|
+
Viem-based package for Morpho Midnight that exports protocol utilities, fetch helpers, and Midnight API utilities.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @morpho-org/midnight-sdk @morpho-org/morpho-ts viem
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
yarn add @morpho-org/midnight-sdk @morpho-org/morpho-ts viem
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## API Import Stability
|
|
16
|
+
|
|
17
|
+
Midnight HTTP API helpers are exported from `@morpho-org/midnight-sdk/api`. This import path is not stable and may not respect semver versioning.
|
|
18
|
+
|
|
19
|
+
## Making offers
|
|
20
|
+
|
|
21
|
+
The make-side starts with local offer construction, groups offers that should share consumption, and
|
|
22
|
+
commits grouped and standalone offers into one tree. Validate the tree before asking the maker or an
|
|
23
|
+
authorized signer to sign, or before asking the maker contract to approve the root. Then encode the
|
|
24
|
+
ratified items into a mempool payload and submit the raw payload bytes onchain.
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { addresses } from "@morpho-org/morpho-ts";
|
|
28
|
+
import {
|
|
29
|
+
EcrecoverRatifierUtils,
|
|
30
|
+
Offer,
|
|
31
|
+
Payload,
|
|
32
|
+
Tree,
|
|
33
|
+
} from "@morpho-org/midnight-sdk";
|
|
34
|
+
import {
|
|
35
|
+
parseUnits,
|
|
36
|
+
zeroAddress,
|
|
37
|
+
type Address,
|
|
38
|
+
type Chain,
|
|
39
|
+
type Transport,
|
|
40
|
+
type WalletClient,
|
|
41
|
+
} from "viem";
|
|
42
|
+
|
|
43
|
+
const chainId = 8453;
|
|
44
|
+
const usdc = addresses[chainId].usdc!;
|
|
45
|
+
const weth = addresses[chainId].wNative!;
|
|
46
|
+
const ecrecoverRatifier = addresses[chainId].ecrecoverRatifier!;
|
|
47
|
+
const midnightMempool = addresses[chainId].midnightMempool!;
|
|
48
|
+
|
|
49
|
+
export async function makeBaseUsdcWethOffers(params: {
|
|
50
|
+
readonly walletClient: WalletClient<Transport, Chain>;
|
|
51
|
+
readonly maker: Address;
|
|
52
|
+
readonly wethUsdcOracle: Address;
|
|
53
|
+
}) {
|
|
54
|
+
const market = {
|
|
55
|
+
loanToken: usdc,
|
|
56
|
+
collateralParams: [
|
|
57
|
+
{
|
|
58
|
+
token: weth,
|
|
59
|
+
lltv: 770_000000000000000000n,
|
|
60
|
+
maxLif: 1_061007957559681697n,
|
|
61
|
+
oracle: params.wethUsdcOracle,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
maturity: 1_789_743_600n, // 2026-09-18 15:00:00 UTC.
|
|
65
|
+
rcfThreshold: 0n,
|
|
66
|
+
enterGate: zeroAddress,
|
|
67
|
+
liquidatorGate: zeroAddress,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const commonOffer = {
|
|
71
|
+
market,
|
|
72
|
+
maker: params.maker,
|
|
73
|
+
expiry: 1_789_741_800n,
|
|
74
|
+
ratifier: ecrecoverRatifier,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const lend250kUsdc = Offer.create({
|
|
78
|
+
...commonOffer,
|
|
79
|
+
buy: true,
|
|
80
|
+
tick: 5_000n,
|
|
81
|
+
maxAssets: parseUnits("250000", 6),
|
|
82
|
+
});
|
|
83
|
+
const lend100kUsdc = Offer.create({
|
|
84
|
+
...commonOffer,
|
|
85
|
+
buy: true,
|
|
86
|
+
tick: 5_012n,
|
|
87
|
+
maxAssets: parseUnits("100000", 6),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const standaloneBorrowOffer = Offer.create({
|
|
91
|
+
...commonOffer,
|
|
92
|
+
buy: false,
|
|
93
|
+
tick: 5_024n,
|
|
94
|
+
maxUnits: parseUnits("50", 18),
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const tree = Tree.create([
|
|
98
|
+
lend250kUsdc,
|
|
99
|
+
lend100kUsdc,
|
|
100
|
+
standaloneBorrowOffer,
|
|
101
|
+
]);
|
|
102
|
+
|
|
103
|
+
const treeValidation = await tree.mempoolValidate({
|
|
104
|
+
chainId,
|
|
105
|
+
});
|
|
106
|
+
if (!treeValidation.valid) {
|
|
107
|
+
return { ok: false as const, issues: treeValidation.issues };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// EcrecoverRatifierUtils derives the verifier from offer.ratifier and rejects mixed-ratifier trees.
|
|
111
|
+
// The account may be the maker or an authorized signer for every maker in the tree.
|
|
112
|
+
const items = await EcrecoverRatifierUtils.ratify({
|
|
113
|
+
tree,
|
|
114
|
+
client: params.walletClient,
|
|
115
|
+
account: params.maker,
|
|
116
|
+
});
|
|
117
|
+
const payload = await Payload.encode(items);
|
|
118
|
+
|
|
119
|
+
const transactionHash = await params.walletClient.sendTransaction({
|
|
120
|
+
account: params.maker,
|
|
121
|
+
to: midnightMempool,
|
|
122
|
+
data: payload,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return { ok: true as const, transactionHash };
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Use `SetterRatifierUtils` instead when a contract maker approves the tree root onchain. In that
|
|
130
|
+
route, build the `Tree`, validate it, submit the root approval transaction for every maker in the
|
|
131
|
+
tree, then call `SetterRatifierUtils.ratify({ tree })` before `Payload.encode(...)`.
|
|
132
|
+
|
|
133
|
+
## Taking offers
|
|
134
|
+
|
|
135
|
+
The take-side starts from API book, quote, or maker takeable-offer responses. `MidnightApi` maps the
|
|
136
|
+
router response into ABI-ready take objects: each item has `offer`, `ratifierData`, and `units` for
|
|
137
|
+
`IMidnight.take`, plus `marketId` metadata from the API. Book `asks` are maker sell offers, while
|
|
138
|
+
book `bids` are maker buy offers.
|
|
139
|
+
For a quote that spans several offers, use `MidnightBundles`: it receives the returned take objects,
|
|
140
|
+
calls `take` internally in order, and fills toward the target in one transaction.
|
|
141
|
+
When executing offers one-by-one with `Midnight.take`, clamp each take to the remaining target instead
|
|
142
|
+
of submitting every returned cap blindly.
|
|
143
|
+
The no-permit bundle example assumes the taker has authorized `MidnightBundles` on Midnight and has
|
|
144
|
+
approved the bundle contract to pull the market loan token. Set `minUnits` or `maxUnits` from your
|
|
145
|
+
own price guard; the example uses `0n` to focus on the route mechanics.
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
import { addresses } from "@morpho-org/morpho-ts";
|
|
149
|
+
import {
|
|
150
|
+
MidnightApi,
|
|
151
|
+
type MidnightApiTake,
|
|
152
|
+
} from "@morpho-org/midnight-sdk/api";
|
|
153
|
+
import {
|
|
154
|
+
midnightAbi,
|
|
155
|
+
midnightBundlesAbi,
|
|
156
|
+
} from "@morpho-org/midnight-sdk";
|
|
157
|
+
import {
|
|
158
|
+
parseUnits,
|
|
159
|
+
zeroAddress,
|
|
160
|
+
type Address,
|
|
161
|
+
type Hash,
|
|
162
|
+
type WalletClient,
|
|
163
|
+
} from "viem";
|
|
164
|
+
|
|
165
|
+
const chainId = 8453;
|
|
166
|
+
const midnight = addresses[chainId].midnight!;
|
|
167
|
+
const midnightBundles = addresses[chainId].midnightBundles!;
|
|
168
|
+
const tokenPermitNone = { kind: 0, data: "0x" } as const;
|
|
169
|
+
|
|
170
|
+
async function buildAskQuoteTakes(marketId: Hash, targetBuyerAssets: bigint) {
|
|
171
|
+
const quote = await MidnightApi.fetchBookQuote({
|
|
172
|
+
marketId,
|
|
173
|
+
side: "asks",
|
|
174
|
+
assets: targetBuyerAssets,
|
|
175
|
+
slippage: "0.5",
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
return quote.data;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export async function takeOneOffer(params: {
|
|
182
|
+
readonly walletClient: WalletClient;
|
|
183
|
+
readonly taker: Address;
|
|
184
|
+
readonly receiverIfTakerIsSeller: Address;
|
|
185
|
+
readonly take: MidnightApiTake;
|
|
186
|
+
}) {
|
|
187
|
+
return params.walletClient.writeContract({
|
|
188
|
+
account: params.taker,
|
|
189
|
+
address: midnight,
|
|
190
|
+
abi: midnightAbi,
|
|
191
|
+
functionName: "take",
|
|
192
|
+
args: [
|
|
193
|
+
params.take.offer,
|
|
194
|
+
params.take.ratifierData,
|
|
195
|
+
params.take.units,
|
|
196
|
+
params.taker,
|
|
197
|
+
params.receiverIfTakerIsSeller,
|
|
198
|
+
zeroAddress,
|
|
199
|
+
"0x",
|
|
200
|
+
],
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export async function takeAskQuoteWithBundle(params: {
|
|
205
|
+
readonly walletClient: WalletClient;
|
|
206
|
+
readonly taker: Address;
|
|
207
|
+
readonly marketId: Hash;
|
|
208
|
+
}) {
|
|
209
|
+
const targetBuyerAssets = parseUnits("10000", 6);
|
|
210
|
+
const minUnits = 0n;
|
|
211
|
+
const quote = await buildAskQuoteTakes(params.marketId, targetBuyerAssets);
|
|
212
|
+
|
|
213
|
+
return params.walletClient.writeContract({
|
|
214
|
+
account: params.taker,
|
|
215
|
+
address: midnightBundles,
|
|
216
|
+
abi: midnightBundlesAbi,
|
|
217
|
+
functionName: "buyWithAssetsTargetAndWithdrawCollateral",
|
|
218
|
+
args: [
|
|
219
|
+
targetBuyerAssets,
|
|
220
|
+
minUnits,
|
|
221
|
+
params.taker,
|
|
222
|
+
tokenPermitNone,
|
|
223
|
+
quote.takeableOffers,
|
|
224
|
+
[],
|
|
225
|
+
params.taker,
|
|
226
|
+
0n,
|
|
227
|
+
zeroAddress,
|
|
228
|
+
],
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Midnight API
|
|
234
|
+
|
|
235
|
+
Instantiate `MidnightApi` when an integration makes more than one Midnight API call or needs shared
|
|
236
|
+
request options. The instance keeps `baseUrl`, `fetch`, headers, credentials, and abort signals in
|
|
237
|
+
one place, while the SDK still owns endpoint paths, HTTP methods, request bodies, and response
|
|
238
|
+
normalization. Caller inputs and successful JSON output shapes are trusted at runtime; returned
|
|
239
|
+
TypeScript types model the API contract.
|
|
240
|
+
|
|
241
|
+
Use `tree.mempoolValidate({ chainId })` in normal make-side flows before the maker signs or approves
|
|
242
|
+
the root. Pass `apiUrl` to that method when using a custom Midnight API URL. `MidnightApi` keeps the
|
|
243
|
+
raw HTTP surface, including `validateMempoolPayload` for already encoded payload bytes.
|
|
244
|
+
|
|
245
|
+
## Development
|
|
246
|
+
|
|
247
|
+
Contribute from the monorepo root. See [CONTRIBUTING.md](../../CONTRIBUTING.md) for setup, checks,
|
|
248
|
+
and package workflow.
|
|
249
|
+
|
|
250
|
+
## License
|
|
251
|
+
|
|
252
|
+
MIT. See [LICENSE](../../LICENSE).
|