Make offer (build typed-data)
GET/v1/actions/midnight/make
MAKE — step 1 of 2. Build the EIP-712 typed-data for a limit offer at your own rate.
Morpho Midnight is an order-book lender — liquidity is a book of maker offers, not a pool — so there are two ways to interact:
- TAKE (fill existing offers): use the standard lending actions, which route to Midnight automatically for a
MORPHO_MIDNIGHT_<id>market. There is no separate "take" endpoint.- lend →
/v1/actions/lending/deposit— fills the ask side (supply offers) - borrow →
/v1/actions/lending/borrow— fills the bid side (demand offers) - repay / withdraw →
/v1/actions/lending/repay·/withdraw - Read the live two-sided ladder from
/v1/data/lending/latest?includeOffers=true— each order-book market's loan leg carriesoffers(bids) andlendOffers(asks), best-first, with per-levelaprPct,assets, andcumulativeAssets.
- lend →
- MAKE (post your own limit offer at a chosen rate): the endpoints in this section (
/v1/actions/midnight/*) plus/v1/data/lending/ordersto list and cancel them.
Make flow (worker-assisted signing):
GET /v1/actions/midnight/make→ returnstypedData, the echoedinputs, and a one-timeauthorizationtx.- The maker signs
typedDatawith their wallet (wallet.signTypedData). POST /v1/actions/midnight/finalizewith{ inputs, signature }→ the on-chain transaction that publishes the offer to the Midnight mempool.
If authorization is present and the maker has not yet authorized the ratifier (read isAuthorized on-chain), send that one-time setIsAuthorized transaction before finalizing. The APR you request is snapped to an order-book tick — aprPctSnapped is the exact rate the offer will quote.
Plain-text reference — GET /v1/actions/midnight/make
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
chainId | query | string | yes | Chain ID (alias: chain). Midnight is Base-only today. See the ChainId schema for the full set of supported chains. |
lender | query | string | yes | MORPHO_MIDNIGHT_<id> lender key (the market to post into). See the LenderId schema for the full set of accepted values. |
side | query | lend, borrow | yes | lend posts a bid (you lend when taken); borrow posts an ask (you borrow when taken). |
aprPct | query | number | yes | Your target APR in percent (alias: rate). Snapped to an order-book tick; see aprPctSnapped in the response. |
size | query | string | yes | Offer size in loan-token units (integer wei). |
expiry | query | integer | yes | Offer expiry, unix seconds. Must be in the future and ≤ the market maturity. |
account | query | string | yes | Maker (offer owner) address. |
Response 200
| Field | Type | Description |
|---|---|---|
success | True | |
data | object | Everything the frontend needs to sign and publish a maker offer (step 1 of the make flow). actions is null — the publish transaction is produced by /finalize after signing. |
data.typedData | object | EIP-712 typed-data to sign with wallet.signTypedData (bigints serialized as strings — sign the response as-is). |
data.inputs | object | Deterministic offer inputs. Returned verbatim by GET /v1/actions/midnight/make; POST them back unchanged to /v1/actions/midnight/finalize alongside the signature so the worker rebuilds the identical offer tree. Any tampering fails on-chain ratification. |
data.inputs.chainId | string | EVM chain id, as a decimal string. See the ChainId schema. |
data.inputs.lender | string | MORPHO_MIDNIGHT_<id> lender key. |
data.inputs.buy | boolean | true = maker BUYS units (a lend offer / bid); false = maker SELLS units (a borrow offer / ask). |
data.inputs.tick | string | Order-book tick the APR snapped to. |
data.inputs.start | string | |
data.inputs.expiry | string | Offer expiry, unix seconds. |
data.inputs.maxAssets | string | Maker-side size in loan-token units. |
data.inputs.maker | string | Maker (offer owner) address. |
data.authorization | object | One-time setIsAuthorized(ecrecoverRatifier, true) transaction on the Midnight core. Send FIRST, only if the maker has not authorized the ratifier yet (read isAuthorized on-chain). |
data.authorization.to | string | |
data.authorization.data | string | Informational payload. null when the endpoint only builds calldata. |
data.authorization.value | string | Native-token value to send with the transaction, in wei. |
data.authorization.ratifier | string | |
data.aprPctSnapped | number | The exact APR (percent) after tick-snapping — what the offer will actually quote once posted. |
data.maturity | number | Market maturity, unix seconds. |
actions | null |
Example response
{
"success": true,
"data": {
"typedData": {},
"inputs": {
"chainId": "8453",
"lender": "MORPHO_MIDNIGHT_0xABC\u2026",
"buy": true,
"tick": "string",
"start": "0",
"expiry": "string",
"maxAssets": "string",
"maker": "string"
},
"authorization": {
"to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"data": "0x617ba037000000000000000000000000c02aaa39b2",
"value": "1000000000000000000",
"ratifier": "string"
},
"aprPctSnapped": 3.49,
"maturity": 1.0
}
}
Request
Responses
- 200
- 400
- 429
- 500
- 502
Offer typed-data, echoed inputs, and one-time authorization
Validation error
Rate limited. Unauthenticated callers share a per-IP budget; send an x-api-key header to lift it. Retry with exponential backoff.
Unexpected server error. Safe to retry with backoff.
An upstream data source or protocol origin failed (error.code is ORIGIN_FAILED). error.details carries the per-origin status. This is also what a missing or malformed required parameter currently returns, rather than a 400.