@morpho-dev/router 0.2.1 → 0.4.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 +67 -71
- package/dist/cli.js +4224 -1627
- package/dist/drizzle/migrations/0015_add-lots-table.sql +12 -0
- package/dist/drizzle/migrations/0016_merkle-metadata.sql +26 -0
- package/dist/drizzle/migrations/0017_dusty_the_hunter.sql +1 -0
- package/dist/drizzle/migrations/0018_add_chain_collector_constraints.sql +3 -0
- package/dist/drizzle/migrations/0019_add-obligation-units-shares.sql +2 -0
- package/dist/drizzle/migrations/0020_add-session.sql +1 -0
- package/dist/drizzle/migrations/0021_drop_chain_collector_epoch_indexes.sql +2 -0
- package/dist/drizzle/migrations/0021_migrate-rate-to-price.sql +15 -0
- package/dist/drizzle/migrations/0022_consolidate-price.sql +15 -0
- package/dist/drizzle/migrations/meta/0015_snapshot.json +1365 -0
- package/dist/drizzle/migrations/meta/0016_snapshot.json +1531 -0
- package/dist/drizzle/migrations/meta/0017_snapshot.json +1525 -0
- package/dist/drizzle/migrations/meta/0018_snapshot.json +1572 -0
- package/dist/drizzle/migrations/meta/0019_snapshot.json +1586 -0
- package/dist/drizzle/migrations/meta/_journal.json +56 -0
- package/dist/evm/bytecode/erc20.txt +1 -0
- package/dist/evm/bytecode/factory.txt +1 -0
- package/dist/evm/bytecode/mempool.txt +1 -0
- package/dist/evm/bytecode/morpho.txt +1 -0
- package/dist/evm/bytecode/multicall3.txt +1 -0
- package/dist/evm/bytecode/oracle.txt +1 -0
- package/dist/evm/bytecode/terms.txt +1 -0
- package/dist/evm/bytecode/vault.txt +1 -0
- package/dist/evm/bytecode/vaultV1.txt +1 -0
- package/dist/index.browser.d.mts +1376 -651
- package/dist/index.browser.d.mts.map +1 -1
- package/dist/index.browser.d.ts +1375 -654
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +2398 -1526
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.mjs +2394 -1522
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.node.d.mts +2372 -1039
- package/dist/index.node.d.mts.map +1 -1
- package/dist/index.node.d.ts +2372 -1039
- package/dist/index.node.d.ts.map +1 -1
- package/dist/index.node.js +3094 -1399
- package/dist/index.node.js.map +1 -1
- package/dist/index.node.mjs +3075 -1399
- package/dist/index.node.mjs.map +1 -1
- package/docs/integrator.md +78 -0
- package/package.json +11 -6
package/dist/index.browser.mjs
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
import { t as __export } from "./chunk-jass6xSI.mjs";
|
|
2
2
|
import { z } from "zod/v4";
|
|
3
|
-
import { bytesToHex, decodeAbiParameters, encodeAbiParameters, getAddress, hashTypedData, hexToBytes, isAddress, isHex, keccak256, maxUint256, parseAbi, publicActions, zeroAddress } from "viem";
|
|
4
|
-
import "reflect-metadata";
|
|
5
|
-
import { generateDocument } from "openapi-metadata";
|
|
6
|
-
import { ApiBody, ApiOperation, ApiProperty, ApiQuery, ApiResponse, ApiTags } from "openapi-metadata/decorators";
|
|
7
|
-
import * as z$1 from "zod";
|
|
8
|
-
import { Base64 } from "js-base64";
|
|
9
|
-
import createOpenApiFetchClient from "openapi-fetch";
|
|
3
|
+
import { bytesToHex, decodeAbiParameters, encodeAbiParameters, getAddress, hashMessage, hashTypedData, hexToBytes, isAddress, isHex, keccak256, maxUint256, numberToHex, pad, parseAbi, publicActions, recoverAddress, zeroAddress } from "viem";
|
|
10
4
|
import { getBlock, getLogs, multicall } from "viem/actions";
|
|
11
5
|
import { anvil, base, mainnet } from "viem/chains";
|
|
12
|
-
import
|
|
6
|
+
import * as z$1 from "zod";
|
|
13
7
|
import { StandardMerkleTree } from "@openzeppelin/merkle-tree";
|
|
14
8
|
import { gzip, ungzip } from "pako";
|
|
9
|
+
import "reflect-metadata";
|
|
10
|
+
import { generateDocument } from "openapi-metadata";
|
|
11
|
+
import { ApiBody, ApiOperation, ApiParam, ApiProperty, ApiQuery, ApiResponse, ApiTags } from "openapi-metadata/decorators";
|
|
12
|
+
import createOpenApiFetchClient from "openapi-fetch";
|
|
15
13
|
|
|
16
14
|
//#region src/api/Schema/BookResponse.ts
|
|
17
|
-
var BookResponse_exports = /* @__PURE__ */ __export({ from: () => from$
|
|
18
|
-
function from$
|
|
15
|
+
var BookResponse_exports = /* @__PURE__ */ __export({ from: () => from$14 });
|
|
16
|
+
function from$14(level) {
|
|
19
17
|
return {
|
|
20
|
-
|
|
18
|
+
price: level.price.toString(),
|
|
21
19
|
assets: level.assets.toString(),
|
|
22
20
|
count: level.count
|
|
23
21
|
};
|
|
@@ -35,1041 +33,127 @@ const CollectorHealth = z.object({
|
|
|
35
33
|
"live",
|
|
36
34
|
"lagging",
|
|
37
35
|
"unknown"
|
|
38
|
-
])
|
|
36
|
+
]),
|
|
37
|
+
initialized: z.boolean()
|
|
39
38
|
});
|
|
40
39
|
const CollectorsHealthResponse = z.array(CollectorHealth);
|
|
41
40
|
const ChainHealth = z.object({
|
|
42
41
|
chain_id: z.number(),
|
|
43
|
-
local_block_number: z.number(),
|
|
42
|
+
local_block_number: z.number().nullable(),
|
|
44
43
|
remote_block_number: z.number().nullable(),
|
|
45
|
-
updated_at: z.string()
|
|
44
|
+
updated_at: z.string().nullable(),
|
|
45
|
+
initialized: z.boolean()
|
|
46
46
|
});
|
|
47
47
|
const ChainsHealthResponse = z.array(ChainHealth);
|
|
48
|
-
const RouterStatusResponse = z.object({
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
const RouterStatusResponse = z.object({
|
|
49
|
+
status: z.enum(["live", "syncing"]),
|
|
50
|
+
initialized: z.boolean(),
|
|
51
|
+
missing_chains: z.array(z.number()),
|
|
52
|
+
missing_collectors: z.array(z.object({
|
|
53
|
+
chain_id: z.number(),
|
|
54
|
+
name: z.string()
|
|
55
|
+
}))
|
|
56
56
|
});
|
|
57
|
-
/**
|
|
58
|
-
* Formats object keys to snake case.
|
|
59
|
-
* Preserves ethereum addresses as is.
|
|
60
|
-
* Converts ethereum addresses to checksummed if used as values.
|
|
61
|
-
* Stringifies bigint values to strings.
|
|
62
|
-
*/
|
|
63
|
-
function toSnakeCase$1(obj) {
|
|
64
|
-
return stringifyBigint(processObject(obj, (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`), (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? getAddress(value.toLowerCase()) : value));
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Formats a snake case object to its camel case type.
|
|
68
|
-
* Preserves ethereum addresses as is.
|
|
69
|
-
* Converts checksummed ethereum addresses to lowercase if used as values.
|
|
70
|
-
* @warning Does not unstringify bigint values.
|
|
71
|
-
*/
|
|
72
|
-
function fromSnakeCase$3(obj) {
|
|
73
|
-
return processObject(obj, (s) => isAddress(s.toLowerCase()) ? s : s.replace(/_([a-z])/g, (_, c) => c.toUpperCase()), (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? value.toLowerCase() : value);
|
|
74
|
-
}
|
|
75
|
-
function processObject(obj, fnKey, fnValue) {
|
|
76
|
-
if (typeof obj !== "object" || obj === null) return obj;
|
|
77
|
-
if (Array.isArray(obj)) return obj.map((item) => processObject(item, fnKey, fnValue));
|
|
78
|
-
return Object.entries(obj).reduce((acc, [key, value]) => {
|
|
79
|
-
const newKey = fnKey(key);
|
|
80
|
-
acc[newKey] = typeof value === "object" && value !== null ? processObject(value, fnKey, fnValue) : fnValue(value);
|
|
81
|
-
return acc;
|
|
82
|
-
}, {});
|
|
83
|
-
}
|
|
84
|
-
function stringifyBigint(value) {
|
|
85
|
-
if (typeof value === "bigint") return value.toString();
|
|
86
|
-
if (Array.isArray(value)) return value.map(stringifyBigint);
|
|
87
|
-
if (value && typeof value === "object") {
|
|
88
|
-
const out = {};
|
|
89
|
-
for (const [k, v] of Object.entries(value)) out[k] = stringifyBigint(v);
|
|
90
|
-
return out;
|
|
91
|
-
}
|
|
92
|
-
return value;
|
|
93
|
-
}
|
|
94
57
|
|
|
95
58
|
//#endregion
|
|
96
59
|
//#region src/api/Schema/ObligationResponse.ts
|
|
97
|
-
var ObligationResponse_exports = /* @__PURE__ */ __export({ from: () => from$
|
|
60
|
+
var ObligationResponse_exports = /* @__PURE__ */ __export({ from: () => from$13 });
|
|
98
61
|
/**
|
|
99
62
|
* Creates an `ObligationResponse` from a `Obligation`.
|
|
100
63
|
* @constructor
|
|
101
64
|
* @param obligation - {@link Obligation}
|
|
102
65
|
* @returns The created `ObligationResponse`. {@link ObligationResponse}
|
|
103
66
|
*/
|
|
104
|
-
function from$
|
|
105
|
-
return toSnakeCase$1({
|
|
106
|
-
id: quote.obligationId,
|
|
107
|
-
...obligation,
|
|
108
|
-
ask: quote.ask,
|
|
109
|
-
bid: quote.bid
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
//#endregion
|
|
114
|
-
//#region src/api/Schema/OfferResponse.ts
|
|
115
|
-
var OfferResponse_exports = /* @__PURE__ */ __export({ from: () => from$11 });
|
|
116
|
-
/**
|
|
117
|
-
* Creates an `OfferResponse` from an `Offer`.
|
|
118
|
-
* @constructor
|
|
119
|
-
* @param offer - {@link Offer}
|
|
120
|
-
* @returns The created `OfferResponse`. {@link OfferResponse}
|
|
121
|
-
*/
|
|
122
|
-
function from$11(offer) {
|
|
123
|
-
const result = toSnakeCase$1(offer);
|
|
67
|
+
function from$13(obligation, quote) {
|
|
124
68
|
return {
|
|
125
|
-
|
|
126
|
-
|
|
69
|
+
id: quote.obligationId,
|
|
70
|
+
chain_id: obligation.chainId,
|
|
71
|
+
loan_token: obligation.loanToken,
|
|
72
|
+
collaterals: obligation.collaterals.map((c) => ({
|
|
73
|
+
token: c.asset,
|
|
74
|
+
lltv: c.lltv.toString(),
|
|
75
|
+
oracle: c.oracle
|
|
76
|
+
})),
|
|
77
|
+
maturity: obligation.maturity,
|
|
78
|
+
ask: { price: quote.ask.price.toString() },
|
|
79
|
+
bid: { price: quote.bid.price.toString() }
|
|
127
80
|
};
|
|
128
81
|
}
|
|
129
82
|
|
|
130
83
|
//#endregion
|
|
131
|
-
//#region src/
|
|
132
|
-
const
|
|
133
|
-
"
|
|
134
|
-
"
|
|
135
|
-
"
|
|
136
|
-
"
|
|
137
|
-
|
|
84
|
+
//#region src/core/Abi/MetaMorpho.ts
|
|
85
|
+
const MetaMorpho = parseAbi([
|
|
86
|
+
"function balanceOf(address account) view returns (uint256)",
|
|
87
|
+
"function DECIMALS_OFFSET() view returns (uint8)",
|
|
88
|
+
"function totalAssets() view returns (uint256)",
|
|
89
|
+
"function totalSupply() view returns (uint256)",
|
|
90
|
+
"function maxWithdraw(address owner) view returns (uint256 assets)",
|
|
91
|
+
"function asset() view returns (address)",
|
|
92
|
+
"event Transfer(address indexed from, address indexed to, uint256 value)",
|
|
93
|
+
"function withdrawQueue(uint256 index) view returns (bytes32)",
|
|
94
|
+
"function withdrawQueueLength() view returns (uint256)"
|
|
95
|
+
]);
|
|
138
96
|
|
|
139
97
|
//#endregion
|
|
140
|
-
//#region
|
|
141
|
-
|
|
142
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
143
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
144
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
145
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
146
|
-
}
|
|
98
|
+
//#region src/core/Abi/MetaMorphoFactory.ts
|
|
99
|
+
const MetaMorphoFactory = parseAbi(["event CreateMetaMorpho(address indexed metaMorpho,address indexed caller,address initialOwner,uint256 initialTimelock,address indexed asset,string name,string symbol,bytes32 salt)", "function isMetaMorpho(address) view returns (bool)"]);
|
|
147
100
|
|
|
148
101
|
//#endregion
|
|
149
|
-
//#region src/
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
loan_token: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
|
|
165
|
-
collaterals: [{
|
|
166
|
-
asset: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
|
|
167
|
-
oracle: "0x45093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
168
|
-
lltv: "860000000000000000"
|
|
102
|
+
//#region src/core/Abi/index.ts
|
|
103
|
+
var Abi_exports = /* @__PURE__ */ __export({
|
|
104
|
+
ERC4626: () => ERC4626,
|
|
105
|
+
MetaMorpho: () => MetaMorpho,
|
|
106
|
+
MetaMorphoFactory: () => MetaMorphoFactory,
|
|
107
|
+
Morpho: () => Morpho,
|
|
108
|
+
Oracle: () => Oracle
|
|
109
|
+
});
|
|
110
|
+
const Oracle = [{
|
|
111
|
+
type: "function",
|
|
112
|
+
name: "price",
|
|
113
|
+
inputs: [],
|
|
114
|
+
outputs: [{
|
|
115
|
+
name: "",
|
|
116
|
+
type: "uint256"
|
|
169
117
|
}],
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
type: "string",
|
|
210
|
-
example: "Limit must be greater than 0."
|
|
211
|
-
})], ErrorResponse.prototype, "message", void 0);
|
|
212
|
-
__decorate([ApiProperty({
|
|
213
|
-
type: "object",
|
|
214
|
-
example: [{
|
|
215
|
-
field: "limit",
|
|
216
|
-
issue: "Limit must be greater than 0."
|
|
217
|
-
}]
|
|
218
|
-
})], ErrorResponse.prototype, "details", void 0);
|
|
219
|
-
var BadRequestResponse = class {};
|
|
220
|
-
__decorate([ApiProperty({ type: () => ErrorResponse })], BadRequestResponse.prototype, "error", void 0);
|
|
221
|
-
__decorate([ApiProperty({ type: () => Meta })], BadRequestResponse.prototype, "meta", void 0);
|
|
222
|
-
var CollateralResponse = class {};
|
|
223
|
-
__decorate([ApiProperty({
|
|
224
|
-
type: "string",
|
|
225
|
-
example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751"
|
|
226
|
-
})], CollateralResponse.prototype, "asset", void 0);
|
|
227
|
-
__decorate([ApiProperty({
|
|
228
|
-
type: "string",
|
|
229
|
-
example: "0x45093658BE7f90B63D7c359e8f408e503c2D9401"
|
|
230
|
-
})], CollateralResponse.prototype, "oracle", void 0);
|
|
231
|
-
__decorate([ApiProperty({
|
|
232
|
-
type: "string",
|
|
233
|
-
example: "860000000000000000"
|
|
234
|
-
})], CollateralResponse.prototype, "lltv", void 0);
|
|
235
|
-
var AskResponse = class {};
|
|
236
|
-
__decorate([ApiProperty({
|
|
237
|
-
type: "string",
|
|
238
|
-
example: "1000000000000000000"
|
|
239
|
-
})], AskResponse.prototype, "rate", void 0);
|
|
240
|
-
var BidResponse = class {};
|
|
241
|
-
__decorate([ApiProperty({
|
|
242
|
-
type: "string",
|
|
243
|
-
example: "1000000000000000000"
|
|
244
|
-
})], BidResponse.prototype, "rate", void 0);
|
|
245
|
-
var OfferCallbackResponse = class {};
|
|
246
|
-
__decorate([ApiProperty({
|
|
247
|
-
type: "string",
|
|
248
|
-
example: offerExample.callback.address
|
|
249
|
-
})], OfferCallbackResponse.prototype, "address", void 0);
|
|
250
|
-
__decorate([ApiProperty({
|
|
251
|
-
type: "string",
|
|
252
|
-
example: offerExample.callback.data
|
|
253
|
-
})], OfferCallbackResponse.prototype, "data", void 0);
|
|
254
|
-
__decorate([ApiProperty({
|
|
255
|
-
type: "string",
|
|
256
|
-
example: offerExample.callback.gas_limit
|
|
257
|
-
})], OfferCallbackResponse.prototype, "gas_limit", void 0);
|
|
258
|
-
var OfferListItemResponse = class {};
|
|
259
|
-
__decorate([ApiProperty({
|
|
260
|
-
type: "string",
|
|
261
|
-
example: offerExample.hash
|
|
262
|
-
})], OfferListItemResponse.prototype, "hash", void 0);
|
|
263
|
-
__decorate([ApiProperty({
|
|
264
|
-
type: "string",
|
|
265
|
-
example: offerExample.offering
|
|
266
|
-
})], OfferListItemResponse.prototype, "offering", void 0);
|
|
267
|
-
__decorate([ApiProperty({
|
|
268
|
-
type: "string",
|
|
269
|
-
example: offerExample.assets
|
|
270
|
-
})], OfferListItemResponse.prototype, "assets", void 0);
|
|
271
|
-
__decorate([ApiProperty({
|
|
272
|
-
type: "string",
|
|
273
|
-
example: offerExample.rate
|
|
274
|
-
})], OfferListItemResponse.prototype, "rate", void 0);
|
|
275
|
-
__decorate([ApiProperty({
|
|
276
|
-
type: "number",
|
|
277
|
-
example: offerExample.maturity
|
|
278
|
-
})], OfferListItemResponse.prototype, "maturity", void 0);
|
|
279
|
-
__decorate([ApiProperty({
|
|
280
|
-
type: "number",
|
|
281
|
-
example: offerExample.expiry
|
|
282
|
-
})], OfferListItemResponse.prototype, "expiry", void 0);
|
|
283
|
-
__decorate([ApiProperty({
|
|
284
|
-
type: "number",
|
|
285
|
-
example: offerExample.start
|
|
286
|
-
})], OfferListItemResponse.prototype, "start", void 0);
|
|
287
|
-
__decorate([ApiProperty({
|
|
288
|
-
type: "string",
|
|
289
|
-
example: offerExample.nonce
|
|
290
|
-
})], OfferListItemResponse.prototype, "nonce", void 0);
|
|
291
|
-
__decorate([ApiProperty({
|
|
292
|
-
type: "boolean",
|
|
293
|
-
example: offerExample.buy
|
|
294
|
-
})], OfferListItemResponse.prototype, "buy", void 0);
|
|
295
|
-
__decorate([ApiProperty({
|
|
296
|
-
type: "number",
|
|
297
|
-
example: offerExample.chain_id
|
|
298
|
-
})], OfferListItemResponse.prototype, "chain_id", void 0);
|
|
299
|
-
__decorate([ApiProperty({
|
|
300
|
-
type: "string",
|
|
301
|
-
example: offerExample.loan_token
|
|
302
|
-
})], OfferListItemResponse.prototype, "loan_token", void 0);
|
|
303
|
-
__decorate([ApiProperty({
|
|
304
|
-
type: () => [CollateralResponse],
|
|
305
|
-
example: offerExample.collaterals
|
|
306
|
-
})], OfferListItemResponse.prototype, "collaterals", void 0);
|
|
307
|
-
__decorate([ApiProperty({
|
|
308
|
-
type: () => OfferCallbackResponse,
|
|
309
|
-
example: offerExample.callback
|
|
310
|
-
})], OfferListItemResponse.prototype, "callback", void 0);
|
|
311
|
-
__decorate([ApiProperty({
|
|
312
|
-
type: "string",
|
|
313
|
-
example: offerExample.takeable
|
|
314
|
-
})], OfferListItemResponse.prototype, "takeable", void 0);
|
|
315
|
-
__decorate([ApiProperty({
|
|
316
|
-
type: "string",
|
|
317
|
-
example: offerExample.consumed
|
|
318
|
-
})], OfferListItemResponse.prototype, "consumed", void 0);
|
|
319
|
-
__decorate([ApiProperty({
|
|
320
|
-
type: "number",
|
|
321
|
-
example: offerExample.block_number
|
|
322
|
-
})], OfferListItemResponse.prototype, "block_number", void 0);
|
|
323
|
-
__decorate([ApiProperty({
|
|
324
|
-
type: "string",
|
|
325
|
-
nullable: true,
|
|
326
|
-
example: offerExample.signature
|
|
327
|
-
})], OfferListItemResponse.prototype, "signature", void 0);
|
|
328
|
-
var ObligationResponse = class {};
|
|
329
|
-
__decorate([ApiProperty({
|
|
330
|
-
type: "string",
|
|
331
|
-
example: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67"
|
|
332
|
-
})], ObligationResponse.prototype, "id", void 0);
|
|
333
|
-
__decorate([ApiProperty({
|
|
334
|
-
type: "number",
|
|
335
|
-
example: 1
|
|
336
|
-
})], ObligationResponse.prototype, "chain_id", void 0);
|
|
337
|
-
__decorate([ApiProperty({
|
|
338
|
-
type: "string",
|
|
339
|
-
example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078"
|
|
340
|
-
})], ObligationResponse.prototype, "loan_token", void 0);
|
|
341
|
-
__decorate([ApiProperty({ type: () => [CollateralResponse] })], ObligationResponse.prototype, "collaterals", void 0);
|
|
342
|
-
__decorate([ApiProperty({
|
|
343
|
-
type: "number",
|
|
344
|
-
example: 1761922800
|
|
345
|
-
})], ObligationResponse.prototype, "maturity", void 0);
|
|
346
|
-
__decorate([ApiProperty({ type: () => AskResponse })], ObligationResponse.prototype, "ask", void 0);
|
|
347
|
-
__decorate([ApiProperty({ type: () => BidResponse })], ObligationResponse.prototype, "bid", void 0);
|
|
348
|
-
var ObligationListResponse = class extends SuccessResponse {};
|
|
349
|
-
__decorate([ApiProperty({
|
|
350
|
-
type: "string",
|
|
351
|
-
nullable: true,
|
|
352
|
-
example: obligationCursorExample
|
|
353
|
-
})], ObligationListResponse.prototype, "cursor", void 0);
|
|
354
|
-
__decorate([ApiProperty({
|
|
355
|
-
type: () => [ObligationResponse],
|
|
356
|
-
description: "List of obligations with takable offers."
|
|
357
|
-
})], ObligationListResponse.prototype, "data", void 0);
|
|
358
|
-
var ObligationSingleSuccessResponse = class extends SuccessResponse {};
|
|
359
|
-
__decorate([ApiProperty({
|
|
360
|
-
type: "string",
|
|
361
|
-
nullable: true,
|
|
362
|
-
example: null
|
|
363
|
-
})], ObligationSingleSuccessResponse.prototype, "cursor", void 0);
|
|
364
|
-
__decorate([ApiProperty({
|
|
365
|
-
type: () => ObligationResponse,
|
|
366
|
-
description: "Obligation details."
|
|
367
|
-
})], ObligationSingleSuccessResponse.prototype, "data", void 0);
|
|
368
|
-
var OfferListResponse = class extends SuccessResponse {};
|
|
369
|
-
__decorate([ApiProperty({
|
|
370
|
-
type: "string",
|
|
371
|
-
nullable: true,
|
|
372
|
-
example: offerCursorExample
|
|
373
|
-
})], OfferListResponse.prototype, "cursor", void 0);
|
|
374
|
-
__decorate([ApiProperty({
|
|
375
|
-
type: () => [OfferListItemResponse],
|
|
376
|
-
description: "Offers matching the provided filters.",
|
|
377
|
-
example: [offerExample]
|
|
378
|
-
})], OfferListResponse.prototype, "data", void 0);
|
|
379
|
-
var RouterStatusDataResponse = class {};
|
|
380
|
-
__decorate([ApiProperty({
|
|
381
|
-
type: "string",
|
|
382
|
-
enum: ["live", "syncing"],
|
|
383
|
-
example: routerStatusExample.status
|
|
384
|
-
})], RouterStatusDataResponse.prototype, "status", void 0);
|
|
385
|
-
var RouterStatusSuccessResponse = class extends SuccessResponse {};
|
|
386
|
-
__decorate([ApiProperty({
|
|
387
|
-
type: () => RouterStatusDataResponse,
|
|
388
|
-
description: "Aggregated router status.",
|
|
389
|
-
example: routerStatusExample
|
|
390
|
-
})], RouterStatusSuccessResponse.prototype, "data", void 0);
|
|
391
|
-
var CollectorHealthResponse = class {};
|
|
392
|
-
__decorate([ApiProperty({
|
|
393
|
-
type: "string",
|
|
394
|
-
example: collectorsHealthExample.name
|
|
395
|
-
})], CollectorHealthResponse.prototype, "name", void 0);
|
|
396
|
-
__decorate([ApiProperty({
|
|
397
|
-
type: "number",
|
|
398
|
-
example: collectorsHealthExample.chain_id
|
|
399
|
-
})], CollectorHealthResponse.prototype, "chain_id", void 0);
|
|
400
|
-
__decorate([ApiProperty({
|
|
401
|
-
type: "number",
|
|
402
|
-
nullable: true,
|
|
403
|
-
example: collectorsHealthExample.block_number
|
|
404
|
-
})], CollectorHealthResponse.prototype, "block_number", void 0);
|
|
405
|
-
__decorate([ApiProperty({
|
|
406
|
-
type: "string",
|
|
407
|
-
nullable: true,
|
|
408
|
-
example: collectorsHealthExample.updated_at
|
|
409
|
-
})], CollectorHealthResponse.prototype, "updated_at", void 0);
|
|
410
|
-
__decorate([ApiProperty({
|
|
411
|
-
type: "number",
|
|
412
|
-
nullable: true,
|
|
413
|
-
example: collectorsHealthExample.lag
|
|
414
|
-
})], CollectorHealthResponse.prototype, "lag", void 0);
|
|
415
|
-
__decorate([ApiProperty({
|
|
416
|
-
type: "string",
|
|
417
|
-
enum: [
|
|
418
|
-
"live",
|
|
419
|
-
"lagging",
|
|
420
|
-
"unknown"
|
|
421
|
-
],
|
|
422
|
-
example: collectorsHealthExample.status
|
|
423
|
-
})], CollectorHealthResponse.prototype, "status", void 0);
|
|
424
|
-
var CollectorsHealthSuccessResponse = class extends SuccessResponse {};
|
|
425
|
-
__decorate([ApiProperty({
|
|
426
|
-
type: () => [CollectorHealthResponse],
|
|
427
|
-
description: "Collectors health details and sync status.",
|
|
428
|
-
example: [collectorsHealthExample]
|
|
429
|
-
})], CollectorsHealthSuccessResponse.prototype, "data", void 0);
|
|
430
|
-
var ChainHealthResponse = class {};
|
|
431
|
-
__decorate([ApiProperty({
|
|
432
|
-
type: "number",
|
|
433
|
-
example: chainsHealthExample.chain_id
|
|
434
|
-
})], ChainHealthResponse.prototype, "chain_id", void 0);
|
|
435
|
-
__decorate([ApiProperty({
|
|
436
|
-
type: "number",
|
|
437
|
-
example: chainsHealthExample.local_block_number
|
|
438
|
-
})], ChainHealthResponse.prototype, "local_block_number", void 0);
|
|
439
|
-
__decorate([ApiProperty({
|
|
440
|
-
type: "number",
|
|
441
|
-
nullable: true,
|
|
442
|
-
example: chainsHealthExample.remote_block_number
|
|
443
|
-
})], ChainHealthResponse.prototype, "remote_block_number", void 0);
|
|
444
|
-
__decorate([ApiProperty({
|
|
445
|
-
type: "string",
|
|
446
|
-
example: chainsHealthExample.updated_at
|
|
447
|
-
})], ChainHealthResponse.prototype, "updated_at", void 0);
|
|
448
|
-
var ChainsHealthSuccessResponse = class extends SuccessResponse {};
|
|
449
|
-
__decorate([ApiProperty({
|
|
450
|
-
type: () => [ChainHealthResponse],
|
|
451
|
-
description: "Latest processed block per chain.",
|
|
452
|
-
example: [chainsHealthExample]
|
|
453
|
-
})], ChainsHealthSuccessResponse.prototype, "data", void 0);
|
|
454
|
-
var ValidateOfferRequest = class {};
|
|
455
|
-
__decorate([ApiProperty({
|
|
456
|
-
type: "string",
|
|
457
|
-
example: offerExample.offering
|
|
458
|
-
})], ValidateOfferRequest.prototype, "offering", void 0);
|
|
459
|
-
__decorate([ApiProperty({
|
|
460
|
-
type: "string",
|
|
461
|
-
example: offerExample.assets
|
|
462
|
-
})], ValidateOfferRequest.prototype, "assets", void 0);
|
|
463
|
-
__decorate([ApiProperty({
|
|
464
|
-
type: "string",
|
|
465
|
-
example: offerExample.rate
|
|
466
|
-
})], ValidateOfferRequest.prototype, "rate", void 0);
|
|
467
|
-
__decorate([ApiProperty({
|
|
468
|
-
type: "number",
|
|
469
|
-
example: offerExample.maturity
|
|
470
|
-
})], ValidateOfferRequest.prototype, "maturity", void 0);
|
|
471
|
-
__decorate([ApiProperty({
|
|
472
|
-
type: "number",
|
|
473
|
-
example: offerExample.expiry
|
|
474
|
-
})], ValidateOfferRequest.prototype, "expiry", void 0);
|
|
475
|
-
__decorate([ApiProperty({
|
|
476
|
-
type: "number",
|
|
477
|
-
example: offerExample.start
|
|
478
|
-
})], ValidateOfferRequest.prototype, "start", void 0);
|
|
479
|
-
__decorate([ApiProperty({
|
|
480
|
-
type: "string",
|
|
481
|
-
example: offerExample.nonce
|
|
482
|
-
})], ValidateOfferRequest.prototype, "nonce", void 0);
|
|
483
|
-
__decorate([ApiProperty({
|
|
484
|
-
type: "boolean",
|
|
485
|
-
example: offerExample.buy
|
|
486
|
-
})], ValidateOfferRequest.prototype, "buy", void 0);
|
|
487
|
-
__decorate([ApiProperty({
|
|
488
|
-
type: "number",
|
|
489
|
-
example: offerExample.chain_id
|
|
490
|
-
})], ValidateOfferRequest.prototype, "chain_id", void 0);
|
|
491
|
-
__decorate([ApiProperty({
|
|
492
|
-
type: "string",
|
|
493
|
-
example: offerExample.loan_token
|
|
494
|
-
})], ValidateOfferRequest.prototype, "loan_token", void 0);
|
|
495
|
-
__decorate([ApiProperty({
|
|
496
|
-
type: () => [CollateralResponse],
|
|
497
|
-
example: offerExample.collaterals
|
|
498
|
-
})], ValidateOfferRequest.prototype, "collaterals", void 0);
|
|
499
|
-
__decorate([ApiProperty({
|
|
500
|
-
type: () => OfferCallbackResponse,
|
|
501
|
-
example: offerExample.callback
|
|
502
|
-
})], ValidateOfferRequest.prototype, "callback", void 0);
|
|
503
|
-
var ValidateOffersRequest = class {};
|
|
504
|
-
__decorate([ApiProperty({
|
|
505
|
-
type: () => [ValidateOfferRequest],
|
|
506
|
-
description: "Array of offers in snake_case format. Mutually exclusive with 'calldata'.",
|
|
507
|
-
required: false
|
|
508
|
-
})], ValidateOffersRequest.prototype, "offers", void 0);
|
|
509
|
-
__decorate([ApiProperty({
|
|
510
|
-
type: "string",
|
|
511
|
-
description: "Encoded tree calldata as a hex string (0x-prefixed). Mutually exclusive with 'offers'.",
|
|
512
|
-
example: "0x01...",
|
|
513
|
-
required: false
|
|
514
|
-
})], ValidateOffersRequest.prototype, "calldata", void 0);
|
|
515
|
-
var ValidateOfferResultResponse = class {};
|
|
516
|
-
__decorate([ApiProperty({
|
|
517
|
-
type: "string",
|
|
518
|
-
example: offerExample.hash
|
|
519
|
-
})], ValidateOfferResultResponse.prototype, "offer_hash", void 0);
|
|
520
|
-
__decorate([ApiProperty({
|
|
521
|
-
type: "boolean",
|
|
522
|
-
example: false
|
|
523
|
-
})], ValidateOfferResultResponse.prototype, "valid", void 0);
|
|
524
|
-
__decorate([ApiProperty({
|
|
525
|
-
type: "string",
|
|
526
|
-
example: "parse_error",
|
|
527
|
-
nullable: true
|
|
528
|
-
})], ValidateOfferResultResponse.prototype, "rule", void 0);
|
|
529
|
-
__decorate([ApiProperty({
|
|
530
|
-
type: "string",
|
|
531
|
-
example: "Invalid offer. 'offering': invalid address",
|
|
532
|
-
nullable: true
|
|
533
|
-
})], ValidateOfferResultResponse.prototype, "message", void 0);
|
|
534
|
-
var ValidateOffersListResponse = class extends SuccessResponse {};
|
|
535
|
-
__decorate([ApiProperty({
|
|
536
|
-
type: "string",
|
|
537
|
-
nullable: true,
|
|
538
|
-
example: null
|
|
539
|
-
})], ValidateOffersListResponse.prototype, "cursor", void 0);
|
|
540
|
-
__decorate([ApiProperty({
|
|
541
|
-
type: () => [ValidateOfferResultResponse],
|
|
542
|
-
description: "Validation results for each offer."
|
|
543
|
-
})], ValidateOffersListResponse.prototype, "data", void 0);
|
|
544
|
-
var BookLevelResponse = class {};
|
|
545
|
-
__decorate([ApiProperty({
|
|
546
|
-
type: "string",
|
|
547
|
-
example: "2750000000000000000"
|
|
548
|
-
})], BookLevelResponse.prototype, "rate", void 0);
|
|
549
|
-
__decorate([ApiProperty({
|
|
550
|
-
type: "string",
|
|
551
|
-
example: "369216000000000000000000"
|
|
552
|
-
})], BookLevelResponse.prototype, "assets", void 0);
|
|
553
|
-
__decorate([ApiProperty({
|
|
554
|
-
type: "number",
|
|
555
|
-
example: 5
|
|
556
|
-
})], BookLevelResponse.prototype, "count", void 0);
|
|
557
|
-
var BookListResponse = class extends SuccessResponse {};
|
|
558
|
-
__decorate([ApiProperty({
|
|
559
|
-
type: "string",
|
|
560
|
-
nullable: true,
|
|
561
|
-
example: offerCursorExample
|
|
562
|
-
})], BookListResponse.prototype, "cursor", void 0);
|
|
563
|
-
__decorate([ApiProperty({
|
|
564
|
-
type: () => [BookLevelResponse],
|
|
565
|
-
description: "Aggregated book levels grouped by rate."
|
|
566
|
-
})], BookListResponse.prototype, "data", void 0);
|
|
567
|
-
let BooksController = class BooksController$1 {
|
|
568
|
-
async getBook() {}
|
|
569
|
-
};
|
|
570
|
-
__decorate([
|
|
571
|
-
ApiOperation({
|
|
572
|
-
methods: ["get"],
|
|
573
|
-
path: "/v1/books/{obligationId}/{side}",
|
|
574
|
-
summary: "Get aggregated book",
|
|
575
|
-
description: "Returns aggregated book data for a given obligation and side. Offers are grouped by rate with summed takeable amounts. Book levels are sorted by rate (ascending for buy side, descending for sell side)."
|
|
576
|
-
}),
|
|
577
|
-
ApiQuery({
|
|
578
|
-
name: "cursor",
|
|
579
|
-
type: "string",
|
|
580
|
-
example: offerCursorExample,
|
|
581
|
-
description: "Pagination cursor in base64url-encoded format."
|
|
582
|
-
}),
|
|
583
|
-
ApiQuery({
|
|
584
|
-
name: "limit",
|
|
585
|
-
type: "number",
|
|
586
|
-
example: 10,
|
|
587
|
-
description: "Maximum number of rate levels to return."
|
|
588
|
-
}),
|
|
589
|
-
ApiResponse({
|
|
590
|
-
status: 200,
|
|
591
|
-
description: "Success",
|
|
592
|
-
type: BookListResponse
|
|
593
|
-
})
|
|
594
|
-
], BooksController.prototype, "getBook", null);
|
|
595
|
-
BooksController = __decorate([ApiTags("Books"), ApiResponse({
|
|
596
|
-
status: 400,
|
|
597
|
-
description: "Bad Request",
|
|
598
|
-
type: BadRequestResponse
|
|
599
|
-
})], BooksController);
|
|
600
|
-
let ValidateController = class ValidateController$1 {
|
|
601
|
-
async validateOffers() {}
|
|
602
|
-
};
|
|
603
|
-
__decorate([
|
|
604
|
-
ApiOperation({
|
|
605
|
-
methods: ["post"],
|
|
606
|
-
path: "/v1/validate",
|
|
607
|
-
summary: "Validate offers",
|
|
608
|
-
description: "Validates offers against router validation rules. Returns validation status for each offer. Accepts either an array of offers or encoded calldata (mutually exclusive)."
|
|
609
|
-
}),
|
|
610
|
-
ApiBody({ type: ValidateOffersRequest }),
|
|
611
|
-
ApiResponse({
|
|
612
|
-
status: 200,
|
|
613
|
-
description: "Success",
|
|
614
|
-
type: ValidateOffersListResponse
|
|
615
|
-
})
|
|
616
|
-
], ValidateController.prototype, "validateOffers", null);
|
|
617
|
-
ValidateController = __decorate([ApiTags("Validate"), ApiResponse({
|
|
618
|
-
status: 400,
|
|
619
|
-
description: "Bad Request",
|
|
620
|
-
type: BadRequestResponse
|
|
621
|
-
})], ValidateController);
|
|
622
|
-
let OffersController = class OffersController$1 {
|
|
623
|
-
async getOffers() {}
|
|
624
|
-
};
|
|
625
|
-
__decorate([
|
|
626
|
-
ApiOperation({
|
|
627
|
-
methods: ["get"],
|
|
628
|
-
path: "/v1/offers",
|
|
629
|
-
summary: "List all offers",
|
|
630
|
-
description: "Returns offers. Provide either `obligation_id` + `side` (order book) or `offering` (by maker)."
|
|
631
|
-
}),
|
|
632
|
-
ApiQuery({
|
|
633
|
-
name: "side",
|
|
634
|
-
type: "string",
|
|
635
|
-
required: false,
|
|
636
|
-
enum: ["buy", "sell"],
|
|
637
|
-
example: "buy",
|
|
638
|
-
description: "Side of the offer. Required when using obligation_id."
|
|
639
|
-
}),
|
|
640
|
-
ApiQuery({
|
|
641
|
-
name: "obligation_id",
|
|
642
|
-
type: "string",
|
|
643
|
-
required: false,
|
|
644
|
-
example: "0x1234567890123456789012345678901234567890123456789012345678901234",
|
|
645
|
-
description: "Obligation id used to filter offers. Required when not using offering."
|
|
646
|
-
}),
|
|
647
|
-
ApiQuery({
|
|
648
|
-
name: "offering",
|
|
649
|
-
type: "string",
|
|
650
|
-
required: false,
|
|
651
|
-
example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
652
|
-
description: "Maker address to filter offers by. Alternative to obligation_id + side."
|
|
653
|
-
}),
|
|
654
|
-
ApiQuery({
|
|
655
|
-
name: "cursor",
|
|
656
|
-
type: "string",
|
|
657
|
-
example: offerCursorExample,
|
|
658
|
-
description: "Pagination cursor in base64url-encoded format."
|
|
659
|
-
}),
|
|
660
|
-
ApiQuery({
|
|
661
|
-
name: "limit",
|
|
662
|
-
type: "number",
|
|
663
|
-
example: 10,
|
|
664
|
-
description: "Maximum number of offers to return."
|
|
665
|
-
}),
|
|
666
|
-
ApiResponse({
|
|
667
|
-
status: 200,
|
|
668
|
-
description: "Success",
|
|
669
|
-
type: OfferListResponse
|
|
670
|
-
})
|
|
671
|
-
], OffersController.prototype, "getOffers", null);
|
|
672
|
-
OffersController = __decorate([ApiTags("Offers"), ApiResponse({
|
|
673
|
-
status: 400,
|
|
674
|
-
description: "Bad Request",
|
|
675
|
-
type: BadRequestResponse
|
|
676
|
-
})], OffersController);
|
|
677
|
-
let HealthController = class HealthController$1 {
|
|
678
|
-
async getRouterStatus() {}
|
|
679
|
-
async getCollectorsHealth() {}
|
|
680
|
-
async getChainsHealth() {}
|
|
681
|
-
};
|
|
682
|
-
__decorate([ApiOperation({
|
|
683
|
-
methods: ["get"],
|
|
684
|
-
path: "/v1/health",
|
|
685
|
-
summary: "Retrieve global health",
|
|
686
|
-
description: "Returns the aggregated status of the router."
|
|
687
|
-
}), ApiResponse({
|
|
688
|
-
status: 200,
|
|
689
|
-
description: "Success",
|
|
690
|
-
type: RouterStatusSuccessResponse
|
|
691
|
-
})], HealthController.prototype, "getRouterStatus", null);
|
|
692
|
-
__decorate([ApiOperation({
|
|
693
|
-
methods: ["get"],
|
|
694
|
-
path: "/v1/health/collectors",
|
|
695
|
-
summary: "Retrieve collectors health",
|
|
696
|
-
description: "Returns the latest block numbers processed by collectors and their sync status."
|
|
697
|
-
}), ApiResponse({
|
|
698
|
-
status: 200,
|
|
699
|
-
description: "Success",
|
|
700
|
-
type: CollectorsHealthSuccessResponse
|
|
701
|
-
})], HealthController.prototype, "getCollectorsHealth", null);
|
|
702
|
-
__decorate([ApiOperation({
|
|
703
|
-
methods: ["get"],
|
|
704
|
-
path: "/v1/health/chains",
|
|
705
|
-
summary: "Retrieve chains health",
|
|
706
|
-
description: "Returns the latest block that can be processed by collectors for each chain."
|
|
707
|
-
}), ApiResponse({
|
|
708
|
-
status: 200,
|
|
709
|
-
description: "Success",
|
|
710
|
-
type: ChainsHealthSuccessResponse
|
|
711
|
-
})], HealthController.prototype, "getChainsHealth", null);
|
|
712
|
-
HealthController = __decorate([ApiTags("Health")], HealthController);
|
|
713
|
-
let ObligationsController = class ObligationsController$1 {
|
|
714
|
-
async getObligations() {}
|
|
715
|
-
async getObligation() {}
|
|
716
|
-
};
|
|
717
|
-
__decorate([
|
|
718
|
-
ApiOperation({
|
|
719
|
-
methods: ["get"],
|
|
720
|
-
path: "/v1/obligations",
|
|
721
|
-
summary: "List all obligations",
|
|
722
|
-
description: "Returns a list of obligations with their current best ask and bid. Obligations are sorted by their id in ascending order by default."
|
|
723
|
-
}),
|
|
724
|
-
ApiQuery({
|
|
725
|
-
name: "cursor",
|
|
726
|
-
type: "string",
|
|
727
|
-
example: obligationCursorExample
|
|
728
|
-
}),
|
|
729
|
-
ApiQuery({
|
|
730
|
-
name: "limit",
|
|
731
|
-
type: "number",
|
|
732
|
-
example: 10
|
|
733
|
-
}),
|
|
734
|
-
ApiResponse({
|
|
735
|
-
status: 200,
|
|
736
|
-
description: "Success",
|
|
737
|
-
type: ObligationListResponse
|
|
738
|
-
})
|
|
739
|
-
], ObligationsController.prototype, "getObligations", null);
|
|
740
|
-
__decorate([ApiOperation({
|
|
741
|
-
methods: ["get"],
|
|
742
|
-
path: "/v1/obligations/{obligationId}",
|
|
743
|
-
summary: "Get an obligation",
|
|
744
|
-
description: "Returns an obligation by its id."
|
|
745
|
-
}), ApiResponse({
|
|
746
|
-
status: 200,
|
|
747
|
-
description: "Success",
|
|
748
|
-
type: ObligationSingleSuccessResponse
|
|
749
|
-
})], ObligationsController.prototype, "getObligation", null);
|
|
750
|
-
ObligationsController = __decorate([ApiTags("Obligations"), ApiResponse({
|
|
751
|
-
status: 400,
|
|
752
|
-
description: "Bad Request",
|
|
753
|
-
type: BadRequestResponse
|
|
754
|
-
})], ObligationsController);
|
|
755
|
-
const OpenApi = async (options = {}) => {
|
|
756
|
-
const document = await generateDocument({
|
|
757
|
-
controllers: [
|
|
758
|
-
BooksController,
|
|
759
|
-
OffersController,
|
|
760
|
-
ObligationsController,
|
|
761
|
-
HealthController,
|
|
762
|
-
ValidateController
|
|
763
|
-
],
|
|
764
|
-
document: {
|
|
765
|
-
openapi: "3.1.0",
|
|
766
|
-
info: {
|
|
767
|
-
title: "Router API",
|
|
768
|
-
version: "1.0.0",
|
|
769
|
-
description: "API for the Morpho Router"
|
|
770
|
-
},
|
|
771
|
-
servers: [{
|
|
772
|
-
url: "https://router.morpho.dev",
|
|
773
|
-
description: "Production server"
|
|
774
|
-
}, {
|
|
775
|
-
url: "http://localhost:7891",
|
|
776
|
-
description: "Local development server"
|
|
777
|
-
}]
|
|
778
|
-
}
|
|
779
|
-
});
|
|
780
|
-
if (options.rules && options.rules.length > 0) {
|
|
781
|
-
const rulesDescription = options.rules.map((rule) => `- **${rule.name}**: ${rule.description}`).join("\n");
|
|
782
|
-
const validatePath = document.paths?.["/v1/validate"];
|
|
783
|
-
if (validatePath && "post" in validatePath && validatePath.post) validatePath.post.description = `Validates offers against router validation rules. Returns validation status for each offer.\n\n**Available validation rules:**\n${rulesDescription}`;
|
|
784
|
-
}
|
|
785
|
-
return document;
|
|
786
|
-
};
|
|
787
|
-
|
|
788
|
-
//#endregion
|
|
789
|
-
//#region src/database/utils/Cursor.ts
|
|
790
|
-
var Cursor_exports = /* @__PURE__ */ __export({
|
|
791
|
-
decode: () => decode$3,
|
|
792
|
-
encode: () => encode$3,
|
|
793
|
-
validate: () => validate
|
|
794
|
-
});
|
|
795
|
-
function validate(cursor) {
|
|
796
|
-
if (!cursor || typeof cursor !== "object") throw new Error("Cursor must be an object");
|
|
797
|
-
const c = cursor;
|
|
798
|
-
if (![
|
|
799
|
-
"rate",
|
|
800
|
-
"maturity",
|
|
801
|
-
"expiry",
|
|
802
|
-
"amount"
|
|
803
|
-
].includes(c.sort)) throw new Error(`Invalid sort field: ${c.sort}. Must be one of: rate, maturity, expiry, amount`);
|
|
804
|
-
if (!["asc", "desc"].includes(c.dir)) throw new Error(`Invalid direction: ${c.dir}. Must be one of: asc, desc`);
|
|
805
|
-
if (!/^0x[a-fA-F0-9]{64}$/.test(c.hash)) throw new Error(`Invalid hash format: ${c.hash}. Must be a 64-character hex string starting with 0x`);
|
|
806
|
-
const validation = {
|
|
807
|
-
rate: {
|
|
808
|
-
field: "rate",
|
|
809
|
-
type: "string",
|
|
810
|
-
pattern: /^\d+$/,
|
|
811
|
-
error: "numeric string"
|
|
812
|
-
},
|
|
813
|
-
amount: {
|
|
814
|
-
field: "assets",
|
|
815
|
-
type: "string",
|
|
816
|
-
pattern: /^\d+$/,
|
|
817
|
-
error: "numeric string"
|
|
818
|
-
},
|
|
819
|
-
maturity: {
|
|
820
|
-
field: "maturity",
|
|
821
|
-
type: "number",
|
|
822
|
-
validator: (val) => val > 0,
|
|
823
|
-
error: "positive number"
|
|
824
|
-
},
|
|
825
|
-
expiry: {
|
|
826
|
-
field: "expiry",
|
|
827
|
-
type: "number",
|
|
828
|
-
validator: (val) => val > 0,
|
|
829
|
-
error: "positive number"
|
|
830
|
-
}
|
|
831
|
-
}[c.sort];
|
|
832
|
-
if (!validation) throw new Error(`Invalid sort field: ${c.sort}`);
|
|
833
|
-
const fieldValue = c[validation.field];
|
|
834
|
-
if (!fieldValue) throw new Error(`${c.sort} sort requires '${validation.field}' field to be present`);
|
|
835
|
-
if (typeof fieldValue !== validation.type) throw new Error(`${c.sort} sort requires '${validation.field}' field of type ${validation.type}`);
|
|
836
|
-
if (validation.pattern && !validation.pattern.test(fieldValue)) throw new Error(`Invalid ${validation.field} format: ${fieldValue}. Must be a ${validation.error}`);
|
|
837
|
-
if (validation.validator && !validation.validator(fieldValue)) throw new Error(`Invalid ${validation.field} value: ${fieldValue}. Must be a ${validation.error}`);
|
|
838
|
-
if (c.page !== void 0) {
|
|
839
|
-
if (typeof c.page !== "number" || !Number.isInteger(c.page) || c.page < 1) throw new Error("Invalid page: must be a positive integer");
|
|
840
|
-
}
|
|
841
|
-
return true;
|
|
842
|
-
}
|
|
843
|
-
function encode$3(c) {
|
|
844
|
-
return Base64.encodeURL(JSON.stringify(c));
|
|
845
|
-
}
|
|
846
|
-
function decode$3(token$1) {
|
|
847
|
-
if (!token$1) return null;
|
|
848
|
-
const decoded = JSON.parse(Base64.decode(token$1));
|
|
849
|
-
validate(decoded);
|
|
850
|
-
return decoded;
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
//#endregion
|
|
854
|
-
//#region src/api/Schema/requests.ts
|
|
855
|
-
const MAX_LIMIT = 100;
|
|
856
|
-
const DEFAULT_LIMIT = 20;
|
|
857
|
-
const PaginationQueryParams = z$1.object({
|
|
858
|
-
cursor: z$1.string().optional().refine((val) => {
|
|
859
|
-
if (!val) return true;
|
|
860
|
-
try {
|
|
861
|
-
return decode$3(val) !== null;
|
|
862
|
-
} catch (_error) {
|
|
863
|
-
return false;
|
|
864
|
-
}
|
|
865
|
-
}, { message: "Invalid cursor format. Must be a valid base64url-encoded cursor object" }).meta({
|
|
866
|
-
description: "Pagination cursor in base64url-encoded format",
|
|
867
|
-
example: "eyJzb3J0IjoicHJpY2UiLCJkaXIiOiJkZXNjIiwicHJpY2UiOiIxMDAwMDAwMDAwMDAwMDAwMDAwIiwiaGFzaCI6IjB4ZGRmZDY4NTllM2UwODJkMTkzODlhMWFlYzFiZGFkN2U4ZDkyZDk2YjFhYTc5NDBkYTkxYTMxMjVkMzFlM2JlNWIifQ"
|
|
868
|
-
}),
|
|
869
|
-
limit: z$1.string().regex(/^[1-9]\d*$/, { message: "Limit must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).pipe(z$1.number().max(MAX_LIMIT, { message: `Limit cannot exceed ${MAX_LIMIT}` })).optional().default(DEFAULT_LIMIT).meta({
|
|
870
|
-
description: `Limit maximum: ${MAX_LIMIT}. Default: ${DEFAULT_LIMIT}`,
|
|
871
|
-
example: 10
|
|
872
|
-
})
|
|
873
|
-
});
|
|
874
|
-
const GetOffersQueryParams = z$1.object({
|
|
875
|
-
...PaginationQueryParams.shape,
|
|
876
|
-
side: z$1.enum(["buy", "sell"]).optional().meta({
|
|
877
|
-
description: "Side of the offer. Required when using obligation_id.",
|
|
878
|
-
example: "buy"
|
|
879
|
-
}),
|
|
880
|
-
obligation_id: z$1.string().regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).optional().meta({
|
|
881
|
-
description: "Offers obligation id. Required when not using offering.",
|
|
882
|
-
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
883
|
-
}),
|
|
884
|
-
offering: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Offering must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
|
|
885
|
-
description: "Maker address to filter offers by. Alternative to obligation_id + side.",
|
|
886
|
-
example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401"
|
|
887
|
-
})
|
|
888
|
-
}).superRefine((val, ctx) => {
|
|
889
|
-
const hasObligation = val.obligation_id !== void 0;
|
|
890
|
-
const hasSide = val.side !== void 0;
|
|
891
|
-
const hasOffering = val.offering !== void 0;
|
|
892
|
-
if (hasOffering && (hasObligation || hasSide)) {
|
|
893
|
-
ctx.addIssue({
|
|
894
|
-
code: "custom",
|
|
895
|
-
message: "Cannot use both offering and obligation_id/side parameters"
|
|
896
|
-
});
|
|
897
|
-
return;
|
|
898
|
-
}
|
|
899
|
-
if (hasOffering) return;
|
|
900
|
-
if (!hasObligation || !hasSide) ctx.addIssue({
|
|
901
|
-
code: "custom",
|
|
902
|
-
message: "Must provide either offering or both obligation_id and side"
|
|
903
|
-
});
|
|
904
|
-
});
|
|
905
|
-
const GetObligationsQueryParams = z$1.object({
|
|
906
|
-
...PaginationQueryParams.shape,
|
|
907
|
-
cursor: z$1.string().optional().meta({
|
|
908
|
-
description: "Obligation id cursor",
|
|
909
|
-
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
910
|
-
})
|
|
911
|
-
});
|
|
912
|
-
const GetObligationParams = z$1.object({ obligation_id: z$1.string({ error: "Obligation id is required and must be a valid 32-byte hex string" }).regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).meta({
|
|
913
|
-
description: "Obligation id",
|
|
914
|
-
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
915
|
-
}) });
|
|
916
|
-
/** Validate a book cursor format: {side, lastRate, offersCursor} */
|
|
917
|
-
function isValidBookCursor(cursorString) {
|
|
918
|
-
const isNumericString = (value) => typeof value === "string" && /^-?\d+$/.test(value);
|
|
919
|
-
try {
|
|
920
|
-
const v = JSON.parse(Buffer.from(cursorString, "base64url").toString("utf8"));
|
|
921
|
-
return (v?.side === "buy" || v?.side === "sell") && isNumericString(v?.lastRate) && (v?.offersCursor === null || typeof v?.offersCursor === "string");
|
|
922
|
-
} catch {
|
|
923
|
-
return false;
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
const BookPaginationQueryParams = z$1.object({
|
|
927
|
-
cursor: z$1.string().optional().refine((value) => {
|
|
928
|
-
if (!value) return true;
|
|
929
|
-
return isValidBookCursor(value);
|
|
930
|
-
}, { message: "Invalid cursor format. Must be a valid base64url-encoded book cursor object" }).meta({
|
|
931
|
-
description: "Pagination cursor in base64url-encoded format for book levels",
|
|
932
|
-
example: "eyJzaWRlIjoiYnV5IiwibGFzdFJhdGUiOiIxMDAwMDAwMDAwMDAwMDAwMDAwIiwib2ZmZXJzQ3Vyc29yIjpudWxsfQ"
|
|
933
|
-
}),
|
|
934
|
-
limit: z$1.string().regex(/^[1-9]\d*$/, { message: "Limit must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).pipe(z$1.number().max(MAX_LIMIT, { message: `Limit cannot exceed ${MAX_LIMIT}` })).optional().default(DEFAULT_LIMIT).meta({
|
|
935
|
-
description: `Limit maximum: ${MAX_LIMIT}. Default: ${DEFAULT_LIMIT}`,
|
|
936
|
-
example: 10
|
|
937
|
-
})
|
|
938
|
-
});
|
|
939
|
-
const GetBookParams = z$1.object({
|
|
940
|
-
...BookPaginationQueryParams.shape,
|
|
941
|
-
obligation_id: z$1.string({ error: "Obligation id is required and must be a valid 32-byte hex string" }).regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).meta({
|
|
942
|
-
description: "Obligation id",
|
|
943
|
-
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
944
|
-
}),
|
|
945
|
-
side: z$1.enum(["buy", "sell"]).meta({
|
|
946
|
-
description: "Side of the book (buy or sell).",
|
|
947
|
-
example: "buy"
|
|
948
|
-
})
|
|
949
|
-
});
|
|
950
|
-
const schemas = {
|
|
951
|
-
get_offers: GetOffersQueryParams,
|
|
952
|
-
get_obligations: GetObligationsQueryParams,
|
|
953
|
-
get_obligation: GetObligationParams,
|
|
954
|
-
get_book: GetBookParams,
|
|
955
|
-
validate_offers: z$1.object({
|
|
956
|
-
offers: z$1.any().refine((val) => val === void 0 || Array.isArray(val), { message: "'offers' must be an array" }),
|
|
957
|
-
calldata: z$1.string().regex(/^0x[a-fA-F0-9]*$/, { message: "'calldata' must be a hex string starting with '0x'" }).optional()
|
|
958
|
-
}).superRefine((val, ctx) => {
|
|
959
|
-
const hasOffers = val.offers !== void 0;
|
|
960
|
-
const hasCalldata = val.calldata !== void 0;
|
|
961
|
-
if (hasOffers && hasCalldata) ctx.addIssue({
|
|
962
|
-
code: "custom",
|
|
963
|
-
message: "Request body must contain either 'offers' or 'calldata', not both"
|
|
964
|
-
});
|
|
965
|
-
if (!hasOffers && !hasCalldata) ctx.addIssue({
|
|
966
|
-
code: "custom",
|
|
967
|
-
message: "Request body must contain either 'offers' array or 'calldata' hex string"
|
|
968
|
-
});
|
|
969
|
-
})
|
|
970
|
-
};
|
|
971
|
-
function parse(action, query) {
|
|
972
|
-
return schemas[action].parse(query);
|
|
973
|
-
}
|
|
974
|
-
function safeParse(action, query, error) {
|
|
975
|
-
return schemas[action].safeParse(query, { error });
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
//#endregion
|
|
979
|
-
//#region src/api/Schema/index.ts
|
|
980
|
-
var Schema_exports = /* @__PURE__ */ __export({
|
|
981
|
-
BookResponse: () => BookResponse_exports,
|
|
982
|
-
BooksController: () => BooksController,
|
|
983
|
-
ChainHealth: () => ChainHealth,
|
|
984
|
-
ChainsHealthResponse: () => ChainsHealthResponse,
|
|
985
|
-
CollectorHealth: () => CollectorHealth,
|
|
986
|
-
CollectorsHealthResponse: () => CollectorsHealthResponse,
|
|
987
|
-
HealthController: () => HealthController,
|
|
988
|
-
ObligationResponse: () => ObligationResponse_exports,
|
|
989
|
-
ObligationsController: () => ObligationsController,
|
|
990
|
-
OfferResponse: () => OfferResponse_exports,
|
|
991
|
-
OffersController: () => OffersController,
|
|
992
|
-
OpenApi: () => OpenApi,
|
|
993
|
-
RouterStatusResponse: () => RouterStatusResponse,
|
|
994
|
-
ValidateController: () => ValidateController,
|
|
995
|
-
parse: () => parse,
|
|
996
|
-
safeParse: () => safeParse
|
|
997
|
-
});
|
|
998
|
-
|
|
999
|
-
//#endregion
|
|
1000
|
-
//#region src/core/Abi/MetaMorpho.ts
|
|
1001
|
-
const MetaMorpho = parseAbi([
|
|
1002
|
-
"function balanceOf(address account) view returns (uint256)",
|
|
1003
|
-
"function DECIMALS_OFFSET() view returns (uint8)",
|
|
1004
|
-
"function totalAssets() view returns (uint256)",
|
|
1005
|
-
"function totalSupply() view returns (uint256)",
|
|
1006
|
-
"function maxWithdraw(address owner) view returns (uint256 assets)",
|
|
1007
|
-
"function asset() view returns (address)",
|
|
1008
|
-
"event Transfer(address indexed from, address indexed to, uint256 value)",
|
|
1009
|
-
"function withdrawQueue(uint256 index) view returns (bytes32)",
|
|
1010
|
-
"function withdrawQueueLength() view returns (uint256)"
|
|
1011
|
-
]);
|
|
1012
|
-
|
|
1013
|
-
//#endregion
|
|
1014
|
-
//#region src/core/Abi/MetaMorphoFactory.ts
|
|
1015
|
-
const MetaMorphoFactory = parseAbi(["event CreateMetaMorpho(address indexed metaMorpho,address indexed caller,address initialOwner,uint256 initialTimelock,address indexed asset,string name,string symbol,bytes32 salt)", "function isMetaMorpho(address) view returns (bool)"]);
|
|
1016
|
-
|
|
1017
|
-
//#endregion
|
|
1018
|
-
//#region src/core/Abi/index.ts
|
|
1019
|
-
var Abi_exports = /* @__PURE__ */ __export({
|
|
1020
|
-
ERC4626: () => ERC4626,
|
|
1021
|
-
MetaMorpho: () => MetaMorpho,
|
|
1022
|
-
MetaMorphoFactory: () => MetaMorphoFactory,
|
|
1023
|
-
Morpho: () => Morpho,
|
|
1024
|
-
Oracle: () => Oracle
|
|
1025
|
-
});
|
|
1026
|
-
const Oracle = [{
|
|
1027
|
-
type: "function",
|
|
1028
|
-
name: "price",
|
|
1029
|
-
inputs: [],
|
|
1030
|
-
outputs: [{
|
|
1031
|
-
name: "",
|
|
1032
|
-
type: "uint256"
|
|
1033
|
-
}],
|
|
1034
|
-
stateMutability: "view"
|
|
1035
|
-
}];
|
|
1036
|
-
const ERC4626 = [{
|
|
1037
|
-
type: "function",
|
|
1038
|
-
name: "asset",
|
|
1039
|
-
inputs: [],
|
|
1040
|
-
outputs: [{
|
|
1041
|
-
name: "",
|
|
1042
|
-
type: "address"
|
|
1043
|
-
}],
|
|
1044
|
-
stateMutability: "view"
|
|
1045
|
-
}];
|
|
1046
|
-
const Morpho = [
|
|
1047
|
-
{
|
|
1048
|
-
type: "function",
|
|
1049
|
-
name: "collateralOf",
|
|
1050
|
-
inputs: [
|
|
1051
|
-
{
|
|
1052
|
-
name: "",
|
|
1053
|
-
type: "address",
|
|
1054
|
-
internalType: "address"
|
|
1055
|
-
},
|
|
1056
|
-
{
|
|
1057
|
-
name: "",
|
|
1058
|
-
type: "bytes32",
|
|
1059
|
-
internalType: "bytes32"
|
|
1060
|
-
},
|
|
1061
|
-
{
|
|
1062
|
-
name: "",
|
|
1063
|
-
type: "address",
|
|
1064
|
-
internalType: "address"
|
|
1065
|
-
}
|
|
1066
|
-
],
|
|
1067
|
-
outputs: [{
|
|
1068
|
-
name: "",
|
|
1069
|
-
type: "uint256",
|
|
1070
|
-
internalType: "uint256"
|
|
1071
|
-
}],
|
|
1072
|
-
stateMutability: "view"
|
|
118
|
+
stateMutability: "view"
|
|
119
|
+
}];
|
|
120
|
+
const ERC4626 = [{
|
|
121
|
+
type: "function",
|
|
122
|
+
name: "asset",
|
|
123
|
+
inputs: [],
|
|
124
|
+
outputs: [{
|
|
125
|
+
name: "",
|
|
126
|
+
type: "address"
|
|
127
|
+
}],
|
|
128
|
+
stateMutability: "view"
|
|
129
|
+
}];
|
|
130
|
+
const Morpho = [
|
|
131
|
+
{
|
|
132
|
+
type: "function",
|
|
133
|
+
name: "collateralOf",
|
|
134
|
+
inputs: [
|
|
135
|
+
{
|
|
136
|
+
name: "",
|
|
137
|
+
type: "address",
|
|
138
|
+
internalType: "address"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "",
|
|
142
|
+
type: "bytes32",
|
|
143
|
+
internalType: "bytes32"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: "",
|
|
147
|
+
type: "address",
|
|
148
|
+
internalType: "address"
|
|
149
|
+
}
|
|
150
|
+
],
|
|
151
|
+
outputs: [{
|
|
152
|
+
name: "",
|
|
153
|
+
type: "uint256",
|
|
154
|
+
internalType: "uint256"
|
|
155
|
+
}],
|
|
156
|
+
stateMutability: "view"
|
|
1073
157
|
},
|
|
1074
158
|
{
|
|
1075
159
|
type: "function",
|
|
@@ -1193,8 +277,12 @@ function decode$2(type, data) {
|
|
|
1193
277
|
}
|
|
1194
278
|
function encode$2(type, data) {
|
|
1195
279
|
switch (type) {
|
|
1196
|
-
case CallbackType.BuyVaultV1Callback:
|
|
1197
|
-
|
|
280
|
+
case CallbackType.BuyVaultV1Callback:
|
|
281
|
+
if (!("vaults" in data)) throw new Error("Invalid callback data");
|
|
282
|
+
return encodeBuyVaultV1Callback(data);
|
|
283
|
+
case CallbackType.SellERC20Callback:
|
|
284
|
+
if (!("collaterals" in data)) throw new Error("Invalid callback data");
|
|
285
|
+
return encodeSellERC20Callback(data);
|
|
1198
286
|
default: throw new Error("Invalid callback type");
|
|
1199
287
|
}
|
|
1200
288
|
}
|
|
@@ -1239,6 +327,19 @@ function max$1(a, b) {
|
|
|
1239
327
|
function min(a, b) {
|
|
1240
328
|
return a < b ? a : b;
|
|
1241
329
|
}
|
|
330
|
+
/**
|
|
331
|
+
* Checks if at most one of the given values is non-zero.
|
|
332
|
+
* @param values - The bigint values to check.
|
|
333
|
+
* @returns True if zero or one value is non-zero, false if two or more are non-zero.
|
|
334
|
+
*/
|
|
335
|
+
function atMostOneNonZero(...values) {
|
|
336
|
+
let nonZeroCount = 0;
|
|
337
|
+
for (const value of values) if (value !== 0n) {
|
|
338
|
+
nonZeroCount++;
|
|
339
|
+
if (nonZeroCount > 1) return false;
|
|
340
|
+
}
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
1242
343
|
|
|
1243
344
|
//#endregion
|
|
1244
345
|
//#region src/utils/batch.ts
|
|
@@ -1522,22 +623,22 @@ const DEFAULT_BATCH_SIZE$1 = 2500;
|
|
|
1522
623
|
const MAX_BLOCK_WINDOW = 1e4;
|
|
1523
624
|
const DEFAULT_BLOCK_WINDOW = 8e3;
|
|
1524
625
|
async function* streamLogs(parameters) {
|
|
1525
|
-
const { client, contractAddress, event, blockNumberGte, blockNumberLte, order
|
|
626
|
+
const { client, contractAddress, event, blockNumberGte, blockNumberLte, order = "desc", options: { maxBatchSize = DEFAULT_BATCH_SIZE$1, blockWindow = DEFAULT_BLOCK_WINDOW } = {} } = parameters;
|
|
1526
627
|
if (maxBatchSize > MAX_BATCH_SIZE) throw new InvalidBatchSizeError(maxBatchSize);
|
|
1527
628
|
if (blockWindow > MAX_BLOCK_WINDOW) throw new InvalidBlockWindowError(blockWindow);
|
|
1528
|
-
if (order
|
|
629
|
+
if (order === "asc" && blockNumberGte === void 0) throw new MissingBlockNumberError();
|
|
1529
630
|
const latestBlock = (await getBlock(client, {
|
|
1530
631
|
blockTag: "latest",
|
|
1531
632
|
includeTransactions: false
|
|
1532
633
|
})).number;
|
|
1533
634
|
let toBlock = 0n;
|
|
1534
|
-
if (order
|
|
1535
|
-
if (order
|
|
635
|
+
if (order === "asc") toBlock = min(BigInt(blockNumberGte) + BigInt(blockWindow), blockNumberLte ? BigInt(blockNumberLte) : latestBlock);
|
|
636
|
+
if (order === "desc") toBlock = blockNumberLte === void 0 ? latestBlock : min(BigInt(blockNumberLte), latestBlock);
|
|
1536
637
|
let fromBlock = 0n;
|
|
1537
|
-
if (order
|
|
1538
|
-
if (order
|
|
1539
|
-
if (order
|
|
1540
|
-
if (order
|
|
638
|
+
if (order === "asc") fromBlock = min(BigInt(blockNumberGte), latestBlock);
|
|
639
|
+
if (order === "desc") fromBlock = max$1(BigInt(blockNumberGte || toBlock - BigInt(blockWindow)), 0n);
|
|
640
|
+
if (order === "asc") toBlock = min(toBlock, fromBlock + BigInt(blockWindow));
|
|
641
|
+
if (order === "desc") fromBlock = max$1(fromBlock, toBlock - BigInt(blockWindow));
|
|
1541
642
|
if (fromBlock > toBlock) throw new InvalidBlockRangeError(fromBlock, toBlock);
|
|
1542
643
|
let streaming = true;
|
|
1543
644
|
while (streaming) {
|
|
@@ -1547,29 +648,29 @@ async function* streamLogs(parameters) {
|
|
|
1547
648
|
fromBlock,
|
|
1548
649
|
toBlock
|
|
1549
650
|
});
|
|
1550
|
-
streaming = order
|
|
651
|
+
streaming = order === "asc" ? toBlock < (blockNumberLte || latestBlock) : fromBlock > (blockNumberGte || 0n);
|
|
1551
652
|
if (logs.length === 0 && !streaming) break;
|
|
1552
653
|
if (logs.length === 0 && streaming) yield {
|
|
1553
654
|
logs: [],
|
|
1554
|
-
blockNumber: order
|
|
655
|
+
blockNumber: order === "asc" ? Number(toBlock) : Number(fromBlock)
|
|
1555
656
|
};
|
|
1556
657
|
logs.sort((a, b) => {
|
|
1557
|
-
if (a.blockNumber !== b.blockNumber) return order
|
|
1558
|
-
if (a.transactionIndex !== b.transactionIndex) return order
|
|
1559
|
-
return order
|
|
658
|
+
if (a.blockNumber !== b.blockNumber) return order === "asc" ? Number(a.blockNumber - b.blockNumber) : Number(b.blockNumber - a.blockNumber);
|
|
659
|
+
if (a.transactionIndex !== b.transactionIndex) return order === "asc" ? a.transactionIndex - b.transactionIndex : b.transactionIndex - a.transactionIndex;
|
|
660
|
+
return order === "asc" ? a.logIndex - b.logIndex : b.logIndex - a.logIndex;
|
|
1560
661
|
});
|
|
1561
662
|
for (const logBatch of batch(logs, maxBatchSize)) yield {
|
|
1562
663
|
logs: logBatch,
|
|
1563
|
-
blockNumber: logBatch.length === maxBatchSize ? Number(logBatch[logBatch.length - 1]?.blockNumber) : order
|
|
664
|
+
blockNumber: logBatch.length === maxBatchSize ? Number(logBatch[logBatch.length - 1]?.blockNumber) : order === "asc" ? Number(toBlock) : Number(fromBlock)
|
|
1564
665
|
};
|
|
1565
|
-
if (order
|
|
666
|
+
if (order === "asc") {
|
|
1566
667
|
const upperBound = BigInt(blockNumberLte || latestBlock);
|
|
1567
668
|
const nextFromBlock = min(BigInt(toBlock) + 1n, upperBound);
|
|
1568
669
|
const nextToBlock = min(toBlock + BigInt(blockWindow) + 1n, upperBound);
|
|
1569
670
|
fromBlock = nextFromBlock;
|
|
1570
671
|
toBlock = nextToBlock;
|
|
1571
672
|
}
|
|
1572
|
-
if (order
|
|
673
|
+
if (order === "desc") {
|
|
1573
674
|
const lowerBound = BigInt(blockNumberGte || 0);
|
|
1574
675
|
const nextToBlock = max$1(fromBlock - 1n, lowerBound);
|
|
1575
676
|
const nextFromBlock = max$1(fromBlock - BigInt(blockWindow) - 1n, lowerBound);
|
|
@@ -1579,7 +680,7 @@ async function* streamLogs(parameters) {
|
|
|
1579
680
|
}
|
|
1580
681
|
yield {
|
|
1581
682
|
logs: [],
|
|
1582
|
-
blockNumber: order
|
|
683
|
+
blockNumber: order === "asc" ? Number(toBlock) : Number(fromBlock)
|
|
1583
684
|
};
|
|
1584
685
|
}
|
|
1585
686
|
var InvalidBlockRangeError = class extends BaseError {
|
|
@@ -1607,25 +708,185 @@ var MissingBlockNumberError = class extends BaseError {
|
|
|
1607
708
|
}
|
|
1608
709
|
};
|
|
1609
710
|
|
|
711
|
+
//#endregion
|
|
712
|
+
//#region src/core/ChainRegistry.ts
|
|
713
|
+
var ChainRegistry_exports = /* @__PURE__ */ __export({ create: () => create$1 });
|
|
714
|
+
function create$1(chains$2) {
|
|
715
|
+
const byId = /* @__PURE__ */ new Map();
|
|
716
|
+
for (const chain of chains$2) byId.set(chain.id, chain);
|
|
717
|
+
return {
|
|
718
|
+
getById: (chainId) => byId.get(chainId),
|
|
719
|
+
list: () => Array.from(byId.values())
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
//#endregion
|
|
724
|
+
//#region src/utils/Random.ts
|
|
725
|
+
var Random_exports = /* @__PURE__ */ __export({
|
|
726
|
+
address: () => address,
|
|
727
|
+
bool: () => bool,
|
|
728
|
+
bytes: () => bytes,
|
|
729
|
+
float: () => float,
|
|
730
|
+
hex: () => hex,
|
|
731
|
+
int: () => int,
|
|
732
|
+
seed: () => seed,
|
|
733
|
+
withSeed: () => withSeed
|
|
734
|
+
});
|
|
735
|
+
let currentRng = Math.random;
|
|
736
|
+
const FNV_OFFSET_BASIS = 2166136261;
|
|
737
|
+
const FNV_PRIME = 16777619;
|
|
738
|
+
const hashSeed = (seed$1) => {
|
|
739
|
+
let hash$1 = FNV_OFFSET_BASIS;
|
|
740
|
+
for (let i = 0; i < seed$1.length; i += 1) {
|
|
741
|
+
hash$1 ^= seed$1.charCodeAt(i);
|
|
742
|
+
hash$1 = Math.imul(hash$1, FNV_PRIME);
|
|
743
|
+
}
|
|
744
|
+
return hash$1 >>> 0;
|
|
745
|
+
};
|
|
746
|
+
const createSeededRng = (seed$1) => {
|
|
747
|
+
let state = hashSeed(seed$1);
|
|
748
|
+
return () => {
|
|
749
|
+
state += 1831565813;
|
|
750
|
+
let t = Math.imul(state ^ state >>> 15, state | 1);
|
|
751
|
+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
752
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
753
|
+
};
|
|
754
|
+
};
|
|
755
|
+
/**
|
|
756
|
+
* Runs a function with a deterministic RNG derived from the given seed.
|
|
757
|
+
*/
|
|
758
|
+
function withSeed(seed$1, fn) {
|
|
759
|
+
const previous = currentRng;
|
|
760
|
+
currentRng = createSeededRng(seed$1);
|
|
761
|
+
try {
|
|
762
|
+
return fn();
|
|
763
|
+
} finally {
|
|
764
|
+
currentRng = previous;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Seeds the global RNG for deterministic test runs.
|
|
769
|
+
*/
|
|
770
|
+
function seed(seed$1) {
|
|
771
|
+
currentRng = createSeededRng(seed$1);
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Returns a deterministic random float in [0, 1).
|
|
775
|
+
*/
|
|
776
|
+
function float() {
|
|
777
|
+
return currentRng();
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* Returns a deterministic random integer in [min, maxExclusive).
|
|
781
|
+
*/
|
|
782
|
+
function int(maxExclusive, min$1 = 0) {
|
|
783
|
+
return Math.floor(float() * (maxExclusive - min$1)) + min$1;
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* Returns a deterministic random boolean.
|
|
787
|
+
*/
|
|
788
|
+
function bool(probability = .5) {
|
|
789
|
+
return float() < probability;
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Returns deterministic random bytes.
|
|
793
|
+
*/
|
|
794
|
+
function bytes(length) {
|
|
795
|
+
const output = new Uint8Array(length);
|
|
796
|
+
for (let i = 0; i < length; i += 1) output[i] = int(256);
|
|
797
|
+
return output;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Returns a deterministic random hex string for the given byte length.
|
|
801
|
+
*/
|
|
802
|
+
function hex(byteLength) {
|
|
803
|
+
const output = bytes(byteLength);
|
|
804
|
+
return `0x${Array.from(output, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* Returns a deterministic random address.
|
|
808
|
+
*/
|
|
809
|
+
function address() {
|
|
810
|
+
return hex(20);
|
|
811
|
+
}
|
|
812
|
+
|
|
1610
813
|
//#endregion
|
|
1611
814
|
//#region src/utils/zod.ts
|
|
815
|
+
/**
|
|
816
|
+
* Converts a hex string to a padded bytes32.
|
|
817
|
+
* Returns null if the value is not a valid hex string.
|
|
818
|
+
*/
|
|
819
|
+
const hexToBytes32 = (val) => {
|
|
820
|
+
if (!isHex(val)) return null;
|
|
821
|
+
return pad(val, { size: 32 });
|
|
822
|
+
};
|
|
823
|
+
/**
|
|
824
|
+
* Converts a numeric string to a padded bytes32.
|
|
825
|
+
* @throws {Error} If parsing fails or value is negative.
|
|
826
|
+
*/
|
|
827
|
+
const numericStringToBytes32 = (val) => {
|
|
828
|
+
const num = BigInt(val);
|
|
829
|
+
if (num < 0n) throw new Error("expected bigint to be >=0");
|
|
830
|
+
return pad(numberToHex(num), { size: 32 });
|
|
831
|
+
};
|
|
832
|
+
/**
|
|
833
|
+
* Converts a number or bigint to a padded bytes32.
|
|
834
|
+
* @throws {Error} If value is negative.
|
|
835
|
+
*/
|
|
836
|
+
const numericToBytes32 = (val) => {
|
|
837
|
+
const num = BigInt(val);
|
|
838
|
+
if (num < 0n) throw new Error("expected bigint to be >=0");
|
|
839
|
+
return pad(numberToHex(num), { size: 32 });
|
|
840
|
+
};
|
|
841
|
+
/**
|
|
842
|
+
* Transforms a value to a bytes32 hex string.
|
|
843
|
+
* Accepts:
|
|
844
|
+
* - Hex strings (0x...) - pads to 32 bytes if needed
|
|
845
|
+
* - Numeric strings - converts to padded hex
|
|
846
|
+
* - Numbers/bigints - converts to padded hex (must be non-negative)
|
|
847
|
+
*/
|
|
848
|
+
const transformBytes32 = (val, ctx) => {
|
|
849
|
+
if (typeof val === "string") {
|
|
850
|
+
const hexResult = hexToBytes32(val);
|
|
851
|
+
if (hexResult !== null) return hexResult;
|
|
852
|
+
try {
|
|
853
|
+
return numericStringToBytes32(val);
|
|
854
|
+
} catch (error) {
|
|
855
|
+
ctx.addIssue({
|
|
856
|
+
code: z$1.ZodIssueCode.custom,
|
|
857
|
+
message: `Not a valid bytes32 value: ${error instanceof Error ? error.message : String(error)}`
|
|
858
|
+
});
|
|
859
|
+
return z$1.NEVER;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
if (typeof val === "number" || typeof val === "bigint") try {
|
|
863
|
+
return numericToBytes32(val);
|
|
864
|
+
} catch (error) {
|
|
865
|
+
ctx.addIssue({
|
|
866
|
+
code: z$1.ZodIssueCode.custom,
|
|
867
|
+
message: `Too small: ${error instanceof Error ? error.message : String(error)}`
|
|
868
|
+
});
|
|
869
|
+
return z$1.NEVER;
|
|
870
|
+
}
|
|
871
|
+
ctx.addIssue({
|
|
872
|
+
code: z$1.ZodIssueCode.custom,
|
|
873
|
+
message: "Not a valid bytes32 value"
|
|
874
|
+
});
|
|
875
|
+
return z$1.NEVER;
|
|
876
|
+
};
|
|
1612
877
|
const transformHex = (val, ctx) => {
|
|
1613
878
|
if (isHex(val)) return val;
|
|
1614
879
|
ctx.addIssue({
|
|
1615
|
-
code:
|
|
1616
|
-
|
|
1617
|
-
format: "hex",
|
|
1618
|
-
error: "not a hex"
|
|
880
|
+
code: z$1.ZodIssueCode.custom,
|
|
881
|
+
message: "Invalid hex"
|
|
1619
882
|
});
|
|
1620
883
|
return z$1.NEVER;
|
|
1621
884
|
};
|
|
1622
885
|
const transformAddress = (val, ctx) => {
|
|
1623
886
|
if (isAddress(val.toLowerCase())) return val.toLowerCase();
|
|
1624
887
|
ctx.addIssue({
|
|
1625
|
-
code:
|
|
1626
|
-
|
|
1627
|
-
format: "address",
|
|
1628
|
-
error: "not a valid address"
|
|
888
|
+
code: z$1.ZodIssueCode.custom,
|
|
889
|
+
message: "Invalid address"
|
|
1629
890
|
});
|
|
1630
891
|
return z$1.NEVER;
|
|
1631
892
|
};
|
|
@@ -1637,7 +898,7 @@ var LLTV_exports = /* @__PURE__ */ __export({
|
|
|
1637
898
|
InvalidOptionError: () => InvalidOptionError$1,
|
|
1638
899
|
LLTVSchema: () => LLTVSchema,
|
|
1639
900
|
Options: () => Options,
|
|
1640
|
-
from: () => from$
|
|
901
|
+
from: () => from$12
|
|
1641
902
|
});
|
|
1642
903
|
const Options = [
|
|
1643
904
|
.385,
|
|
@@ -1656,7 +917,7 @@ const LLTV_SCALED = Options.map((lltv) => BigInt(lltv * 10 ** 18));
|
|
|
1656
917
|
* @param lltv - The LLTV option or the scaled LLTV.
|
|
1657
918
|
* @returns The LLTV.
|
|
1658
919
|
*/
|
|
1659
|
-
function from$
|
|
920
|
+
function from$12(lltv) {
|
|
1660
921
|
if (typeof lltv === "bigint" && !LLTV_SCALED.includes(lltv)) throw new InvalidLLTVError(lltv);
|
|
1661
922
|
if (typeof lltv === "bigint") return lltv;
|
|
1662
923
|
if (typeof lltv === "number" && !Options.includes(lltv)) throw new InvalidOptionError$1(lltv);
|
|
@@ -1676,21 +937,21 @@ var InvalidLLTVError = class extends BaseError {
|
|
|
1676
937
|
};
|
|
1677
938
|
const LLTVSchema = z$1.bigint({ coerce: true }).refine((lltv) => {
|
|
1678
939
|
try {
|
|
1679
|
-
from$
|
|
940
|
+
from$12(lltv);
|
|
1680
941
|
return true;
|
|
1681
942
|
} catch (_) {
|
|
1682
943
|
return false;
|
|
1683
944
|
}
|
|
1684
945
|
}, { error: () => {
|
|
1685
946
|
return "Invalid LLTV: must be one of 0.385, 0.625, 0.77, 0.86, 0.915, 0.945, 0.965 or 0.98 (scaled by 1e18)";
|
|
1686
|
-
} }).transform((lltv) => from$
|
|
947
|
+
} }).transform((lltv) => from$12(lltv));
|
|
1687
948
|
|
|
1688
949
|
//#endregion
|
|
1689
950
|
//#region src/core/Collateral.ts
|
|
1690
951
|
var Collateral_exports = /* @__PURE__ */ __export({
|
|
1691
952
|
CollateralSchema: () => CollateralSchema,
|
|
1692
953
|
CollateralsSchema: () => CollateralsSchema,
|
|
1693
|
-
from: () => from$
|
|
954
|
+
from: () => from$11,
|
|
1694
955
|
random: () => random$3
|
|
1695
956
|
});
|
|
1696
957
|
const CollateralSchema = z$1.object({
|
|
@@ -1710,10 +971,10 @@ const CollateralsSchema = z$1.array(CollateralSchema).min(1, { message: "At leas
|
|
|
1710
971
|
}
|
|
1711
972
|
return true;
|
|
1712
973
|
}, { message: "Collaterals must not contain duplicate assets" });
|
|
1713
|
-
const from$
|
|
974
|
+
const from$11 = (parameters) => {
|
|
1714
975
|
return {
|
|
1715
976
|
asset: parameters.asset.toLowerCase(),
|
|
1716
|
-
lltv: from$
|
|
977
|
+
lltv: from$12(parameters.lltv),
|
|
1717
978
|
oracle: parameters.oracle.toLowerCase()
|
|
1718
979
|
};
|
|
1719
980
|
};
|
|
@@ -1727,9 +988,9 @@ const from$9 = (parameters) => {
|
|
|
1727
988
|
* ```
|
|
1728
989
|
*/
|
|
1729
990
|
function random$3() {
|
|
1730
|
-
return from$
|
|
1731
|
-
asset:
|
|
1732
|
-
oracle:
|
|
991
|
+
return from$11({
|
|
992
|
+
asset: address(),
|
|
993
|
+
oracle: address(),
|
|
1733
994
|
lltv: .965
|
|
1734
995
|
});
|
|
1735
996
|
}
|
|
@@ -1896,11 +1157,11 @@ var Maturity_exports = /* @__PURE__ */ __export({
|
|
|
1896
1157
|
InvalidOptionError: () => InvalidOptionError,
|
|
1897
1158
|
MaturitySchema: () => MaturitySchema,
|
|
1898
1159
|
MaturityType: () => MaturityType,
|
|
1899
|
-
from: () => from$
|
|
1160
|
+
from: () => from$10
|
|
1900
1161
|
});
|
|
1901
1162
|
const MaturitySchema = z$1.number().int().refine((maturity$1) => {
|
|
1902
1163
|
try {
|
|
1903
|
-
from$
|
|
1164
|
+
from$10(maturity$1);
|
|
1904
1165
|
return true;
|
|
1905
1166
|
} catch (_e) {
|
|
1906
1167
|
return false;
|
|
@@ -1935,7 +1196,7 @@ const MaturityOptions = {
|
|
|
1935
1196
|
* @throws {InvalidDateError} If the maturity is in seconds but not a valid date.
|
|
1936
1197
|
* @throws {InvalidOptionError} If the maturity is not a valid option.
|
|
1937
1198
|
*/
|
|
1938
|
-
function from$
|
|
1199
|
+
function from$10(ts) {
|
|
1939
1200
|
if (typeof ts === "string") {
|
|
1940
1201
|
if (ts in MaturityOptions) return MaturityOptions[ts]();
|
|
1941
1202
|
throw new InvalidOptionError(ts);
|
|
@@ -2014,13 +1275,58 @@ var InvalidOptionError = class extends BaseError {
|
|
|
2014
1275
|
}
|
|
2015
1276
|
};
|
|
2016
1277
|
|
|
1278
|
+
//#endregion
|
|
1279
|
+
//#region src/utils/Format.ts
|
|
1280
|
+
var Format_exports = /* @__PURE__ */ __export({
|
|
1281
|
+
fromSnakeCase: () => fromSnakeCase$3,
|
|
1282
|
+
stringifyBigint: () => stringifyBigint,
|
|
1283
|
+
toSnakeCase: () => toSnakeCase$1
|
|
1284
|
+
});
|
|
1285
|
+
/**
|
|
1286
|
+
* Formats object keys to snake case.
|
|
1287
|
+
* Preserves ethereum addresses as is.
|
|
1288
|
+
* Converts ethereum addresses to checksummed if used as values.
|
|
1289
|
+
* Stringifies bigint values to strings.
|
|
1290
|
+
*/
|
|
1291
|
+
function toSnakeCase$1(obj) {
|
|
1292
|
+
return stringifyBigint(processObject(obj, (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`), (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? getAddress(value.toLowerCase()) : value));
|
|
1293
|
+
}
|
|
1294
|
+
/**
|
|
1295
|
+
* Formats a snake case object to its camel case type.
|
|
1296
|
+
* Preserves ethereum addresses as is.
|
|
1297
|
+
* Converts checksummed ethereum addresses to lowercase if used as values.
|
|
1298
|
+
* @warning Does not unstringify bigint values.
|
|
1299
|
+
*/
|
|
1300
|
+
function fromSnakeCase$3(obj) {
|
|
1301
|
+
return processObject(obj, (s) => isAddress(s.toLowerCase()) ? s : s.replace(/_([a-z])/g, (_, c) => c.toUpperCase()), (value) => typeof value === "string" && isAddress(value.toLowerCase()) ? value.toLowerCase() : value);
|
|
1302
|
+
}
|
|
1303
|
+
function processObject(obj, fnKey, fnValue) {
|
|
1304
|
+
if (typeof obj !== "object" || obj === null) return obj;
|
|
1305
|
+
if (Array.isArray(obj)) return obj.map((item) => processObject(item, fnKey, fnValue));
|
|
1306
|
+
return Object.entries(obj).reduce((acc, [key, value]) => {
|
|
1307
|
+
const newKey = fnKey(key);
|
|
1308
|
+
acc[newKey] = typeof value === "object" && value !== null ? processObject(value, fnKey, fnValue) : fnValue(value);
|
|
1309
|
+
return acc;
|
|
1310
|
+
}, {});
|
|
1311
|
+
}
|
|
1312
|
+
function stringifyBigint(value) {
|
|
1313
|
+
if (typeof value === "bigint") return value.toString();
|
|
1314
|
+
if (Array.isArray(value)) return value.map(stringifyBigint);
|
|
1315
|
+
if (value && typeof value === "object") {
|
|
1316
|
+
const out = {};
|
|
1317
|
+
for (const [k, v] of Object.entries(value)) out[k] = stringifyBigint(v);
|
|
1318
|
+
return out;
|
|
1319
|
+
}
|
|
1320
|
+
return value;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
2017
1323
|
//#endregion
|
|
2018
1324
|
//#region src/core/Obligation.ts
|
|
2019
1325
|
var Obligation_exports = /* @__PURE__ */ __export({
|
|
2020
1326
|
CollateralsAreNotSortedError: () => CollateralsAreNotSortedError,
|
|
2021
1327
|
InvalidObligationError: () => InvalidObligationError,
|
|
2022
1328
|
ObligationSchema: () => ObligationSchema,
|
|
2023
|
-
from: () => from$
|
|
1329
|
+
from: () => from$9,
|
|
2024
1330
|
fromSnakeCase: () => fromSnakeCase$2,
|
|
2025
1331
|
id: () => id,
|
|
2026
1332
|
random: () => random$2
|
|
@@ -2054,11 +1360,11 @@ const ObligationSchema = z$1.object({
|
|
|
2054
1360
|
* });
|
|
2055
1361
|
* ```
|
|
2056
1362
|
*/
|
|
2057
|
-
function from$
|
|
1363
|
+
function from$9(parameters) {
|
|
2058
1364
|
try {
|
|
2059
1365
|
const parsedObligation = ObligationSchema.parse({
|
|
2060
1366
|
...parameters,
|
|
2061
|
-
maturity: from$
|
|
1367
|
+
maturity: from$10(parameters.maturity)
|
|
2062
1368
|
});
|
|
2063
1369
|
return {
|
|
2064
1370
|
chainId: parsedObligation.chainId,
|
|
@@ -2077,13 +1383,13 @@ function from$7(parameters) {
|
|
|
2077
1383
|
* @returns The created obligation. {@link fromSnakeCase.ReturnType}
|
|
2078
1384
|
*/
|
|
2079
1385
|
function fromSnakeCase$2(input) {
|
|
2080
|
-
return from$
|
|
1386
|
+
return from$9(fromSnakeCase$3(input));
|
|
2081
1387
|
}
|
|
2082
1388
|
/**
|
|
2083
1389
|
* Calculates the obligation id based on the smart contract's Obligation struct.
|
|
2084
1390
|
* The id is computed as keccak256(abi.encode(chainId, loanToken, collaterals, maturity)).
|
|
2085
1391
|
* @throws If the collaterals are not sorted alphabetically by address. {@link CollateralsAreNotSortedError}
|
|
2086
|
-
* @param
|
|
1392
|
+
* @param parameters - {@link id.Parameters}
|
|
2087
1393
|
* @returns The obligation id as a 32-byte hex string. {@link id.ReturnType}
|
|
2088
1394
|
*
|
|
2089
1395
|
* @example
|
|
@@ -2093,9 +1399,9 @@ function fromSnakeCase$2(input) {
|
|
|
2093
1399
|
* console.log(id); // 0x1234567890123456789012345678901234567890123456789012345678901234
|
|
2094
1400
|
* ```
|
|
2095
1401
|
*/
|
|
2096
|
-
function id(
|
|
1402
|
+
function id(parameters) {
|
|
2097
1403
|
let lastAsset = "";
|
|
2098
|
-
for (const collateral of
|
|
1404
|
+
for (const collateral of parameters.collaterals) {
|
|
2099
1405
|
const newAsset = collateral.asset.toLowerCase();
|
|
2100
1406
|
if (newAsset.localeCompare(lastAsset) < 0) throw new CollateralsAreNotSortedError();
|
|
2101
1407
|
lastAsset = newAsset;
|
|
@@ -2122,14 +1428,14 @@ function id(obligation) {
|
|
|
2122
1428
|
},
|
|
2123
1429
|
{ type: "uint256" }
|
|
2124
1430
|
], [
|
|
2125
|
-
BigInt(
|
|
2126
|
-
|
|
2127
|
-
|
|
1431
|
+
BigInt(parameters.chainId),
|
|
1432
|
+
parameters.loanToken.toLowerCase(),
|
|
1433
|
+
parameters.collaterals.map((c) => ({
|
|
2128
1434
|
token: c.asset.toLowerCase(),
|
|
2129
1435
|
lltv: c.lltv,
|
|
2130
1436
|
oracle: c.oracle.toLowerCase()
|
|
2131
1437
|
})),
|
|
2132
|
-
BigInt(
|
|
1438
|
+
BigInt(parameters.maturity)
|
|
2133
1439
|
]));
|
|
2134
1440
|
}
|
|
2135
1441
|
/**
|
|
@@ -2142,15 +1448,11 @@ function id(obligation) {
|
|
|
2142
1448
|
* ```
|
|
2143
1449
|
*/
|
|
2144
1450
|
function random$2() {
|
|
2145
|
-
return from$
|
|
1451
|
+
return from$9({
|
|
2146
1452
|
chainId: 1,
|
|
2147
|
-
loanToken:
|
|
2148
|
-
collaterals: [
|
|
2149
|
-
|
|
2150
|
-
oracle: privateKeyToAccount(generatePrivateKey()).address,
|
|
2151
|
-
lltv: .965
|
|
2152
|
-
})],
|
|
2153
|
-
maturity: from$8("end_of_next_quarter")
|
|
1453
|
+
loanToken: address(),
|
|
1454
|
+
collaterals: [random$3()],
|
|
1455
|
+
maturity: from$10("end_of_next_quarter")
|
|
2154
1456
|
});
|
|
2155
1457
|
}
|
|
2156
1458
|
var InvalidObligationError = class extends BaseError {
|
|
@@ -2169,101 +1471,249 @@ var CollateralsAreNotSortedError = class extends BaseError {
|
|
|
2169
1471
|
//#endregion
|
|
2170
1472
|
//#region src/core/Tree.ts
|
|
2171
1473
|
var Tree_exports = /* @__PURE__ */ __export({
|
|
1474
|
+
DecodeError: () => DecodeError,
|
|
1475
|
+
EncodeError: () => EncodeError,
|
|
1476
|
+
TreeError: () => TreeError,
|
|
2172
1477
|
VERSION: () => VERSION,
|
|
2173
1478
|
decode: () => decode$1,
|
|
2174
1479
|
encode: () => encode$1,
|
|
2175
|
-
|
|
1480
|
+
encodeUnsigned: () => encodeUnsigned,
|
|
1481
|
+
from: () => from$8,
|
|
1482
|
+
proofs: () => proofs
|
|
2176
1483
|
});
|
|
2177
1484
|
const VERSION = 1;
|
|
1485
|
+
const normalizeHash = (hash$1) => hash$1.toLowerCase();
|
|
2178
1486
|
/**
|
|
2179
1487
|
* Builds a Merkle tree from a list of offers.
|
|
2180
1488
|
*
|
|
2181
1489
|
* Leaves are the offer `hash` values as `bytes32` and are deterministically
|
|
2182
|
-
* ordered
|
|
2183
|
-
* regardless of the input order.
|
|
1490
|
+
* ordered following the StandardMerkleTree leaf ordering so that the resulting
|
|
1491
|
+
* root is stable regardless of the input order.
|
|
2184
1492
|
*
|
|
2185
1493
|
* @param offers - Offers to include in the tree.
|
|
2186
1494
|
* @returns A `StandardMerkleTree` of `bytes32` leaves representing the offers.
|
|
1495
|
+
* @throws {TreeError} If tree building fails due to offer inconsistencies.
|
|
2187
1496
|
*/
|
|
2188
|
-
const from$
|
|
2189
|
-
const leaves =
|
|
2190
|
-
return [offer.hash];
|
|
2191
|
-
});
|
|
1497
|
+
const from$8 = (offers) => {
|
|
1498
|
+
const leaves = offers.map((offer) => [hash(offer)]);
|
|
2192
1499
|
const tree = StandardMerkleTree.of(leaves, ["bytes32"]);
|
|
2193
|
-
|
|
1500
|
+
const orderedOffers = orderOffers(tree, offers);
|
|
1501
|
+
return Object.assign(tree, { offers: orderedOffers });
|
|
2194
1502
|
};
|
|
2195
|
-
const
|
|
2196
|
-
const
|
|
2197
|
-
|
|
1503
|
+
const orderOffers = (tree, offers) => {
|
|
1504
|
+
const offerByHash = /* @__PURE__ */ new Map();
|
|
1505
|
+
for (const offer of offers) offerByHash.set(normalizeHash(hash(offer)), offer);
|
|
1506
|
+
const entries = tree.dump().values.map((value) => {
|
|
1507
|
+
const hash$1 = normalizeHash(value.value[0]);
|
|
1508
|
+
const offer = offerByHash.get(hash$1);
|
|
1509
|
+
if (!offer) throw new TreeError(`missing offer for leaf ${hash$1}`);
|
|
1510
|
+
return {
|
|
1511
|
+
offer,
|
|
1512
|
+
treeIndex: value.treeIndex
|
|
1513
|
+
};
|
|
1514
|
+
});
|
|
1515
|
+
entries.sort((a, b) => b.treeIndex - a.treeIndex);
|
|
1516
|
+
return entries.map((item) => item.offer);
|
|
2198
1517
|
};
|
|
2199
1518
|
/**
|
|
2200
|
-
*
|
|
1519
|
+
* Generates merkle proofs for all offers in a tree.
|
|
2201
1520
|
*
|
|
2202
|
-
*
|
|
2203
|
-
*
|
|
1521
|
+
* Each proof allows independent verification that an offer is included in the tree
|
|
1522
|
+
* without requiring the full tree. Proofs are ordered by StandardMerkleTree leaf ordering.
|
|
2204
1523
|
*
|
|
2205
|
-
* @param tree - The
|
|
2206
|
-
* @returns
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
1524
|
+
* @param tree - The {@link Tree} to generate proofs for.
|
|
1525
|
+
* @returns Array of proofs - {@link Proof}
|
|
1526
|
+
*/
|
|
1527
|
+
const proofs = (tree) => {
|
|
1528
|
+
return tree.offers.map((offer) => {
|
|
1529
|
+
return {
|
|
1530
|
+
offer,
|
|
1531
|
+
path: tree.getProof([hash(offer)])
|
|
1532
|
+
};
|
|
1533
|
+
});
|
|
1534
|
+
};
|
|
1535
|
+
const assertHex = (value, expectedBytes, name) => {
|
|
1536
|
+
if (typeof value !== "string" || !isHex(value)) throw new DecodeError(`${name} is not a valid hex string`);
|
|
1537
|
+
if (hexToBytes(value).length !== expectedBytes) throw new DecodeError(`${name}: expected ${expectedBytes} bytes`);
|
|
1538
|
+
};
|
|
1539
|
+
const verifySignatureAndRecoverAddress = async (params) => {
|
|
1540
|
+
const { root, signature } = params;
|
|
1541
|
+
assertHex(signature, 65, "signature");
|
|
1542
|
+
const hash$1 = hashMessage({ raw: root });
|
|
1543
|
+
try {
|
|
1544
|
+
return await recoverAddress({
|
|
1545
|
+
hash: hash$1,
|
|
1546
|
+
signature
|
|
1547
|
+
});
|
|
1548
|
+
} catch {
|
|
1549
|
+
throw new DecodeError("signature recovery failed");
|
|
1550
|
+
}
|
|
1551
|
+
};
|
|
1552
|
+
/**
|
|
1553
|
+
* Encodes a merkle tree with signature into hex calldata for onchain broadcast.
|
|
1554
|
+
*
|
|
1555
|
+
* Layout: `0x{vv}{gzip([...offers])}{root}{signature}` where:
|
|
1556
|
+
* - `{vv}`: 1-byte version (currently 0x01)
|
|
1557
|
+
* - `{gzip([...offers])}`: gzipped JSON array of serialized offers
|
|
1558
|
+
* - `{root}`: 32-byte merkle root
|
|
1559
|
+
* - `{signature}`: 65-byte EIP-191 signature over raw root bytes
|
|
1560
|
+
*
|
|
1561
|
+
* Validates signature authenticity and root integrity before encoding.
|
|
1562
|
+
*
|
|
1563
|
+
* @example
|
|
1564
|
+
* ```typescript
|
|
1565
|
+
* const tree = Tree.from(offers);
|
|
1566
|
+
* const signature = await wallet.signMessage({ message: { raw: tree.root } });
|
|
1567
|
+
* const calldata = await Tree.encode(tree, signature);
|
|
1568
|
+
* await broadcast(calldata);
|
|
1569
|
+
* ```
|
|
1570
|
+
*
|
|
1571
|
+
* @example
|
|
1572
|
+
* Manual construction (for advanced users):
|
|
1573
|
+
* ```typescript
|
|
1574
|
+
* const tree = Tree.from(offers);
|
|
1575
|
+
* const compressed = gzip(JSON.stringify(tree.offers.map(Offer.serialize)));
|
|
1576
|
+
* const partial = `0x01${bytesToHex(compressed)}${tree.root.slice(2)}`;
|
|
1577
|
+
* const signature = await wallet.signMessage({ message: { raw: tree.root } });
|
|
1578
|
+
* const calldata = `${partial}${signature.slice(2)}`;
|
|
1579
|
+
* ```
|
|
1580
|
+
*
|
|
1581
|
+
* @param tree - Merkle tree of offers
|
|
1582
|
+
* @param signature - EIP-191 signature over raw root bytes
|
|
1583
|
+
* @returns Hex-encoded calldata ready for onchain broadcast
|
|
1584
|
+
* @throws {EncodeError} If signature verification fails or root mismatch
|
|
1585
|
+
*/
|
|
1586
|
+
const encode$1 = async (tree, signature) => {
|
|
1587
|
+
validateTreeForEncoding(tree);
|
|
1588
|
+
await verifySignatureAndRecoverAddress({
|
|
1589
|
+
root: tree.root,
|
|
1590
|
+
signature
|
|
1591
|
+
});
|
|
1592
|
+
const unsigned = encodeUnsignedBytes(tree);
|
|
1593
|
+
const sigBytes = hexToBytes(signature);
|
|
1594
|
+
const encoded = new Uint8Array(unsigned.length + sigBytes.length);
|
|
1595
|
+
encoded.set(unsigned, 0);
|
|
1596
|
+
encoded.set(sigBytes, unsigned.length);
|
|
2240
1597
|
return bytesToHex(encoded);
|
|
2241
1598
|
};
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
1599
|
+
/**
|
|
1600
|
+
* Encodes a merkle tree without a signature into hex payload for client-side signing.
|
|
1601
|
+
*
|
|
1602
|
+
* Layout: `0x{vv}{gzip([...offers])}{root}` where:
|
|
1603
|
+
* - `{vv}`: 1-byte version (currently 0x01)
|
|
1604
|
+
* - `{gzip([...offers])}`: gzipped JSON array of serialized offers
|
|
1605
|
+
* - `{root}`: 32-byte merkle root
|
|
1606
|
+
*
|
|
1607
|
+
* Validates root integrity before encoding.
|
|
1608
|
+
*
|
|
1609
|
+
* @param tree - Merkle tree of offers
|
|
1610
|
+
* @returns Hex-encoded unsigned payload
|
|
1611
|
+
* @throws {EncodeError} If root mismatch
|
|
1612
|
+
*/
|
|
1613
|
+
const encodeUnsigned = (tree) => {
|
|
1614
|
+
validateTreeForEncoding(tree);
|
|
1615
|
+
return bytesToHex(encodeUnsignedBytes(tree));
|
|
1616
|
+
};
|
|
1617
|
+
const validateTreeForEncoding = (tree) => {
|
|
1618
|
+
if (VERSION > 255) throw new EncodeError(`version overflow: ${VERSION} exceeds 255`);
|
|
1619
|
+
const computed = from$8(tree.offers);
|
|
1620
|
+
if (tree.root !== computed.root) throw new EncodeError(`root mismatch: expected ${computed.root}, got ${tree.root}`);
|
|
1621
|
+
};
|
|
1622
|
+
const encodeUnsignedBytes = (tree) => {
|
|
1623
|
+
const offersPayload = tree.offers.map(serialize);
|
|
1624
|
+
const compressed = gzip(JSON.stringify(offersPayload));
|
|
1625
|
+
const rootBytes = hexToBytes(tree.root);
|
|
1626
|
+
const encoded = new Uint8Array(1 + compressed.length + 32);
|
|
1627
|
+
encoded[0] = VERSION;
|
|
1628
|
+
encoded.set(compressed, 1);
|
|
1629
|
+
encoded.set(rootBytes, 1 + compressed.length);
|
|
1630
|
+
return encoded;
|
|
2245
1631
|
};
|
|
2246
1632
|
/**
|
|
2247
|
-
* Decodes
|
|
1633
|
+
* Decodes hex calldata into a validated merkle tree.
|
|
1634
|
+
*
|
|
1635
|
+
* Validates signature before decompression for fail-fast rejection of invalid payloads.
|
|
1636
|
+
* Returns the tree with separately validated signature and recovered signer address.
|
|
2248
1637
|
*
|
|
2249
|
-
*
|
|
2250
|
-
*
|
|
1638
|
+
* Validation order:
|
|
1639
|
+
* 1. Version check
|
|
1640
|
+
* 2. Signature verification (fail-fast, before decompression)
|
|
1641
|
+
* 3. Decompression (only if signature valid)
|
|
1642
|
+
* 4. Root verification (computed from offers vs embedded root)
|
|
1643
|
+
*
|
|
1644
|
+
* @example
|
|
1645
|
+
* ```typescript
|
|
1646
|
+
* const { tree, signature, signer } = await Tree.decode(calldata);
|
|
1647
|
+
* console.log(`Tree signed by ${signer} with ${tree.offers.length} offers`);
|
|
1648
|
+
* ```
|
|
2251
1649
|
*
|
|
2252
|
-
* @param encoded - Hex
|
|
2253
|
-
* @returns
|
|
2254
|
-
* @throws
|
|
2255
|
-
*/
|
|
2256
|
-
const decode$1 = (encoded) => {
|
|
2257
|
-
const bytes = hexToBytes(encoded);
|
|
2258
|
-
if (bytes.length <
|
|
2259
|
-
const version = bytes[0];
|
|
2260
|
-
if (version !== (VERSION & 255)) throw new
|
|
2261
|
-
const
|
|
2262
|
-
const
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
1650
|
+
* @param encoded - Hex calldata in format `0x{vv}{gzip}{root}{signature}`
|
|
1651
|
+
* @returns Validated tree, signature, and recovered signer address
|
|
1652
|
+
* @throws {DecodeError} If version invalid, signature invalid, or root mismatch
|
|
1653
|
+
*/
|
|
1654
|
+
const decode$1 = async (encoded) => {
|
|
1655
|
+
const bytes$1 = hexToBytes(encoded);
|
|
1656
|
+
if (bytes$1.length < 98) throw new DecodeError("payload too short");
|
|
1657
|
+
const version = bytes$1[0];
|
|
1658
|
+
if (version !== (VERSION & 255)) throw new DecodeError(`invalid version: expected ${VERSION}, got ${version ?? 0}`);
|
|
1659
|
+
const signature = bytesToHex(bytes$1.slice(-65));
|
|
1660
|
+
const root = bytesToHex(bytes$1.slice(-97, -65));
|
|
1661
|
+
assertHex(root, 32, "root");
|
|
1662
|
+
assertHex(signature, 65, "signature");
|
|
1663
|
+
const signer = await verifySignatureAndRecoverAddress({
|
|
1664
|
+
root,
|
|
1665
|
+
signature
|
|
1666
|
+
});
|
|
1667
|
+
const compressed = bytes$1.slice(1, -97);
|
|
1668
|
+
let decoded;
|
|
1669
|
+
try {
|
|
1670
|
+
decoded = ungzip(compressed, { to: "string" });
|
|
1671
|
+
} catch {
|
|
1672
|
+
throw new DecodeError("decompression failed");
|
|
1673
|
+
}
|
|
1674
|
+
let rawOffers;
|
|
1675
|
+
try {
|
|
1676
|
+
rawOffers = JSON.parse(decoded);
|
|
1677
|
+
} catch {
|
|
1678
|
+
throw new DecodeError("JSON parse failed");
|
|
1679
|
+
}
|
|
1680
|
+
const tree = from$8(rawOffers.map((o) => OfferSchema().parse(o)));
|
|
1681
|
+
if (root !== tree.root) throw new DecodeError(`root mismatch: expected ${tree.root}, got ${root}`);
|
|
1682
|
+
return {
|
|
1683
|
+
tree,
|
|
1684
|
+
signature,
|
|
1685
|
+
signer
|
|
1686
|
+
};
|
|
1687
|
+
};
|
|
1688
|
+
/**
|
|
1689
|
+
* Error thrown during tree building operations.
|
|
1690
|
+
* Indicates structural issues with the tree (missing offers, inconsistent state).
|
|
1691
|
+
*/
|
|
1692
|
+
var TreeError = class extends BaseError {
|
|
1693
|
+
constructor(reason) {
|
|
1694
|
+
super(`Tree error: ${reason}`);
|
|
1695
|
+
_defineProperty(this, "name", "Tree.TreeError");
|
|
1696
|
+
}
|
|
1697
|
+
};
|
|
1698
|
+
/**
|
|
1699
|
+
* Error thrown during tree encoding.
|
|
1700
|
+
* Indicates validation failures (signature, root mismatch, mixed makers).
|
|
1701
|
+
*/
|
|
1702
|
+
var EncodeError = class extends BaseError {
|
|
1703
|
+
constructor(reason) {
|
|
1704
|
+
super(`Failed to encode tree: ${reason}`);
|
|
1705
|
+
_defineProperty(this, "name", "Tree.EncodeError");
|
|
1706
|
+
}
|
|
1707
|
+
};
|
|
1708
|
+
/**
|
|
1709
|
+
* Error thrown during tree decoding.
|
|
1710
|
+
* Indicates payload corruption, version mismatch, or validation failures.
|
|
1711
|
+
*/
|
|
1712
|
+
var DecodeError = class extends BaseError {
|
|
1713
|
+
constructor(reason) {
|
|
1714
|
+
super(`Failed to decode tree: ${reason}`);
|
|
1715
|
+
_defineProperty(this, "name", "Tree.DecodeError");
|
|
1716
|
+
}
|
|
2267
1717
|
};
|
|
2268
1718
|
|
|
2269
1719
|
//#endregion
|
|
@@ -2271,59 +1721,63 @@ const decode$1 = (encoded) => {
|
|
|
2271
1721
|
var Offer_exports = /* @__PURE__ */ __export({
|
|
2272
1722
|
AccountNotSetError: () => AccountNotSetError,
|
|
2273
1723
|
InvalidOfferError: () => InvalidOfferError,
|
|
2274
|
-
OfferHashSchema: () => OfferHashSchema,
|
|
2275
1724
|
OfferSchema: () => OfferSchema,
|
|
2276
1725
|
Status: () => Status,
|
|
2277
1726
|
consumedEvent: () => consumedEvent,
|
|
2278
1727
|
decode: () => decode,
|
|
2279
1728
|
domain: () => domain,
|
|
2280
1729
|
encode: () => encode,
|
|
2281
|
-
from: () => from$
|
|
1730
|
+
from: () => from$7,
|
|
2282
1731
|
fromSnakeCase: () => fromSnakeCase$1,
|
|
2283
1732
|
hash: () => hash,
|
|
2284
1733
|
obligationId: () => obligationId,
|
|
2285
1734
|
random: () => random$1,
|
|
1735
|
+
serialize: () => serialize,
|
|
2286
1736
|
sign: () => sign,
|
|
2287
1737
|
signatureMsg: () => signatureMsg,
|
|
2288
1738
|
toSnakeCase: () => toSnakeCase,
|
|
2289
1739
|
types: () => types
|
|
2290
1740
|
});
|
|
1741
|
+
/** Internal symbol for caching the computed hash. */
|
|
1742
|
+
const HASH_CACHE = Symbol("offer.hash");
|
|
2291
1743
|
let Status = /* @__PURE__ */ function(Status$1) {
|
|
2292
1744
|
Status$1["VALID"] = "VALID";
|
|
2293
1745
|
Status$1["SIMULATION_ERROR"] = "SIMULATION_ERROR";
|
|
2294
1746
|
return Status$1;
|
|
2295
1747
|
}({});
|
|
2296
|
-
const
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
let base$1 = z$1.object({
|
|
2300
|
-
offering: z$1.string().transform(transformAddress),
|
|
1748
|
+
const OfferSchema = () => {
|
|
1749
|
+
return z$1.object({
|
|
1750
|
+
maker: z$1.string().transform(transformAddress),
|
|
2301
1751
|
assets: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
|
|
2302
|
-
|
|
1752
|
+
obligationUnits: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional().default(0n),
|
|
1753
|
+
obligationShares: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional().default(0n),
|
|
1754
|
+
price: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
|
|
2303
1755
|
maturity: MaturitySchema,
|
|
2304
1756
|
expiry: z$1.number().int().max(Number.MAX_SAFE_INTEGER),
|
|
2305
1757
|
start: z$1.number().int().max(Number.MAX_SAFE_INTEGER),
|
|
2306
|
-
|
|
1758
|
+
group: z$1.union([
|
|
1759
|
+
z$1.string(),
|
|
1760
|
+
z$1.number(),
|
|
1761
|
+
z$1.bigint()
|
|
1762
|
+
]).transform(transformBytes32),
|
|
1763
|
+
session: z$1.union([
|
|
1764
|
+
z$1.string(),
|
|
1765
|
+
z$1.number(),
|
|
1766
|
+
z$1.bigint()
|
|
1767
|
+
]).optional().default("0x0000000000000000000000000000000000000000000000000000000000000000").transform(transformBytes32),
|
|
2307
1768
|
buy: z$1.boolean(),
|
|
2308
1769
|
chainId: z$1.number().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
2309
1770
|
loanToken: z$1.string().transform(transformAddress),
|
|
2310
1771
|
collaterals: CollateralsSchema,
|
|
2311
1772
|
callback: z$1.object({
|
|
2312
1773
|
address: z$1.string().transform(transformAddress),
|
|
2313
|
-
data: z$1.string().transform(transformHex)
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
consumed: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional(),
|
|
2318
|
-
takeable: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional(),
|
|
2319
|
-
blockNumber: z$1.number().int().max(Number.MAX_SAFE_INTEGER).optional()
|
|
2320
|
-
});
|
|
2321
|
-
if (!omitHash) base$1 = base$1.extend({ hash: OfferHashSchema });
|
|
2322
|
-
return base$1.refine((data) => data.start < data.expiry, {
|
|
2323
|
-
message: "Start must be before expiry",
|
|
1774
|
+
data: z$1.string().transform(transformHex)
|
|
1775
|
+
})
|
|
1776
|
+
}).refine((data) => data.start < data.expiry, {
|
|
1777
|
+
message: "start must be before expiry",
|
|
2324
1778
|
path: ["start"]
|
|
2325
1779
|
}).refine((data) => data.expiry <= data.maturity, {
|
|
2326
|
-
message: "
|
|
1780
|
+
message: "expiry must be before or equal to maturity",
|
|
2327
1781
|
path: ["expiry"]
|
|
2328
1782
|
});
|
|
2329
1783
|
};
|
|
@@ -2331,16 +1785,11 @@ const OfferSchema = (parameters) => {
|
|
|
2331
1785
|
* Creates an offer from a plain object.
|
|
2332
1786
|
* @throws {InvalidOfferError} If the offer is invalid.
|
|
2333
1787
|
* @param input - The offer to create.
|
|
2334
|
-
* @returns The created offer
|
|
1788
|
+
* @returns The created offer.
|
|
2335
1789
|
*/
|
|
2336
|
-
function from$
|
|
1790
|
+
function from$7(input) {
|
|
2337
1791
|
try {
|
|
2338
|
-
|
|
2339
|
-
const parsedHash = OfferHashSchema.parse(hash(parsedOffer));
|
|
2340
|
-
return {
|
|
2341
|
-
...parsedOffer,
|
|
2342
|
-
hash: parsedHash
|
|
2343
|
-
};
|
|
1792
|
+
return OfferSchema().parse(input);
|
|
2344
1793
|
} catch (error) {
|
|
2345
1794
|
throw new InvalidOfferError(error);
|
|
2346
1795
|
}
|
|
@@ -2349,10 +1798,10 @@ function from$5(input) {
|
|
|
2349
1798
|
* Creates an offer from a snake case object.
|
|
2350
1799
|
* @throws {InvalidOfferError} If the offer is invalid.
|
|
2351
1800
|
* @param input - The offer to create.
|
|
2352
|
-
* @returns The created offer
|
|
1801
|
+
* @returns The created offer.
|
|
2353
1802
|
*/
|
|
2354
1803
|
function fromSnakeCase$1(input) {
|
|
2355
|
-
return from$
|
|
1804
|
+
return from$7(fromSnakeCase$3(input));
|
|
2356
1805
|
}
|
|
2357
1806
|
/**
|
|
2358
1807
|
* Converts an offer to a snake case object.
|
|
@@ -2363,19 +1812,51 @@ function toSnakeCase(offer) {
|
|
|
2363
1812
|
return toSnakeCase$1(offer);
|
|
2364
1813
|
}
|
|
2365
1814
|
/**
|
|
1815
|
+
* Serializes an offer for merkle tree encoding.
|
|
1816
|
+
* Converts BigInt fields to strings for JSON compatibility.
|
|
1817
|
+
*
|
|
1818
|
+
* @param offer - Offer to serialize
|
|
1819
|
+
* @returns JSON-serializable offer object
|
|
1820
|
+
*/
|
|
1821
|
+
const serialize = (offer) => ({
|
|
1822
|
+
maker: offer.maker,
|
|
1823
|
+
assets: offer.assets.toString(),
|
|
1824
|
+
obligationUnits: offer.obligationUnits.toString(),
|
|
1825
|
+
obligationShares: offer.obligationShares.toString(),
|
|
1826
|
+
price: offer.price.toString(),
|
|
1827
|
+
maturity: Number(offer.maturity),
|
|
1828
|
+
expiry: Number(offer.expiry),
|
|
1829
|
+
start: Number(offer.start),
|
|
1830
|
+
group: offer.group,
|
|
1831
|
+
session: offer.session,
|
|
1832
|
+
buy: offer.buy,
|
|
1833
|
+
chainId: offer.chainId,
|
|
1834
|
+
loanToken: offer.loanToken,
|
|
1835
|
+
collaterals: offer.collaterals.map((c) => ({
|
|
1836
|
+
asset: c.asset,
|
|
1837
|
+
oracle: c.oracle,
|
|
1838
|
+
lltv: c.lltv.toString()
|
|
1839
|
+
})),
|
|
1840
|
+
callback: {
|
|
1841
|
+
address: offer.callback.address,
|
|
1842
|
+
data: offer.callback.data
|
|
1843
|
+
},
|
|
1844
|
+
hash: hash(offer)
|
|
1845
|
+
});
|
|
1846
|
+
/**
|
|
2366
1847
|
* Generates a random Offer.
|
|
2367
1848
|
* The returned Offer contains randomly generated values.
|
|
2368
1849
|
* @warning The generated Offer should not be used for production usage.
|
|
2369
1850
|
* @returns {Offer} A randomly generated Offer object.
|
|
2370
1851
|
*/
|
|
2371
1852
|
function random$1(config) {
|
|
2372
|
-
const chain = config?.chains ? config.chains[
|
|
2373
|
-
const loanToken = config?.loanTokens ? config.loanTokens[
|
|
2374
|
-
const collateralCandidates = config?.collateralTokens ? config.collateralTokens.filter((a) => a !== loanToken) : [
|
|
2375
|
-
const collateralAsset = collateralCandidates[
|
|
1853
|
+
const chain = config?.chains ? config.chains[int(config.chains.length)] : chains$1.ethereum;
|
|
1854
|
+
const loanToken = config?.loanTokens ? config.loanTokens[int(config.loanTokens.length)] : address();
|
|
1855
|
+
const collateralCandidates = config?.collateralTokens ? config.collateralTokens.filter((a) => a !== loanToken) : [address()];
|
|
1856
|
+
const collateralAsset = collateralCandidates[int(collateralCandidates.length)];
|
|
2376
1857
|
const maturityOption = weightedChoice([["end_of_month", 1], ["end_of_next_month", 1]]);
|
|
2377
|
-
const maturity$1 = config?.maturity ?? from$
|
|
2378
|
-
const lltv = from$
|
|
1858
|
+
const maturity$1 = config?.maturity ?? from$10(maturityOption);
|
|
1859
|
+
const lltv = from$12(weightedChoice([
|
|
2379
1860
|
[.385, 1],
|
|
2380
1861
|
[.5, 1],
|
|
2381
1862
|
[.625, 2],
|
|
@@ -2386,25 +1867,23 @@ function random$1(config) {
|
|
|
2386
1867
|
[.965, 4],
|
|
2387
1868
|
[.98, 2]
|
|
2388
1869
|
]));
|
|
2389
|
-
const buy = config?.buy !== void 0 ? config.buy :
|
|
1870
|
+
const buy = config?.buy !== void 0 ? config.buy : bool();
|
|
2390
1871
|
const ONE = 1000000000000000000n;
|
|
2391
1872
|
const qMin = buy ? 16 : 4;
|
|
2392
1873
|
const len = (buy ? 32 : 16) - qMin + 1;
|
|
2393
|
-
const
|
|
1874
|
+
const pricePairs = Array.from({ length: len }, (_, idx) => {
|
|
2394
1875
|
const q = qMin + idx;
|
|
2395
1876
|
return [BigInt(q) * (ONE / 4n), buy ? 1 + idx : 1 + (len - 1 - idx)];
|
|
2396
1877
|
});
|
|
2397
|
-
const
|
|
1878
|
+
const price = config?.price ?? weightedChoice(pricePairs);
|
|
2398
1879
|
const loanTokenDecimals = config?.assetsDecimals?.[loanToken] ?? 18;
|
|
2399
1880
|
const unit = BigInt(10) ** BigInt(loanTokenDecimals);
|
|
2400
|
-
const amountBase = BigInt(100 +
|
|
1881
|
+
const amountBase = BigInt(100 + int(999901));
|
|
2401
1882
|
const assetsScaled = config?.assets ?? amountBase * unit;
|
|
2402
|
-
const consumed = config?.consumed !== void 0 ? config.consumed : Math.random() < .8 ? 0n : assetsScaled * BigInt(1 + Math.floor(Math.random() * 900)) / 1000n;
|
|
2403
1883
|
const callbackBySide = (() => {
|
|
2404
1884
|
if (buy) return {
|
|
2405
1885
|
address: zeroAddress,
|
|
2406
|
-
data: "0x"
|
|
2407
|
-
gasLimit: 0n
|
|
1886
|
+
data: "0x"
|
|
2408
1887
|
};
|
|
2409
1888
|
const sellCallbackAddress = "0x3333333333333333333333333333333333333333";
|
|
2410
1889
|
const amount = assetsScaled * 1000000000000000000000n;
|
|
@@ -2413,34 +1892,33 @@ function random$1(config) {
|
|
|
2413
1892
|
data: encodeSellERC20Callback({
|
|
2414
1893
|
collaterals: [collateralAsset],
|
|
2415
1894
|
amounts: [amount]
|
|
2416
|
-
})
|
|
2417
|
-
gasLimit: 0n
|
|
1895
|
+
})
|
|
2418
1896
|
};
|
|
2419
1897
|
})();
|
|
2420
|
-
return from$
|
|
2421
|
-
|
|
1898
|
+
return from$7({
|
|
1899
|
+
maker: config?.maker ?? address(),
|
|
2422
1900
|
assets: assetsScaled,
|
|
2423
|
-
|
|
1901
|
+
obligationUnits: config?.obligationUnits ?? 0n,
|
|
1902
|
+
obligationShares: config?.obligationShares ?? 0n,
|
|
1903
|
+
price,
|
|
2424
1904
|
maturity: maturity$1,
|
|
2425
1905
|
expiry: config?.expiry ?? maturity$1 - 1,
|
|
2426
1906
|
start: config?.start ?? maturity$1 - 10,
|
|
2427
|
-
|
|
1907
|
+
group: config?.group ?? hex(32),
|
|
1908
|
+
session: config?.session ?? hex(32),
|
|
2428
1909
|
buy,
|
|
2429
1910
|
chainId: chain.id,
|
|
2430
1911
|
loanToken,
|
|
2431
|
-
collaterals: config?.collaterals ?? Array.from({ length:
|
|
1912
|
+
collaterals: config?.collaterals ?? Array.from({ length: int(3) + 1 }, () => ({
|
|
2432
1913
|
...random$3(),
|
|
2433
1914
|
lltv
|
|
2434
1915
|
})).sort((a, b) => a.asset.localeCompare(b.asset)),
|
|
2435
|
-
callback: config?.callback ?? callbackBySide
|
|
2436
|
-
consumed,
|
|
2437
|
-
takeable: config?.takeable ?? assetsScaled - consumed,
|
|
2438
|
-
blockNumber: config?.blockNumber ?? Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)
|
|
1916
|
+
callback: config?.callback ?? callbackBySide
|
|
2439
1917
|
});
|
|
2440
1918
|
}
|
|
2441
1919
|
const weightedChoice = (pairs) => {
|
|
2442
1920
|
const total = pairs.reduce((sum, [, weight]) => sum + weight, 0);
|
|
2443
|
-
let roll =
|
|
1921
|
+
let roll = float() * total;
|
|
2444
1922
|
for (const [value, weight] of pairs) {
|
|
2445
1923
|
roll -= weight;
|
|
2446
1924
|
if (roll < 0) return value;
|
|
@@ -2471,7 +1949,7 @@ const types = {
|
|
|
2471
1949
|
}],
|
|
2472
1950
|
Offer: [
|
|
2473
1951
|
{
|
|
2474
|
-
name: "
|
|
1952
|
+
name: "maker",
|
|
2475
1953
|
type: "address"
|
|
2476
1954
|
},
|
|
2477
1955
|
{
|
|
@@ -2479,7 +1957,15 @@ const types = {
|
|
|
2479
1957
|
type: "uint256"
|
|
2480
1958
|
},
|
|
2481
1959
|
{
|
|
2482
|
-
name: "
|
|
1960
|
+
name: "obligationUnits",
|
|
1961
|
+
type: "uint256"
|
|
1962
|
+
},
|
|
1963
|
+
{
|
|
1964
|
+
name: "obligationShares",
|
|
1965
|
+
type: "uint256"
|
|
1966
|
+
},
|
|
1967
|
+
{
|
|
1968
|
+
name: "price",
|
|
2483
1969
|
type: "uint256"
|
|
2484
1970
|
},
|
|
2485
1971
|
{
|
|
@@ -2491,8 +1977,12 @@ const types = {
|
|
|
2491
1977
|
type: "uint256"
|
|
2492
1978
|
},
|
|
2493
1979
|
{
|
|
2494
|
-
name: "
|
|
2495
|
-
type: "
|
|
1980
|
+
name: "group",
|
|
1981
|
+
type: "bytes32"
|
|
1982
|
+
},
|
|
1983
|
+
{
|
|
1984
|
+
name: "session",
|
|
1985
|
+
type: "bytes32"
|
|
2496
1986
|
},
|
|
2497
1987
|
{
|
|
2498
1988
|
name: "buy",
|
|
@@ -2508,37 +1998,30 @@ const types = {
|
|
|
2508
1998
|
},
|
|
2509
1999
|
{
|
|
2510
2000
|
name: "callback",
|
|
2511
|
-
type: "Callback"
|
|
2512
|
-
}
|
|
2513
|
-
],
|
|
2514
|
-
Collateral: [
|
|
2515
|
-
{
|
|
2516
|
-
name: "asset",
|
|
2517
|
-
type: "address"
|
|
2518
|
-
},
|
|
2519
|
-
{
|
|
2520
|
-
name: "oracle",
|
|
2521
|
-
type: "address"
|
|
2522
|
-
},
|
|
2523
|
-
{
|
|
2524
|
-
name: "lltv",
|
|
2525
|
-
type: "uint256"
|
|
2001
|
+
type: "Callback"
|
|
2526
2002
|
}
|
|
2527
2003
|
],
|
|
2528
|
-
|
|
2004
|
+
Collateral: [
|
|
2529
2005
|
{
|
|
2530
|
-
name: "
|
|
2006
|
+
name: "asset",
|
|
2531
2007
|
type: "address"
|
|
2532
2008
|
},
|
|
2533
2009
|
{
|
|
2534
|
-
name: "
|
|
2535
|
-
type: "
|
|
2010
|
+
name: "oracle",
|
|
2011
|
+
type: "address"
|
|
2536
2012
|
},
|
|
2537
2013
|
{
|
|
2538
|
-
name: "
|
|
2014
|
+
name: "lltv",
|
|
2539
2015
|
type: "uint256"
|
|
2540
2016
|
}
|
|
2541
|
-
]
|
|
2017
|
+
],
|
|
2018
|
+
Callback: [{
|
|
2019
|
+
name: "address",
|
|
2020
|
+
type: "address"
|
|
2021
|
+
}, {
|
|
2022
|
+
name: "data",
|
|
2023
|
+
type: "bytes"
|
|
2024
|
+
}]
|
|
2542
2025
|
};
|
|
2543
2026
|
/**
|
|
2544
2027
|
* Signs an array of offers.
|
|
@@ -2555,30 +2038,36 @@ async function sign(offers, wallet) {
|
|
|
2555
2038
|
});
|
|
2556
2039
|
}
|
|
2557
2040
|
function signatureMsg(offers) {
|
|
2558
|
-
return from$
|
|
2041
|
+
return from$8(offers).root;
|
|
2559
2042
|
}
|
|
2560
2043
|
function hash(offer) {
|
|
2561
|
-
|
|
2044
|
+
const cached = offer[HASH_CACHE];
|
|
2045
|
+
if (cached) return cached;
|
|
2046
|
+
const computed = hashTypedData({
|
|
2562
2047
|
domain: domain(offer.chainId),
|
|
2563
2048
|
message: {
|
|
2564
|
-
|
|
2049
|
+
maker: offer.maker.toLowerCase(),
|
|
2565
2050
|
assets: offer.assets,
|
|
2566
|
-
|
|
2051
|
+
obligationUnits: offer.obligationUnits,
|
|
2052
|
+
obligationShares: offer.obligationShares,
|
|
2053
|
+
price: offer.price,
|
|
2567
2054
|
maturity: BigInt(offer.maturity),
|
|
2568
2055
|
expiry: BigInt(offer.expiry),
|
|
2569
|
-
|
|
2056
|
+
group: offer.group,
|
|
2057
|
+
session: offer.session,
|
|
2570
2058
|
buy: offer.buy,
|
|
2571
2059
|
loanToken: offer.loanToken.toLowerCase(),
|
|
2572
2060
|
collaterals: offer.collaterals,
|
|
2573
2061
|
callback: {
|
|
2574
2062
|
address: offer.callback.address.toLowerCase(),
|
|
2575
|
-
data: offer.callback.data
|
|
2576
|
-
gasLimit: offer.callback.gasLimit
|
|
2063
|
+
data: offer.callback.data
|
|
2577
2064
|
}
|
|
2578
2065
|
},
|
|
2579
2066
|
primaryType: "Offer",
|
|
2580
2067
|
types
|
|
2581
2068
|
});
|
|
2069
|
+
offer[HASH_CACHE] = computed;
|
|
2070
|
+
return computed;
|
|
2582
2071
|
}
|
|
2583
2072
|
/**
|
|
2584
2073
|
* Calculates the obligation id for an offer based on the smart contract's Obligation struct.
|
|
@@ -2587,7 +2076,7 @@ function hash(offer) {
|
|
|
2587
2076
|
* @returns The obligation id as a 32-byte hex string.
|
|
2588
2077
|
*/
|
|
2589
2078
|
function obligationId(offer) {
|
|
2590
|
-
return id(from$
|
|
2079
|
+
return id(from$9({
|
|
2591
2080
|
chainId: offer.chainId,
|
|
2592
2081
|
loanToken: offer.loanToken,
|
|
2593
2082
|
collaterals: offer.collaterals,
|
|
@@ -2596,7 +2085,7 @@ function obligationId(offer) {
|
|
|
2596
2085
|
}
|
|
2597
2086
|
const OfferAbi = [
|
|
2598
2087
|
{
|
|
2599
|
-
name: "
|
|
2088
|
+
name: "maker",
|
|
2600
2089
|
type: "address"
|
|
2601
2090
|
},
|
|
2602
2091
|
{
|
|
@@ -2604,7 +2093,15 @@ const OfferAbi = [
|
|
|
2604
2093
|
type: "uint256"
|
|
2605
2094
|
},
|
|
2606
2095
|
{
|
|
2607
|
-
name: "
|
|
2096
|
+
name: "obligationUnits",
|
|
2097
|
+
type: "uint256"
|
|
2098
|
+
},
|
|
2099
|
+
{
|
|
2100
|
+
name: "obligationShares",
|
|
2101
|
+
type: "uint256"
|
|
2102
|
+
},
|
|
2103
|
+
{
|
|
2104
|
+
name: "price",
|
|
2608
2105
|
type: "uint256"
|
|
2609
2106
|
},
|
|
2610
2107
|
{
|
|
@@ -2616,8 +2113,12 @@ const OfferAbi = [
|
|
|
2616
2113
|
type: "uint256"
|
|
2617
2114
|
},
|
|
2618
2115
|
{
|
|
2619
|
-
name: "
|
|
2620
|
-
type: "
|
|
2116
|
+
name: "group",
|
|
2117
|
+
type: "bytes32"
|
|
2118
|
+
},
|
|
2119
|
+
{
|
|
2120
|
+
name: "session",
|
|
2121
|
+
type: "bytes32"
|
|
2621
2122
|
},
|
|
2622
2123
|
{
|
|
2623
2124
|
name: "buy",
|
|
@@ -2656,85 +2157,74 @@ const OfferAbi = [
|
|
|
2656
2157
|
{
|
|
2657
2158
|
name: "callback",
|
|
2658
2159
|
type: "tuple",
|
|
2659
|
-
components: [
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
type: "bytes"
|
|
2667
|
-
},
|
|
2668
|
-
{
|
|
2669
|
-
name: "gasLimit",
|
|
2670
|
-
type: "uint256"
|
|
2671
|
-
}
|
|
2672
|
-
]
|
|
2673
|
-
},
|
|
2674
|
-
{
|
|
2675
|
-
name: "signature",
|
|
2676
|
-
type: "bytes"
|
|
2160
|
+
components: [{
|
|
2161
|
+
name: "address",
|
|
2162
|
+
type: "address"
|
|
2163
|
+
}, {
|
|
2164
|
+
name: "data",
|
|
2165
|
+
type: "bytes"
|
|
2166
|
+
}]
|
|
2677
2167
|
}
|
|
2678
2168
|
];
|
|
2679
2169
|
function encode(offer) {
|
|
2680
2170
|
return encodeAbiParameters(OfferAbi, [
|
|
2681
|
-
offer.
|
|
2171
|
+
offer.maker,
|
|
2682
2172
|
offer.assets,
|
|
2683
|
-
offer.
|
|
2173
|
+
offer.obligationUnits,
|
|
2174
|
+
offer.obligationShares,
|
|
2175
|
+
offer.price,
|
|
2684
2176
|
BigInt(offer.maturity),
|
|
2685
2177
|
BigInt(offer.expiry),
|
|
2686
|
-
offer.
|
|
2178
|
+
offer.group,
|
|
2179
|
+
offer.session,
|
|
2687
2180
|
offer.buy,
|
|
2688
2181
|
BigInt(offer.chainId),
|
|
2689
2182
|
offer.loanToken,
|
|
2690
2183
|
BigInt(offer.start),
|
|
2691
2184
|
offer.collaterals,
|
|
2692
|
-
offer.callback
|
|
2693
|
-
offer.signature ?? "0x"
|
|
2185
|
+
offer.callback
|
|
2694
2186
|
]);
|
|
2695
2187
|
}
|
|
2696
|
-
function decode(data
|
|
2188
|
+
function decode(data) {
|
|
2697
2189
|
let decoded;
|
|
2698
2190
|
try {
|
|
2699
2191
|
decoded = decodeAbiParameters(OfferAbi, data);
|
|
2700
2192
|
} catch (error) {
|
|
2701
2193
|
throw new InvalidOfferError(error);
|
|
2702
2194
|
}
|
|
2703
|
-
return from$
|
|
2704
|
-
|
|
2195
|
+
return from$7({
|
|
2196
|
+
maker: decoded[0],
|
|
2705
2197
|
assets: decoded[1],
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2198
|
+
obligationUnits: decoded[2],
|
|
2199
|
+
obligationShares: decoded[3],
|
|
2200
|
+
price: decoded[4],
|
|
2201
|
+
maturity: from$10(Number(decoded[5])),
|
|
2202
|
+
expiry: Number(decoded[6]),
|
|
2203
|
+
group: decoded[7],
|
|
2204
|
+
session: decoded[8],
|
|
2205
|
+
buy: decoded[9],
|
|
2206
|
+
chainId: Number(decoded[10]),
|
|
2207
|
+
loanToken: decoded[11],
|
|
2208
|
+
start: Number(decoded[12]),
|
|
2209
|
+
collaterals: decoded[13].map((c) => {
|
|
2210
|
+
return from$11({
|
|
2716
2211
|
asset: c.asset,
|
|
2717
2212
|
oracle: c.oracle,
|
|
2718
2213
|
lltv: c.lltv
|
|
2719
2214
|
});
|
|
2720
2215
|
}),
|
|
2721
2216
|
callback: {
|
|
2722
|
-
address: decoded[
|
|
2723
|
-
data: decoded[
|
|
2724
|
-
|
|
2725
|
-
},
|
|
2726
|
-
consumed: 0n,
|
|
2727
|
-
blockNumber: Number(blockNumber),
|
|
2728
|
-
takeable: decoded[1],
|
|
2729
|
-
...decoded[12] === "0x" ? {} : { signature: decoded[12] }
|
|
2217
|
+
address: decoded[14].address,
|
|
2218
|
+
data: decoded[14].data
|
|
2219
|
+
}
|
|
2730
2220
|
});
|
|
2731
2221
|
}
|
|
2732
2222
|
/**
|
|
2733
|
-
* ABI for the
|
|
2223
|
+
* ABI for the Consume event emitted by the Obligation contract.
|
|
2734
2224
|
*/
|
|
2735
2225
|
const consumedEvent = {
|
|
2736
2226
|
type: "event",
|
|
2737
|
-
name: "
|
|
2227
|
+
name: "Consume",
|
|
2738
2228
|
inputs: [
|
|
2739
2229
|
{
|
|
2740
2230
|
name: "user",
|
|
@@ -2743,212 +2233,1524 @@ const consumedEvent = {
|
|
|
2743
2233
|
internalType: "address"
|
|
2744
2234
|
},
|
|
2745
2235
|
{
|
|
2746
|
-
name: "
|
|
2747
|
-
type: "
|
|
2236
|
+
name: "group",
|
|
2237
|
+
type: "bytes32",
|
|
2748
2238
|
indexed: true,
|
|
2239
|
+
internalType: "bytes32"
|
|
2240
|
+
},
|
|
2241
|
+
{
|
|
2242
|
+
name: "amount",
|
|
2243
|
+
type: "uint256",
|
|
2244
|
+
indexed: false,
|
|
2749
2245
|
internalType: "uint256"
|
|
2246
|
+
}
|
|
2247
|
+
],
|
|
2248
|
+
anonymous: false
|
|
2249
|
+
};
|
|
2250
|
+
var InvalidOfferError = class InvalidOfferError extends BaseError {
|
|
2251
|
+
constructor(error) {
|
|
2252
|
+
super("Invalid offer.", { cause: error });
|
|
2253
|
+
_defineProperty(this, "name", "Offer.InvalidOfferError");
|
|
2254
|
+
}
|
|
2255
|
+
/**
|
|
2256
|
+
* Formats ZodError issues into a human-readable string with line breaks.
|
|
2257
|
+
* @example
|
|
2258
|
+
* "- 'assets': too small, expected >= 0
|
|
2259
|
+
* - 'start': must be before expiry"
|
|
2260
|
+
*/
|
|
2261
|
+
static formatDetails(error) {
|
|
2262
|
+
if (!(error instanceof z$1.ZodError)) return error.message;
|
|
2263
|
+
return error.issues.map((issue) => {
|
|
2264
|
+
return `'${issue.path.join(".")}': ${issue.message.trim().toLowerCase()}`;
|
|
2265
|
+
}).join(". ");
|
|
2266
|
+
}
|
|
2267
|
+
/**
|
|
2268
|
+
* Returns the formatted human-readable message.
|
|
2269
|
+
*/
|
|
2270
|
+
get formattedMessage() {
|
|
2271
|
+
return `Invalid offer. ${InvalidOfferError.formatDetails(this.cause)}`;
|
|
2272
|
+
}
|
|
2273
|
+
};
|
|
2274
|
+
var AccountNotSetError = class extends BaseError {
|
|
2275
|
+
constructor() {
|
|
2276
|
+
super("Account not set.");
|
|
2277
|
+
_defineProperty(this, "name", "Offer.AccountNotSetError");
|
|
2278
|
+
}
|
|
2279
|
+
};
|
|
2280
|
+
|
|
2281
|
+
//#endregion
|
|
2282
|
+
//#region src/core/Oracle.ts
|
|
2283
|
+
var Oracle_exports = /* @__PURE__ */ __export({
|
|
2284
|
+
Conversion: () => Conversion,
|
|
2285
|
+
from: () => from$6
|
|
2286
|
+
});
|
|
2287
|
+
/**
|
|
2288
|
+
* Create an Oracle from a plain object.
|
|
2289
|
+
* @param data - The data to create the oracle from.
|
|
2290
|
+
* @returns The created oracle.
|
|
2291
|
+
*/
|
|
2292
|
+
function from$6(data) {
|
|
2293
|
+
return {
|
|
2294
|
+
chainId: data.chainId,
|
|
2295
|
+
address: data.address.toLowerCase(),
|
|
2296
|
+
price: data.price ? BigInt(data.price) : null,
|
|
2297
|
+
blockNumber: data.blockNumber
|
|
2298
|
+
};
|
|
2299
|
+
}
|
|
2300
|
+
let Conversion;
|
|
2301
|
+
(function(_Conversion) {
|
|
2302
|
+
function collateralToLoan(amount, params) {
|
|
2303
|
+
return amount * params.price / 10n ** 36n * params.lltv / 10n ** 18n;
|
|
2304
|
+
}
|
|
2305
|
+
_Conversion.collateralToLoan = collateralToLoan;
|
|
2306
|
+
function loanToCollateral(amount, params) {
|
|
2307
|
+
if (params.price === 0n || params.lltv === 0n) return 0n;
|
|
2308
|
+
return amount * 10n ** 36n / params.price * 10n ** 18n / params.lltv;
|
|
2309
|
+
}
|
|
2310
|
+
_Conversion.loanToCollateral = loanToCollateral;
|
|
2311
|
+
})(Conversion || (Conversion = {}));
|
|
2312
|
+
|
|
2313
|
+
//#endregion
|
|
2314
|
+
//#region src/core/Position.ts
|
|
2315
|
+
var Position_exports = /* @__PURE__ */ __export({
|
|
2316
|
+
Type: () => Type,
|
|
2317
|
+
from: () => from$5
|
|
2318
|
+
});
|
|
2319
|
+
let Type = /* @__PURE__ */ function(Type$1) {
|
|
2320
|
+
Type$1["ERC20"] = "erc20";
|
|
2321
|
+
Type$1["VAULT_V1"] = "vault_v1";
|
|
2322
|
+
return Type$1;
|
|
2323
|
+
}({});
|
|
2324
|
+
/**
|
|
2325
|
+
* @constructor
|
|
2326
|
+
* Creates a Position.
|
|
2327
|
+
* @param parameters - {@link from.Parameters}
|
|
2328
|
+
* @returns The created Position. {@link from.ReturnType}
|
|
2329
|
+
*/
|
|
2330
|
+
function from$5(parameters) {
|
|
2331
|
+
return {
|
|
2332
|
+
chainId: parameters.chainId,
|
|
2333
|
+
contract: parameters.contract.toLowerCase(),
|
|
2334
|
+
user: parameters.user.toLowerCase(),
|
|
2335
|
+
type: parameters.type,
|
|
2336
|
+
balance: parameters.balance,
|
|
2337
|
+
...parameters.asset !== void 0 ? { asset: parameters.asset.toLowerCase() } : {},
|
|
2338
|
+
blockNumber: parameters.blockNumber
|
|
2339
|
+
};
|
|
2340
|
+
}
|
|
2341
|
+
|
|
2342
|
+
//#endregion
|
|
2343
|
+
//#region src/core/Quote.ts
|
|
2344
|
+
var Quote_exports = /* @__PURE__ */ __export({
|
|
2345
|
+
InvalidQuoteError: () => InvalidQuoteError,
|
|
2346
|
+
QuoteSchema: () => QuoteSchema,
|
|
2347
|
+
from: () => from$4,
|
|
2348
|
+
fromSnakeCase: () => fromSnakeCase,
|
|
2349
|
+
random: () => random
|
|
2350
|
+
});
|
|
2351
|
+
const QuoteSchema = z$1.object({
|
|
2352
|
+
obligationId: z$1.string().transform(transformHex),
|
|
2353
|
+
ask: z$1.object({ price: z$1.bigint({ coerce: true }).min(0n).max(maxUint256) }),
|
|
2354
|
+
bid: z$1.object({ price: z$1.bigint({ coerce: true }).min(0n).max(maxUint256) })
|
|
2355
|
+
});
|
|
2356
|
+
/**
|
|
2357
|
+
* Creates a quote for a given obligation.
|
|
2358
|
+
* @constructor
|
|
2359
|
+
* @param parameters - {@link from.Parameters}
|
|
2360
|
+
* @returns The created quote. {@link Quote}
|
|
2361
|
+
* @throws If the quote is invalid. {@link InvalidQuoteError}
|
|
2362
|
+
*
|
|
2363
|
+
* @example
|
|
2364
|
+
* ```ts
|
|
2365
|
+
* const quote = Quote.from({ obligationId: "0x123", ask: { price: 100n }, bid: { price: 100n } });
|
|
2366
|
+
* ```
|
|
2367
|
+
*/
|
|
2368
|
+
function from$4(parameters) {
|
|
2369
|
+
try {
|
|
2370
|
+
const parsedQuote = QuoteSchema.parse(parameters);
|
|
2371
|
+
return {
|
|
2372
|
+
obligationId: parsedQuote.obligationId,
|
|
2373
|
+
ask: parsedQuote.ask,
|
|
2374
|
+
bid: parsedQuote.bid
|
|
2375
|
+
};
|
|
2376
|
+
} catch (error) {
|
|
2377
|
+
throw new InvalidQuoteError(error);
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
/**
|
|
2381
|
+
* Creates a quote from a snake case object.
|
|
2382
|
+
* @throws If the quote is invalid. {@link InvalidQuoteError}
|
|
2383
|
+
* @param snake - {@link fromSnakeCase.Parameters}
|
|
2384
|
+
* @returns The created quote. {@link fromSnakeCase.ReturnType}
|
|
2385
|
+
*/
|
|
2386
|
+
function fromSnakeCase(snake) {
|
|
2387
|
+
return from$4(fromSnakeCase$3(snake));
|
|
2388
|
+
}
|
|
2389
|
+
/**
|
|
2390
|
+
* Generates a random quote.
|
|
2391
|
+
* @returns A randomly generated quote. {@link random.ReturnType}
|
|
2392
|
+
*
|
|
2393
|
+
* @example
|
|
2394
|
+
* ```ts
|
|
2395
|
+
* const quote = Quote.random();
|
|
2396
|
+
* ```
|
|
2397
|
+
*/
|
|
2398
|
+
function random() {
|
|
2399
|
+
return from$4({
|
|
2400
|
+
obligationId: id(random$2()),
|
|
2401
|
+
ask: { price: BigInt(int(1e6)) },
|
|
2402
|
+
bid: { price: BigInt(int(1e6)) }
|
|
2403
|
+
});
|
|
2404
|
+
}
|
|
2405
|
+
var InvalidQuoteError = class extends BaseError {
|
|
2406
|
+
constructor(error) {
|
|
2407
|
+
super("Invalid quote.", { cause: error });
|
|
2408
|
+
_defineProperty(this, "name", "Quote.InvalidQuoteError");
|
|
2409
|
+
}
|
|
2410
|
+
};
|
|
2411
|
+
|
|
2412
|
+
//#endregion
|
|
2413
|
+
//#region src/core/Transfer.ts
|
|
2414
|
+
var Transfer_exports = /* @__PURE__ */ __export({ from: () => from$3 });
|
|
2415
|
+
/**
|
|
2416
|
+
* @constructor
|
|
2417
|
+
*
|
|
2418
|
+
* Creates a {@link Transfer}.
|
|
2419
|
+
* @param parameters - {@link from.Parameters}
|
|
2420
|
+
* @returns The created Transfer. {@link from.ReturnType}
|
|
2421
|
+
*
|
|
2422
|
+
* @example
|
|
2423
|
+
* ```ts
|
|
2424
|
+
* const transfer = Transfer.from({ id: "1", chainId: 1, contract: "0x123", from: "0x456", to: "0x789", value: 100n, blockNumber: 100n });
|
|
2425
|
+
* ```
|
|
2426
|
+
*/
|
|
2427
|
+
function from$3(parameters) {
|
|
2428
|
+
return {
|
|
2429
|
+
id: parameters.id,
|
|
2430
|
+
chainId: parameters.chainId,
|
|
2431
|
+
contract: parameters.contract.toLowerCase(),
|
|
2432
|
+
from: parameters.from.toLowerCase(),
|
|
2433
|
+
to: parameters.to.toLowerCase(),
|
|
2434
|
+
value: parameters.value,
|
|
2435
|
+
blockNumber: parameters.blockNumber
|
|
2436
|
+
};
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
//#endregion
|
|
2440
|
+
//#region src/core/types.ts
|
|
2441
|
+
const BrandTypeId = Symbol.for("mempool/Brand");
|
|
2442
|
+
|
|
2443
|
+
//#endregion
|
|
2444
|
+
//#region src/api/Schema/OfferResponse.ts
|
|
2445
|
+
var OfferResponse_exports = /* @__PURE__ */ __export({ from: () => from$2 });
|
|
2446
|
+
/**
|
|
2447
|
+
* Creates an `OfferResponse` matching the Solidity Offer struct layout.
|
|
2448
|
+
* @constructor
|
|
2449
|
+
* @param input - {@link Input}
|
|
2450
|
+
* @returns The created `OfferResponse`. {@link OfferResponse}
|
|
2451
|
+
*/
|
|
2452
|
+
function from$2(input) {
|
|
2453
|
+
const base$1 = {
|
|
2454
|
+
offer: {
|
|
2455
|
+
obligation: {
|
|
2456
|
+
loan_token: input.loanToken,
|
|
2457
|
+
collaterals: input.collaterals.map((c) => ({
|
|
2458
|
+
token: c.asset,
|
|
2459
|
+
lltv: c.lltv.toString(),
|
|
2460
|
+
oracle: c.oracle
|
|
2461
|
+
})),
|
|
2462
|
+
maturity: input.maturity
|
|
2463
|
+
},
|
|
2464
|
+
buy: input.buy,
|
|
2465
|
+
maker: input.maker,
|
|
2466
|
+
assets: input.assets.toString(),
|
|
2467
|
+
obligation_units: input.obligationUnits.toString(),
|
|
2468
|
+
obligation_shares: input.obligationShares.toString(),
|
|
2469
|
+
start: input.start,
|
|
2470
|
+
expiry: input.expiry,
|
|
2471
|
+
price: input.price.toString(),
|
|
2472
|
+
group: input.group,
|
|
2473
|
+
session: input.session,
|
|
2474
|
+
callback: input.callback.address,
|
|
2475
|
+
callback_data: input.callback.data
|
|
2476
|
+
},
|
|
2477
|
+
offer_hash: input.hash,
|
|
2478
|
+
obligation_id: id({
|
|
2479
|
+
chainId: input.chainId,
|
|
2480
|
+
loanToken: input.loanToken,
|
|
2481
|
+
collaterals: [...input.collaterals],
|
|
2482
|
+
maturity: input.maturity
|
|
2483
|
+
}),
|
|
2484
|
+
chain_id: input.chainId,
|
|
2485
|
+
consumed: input.consumed.toString(),
|
|
2486
|
+
takeable: input.takeable.toString(),
|
|
2487
|
+
block_number: input.blockNumber
|
|
2488
|
+
};
|
|
2489
|
+
if (!input.proof || !input.root || !input.signature) return {
|
|
2490
|
+
...base$1,
|
|
2491
|
+
root: null,
|
|
2492
|
+
proof: null,
|
|
2493
|
+
signature: null
|
|
2494
|
+
};
|
|
2495
|
+
return {
|
|
2496
|
+
...base$1,
|
|
2497
|
+
root: input.root.toLowerCase(),
|
|
2498
|
+
proof: input.proof.map((p) => p.toLowerCase()),
|
|
2499
|
+
signature: input.signature.toLowerCase()
|
|
2500
|
+
};
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
//#endregion
|
|
2504
|
+
//#region src/api/Controllers/Payload.ts
|
|
2505
|
+
const API_ERROR_CODES = [
|
|
2506
|
+
"VALIDATION_ERROR",
|
|
2507
|
+
"NOT_FOUND",
|
|
2508
|
+
"INTERNAL_SERVER_ERROR",
|
|
2509
|
+
"BAD_REQUEST"
|
|
2510
|
+
];
|
|
2511
|
+
|
|
2512
|
+
//#endregion
|
|
2513
|
+
//#region \0@oxc-project+runtime@0.97.0/helpers/decorate.js
|
|
2514
|
+
function __decorate(decorators, target, key, desc) {
|
|
2515
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2516
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2517
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2518
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
//#endregion
|
|
2522
|
+
//#region src/api/Schema/openapi.ts
|
|
2523
|
+
const timestampExample = "2024-01-01T12:00:00.000Z";
|
|
2524
|
+
const offerCursorExample = "eyJvZmZzZXQiOjEwMH0";
|
|
2525
|
+
const obligationCursorExample = "0x25690ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9abc";
|
|
2526
|
+
const offerExample = {
|
|
2527
|
+
offer: {
|
|
2528
|
+
obligation: {
|
|
2529
|
+
loan_token: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
|
|
2530
|
+
collaterals: [{
|
|
2531
|
+
token: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
|
|
2532
|
+
lltv: "860000000000000000",
|
|
2533
|
+
oracle: "0x45093658BE7f90B63D7c359e8f408e503c2D9401"
|
|
2534
|
+
}],
|
|
2535
|
+
maturity: 1761922799
|
|
2750
2536
|
},
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2537
|
+
buy: false,
|
|
2538
|
+
maker: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
2539
|
+
assets: "369216000000000000000000",
|
|
2540
|
+
obligation_units: "0",
|
|
2541
|
+
obligation_shares: "0",
|
|
2542
|
+
start: 1761922790,
|
|
2543
|
+
expiry: 1761922799,
|
|
2544
|
+
price: "2750000000000000000",
|
|
2545
|
+
group: "0x000000000000000000000000000000000000000000000000000000000008b8f4",
|
|
2546
|
+
session: "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
2547
|
+
callback: "0x1111111111111111111111111111111111111111",
|
|
2548
|
+
callback_data: "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000034cf890db685fc536e05652fb41f02090c3fb751000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000108e644e3ab01184155270aa92a00000000000"
|
|
2549
|
+
},
|
|
2550
|
+
offer_hash: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427",
|
|
2551
|
+
obligation_id: "0x25690ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9abc",
|
|
2552
|
+
chain_id: 1,
|
|
2553
|
+
consumed: "0",
|
|
2554
|
+
takeable: "369216000000000000000000",
|
|
2555
|
+
block_number: 0xa7495128adfb1,
|
|
2556
|
+
root: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
|
|
2557
|
+
proof: ["0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "0x9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba"],
|
|
2558
|
+
signature: "0x1234567890123456789012345678901234567890123456789012345678901234123456789012345678901234567890123456789012345678901234567890123400"
|
|
2559
|
+
};
|
|
2560
|
+
const collectorsHealthExample = {
|
|
2561
|
+
name: "offers",
|
|
2562
|
+
chain_id: 1,
|
|
2563
|
+
block_number: 21345678,
|
|
2564
|
+
updated_at: timestampExample,
|
|
2565
|
+
lag: 0,
|
|
2566
|
+
status: "live",
|
|
2567
|
+
initialized: true
|
|
2568
|
+
};
|
|
2569
|
+
const chainsHealthExample = {
|
|
2570
|
+
chain_id: 1,
|
|
2571
|
+
local_block_number: 21345678,
|
|
2572
|
+
remote_block_number: 21345690,
|
|
2573
|
+
updated_at: timestampExample,
|
|
2574
|
+
initialized: true
|
|
2575
|
+
};
|
|
2576
|
+
const missingCollectorExample = {
|
|
2577
|
+
chain_id: 1,
|
|
2578
|
+
name: "offers"
|
|
2579
|
+
};
|
|
2580
|
+
const validateOfferExample = {
|
|
2581
|
+
maker: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
2582
|
+
assets: "369216000000000000000000",
|
|
2583
|
+
obligation_units: "0",
|
|
2584
|
+
obligation_shares: "0",
|
|
2585
|
+
price: "2750000000000000000",
|
|
2586
|
+
maturity: 1761922799,
|
|
2587
|
+
expiry: 1761922799,
|
|
2588
|
+
start: 1761922790,
|
|
2589
|
+
group: "0x000000000000000000000000000000000000000000000000000000000008b8f4",
|
|
2590
|
+
session: "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
2591
|
+
buy: false,
|
|
2592
|
+
chain_id: 1,
|
|
2593
|
+
loan_token: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
|
|
2594
|
+
collaterals: [{
|
|
2595
|
+
asset: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
|
|
2596
|
+
oracle: "0x45093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
2597
|
+
lltv: "860000000000000000"
|
|
2598
|
+
}],
|
|
2599
|
+
callback: {
|
|
2600
|
+
address: "0x1111111111111111111111111111111111111111",
|
|
2601
|
+
data: "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000034cf890db685fc536e05652fb41f02090c3fb751000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000108e644e3ab01184155270aa92a00000000000"
|
|
2602
|
+
}
|
|
2603
|
+
};
|
|
2604
|
+
const routerStatusExample = {
|
|
2605
|
+
status: "live",
|
|
2606
|
+
initialized: true,
|
|
2607
|
+
missing_chains: [],
|
|
2608
|
+
missing_collectors: []
|
|
2609
|
+
};
|
|
2610
|
+
var Meta = class {};
|
|
2611
|
+
__decorate([ApiProperty({
|
|
2612
|
+
type: "string",
|
|
2613
|
+
example: timestampExample
|
|
2614
|
+
})], Meta.prototype, "timestamp", void 0);
|
|
2615
|
+
var SuccessResponse = class {};
|
|
2616
|
+
__decorate([ApiProperty({ type: () => Meta })], SuccessResponse.prototype, "meta", void 0);
|
|
2617
|
+
var ErrorResponse = class {};
|
|
2618
|
+
__decorate([ApiProperty({
|
|
2619
|
+
type: "string",
|
|
2620
|
+
enum: API_ERROR_CODES,
|
|
2621
|
+
example: "VALIDATION_ERROR"
|
|
2622
|
+
})], ErrorResponse.prototype, "code", void 0);
|
|
2623
|
+
__decorate([ApiProperty({
|
|
2624
|
+
type: "string",
|
|
2625
|
+
example: "Limit must be greater than 0."
|
|
2626
|
+
})], ErrorResponse.prototype, "message", void 0);
|
|
2627
|
+
__decorate([ApiProperty({
|
|
2628
|
+
type: "object",
|
|
2629
|
+
example: [{
|
|
2630
|
+
field: "limit",
|
|
2631
|
+
issue: "Limit must be greater than 0."
|
|
2632
|
+
}]
|
|
2633
|
+
})], ErrorResponse.prototype, "details", void 0);
|
|
2634
|
+
var BadRequestResponse = class {};
|
|
2635
|
+
__decorate([ApiProperty({ type: () => ErrorResponse })], BadRequestResponse.prototype, "error", void 0);
|
|
2636
|
+
__decorate([ApiProperty({ type: () => Meta })], BadRequestResponse.prototype, "meta", void 0);
|
|
2637
|
+
var CollateralResponse = class {};
|
|
2638
|
+
__decorate([ApiProperty({
|
|
2639
|
+
type: "string",
|
|
2640
|
+
example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751"
|
|
2641
|
+
})], CollateralResponse.prototype, "token", void 0);
|
|
2642
|
+
__decorate([ApiProperty({
|
|
2643
|
+
type: "string",
|
|
2644
|
+
example: "860000000000000000"
|
|
2645
|
+
})], CollateralResponse.prototype, "lltv", void 0);
|
|
2646
|
+
__decorate([ApiProperty({
|
|
2647
|
+
type: "string",
|
|
2648
|
+
example: "0x45093658BE7f90B63D7c359e8f408e503c2D9401"
|
|
2649
|
+
})], CollateralResponse.prototype, "oracle", void 0);
|
|
2650
|
+
var ValidateCollateralRequest = class {};
|
|
2651
|
+
__decorate([ApiProperty({
|
|
2652
|
+
type: "string",
|
|
2653
|
+
example: validateOfferExample.collaterals[0].asset
|
|
2654
|
+
})], ValidateCollateralRequest.prototype, "asset", void 0);
|
|
2655
|
+
__decorate([ApiProperty({
|
|
2656
|
+
type: "string",
|
|
2657
|
+
example: validateOfferExample.collaterals[0].oracle
|
|
2658
|
+
})], ValidateCollateralRequest.prototype, "oracle", void 0);
|
|
2659
|
+
__decorate([ApiProperty({
|
|
2660
|
+
type: "string",
|
|
2661
|
+
example: validateOfferExample.collaterals[0].lltv
|
|
2662
|
+
})], ValidateCollateralRequest.prototype, "lltv", void 0);
|
|
2663
|
+
var ValidateCallbackRequest = class {};
|
|
2664
|
+
__decorate([ApiProperty({
|
|
2665
|
+
type: "string",
|
|
2666
|
+
example: validateOfferExample.callback.address
|
|
2667
|
+
})], ValidateCallbackRequest.prototype, "address", void 0);
|
|
2668
|
+
__decorate([ApiProperty({
|
|
2669
|
+
type: "string",
|
|
2670
|
+
example: validateOfferExample.callback.data
|
|
2671
|
+
})], ValidateCallbackRequest.prototype, "data", void 0);
|
|
2672
|
+
var AskResponse = class {};
|
|
2673
|
+
__decorate([ApiProperty({
|
|
2674
|
+
type: "string",
|
|
2675
|
+
example: "1000000000000000000"
|
|
2676
|
+
})], AskResponse.prototype, "price", void 0);
|
|
2677
|
+
var BidResponse = class {};
|
|
2678
|
+
__decorate([ApiProperty({
|
|
2679
|
+
type: "string",
|
|
2680
|
+
example: "1000000000000000000"
|
|
2681
|
+
})], BidResponse.prototype, "price", void 0);
|
|
2682
|
+
var ObligationOfferResponse = class {};
|
|
2683
|
+
__decorate([ApiProperty({
|
|
2684
|
+
type: "string",
|
|
2685
|
+
example: offerExample.offer.obligation.loan_token
|
|
2686
|
+
})], ObligationOfferResponse.prototype, "loan_token", void 0);
|
|
2687
|
+
__decorate([ApiProperty({
|
|
2688
|
+
type: () => [CollateralResponse],
|
|
2689
|
+
example: offerExample.offer.obligation.collaterals
|
|
2690
|
+
})], ObligationOfferResponse.prototype, "collaterals", void 0);
|
|
2691
|
+
__decorate([ApiProperty({
|
|
2692
|
+
type: "number",
|
|
2693
|
+
example: offerExample.offer.obligation.maturity
|
|
2694
|
+
})], ObligationOfferResponse.prototype, "maturity", void 0);
|
|
2695
|
+
var OfferDataResponse = class {};
|
|
2696
|
+
__decorate([ApiProperty({
|
|
2697
|
+
type: () => ObligationOfferResponse,
|
|
2698
|
+
example: offerExample.offer.obligation
|
|
2699
|
+
})], OfferDataResponse.prototype, "obligation", void 0);
|
|
2700
|
+
__decorate([ApiProperty({
|
|
2701
|
+
type: "boolean",
|
|
2702
|
+
example: offerExample.offer.buy
|
|
2703
|
+
})], OfferDataResponse.prototype, "buy", void 0);
|
|
2704
|
+
__decorate([ApiProperty({
|
|
2705
|
+
type: "string",
|
|
2706
|
+
example: offerExample.offer.maker
|
|
2707
|
+
})], OfferDataResponse.prototype, "maker", void 0);
|
|
2708
|
+
__decorate([ApiProperty({
|
|
2709
|
+
type: "string",
|
|
2710
|
+
example: offerExample.offer.assets
|
|
2711
|
+
})], OfferDataResponse.prototype, "assets", void 0);
|
|
2712
|
+
__decorate([ApiProperty({
|
|
2713
|
+
type: "string",
|
|
2714
|
+
example: offerExample.offer.obligation_units
|
|
2715
|
+
})], OfferDataResponse.prototype, "obligation_units", void 0);
|
|
2716
|
+
__decorate([ApiProperty({
|
|
2717
|
+
type: "string",
|
|
2718
|
+
example: offerExample.offer.obligation_shares
|
|
2719
|
+
})], OfferDataResponse.prototype, "obligation_shares", void 0);
|
|
2720
|
+
__decorate([ApiProperty({
|
|
2721
|
+
type: "number",
|
|
2722
|
+
example: offerExample.offer.start
|
|
2723
|
+
})], OfferDataResponse.prototype, "start", void 0);
|
|
2724
|
+
__decorate([ApiProperty({
|
|
2725
|
+
type: "number",
|
|
2726
|
+
example: offerExample.offer.expiry
|
|
2727
|
+
})], OfferDataResponse.prototype, "expiry", void 0);
|
|
2728
|
+
__decorate([ApiProperty({
|
|
2729
|
+
type: "string",
|
|
2730
|
+
example: offerExample.offer.price
|
|
2731
|
+
})], OfferDataResponse.prototype, "price", void 0);
|
|
2732
|
+
__decorate([ApiProperty({
|
|
2733
|
+
type: "string",
|
|
2734
|
+
example: offerExample.offer.group
|
|
2735
|
+
})], OfferDataResponse.prototype, "group", void 0);
|
|
2736
|
+
__decorate([ApiProperty({
|
|
2737
|
+
type: "string",
|
|
2738
|
+
example: offerExample.offer.session
|
|
2739
|
+
})], OfferDataResponse.prototype, "session", void 0);
|
|
2740
|
+
__decorate([ApiProperty({
|
|
2741
|
+
type: "string",
|
|
2742
|
+
example: offerExample.offer.callback
|
|
2743
|
+
})], OfferDataResponse.prototype, "callback", void 0);
|
|
2744
|
+
__decorate([ApiProperty({
|
|
2745
|
+
type: "string",
|
|
2746
|
+
example: offerExample.offer.callback_data
|
|
2747
|
+
})], OfferDataResponse.prototype, "callback_data", void 0);
|
|
2748
|
+
var OfferListItemResponse = class {};
|
|
2749
|
+
__decorate([ApiProperty({
|
|
2750
|
+
type: () => OfferDataResponse,
|
|
2751
|
+
example: offerExample.offer
|
|
2752
|
+
})], OfferListItemResponse.prototype, "offer", void 0);
|
|
2753
|
+
__decorate([ApiProperty({
|
|
2754
|
+
type: "string",
|
|
2755
|
+
example: offerExample.offer_hash
|
|
2756
|
+
})], OfferListItemResponse.prototype, "offer_hash", void 0);
|
|
2757
|
+
__decorate([ApiProperty({
|
|
2758
|
+
type: "string",
|
|
2759
|
+
example: offerExample.obligation_id
|
|
2760
|
+
})], OfferListItemResponse.prototype, "obligation_id", void 0);
|
|
2761
|
+
__decorate([ApiProperty({
|
|
2762
|
+
type: "number",
|
|
2763
|
+
example: offerExample.chain_id
|
|
2764
|
+
})], OfferListItemResponse.prototype, "chain_id", void 0);
|
|
2765
|
+
__decorate([ApiProperty({
|
|
2766
|
+
type: "string",
|
|
2767
|
+
example: offerExample.consumed
|
|
2768
|
+
})], OfferListItemResponse.prototype, "consumed", void 0);
|
|
2769
|
+
__decorate([ApiProperty({
|
|
2770
|
+
type: "string",
|
|
2771
|
+
example: offerExample.takeable
|
|
2772
|
+
})], OfferListItemResponse.prototype, "takeable", void 0);
|
|
2773
|
+
__decorate([ApiProperty({
|
|
2774
|
+
type: "number",
|
|
2775
|
+
example: offerExample.block_number
|
|
2776
|
+
})], OfferListItemResponse.prototype, "block_number", void 0);
|
|
2777
|
+
__decorate([ApiProperty({
|
|
2778
|
+
type: "string",
|
|
2779
|
+
nullable: true,
|
|
2780
|
+
example: offerExample.root
|
|
2781
|
+
})], OfferListItemResponse.prototype, "root", void 0);
|
|
2782
|
+
__decorate([ApiProperty({
|
|
2783
|
+
type: [String],
|
|
2784
|
+
nullable: true,
|
|
2785
|
+
example: offerExample.proof
|
|
2786
|
+
})], OfferListItemResponse.prototype, "proof", void 0);
|
|
2787
|
+
__decorate([ApiProperty({
|
|
2788
|
+
type: "string",
|
|
2789
|
+
nullable: true,
|
|
2790
|
+
example: offerExample.signature
|
|
2791
|
+
})], OfferListItemResponse.prototype, "signature", void 0);
|
|
2792
|
+
var ObligationResponse = class {};
|
|
2793
|
+
__decorate([ApiProperty({
|
|
2794
|
+
type: "string",
|
|
2795
|
+
example: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67"
|
|
2796
|
+
})], ObligationResponse.prototype, "id", void 0);
|
|
2797
|
+
__decorate([ApiProperty({
|
|
2798
|
+
type: "number",
|
|
2799
|
+
example: 1
|
|
2800
|
+
})], ObligationResponse.prototype, "chain_id", void 0);
|
|
2801
|
+
__decorate([ApiProperty({
|
|
2802
|
+
type: "string",
|
|
2803
|
+
example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078"
|
|
2804
|
+
})], ObligationResponse.prototype, "loan_token", void 0);
|
|
2805
|
+
__decorate([ApiProperty({ type: () => [CollateralResponse] })], ObligationResponse.prototype, "collaterals", void 0);
|
|
2806
|
+
__decorate([ApiProperty({
|
|
2807
|
+
type: "number",
|
|
2808
|
+
example: 1761922800
|
|
2809
|
+
})], ObligationResponse.prototype, "maturity", void 0);
|
|
2810
|
+
__decorate([ApiProperty({ type: () => AskResponse })], ObligationResponse.prototype, "ask", void 0);
|
|
2811
|
+
__decorate([ApiProperty({ type: () => BidResponse })], ObligationResponse.prototype, "bid", void 0);
|
|
2812
|
+
var ObligationListResponse = class extends SuccessResponse {};
|
|
2813
|
+
__decorate([ApiProperty({
|
|
2814
|
+
type: "string",
|
|
2815
|
+
nullable: true,
|
|
2816
|
+
example: obligationCursorExample
|
|
2817
|
+
})], ObligationListResponse.prototype, "cursor", void 0);
|
|
2818
|
+
__decorate([ApiProperty({
|
|
2819
|
+
type: () => [ObligationResponse],
|
|
2820
|
+
description: "List of obligations with takable offers."
|
|
2821
|
+
})], ObligationListResponse.prototype, "data", void 0);
|
|
2822
|
+
var ObligationSingleSuccessResponse = class extends SuccessResponse {};
|
|
2823
|
+
__decorate([ApiProperty({
|
|
2824
|
+
type: "string",
|
|
2825
|
+
nullable: true,
|
|
2826
|
+
example: null
|
|
2827
|
+
})], ObligationSingleSuccessResponse.prototype, "cursor", void 0);
|
|
2828
|
+
__decorate([ApiProperty({
|
|
2829
|
+
type: () => ObligationResponse,
|
|
2830
|
+
description: "Obligation details."
|
|
2831
|
+
})], ObligationSingleSuccessResponse.prototype, "data", void 0);
|
|
2832
|
+
var OfferListResponse = class extends SuccessResponse {};
|
|
2833
|
+
__decorate([ApiProperty({
|
|
2834
|
+
type: "string",
|
|
2835
|
+
nullable: true,
|
|
2836
|
+
example: offerCursorExample
|
|
2837
|
+
})], OfferListResponse.prototype, "cursor", void 0);
|
|
2838
|
+
__decorate([ApiProperty({
|
|
2839
|
+
type: () => [OfferListItemResponse],
|
|
2840
|
+
description: "Offers matching the provided filters.",
|
|
2841
|
+
example: [offerExample]
|
|
2842
|
+
})], OfferListResponse.prototype, "data", void 0);
|
|
2843
|
+
var MissingCollectorResponse = class {};
|
|
2844
|
+
__decorate([ApiProperty({
|
|
2845
|
+
type: "number",
|
|
2846
|
+
example: missingCollectorExample.chain_id
|
|
2847
|
+
})], MissingCollectorResponse.prototype, "chain_id", void 0);
|
|
2848
|
+
__decorate([ApiProperty({
|
|
2849
|
+
type: "string",
|
|
2850
|
+
example: missingCollectorExample.name
|
|
2851
|
+
})], MissingCollectorResponse.prototype, "name", void 0);
|
|
2852
|
+
var RouterStatusDataResponse = class {};
|
|
2853
|
+
__decorate([ApiProperty({
|
|
2854
|
+
type: "string",
|
|
2855
|
+
enum: ["live", "syncing"],
|
|
2856
|
+
example: routerStatusExample.status
|
|
2857
|
+
})], RouterStatusDataResponse.prototype, "status", void 0);
|
|
2858
|
+
__decorate([ApiProperty({
|
|
2859
|
+
type: "boolean",
|
|
2860
|
+
example: routerStatusExample.initialized
|
|
2861
|
+
})], RouterStatusDataResponse.prototype, "initialized", void 0);
|
|
2862
|
+
__decorate([ApiProperty({
|
|
2863
|
+
type: () => [Number],
|
|
2864
|
+
example: routerStatusExample.missing_chains,
|
|
2865
|
+
description: "Configured chain ids missing initialization rows."
|
|
2866
|
+
})], RouterStatusDataResponse.prototype, "missing_chains", void 0);
|
|
2867
|
+
__decorate([ApiProperty({
|
|
2868
|
+
type: () => [MissingCollectorResponse],
|
|
2869
|
+
example: routerStatusExample.missing_collectors,
|
|
2870
|
+
description: "Collectors missing initialization rows."
|
|
2871
|
+
})], RouterStatusDataResponse.prototype, "missing_collectors", void 0);
|
|
2872
|
+
var RouterStatusSuccessResponse = class extends SuccessResponse {};
|
|
2873
|
+
__decorate([ApiProperty({
|
|
2874
|
+
type: () => RouterStatusDataResponse,
|
|
2875
|
+
description: "Aggregated router status.",
|
|
2876
|
+
example: routerStatusExample
|
|
2877
|
+
})], RouterStatusSuccessResponse.prototype, "data", void 0);
|
|
2878
|
+
var CollectorHealthResponse = class {};
|
|
2879
|
+
__decorate([ApiProperty({
|
|
2880
|
+
type: "string",
|
|
2881
|
+
example: collectorsHealthExample.name
|
|
2882
|
+
})], CollectorHealthResponse.prototype, "name", void 0);
|
|
2883
|
+
__decorate([ApiProperty({
|
|
2884
|
+
type: "number",
|
|
2885
|
+
example: collectorsHealthExample.chain_id
|
|
2886
|
+
})], CollectorHealthResponse.prototype, "chain_id", void 0);
|
|
2887
|
+
__decorate([ApiProperty({
|
|
2888
|
+
type: "number",
|
|
2889
|
+
nullable: true,
|
|
2890
|
+
example: collectorsHealthExample.block_number
|
|
2891
|
+
})], CollectorHealthResponse.prototype, "block_number", void 0);
|
|
2892
|
+
__decorate([ApiProperty({
|
|
2893
|
+
type: "string",
|
|
2894
|
+
nullable: true,
|
|
2895
|
+
example: collectorsHealthExample.updated_at
|
|
2896
|
+
})], CollectorHealthResponse.prototype, "updated_at", void 0);
|
|
2897
|
+
__decorate([ApiProperty({
|
|
2898
|
+
type: "number",
|
|
2899
|
+
nullable: true,
|
|
2900
|
+
example: collectorsHealthExample.lag
|
|
2901
|
+
})], CollectorHealthResponse.prototype, "lag", void 0);
|
|
2902
|
+
__decorate([ApiProperty({
|
|
2903
|
+
type: "string",
|
|
2904
|
+
enum: [
|
|
2905
|
+
"live",
|
|
2906
|
+
"lagging",
|
|
2907
|
+
"unknown"
|
|
2757
2908
|
],
|
|
2758
|
-
|
|
2909
|
+
example: collectorsHealthExample.status
|
|
2910
|
+
})], CollectorHealthResponse.prototype, "status", void 0);
|
|
2911
|
+
__decorate([ApiProperty({
|
|
2912
|
+
type: "boolean",
|
|
2913
|
+
example: collectorsHealthExample.initialized
|
|
2914
|
+
})], CollectorHealthResponse.prototype, "initialized", void 0);
|
|
2915
|
+
var CollectorsHealthSuccessResponse = class extends SuccessResponse {};
|
|
2916
|
+
__decorate([ApiProperty({
|
|
2917
|
+
type: () => [CollectorHealthResponse],
|
|
2918
|
+
description: "Collectors health details and sync status.",
|
|
2919
|
+
example: [collectorsHealthExample]
|
|
2920
|
+
})], CollectorsHealthSuccessResponse.prototype, "data", void 0);
|
|
2921
|
+
var ChainHealthResponse = class {};
|
|
2922
|
+
__decorate([ApiProperty({
|
|
2923
|
+
type: "number",
|
|
2924
|
+
example: chainsHealthExample.chain_id
|
|
2925
|
+
})], ChainHealthResponse.prototype, "chain_id", void 0);
|
|
2926
|
+
__decorate([ApiProperty({
|
|
2927
|
+
type: "number",
|
|
2928
|
+
nullable: true,
|
|
2929
|
+
example: chainsHealthExample.local_block_number
|
|
2930
|
+
})], ChainHealthResponse.prototype, "local_block_number", void 0);
|
|
2931
|
+
__decorate([ApiProperty({
|
|
2932
|
+
type: "number",
|
|
2933
|
+
nullable: true,
|
|
2934
|
+
example: chainsHealthExample.remote_block_number
|
|
2935
|
+
})], ChainHealthResponse.prototype, "remote_block_number", void 0);
|
|
2936
|
+
__decorate([ApiProperty({
|
|
2937
|
+
type: "string",
|
|
2938
|
+
nullable: true,
|
|
2939
|
+
example: chainsHealthExample.updated_at
|
|
2940
|
+
})], ChainHealthResponse.prototype, "updated_at", void 0);
|
|
2941
|
+
__decorate([ApiProperty({
|
|
2942
|
+
type: "boolean",
|
|
2943
|
+
example: chainsHealthExample.initialized
|
|
2944
|
+
})], ChainHealthResponse.prototype, "initialized", void 0);
|
|
2945
|
+
var ChainsHealthSuccessResponse = class extends SuccessResponse {};
|
|
2946
|
+
__decorate([ApiProperty({
|
|
2947
|
+
type: () => [ChainHealthResponse],
|
|
2948
|
+
description: "Latest processed block per chain.",
|
|
2949
|
+
example: [chainsHealthExample]
|
|
2950
|
+
})], ChainsHealthSuccessResponse.prototype, "data", void 0);
|
|
2951
|
+
var ValidateOfferRequest = class {};
|
|
2952
|
+
__decorate([ApiProperty({
|
|
2953
|
+
type: "string",
|
|
2954
|
+
example: validateOfferExample.maker
|
|
2955
|
+
})], ValidateOfferRequest.prototype, "maker", void 0);
|
|
2956
|
+
__decorate([ApiProperty({
|
|
2957
|
+
type: "string",
|
|
2958
|
+
example: validateOfferExample.assets
|
|
2959
|
+
})], ValidateOfferRequest.prototype, "assets", void 0);
|
|
2960
|
+
__decorate([ApiProperty({
|
|
2961
|
+
type: "string",
|
|
2962
|
+
example: validateOfferExample.obligation_units,
|
|
2963
|
+
required: false
|
|
2964
|
+
})], ValidateOfferRequest.prototype, "obligation_units", void 0);
|
|
2965
|
+
__decorate([ApiProperty({
|
|
2966
|
+
type: "string",
|
|
2967
|
+
example: validateOfferExample.obligation_shares,
|
|
2968
|
+
required: false
|
|
2969
|
+
})], ValidateOfferRequest.prototype, "obligation_shares", void 0);
|
|
2970
|
+
__decorate([ApiProperty({
|
|
2971
|
+
type: "string",
|
|
2972
|
+
example: validateOfferExample.price
|
|
2973
|
+
})], ValidateOfferRequest.prototype, "price", void 0);
|
|
2974
|
+
__decorate([ApiProperty({
|
|
2975
|
+
type: "number",
|
|
2976
|
+
example: validateOfferExample.maturity
|
|
2977
|
+
})], ValidateOfferRequest.prototype, "maturity", void 0);
|
|
2978
|
+
__decorate([ApiProperty({
|
|
2979
|
+
type: "number",
|
|
2980
|
+
example: validateOfferExample.expiry
|
|
2981
|
+
})], ValidateOfferRequest.prototype, "expiry", void 0);
|
|
2982
|
+
__decorate([ApiProperty({
|
|
2983
|
+
type: "number",
|
|
2984
|
+
example: validateOfferExample.start
|
|
2985
|
+
})], ValidateOfferRequest.prototype, "start", void 0);
|
|
2986
|
+
__decorate([ApiProperty({
|
|
2987
|
+
type: "string",
|
|
2988
|
+
example: validateOfferExample.group
|
|
2989
|
+
})], ValidateOfferRequest.prototype, "group", void 0);
|
|
2990
|
+
__decorate([ApiProperty({
|
|
2991
|
+
type: "string",
|
|
2992
|
+
example: validateOfferExample.session
|
|
2993
|
+
})], ValidateOfferRequest.prototype, "session", void 0);
|
|
2994
|
+
__decorate([ApiProperty({
|
|
2995
|
+
type: "boolean",
|
|
2996
|
+
example: validateOfferExample.buy
|
|
2997
|
+
})], ValidateOfferRequest.prototype, "buy", void 0);
|
|
2998
|
+
__decorate([ApiProperty({
|
|
2999
|
+
type: "number",
|
|
3000
|
+
example: validateOfferExample.chain_id
|
|
3001
|
+
})], ValidateOfferRequest.prototype, "chain_id", void 0);
|
|
3002
|
+
__decorate([ApiProperty({
|
|
3003
|
+
type: "string",
|
|
3004
|
+
example: validateOfferExample.loan_token
|
|
3005
|
+
})], ValidateOfferRequest.prototype, "loan_token", void 0);
|
|
3006
|
+
__decorate([ApiProperty({
|
|
3007
|
+
type: () => [ValidateCollateralRequest],
|
|
3008
|
+
example: validateOfferExample.collaterals
|
|
3009
|
+
})], ValidateOfferRequest.prototype, "collaterals", void 0);
|
|
3010
|
+
__decorate([ApiProperty({
|
|
3011
|
+
type: () => ValidateCallbackRequest,
|
|
3012
|
+
example: validateOfferExample.callback
|
|
3013
|
+
})], ValidateOfferRequest.prototype, "callback", void 0);
|
|
3014
|
+
var ValidateOffersRequest = class {};
|
|
3015
|
+
__decorate([ApiProperty({
|
|
3016
|
+
type: () => [ValidateOfferRequest],
|
|
3017
|
+
description: "Array of offers in snake_case format. Required, non-empty.",
|
|
3018
|
+
required: true
|
|
3019
|
+
})], ValidateOffersRequest.prototype, "offers", void 0);
|
|
3020
|
+
var ValidationSuccessDataResponse = class {};
|
|
3021
|
+
__decorate([ApiProperty({
|
|
3022
|
+
type: "string",
|
|
3023
|
+
description: "Unsigned payload: version (1B) + gzip(offers) + root (32B).",
|
|
3024
|
+
example: "0x01789c..."
|
|
3025
|
+
})], ValidationSuccessDataResponse.prototype, "payload", void 0);
|
|
3026
|
+
__decorate([ApiProperty({
|
|
3027
|
+
type: "string",
|
|
3028
|
+
description: "Merkle tree root to sign with EIP-191.",
|
|
3029
|
+
example: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427"
|
|
3030
|
+
})], ValidationSuccessDataResponse.prototype, "root", void 0);
|
|
3031
|
+
var ValidationSuccessResponse = class extends SuccessResponse {};
|
|
3032
|
+
__decorate([ApiProperty({
|
|
3033
|
+
type: "string",
|
|
3034
|
+
nullable: true,
|
|
3035
|
+
example: null
|
|
3036
|
+
})], ValidationSuccessResponse.prototype, "cursor", void 0);
|
|
3037
|
+
__decorate([ApiProperty({
|
|
3038
|
+
type: () => ValidationSuccessDataResponse,
|
|
3039
|
+
description: "Payload and root for client-side signing."
|
|
3040
|
+
})], ValidationSuccessResponse.prototype, "data", void 0);
|
|
3041
|
+
var ValidationIssueResponse = class {};
|
|
3042
|
+
__decorate([ApiProperty({
|
|
3043
|
+
type: "number",
|
|
3044
|
+
description: "0-indexed position of the failed offer in the request array.",
|
|
3045
|
+
example: 0
|
|
3046
|
+
})], ValidationIssueResponse.prototype, "index", void 0);
|
|
3047
|
+
__decorate([ApiProperty({
|
|
3048
|
+
type: "string",
|
|
3049
|
+
description: "Gatekeeper rule name that rejected the offer.",
|
|
3050
|
+
example: "no_buy"
|
|
3051
|
+
})], ValidationIssueResponse.prototype, "rule", void 0);
|
|
3052
|
+
__decorate([ApiProperty({
|
|
3053
|
+
type: "string",
|
|
3054
|
+
description: "Human-readable rejection reason.",
|
|
3055
|
+
example: "Buy offers are not supported"
|
|
3056
|
+
})], ValidationIssueResponse.prototype, "message", void 0);
|
|
3057
|
+
var ValidationFailureDataResponse = class {};
|
|
3058
|
+
__decorate([ApiProperty({
|
|
3059
|
+
type: () => [ValidationIssueResponse],
|
|
3060
|
+
description: "List of validation issues. Returned when any offer fails validation."
|
|
3061
|
+
})], ValidationFailureDataResponse.prototype, "issues", void 0);
|
|
3062
|
+
var ValidationFailureResponse = class extends SuccessResponse {};
|
|
3063
|
+
__decorate([ApiProperty({
|
|
3064
|
+
type: "string",
|
|
3065
|
+
nullable: true,
|
|
3066
|
+
example: null
|
|
3067
|
+
})], ValidationFailureResponse.prototype, "cursor", void 0);
|
|
3068
|
+
__decorate([ApiProperty({
|
|
3069
|
+
type: () => ValidationFailureDataResponse,
|
|
3070
|
+
description: "List of validation issues. Returned when any offer fails validation."
|
|
3071
|
+
})], ValidationFailureResponse.prototype, "data", void 0);
|
|
3072
|
+
var BookLevelResponse = class {};
|
|
3073
|
+
__decorate([ApiProperty({
|
|
3074
|
+
type: "string",
|
|
3075
|
+
example: "2750000000000000000"
|
|
3076
|
+
})], BookLevelResponse.prototype, "price", void 0);
|
|
3077
|
+
__decorate([ApiProperty({
|
|
3078
|
+
type: "string",
|
|
3079
|
+
example: "369216000000000000000000"
|
|
3080
|
+
})], BookLevelResponse.prototype, "assets", void 0);
|
|
3081
|
+
__decorate([ApiProperty({
|
|
3082
|
+
type: "number",
|
|
3083
|
+
example: 5
|
|
3084
|
+
})], BookLevelResponse.prototype, "count", void 0);
|
|
3085
|
+
const positionExample = {
|
|
3086
|
+
chain_id: 1,
|
|
3087
|
+
contract: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
|
|
3088
|
+
user: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
3089
|
+
reserved: "200000000000000000000",
|
|
3090
|
+
block_number: 21345678
|
|
3091
|
+
};
|
|
3092
|
+
var PositionListItemResponse = class {};
|
|
3093
|
+
__decorate([ApiProperty({
|
|
3094
|
+
type: "number",
|
|
3095
|
+
example: positionExample.chain_id
|
|
3096
|
+
})], PositionListItemResponse.prototype, "chain_id", void 0);
|
|
3097
|
+
__decorate([ApiProperty({
|
|
3098
|
+
type: "string",
|
|
3099
|
+
example: positionExample.contract
|
|
3100
|
+
})], PositionListItemResponse.prototype, "contract", void 0);
|
|
3101
|
+
__decorate([ApiProperty({
|
|
3102
|
+
type: "string",
|
|
3103
|
+
example: positionExample.user
|
|
3104
|
+
})], PositionListItemResponse.prototype, "user", void 0);
|
|
3105
|
+
__decorate([ApiProperty({
|
|
3106
|
+
type: "string",
|
|
3107
|
+
example: positionExample.reserved
|
|
3108
|
+
})], PositionListItemResponse.prototype, "reserved", void 0);
|
|
3109
|
+
__decorate([ApiProperty({
|
|
3110
|
+
type: "number",
|
|
3111
|
+
example: positionExample.block_number
|
|
3112
|
+
})], PositionListItemResponse.prototype, "block_number", void 0);
|
|
3113
|
+
var PositionListResponse = class extends SuccessResponse {};
|
|
3114
|
+
__decorate([ApiProperty({
|
|
3115
|
+
type: "string",
|
|
3116
|
+
nullable: true,
|
|
3117
|
+
example: offerCursorExample
|
|
3118
|
+
})], PositionListResponse.prototype, "cursor", void 0);
|
|
3119
|
+
__decorate([ApiProperty({
|
|
3120
|
+
type: () => [PositionListItemResponse],
|
|
3121
|
+
description: "User positions with reserved balances from active offers.",
|
|
3122
|
+
example: [positionExample]
|
|
3123
|
+
})], PositionListResponse.prototype, "data", void 0);
|
|
3124
|
+
var BookListResponse = class extends SuccessResponse {};
|
|
3125
|
+
__decorate([ApiProperty({
|
|
3126
|
+
type: "string",
|
|
3127
|
+
nullable: true,
|
|
3128
|
+
example: offerCursorExample
|
|
3129
|
+
})], BookListResponse.prototype, "cursor", void 0);
|
|
3130
|
+
__decorate([ApiProperty({
|
|
3131
|
+
type: () => [BookLevelResponse],
|
|
3132
|
+
description: "Aggregated book levels grouped by computed price."
|
|
3133
|
+
})], BookListResponse.prototype, "data", void 0);
|
|
3134
|
+
let BooksController = class BooksController$1 {
|
|
3135
|
+
async getBook() {}
|
|
3136
|
+
};
|
|
3137
|
+
__decorate([
|
|
3138
|
+
ApiOperation({
|
|
3139
|
+
methods: ["get"],
|
|
3140
|
+
path: "/v1/books/{obligationId}/{side}",
|
|
3141
|
+
summary: "Get aggregated book",
|
|
3142
|
+
description: "Returns aggregated book data for a given obligation and side. Offers are grouped by computed price with summed takeable amounts. Book levels are sorted by price (ascending for buy side, descending for sell side)."
|
|
3143
|
+
}),
|
|
3144
|
+
ApiParam({
|
|
3145
|
+
name: "obligationId",
|
|
3146
|
+
type: "string",
|
|
3147
|
+
example: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67",
|
|
3148
|
+
description: "Obligation id."
|
|
3149
|
+
}),
|
|
3150
|
+
ApiParam({
|
|
3151
|
+
name: "side",
|
|
3152
|
+
type: "string",
|
|
3153
|
+
enum: ["buy", "sell"],
|
|
3154
|
+
example: "buy",
|
|
3155
|
+
description: "Book side (buy or sell)."
|
|
3156
|
+
}),
|
|
3157
|
+
ApiQuery({
|
|
3158
|
+
name: "cursor",
|
|
3159
|
+
type: "string",
|
|
3160
|
+
example: offerCursorExample,
|
|
3161
|
+
description: "Pagination cursor in base64url-encoded format."
|
|
3162
|
+
}),
|
|
3163
|
+
ApiQuery({
|
|
3164
|
+
name: "limit",
|
|
3165
|
+
type: "number",
|
|
3166
|
+
example: 10,
|
|
3167
|
+
description: "Maximum number of price levels to return."
|
|
3168
|
+
}),
|
|
3169
|
+
ApiResponse({
|
|
3170
|
+
status: 200,
|
|
3171
|
+
description: "Success",
|
|
3172
|
+
type: BookListResponse
|
|
3173
|
+
})
|
|
3174
|
+
], BooksController.prototype, "getBook", null);
|
|
3175
|
+
BooksController = __decorate([ApiTags("Markets"), ApiResponse({
|
|
3176
|
+
status: 400,
|
|
3177
|
+
description: "Bad Request",
|
|
3178
|
+
type: BadRequestResponse
|
|
3179
|
+
})], BooksController);
|
|
3180
|
+
let ValidateController = class ValidateController$1 {
|
|
3181
|
+
async validateOffers() {}
|
|
3182
|
+
};
|
|
3183
|
+
__decorate([
|
|
3184
|
+
ApiOperation({
|
|
3185
|
+
methods: ["post"],
|
|
3186
|
+
path: "/v1/validate",
|
|
3187
|
+
summary: "Validate offers",
|
|
3188
|
+
description: "Validates offers against router validation rules. Returns unsigned payload + root on success, or issues only on validation failure."
|
|
3189
|
+
}),
|
|
3190
|
+
ApiBody({ type: ValidateOffersRequest }),
|
|
3191
|
+
ApiResponse({
|
|
3192
|
+
status: 200,
|
|
3193
|
+
description: "Success",
|
|
3194
|
+
type: ValidationSuccessResponse
|
|
3195
|
+
}),
|
|
3196
|
+
ApiResponse({
|
|
3197
|
+
status: 200,
|
|
3198
|
+
description: "Validation issues",
|
|
3199
|
+
type: ValidationFailureResponse
|
|
3200
|
+
})
|
|
3201
|
+
], ValidateController.prototype, "validateOffers", null);
|
|
3202
|
+
ValidateController = __decorate([ApiTags("Make"), ApiResponse({
|
|
3203
|
+
status: 400,
|
|
3204
|
+
description: "Bad Request",
|
|
3205
|
+
type: BadRequestResponse
|
|
3206
|
+
})], ValidateController);
|
|
3207
|
+
let OffersController = class OffersController$1 {
|
|
3208
|
+
async getOffers() {}
|
|
3209
|
+
};
|
|
3210
|
+
__decorate([
|
|
3211
|
+
ApiOperation({
|
|
3212
|
+
methods: ["get"],
|
|
3213
|
+
path: "/v1/offers",
|
|
3214
|
+
summary: "List all offers",
|
|
3215
|
+
description: "Returns offers. Provide either `obligation_id` + `side` (order book) or `maker` (by maker address)."
|
|
3216
|
+
}),
|
|
3217
|
+
ApiQuery({
|
|
3218
|
+
name: "side",
|
|
3219
|
+
type: "string",
|
|
3220
|
+
required: false,
|
|
3221
|
+
enum: ["buy", "sell"],
|
|
3222
|
+
example: "buy",
|
|
3223
|
+
description: "Side of the offer. Required when using obligation_id."
|
|
3224
|
+
}),
|
|
3225
|
+
ApiQuery({
|
|
3226
|
+
name: "obligation_id",
|
|
3227
|
+
type: "string",
|
|
3228
|
+
required: false,
|
|
3229
|
+
example: "0x1234567890123456789012345678901234567890123456789012345678901234",
|
|
3230
|
+
description: "Obligation id used to filter offers. Required when not using maker."
|
|
3231
|
+
}),
|
|
3232
|
+
ApiQuery({
|
|
3233
|
+
name: "maker",
|
|
3234
|
+
type: "string",
|
|
3235
|
+
required: false,
|
|
3236
|
+
example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
3237
|
+
description: "Maker address to filter offers by. Alternative to obligation_id + side."
|
|
3238
|
+
}),
|
|
3239
|
+
ApiQuery({
|
|
3240
|
+
name: "cursor",
|
|
3241
|
+
type: "string",
|
|
3242
|
+
example: offerCursorExample,
|
|
3243
|
+
description: "Pagination cursor in base64url-encoded format."
|
|
3244
|
+
}),
|
|
3245
|
+
ApiQuery({
|
|
3246
|
+
name: "limit",
|
|
3247
|
+
type: "number",
|
|
3248
|
+
example: 10,
|
|
3249
|
+
description: "Maximum number of offers to return."
|
|
3250
|
+
}),
|
|
3251
|
+
ApiResponse({
|
|
3252
|
+
status: 200,
|
|
3253
|
+
description: "Success",
|
|
3254
|
+
type: OfferListResponse
|
|
3255
|
+
})
|
|
3256
|
+
], OffersController.prototype, "getOffers", null);
|
|
3257
|
+
OffersController = __decorate([ApiTags("Markets"), ApiResponse({
|
|
3258
|
+
status: 400,
|
|
3259
|
+
description: "Bad Request",
|
|
3260
|
+
type: BadRequestResponse
|
|
3261
|
+
})], OffersController);
|
|
3262
|
+
let HealthController = class HealthController$1 {
|
|
3263
|
+
async getRouterStatus() {}
|
|
3264
|
+
async getCollectorsHealth() {}
|
|
3265
|
+
async getChainsHealth() {}
|
|
2759
3266
|
};
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
3267
|
+
__decorate([
|
|
3268
|
+
ApiOperation({
|
|
3269
|
+
methods: ["get"],
|
|
3270
|
+
path: "/v1/health",
|
|
3271
|
+
summary: "Retrieve global health",
|
|
3272
|
+
description: "Returns the aggregated status of the router."
|
|
3273
|
+
}),
|
|
3274
|
+
ApiQuery({
|
|
3275
|
+
name: "strict",
|
|
3276
|
+
type: "boolean",
|
|
3277
|
+
required: false,
|
|
3278
|
+
example: true,
|
|
3279
|
+
description: "Fail the request if initialization is incomplete."
|
|
3280
|
+
}),
|
|
3281
|
+
ApiResponse({
|
|
3282
|
+
status: 200,
|
|
3283
|
+
description: "Success",
|
|
3284
|
+
type: RouterStatusSuccessResponse
|
|
3285
|
+
})
|
|
3286
|
+
], HealthController.prototype, "getRouterStatus", null);
|
|
3287
|
+
__decorate([
|
|
3288
|
+
ApiOperation({
|
|
3289
|
+
methods: ["get"],
|
|
3290
|
+
path: "/v1/health/collectors",
|
|
3291
|
+
summary: "Retrieve collectors health",
|
|
3292
|
+
description: "Returns the latest block numbers processed by collectors and their sync status."
|
|
3293
|
+
}),
|
|
3294
|
+
ApiQuery({
|
|
3295
|
+
name: "strict",
|
|
3296
|
+
type: "boolean",
|
|
3297
|
+
required: false,
|
|
3298
|
+
example: true,
|
|
3299
|
+
description: "Fail the request if initialization is incomplete."
|
|
3300
|
+
}),
|
|
3301
|
+
ApiResponse({
|
|
3302
|
+
status: 200,
|
|
3303
|
+
description: "Success",
|
|
3304
|
+
type: CollectorsHealthSuccessResponse
|
|
3305
|
+
})
|
|
3306
|
+
], HealthController.prototype, "getCollectorsHealth", null);
|
|
3307
|
+
__decorate([
|
|
3308
|
+
ApiOperation({
|
|
3309
|
+
methods: ["get"],
|
|
3310
|
+
path: "/v1/health/chains",
|
|
3311
|
+
summary: "Retrieve chains health",
|
|
3312
|
+
description: "Returns the latest block that can be processed by collectors for each chain."
|
|
3313
|
+
}),
|
|
3314
|
+
ApiQuery({
|
|
3315
|
+
name: "strict",
|
|
3316
|
+
type: "boolean",
|
|
3317
|
+
required: false,
|
|
3318
|
+
example: true,
|
|
3319
|
+
description: "Fail the request if initialization is incomplete."
|
|
3320
|
+
}),
|
|
3321
|
+
ApiResponse({
|
|
3322
|
+
status: 200,
|
|
3323
|
+
description: "Success",
|
|
3324
|
+
type: ChainsHealthSuccessResponse
|
|
3325
|
+
})
|
|
3326
|
+
], HealthController.prototype, "getChainsHealth", null);
|
|
3327
|
+
HealthController = __decorate([ApiTags("System")], HealthController);
|
|
3328
|
+
const maturitiesExample = {
|
|
3329
|
+
end_of_month: 1738335600,
|
|
3330
|
+
end_of_next_month: 1740754800
|
|
2783
3331
|
};
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
}
|
|
3332
|
+
const chainConfigExample = {
|
|
3333
|
+
chain_id: 505050505,
|
|
3334
|
+
contracts: { mempool: "0xD946246695A9259F3B33a78629026F61B3Ab40aF" },
|
|
3335
|
+
maturities: maturitiesExample
|
|
2789
3336
|
};
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
(
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
3337
|
+
var ConfigContractsResponse = class {};
|
|
3338
|
+
__decorate([ApiProperty({
|
|
3339
|
+
type: "string",
|
|
3340
|
+
example: chainConfigExample.contracts.mempool
|
|
3341
|
+
})], ConfigContractsResponse.prototype, "mempool", void 0);
|
|
3342
|
+
var MaturitiesResponse = class {};
|
|
3343
|
+
__decorate([ApiProperty({
|
|
3344
|
+
type: "number",
|
|
3345
|
+
description: "Unix timestamp for end of current month maturity (last Friday 15:00 UTC).",
|
|
3346
|
+
example: maturitiesExample.end_of_month
|
|
3347
|
+
})], MaturitiesResponse.prototype, "end_of_month", void 0);
|
|
3348
|
+
__decorate([ApiProperty({
|
|
3349
|
+
type: "number",
|
|
3350
|
+
description: "Unix timestamp for end of next month maturity (last Friday 15:00 UTC).",
|
|
3351
|
+
example: maturitiesExample.end_of_next_month
|
|
3352
|
+
})], MaturitiesResponse.prototype, "end_of_next_month", void 0);
|
|
3353
|
+
var ConfigDataResponse = class {};
|
|
3354
|
+
__decorate([ApiProperty({
|
|
3355
|
+
type: "number",
|
|
3356
|
+
example: chainConfigExample.chain_id
|
|
3357
|
+
})], ConfigDataResponse.prototype, "chain_id", void 0);
|
|
3358
|
+
__decorate([ApiProperty({ type: () => ConfigContractsResponse })], ConfigDataResponse.prototype, "contracts", void 0);
|
|
3359
|
+
__decorate([ApiProperty({
|
|
3360
|
+
type: () => MaturitiesResponse,
|
|
3361
|
+
description: "Supported maturity timestamps. Offers must use one of these values.",
|
|
3362
|
+
example: chainConfigExample.maturities
|
|
3363
|
+
})], ConfigDataResponse.prototype, "maturities", void 0);
|
|
3364
|
+
var ConfigSuccessResponse = class extends SuccessResponse {};
|
|
3365
|
+
__decorate([ApiProperty({
|
|
3366
|
+
type: "string",
|
|
3367
|
+
nullable: true,
|
|
3368
|
+
example: null
|
|
3369
|
+
})], ConfigSuccessResponse.prototype, "cursor", void 0);
|
|
3370
|
+
__decorate([ApiProperty({
|
|
3371
|
+
type: () => [ConfigDataResponse],
|
|
3372
|
+
description: "Array of chain configurations for all indexed chains.",
|
|
3373
|
+
example: [chainConfigExample]
|
|
3374
|
+
})], ConfigSuccessResponse.prototype, "data", void 0);
|
|
3375
|
+
let ConfigController = class ConfigController$1 {
|
|
3376
|
+
async getConfig() {}
|
|
3377
|
+
};
|
|
3378
|
+
__decorate([ApiOperation({
|
|
3379
|
+
methods: ["get"],
|
|
3380
|
+
path: "/v1/config",
|
|
3381
|
+
summary: "Get router configuration",
|
|
3382
|
+
description: "Returns chain configurations including contract addresses and supported maturity timestamps."
|
|
3383
|
+
}), ApiResponse({
|
|
3384
|
+
status: 200,
|
|
3385
|
+
description: "Success",
|
|
3386
|
+
type: ConfigSuccessResponse
|
|
3387
|
+
})], ConfigController.prototype, "getConfig", null);
|
|
3388
|
+
ConfigController = __decorate([ApiTags("System")], ConfigController);
|
|
3389
|
+
let ObligationsController = class ObligationsController$1 {
|
|
3390
|
+
async getObligations() {}
|
|
3391
|
+
async getObligation() {}
|
|
3392
|
+
};
|
|
3393
|
+
__decorate([
|
|
3394
|
+
ApiOperation({
|
|
3395
|
+
methods: ["get"],
|
|
3396
|
+
path: "/v1/obligations",
|
|
3397
|
+
summary: "List all obligations",
|
|
3398
|
+
description: "Returns a list of obligations with their current best ask and bid. Obligations are sorted by their id in ascending order by default."
|
|
3399
|
+
}),
|
|
3400
|
+
ApiQuery({
|
|
3401
|
+
name: "cursor",
|
|
3402
|
+
type: "string",
|
|
3403
|
+
example: obligationCursorExample,
|
|
3404
|
+
description: "Obligation id cursor for pagination."
|
|
3405
|
+
}),
|
|
3406
|
+
ApiQuery({
|
|
3407
|
+
name: "limit",
|
|
3408
|
+
type: "number",
|
|
3409
|
+
example: 10,
|
|
3410
|
+
description: "Maximum number of obligations to return."
|
|
3411
|
+
}),
|
|
3412
|
+
ApiQuery({
|
|
3413
|
+
name: "chain",
|
|
3414
|
+
type: "number",
|
|
3415
|
+
required: false,
|
|
3416
|
+
example: 1,
|
|
3417
|
+
description: "Filter by chain ID."
|
|
3418
|
+
}),
|
|
3419
|
+
ApiQuery({
|
|
3420
|
+
name: "loan_token",
|
|
3421
|
+
type: "string",
|
|
3422
|
+
required: false,
|
|
3423
|
+
example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
|
|
3424
|
+
description: "Filter by loan token address."
|
|
3425
|
+
}),
|
|
3426
|
+
ApiQuery({
|
|
3427
|
+
name: "collateral_token",
|
|
3428
|
+
type: "string",
|
|
3429
|
+
required: false,
|
|
3430
|
+
example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751",
|
|
3431
|
+
description: "Filter by collateral token (matches any collateral in the obligation)."
|
|
3432
|
+
}),
|
|
3433
|
+
ApiQuery({
|
|
3434
|
+
name: "maturity",
|
|
3435
|
+
type: "number",
|
|
3436
|
+
required: false,
|
|
3437
|
+
example: 1761922800,
|
|
3438
|
+
description: "Filter by exact maturity timestamp (unix seconds)."
|
|
3439
|
+
}),
|
|
3440
|
+
ApiResponse({
|
|
3441
|
+
status: 200,
|
|
3442
|
+
description: "Success",
|
|
3443
|
+
type: ObligationListResponse
|
|
3444
|
+
})
|
|
3445
|
+
], ObligationsController.prototype, "getObligations", null);
|
|
3446
|
+
__decorate([
|
|
3447
|
+
ApiOperation({
|
|
3448
|
+
methods: ["get"],
|
|
3449
|
+
path: "/v1/obligations/{obligationId}",
|
|
3450
|
+
summary: "Get an obligation",
|
|
3451
|
+
description: "Returns an obligation by its id."
|
|
3452
|
+
}),
|
|
3453
|
+
ApiParam({
|
|
3454
|
+
name: "obligationId",
|
|
3455
|
+
type: "string",
|
|
3456
|
+
example: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67",
|
|
3457
|
+
description: "Obligation id."
|
|
3458
|
+
}),
|
|
3459
|
+
ApiResponse({
|
|
3460
|
+
status: 200,
|
|
3461
|
+
description: "Success",
|
|
3462
|
+
type: ObligationSingleSuccessResponse
|
|
3463
|
+
})
|
|
3464
|
+
], ObligationsController.prototype, "getObligation", null);
|
|
3465
|
+
ObligationsController = __decorate([ApiTags("Markets"), ApiResponse({
|
|
3466
|
+
status: 400,
|
|
3467
|
+
description: "Bad Request",
|
|
3468
|
+
type: BadRequestResponse
|
|
3469
|
+
})], ObligationsController);
|
|
3470
|
+
let UsersController = class UsersController$1 {
|
|
3471
|
+
async getUserPositions() {}
|
|
3472
|
+
};
|
|
3473
|
+
__decorate([
|
|
3474
|
+
ApiOperation({
|
|
3475
|
+
methods: ["get"],
|
|
3476
|
+
path: "/v1/users/{userAddress}/positions",
|
|
3477
|
+
summary: "Get user positions",
|
|
3478
|
+
description: "Returns positions for a user with reserved balance. The reserved balance is the amount locked by active offers (max lot upper - offset - consumed)."
|
|
3479
|
+
}),
|
|
3480
|
+
ApiParam({
|
|
3481
|
+
name: "userAddress",
|
|
3482
|
+
type: "string",
|
|
3483
|
+
example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
3484
|
+
description: "User address to get positions for."
|
|
3485
|
+
}),
|
|
3486
|
+
ApiQuery({
|
|
3487
|
+
name: "cursor",
|
|
3488
|
+
type: "string",
|
|
3489
|
+
example: offerCursorExample,
|
|
3490
|
+
description: "Pagination cursor in base64url-encoded format."
|
|
3491
|
+
}),
|
|
3492
|
+
ApiQuery({
|
|
3493
|
+
name: "limit",
|
|
3494
|
+
type: "number",
|
|
3495
|
+
example: 10,
|
|
3496
|
+
description: "Maximum number of positions to return."
|
|
3497
|
+
}),
|
|
3498
|
+
ApiResponse({
|
|
3499
|
+
status: 200,
|
|
3500
|
+
description: "Success",
|
|
3501
|
+
type: PositionListResponse
|
|
3502
|
+
})
|
|
3503
|
+
], UsersController.prototype, "getUserPositions", null);
|
|
3504
|
+
UsersController = __decorate([ApiTags("Make"), ApiResponse({
|
|
3505
|
+
status: 400,
|
|
3506
|
+
description: "Bad Request",
|
|
3507
|
+
type: BadRequestResponse
|
|
3508
|
+
})], UsersController);
|
|
3509
|
+
const OpenApi = async (options = {}) => {
|
|
3510
|
+
const document = await generateDocument({
|
|
3511
|
+
controllers: [
|
|
3512
|
+
BooksController,
|
|
3513
|
+
ConfigController,
|
|
3514
|
+
OffersController,
|
|
3515
|
+
ObligationsController,
|
|
3516
|
+
HealthController,
|
|
3517
|
+
UsersController,
|
|
3518
|
+
ValidateController
|
|
3519
|
+
],
|
|
3520
|
+
document: {
|
|
3521
|
+
openapi: "3.1.0",
|
|
3522
|
+
info: {
|
|
3523
|
+
title: "Router API",
|
|
3524
|
+
version: "1.0.0",
|
|
3525
|
+
description: "API for the Morpho Router"
|
|
3526
|
+
},
|
|
3527
|
+
servers: [{
|
|
3528
|
+
url: "https://router.morpho.dev",
|
|
3529
|
+
description: "Production server"
|
|
3530
|
+
}, {
|
|
3531
|
+
url: "http://localhost:7891",
|
|
3532
|
+
description: "Local development server"
|
|
3533
|
+
}],
|
|
3534
|
+
tags: [
|
|
3535
|
+
{
|
|
3536
|
+
name: "Markets",
|
|
3537
|
+
description: "Read-only endpoints to discover markets, order books and fetch current offers."
|
|
3538
|
+
},
|
|
3539
|
+
{
|
|
3540
|
+
name: "Make",
|
|
3541
|
+
description: "Utilities to ease making offers."
|
|
3542
|
+
},
|
|
3543
|
+
{
|
|
3544
|
+
name: "System",
|
|
3545
|
+
description: "Router configuration and health monitoring."
|
|
3546
|
+
}
|
|
3547
|
+
]
|
|
3548
|
+
}
|
|
3549
|
+
});
|
|
3550
|
+
if (options.rules && options.rules.length > 0) {
|
|
3551
|
+
const rulesDescription = options.rules.map((rule) => `- **${rule.name}**: ${rule.description}`).join("\n");
|
|
3552
|
+
const validatePath = document.paths?.["/v1/validate"];
|
|
3553
|
+
if (validatePath && "post" in validatePath && validatePath.post) validatePath.post.description = `Validates offers against router validation rules. Returns unsigned payload + root on success, or issues only on validation failure.\n\n**Available validation rules:**\n${rulesDescription}`;
|
|
2819
3554
|
}
|
|
2820
|
-
|
|
2821
|
-
}
|
|
3555
|
+
return document;
|
|
3556
|
+
};
|
|
2822
3557
|
|
|
2823
3558
|
//#endregion
|
|
2824
|
-
//#region src/
|
|
2825
|
-
var
|
|
2826
|
-
Type: () => Type,
|
|
2827
|
-
from: () => from$3
|
|
2828
|
-
});
|
|
2829
|
-
let Type = /* @__PURE__ */ function(Type$1) {
|
|
2830
|
-
Type$1["ERC20"] = "erc20";
|
|
2831
|
-
Type$1["VAULT_V1"] = "vault_v1";
|
|
2832
|
-
return Type$1;
|
|
2833
|
-
}({});
|
|
3559
|
+
//#region src/api/Schema/PositionResponse.ts
|
|
3560
|
+
var PositionResponse_exports = /* @__PURE__ */ __export({ from: () => from$1 });
|
|
2834
3561
|
/**
|
|
2835
|
-
*
|
|
2836
|
-
*
|
|
2837
|
-
* @
|
|
2838
|
-
* @returns The created Position. {@link from.ReturnType}
|
|
3562
|
+
* Creates a `PositionResponse` from a `PositionWithReserved`.
|
|
3563
|
+
* @param position - {@link PositionWithReserved}
|
|
3564
|
+
* @returns The created `PositionResponse`. {@link PositionResponse}
|
|
2839
3565
|
*/
|
|
2840
|
-
function from$
|
|
3566
|
+
function from$1(position) {
|
|
2841
3567
|
return {
|
|
2842
|
-
|
|
2843
|
-
contract:
|
|
2844
|
-
user:
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
...parameters.asset !== void 0 ? { asset: parameters.asset.toLowerCase() } : {},
|
|
2848
|
-
blockNumber: parameters.blockNumber
|
|
3568
|
+
chain_id: position.chainId,
|
|
3569
|
+
contract: position.contract,
|
|
3570
|
+
user: position.user,
|
|
3571
|
+
reserved: position.reserved.toString(),
|
|
3572
|
+
block_number: position.blockNumber
|
|
2849
3573
|
};
|
|
2850
3574
|
}
|
|
2851
3575
|
|
|
2852
3576
|
//#endregion
|
|
2853
|
-
//#region src/
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
random: () => random
|
|
2860
|
-
});
|
|
2861
|
-
const QuoteSchema = z$1.object({
|
|
2862
|
-
obligationId: z$1.string().transform(transformHex),
|
|
2863
|
-
ask: z$1.object({ rate: z$1.bigint({ coerce: true }).min(0n).max(maxUint256) }),
|
|
2864
|
-
bid: z$1.object({ rate: z$1.bigint({ coerce: true }).min(0n).max(maxUint256) })
|
|
2865
|
-
});
|
|
2866
|
-
/**
|
|
2867
|
-
* Creates a quote for a given obligation.
|
|
2868
|
-
* @constructor
|
|
2869
|
-
* @param parameters - {@link from.Parameters}
|
|
2870
|
-
* @returns The created quote. {@link Quote}
|
|
2871
|
-
* @throws If the quote is invalid. {@link InvalidQuoteError}
|
|
2872
|
-
*
|
|
2873
|
-
* @example
|
|
2874
|
-
* ```ts
|
|
2875
|
-
* const quote = Quote.from({ obligationId: "0x123", ask: { assets: 100n, rate: 100n }, bid: { assets: 100n, rate: 100n } });
|
|
2876
|
-
* ```
|
|
2877
|
-
*/
|
|
2878
|
-
function from$2(parameters) {
|
|
3577
|
+
//#region src/api/Schema/requests.ts
|
|
3578
|
+
const MAX_LIMIT = 100;
|
|
3579
|
+
const DEFAULT_LIMIT = 20;
|
|
3580
|
+
/** Validate cursor is a valid base64url-encoded JSON object.
|
|
3581
|
+
* Domain layer handles semantic validation of cursor fields. */
|
|
3582
|
+
function isValidBase64urlJson(val) {
|
|
2879
3583
|
try {
|
|
2880
|
-
const
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
};
|
|
2886
|
-
} catch (error) {
|
|
2887
|
-
throw new InvalidQuoteError(error);
|
|
3584
|
+
const decoded = Buffer.from(val, "base64url").toString("utf8");
|
|
3585
|
+
JSON.parse(decoded);
|
|
3586
|
+
return true;
|
|
3587
|
+
} catch {
|
|
3588
|
+
return false;
|
|
2888
3589
|
}
|
|
2889
3590
|
}
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
}
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
3591
|
+
const PaginationQueryParams = z$1.object({
|
|
3592
|
+
cursor: z$1.string().optional().refine((val) => {
|
|
3593
|
+
if (!val) return true;
|
|
3594
|
+
return isValidBase64urlJson(val);
|
|
3595
|
+
}, { message: "Invalid cursor format. Must be a valid base64url-encoded cursor object" }).meta({
|
|
3596
|
+
description: "Pagination cursor in base64url-encoded format",
|
|
3597
|
+
example: "eyJzaWRlIjoic2VsbCIsImN1cnJlbnRQcmljZSI6IjEwMDAwMDAwMDAwMDAwMDAwMDAiLCJibG9ja051bWJlciI6MSwiYXNzZXRzIjoiMTAwMDAwMDAwMDAwMDAwMDAwMCIsImhhc2giOiIweGRmZDY4NTllM2UwODJkMTkzODlhMWFlYzFiZGFkN2U4ZDkyZDk2YjFhYTc5NDBkYTkxYTMxMjVkMzFlM2JlNWIiLCJ0b3RhbFJldHVybmVkIjoxMCwibm93IjoxNjAwMDAwMDAwfQ"
|
|
3598
|
+
}),
|
|
3599
|
+
limit: z$1.string().regex(/^[1-9]\d*$/, { message: "Limit must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).pipe(z$1.number().max(MAX_LIMIT, { message: `Limit cannot exceed ${MAX_LIMIT}` })).optional().default(DEFAULT_LIMIT).meta({
|
|
3600
|
+
description: `Limit maximum: ${MAX_LIMIT}. Default: ${DEFAULT_LIMIT}`,
|
|
3601
|
+
example: 10
|
|
3602
|
+
})
|
|
3603
|
+
});
|
|
3604
|
+
const GetOffersQueryParams = z$1.object({
|
|
3605
|
+
...PaginationQueryParams.shape,
|
|
3606
|
+
side: z$1.enum(["buy", "sell"]).optional().meta({
|
|
3607
|
+
description: "Side of the offer. Required when using obligation_id.",
|
|
3608
|
+
example: "buy"
|
|
3609
|
+
}),
|
|
3610
|
+
obligation_id: z$1.string().regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).optional().meta({
|
|
3611
|
+
description: "Offers obligation id. Required when not using maker.",
|
|
3612
|
+
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
3613
|
+
}),
|
|
3614
|
+
maker: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Maker must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
|
|
3615
|
+
description: "Maker address to filter offers by. Alternative to obligation_id + side.",
|
|
3616
|
+
example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401"
|
|
3617
|
+
})
|
|
3618
|
+
}).superRefine((val, ctx) => {
|
|
3619
|
+
const hasObligation = val.obligation_id !== void 0;
|
|
3620
|
+
const hasSide = val.side !== void 0;
|
|
3621
|
+
const hasMaker = val.maker !== void 0;
|
|
3622
|
+
if (hasMaker && (hasObligation || hasSide)) {
|
|
3623
|
+
ctx.addIssue({
|
|
3624
|
+
code: "custom",
|
|
3625
|
+
message: "Cannot use both maker and obligation_id/side parameters"
|
|
3626
|
+
});
|
|
3627
|
+
return;
|
|
3628
|
+
}
|
|
3629
|
+
if (hasMaker) return;
|
|
3630
|
+
if (!hasObligation || !hasSide) ctx.addIssue({
|
|
3631
|
+
code: "custom",
|
|
3632
|
+
message: "Must provide either maker or both obligation_id and side"
|
|
2913
3633
|
});
|
|
2914
|
-
}
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
3634
|
+
});
|
|
3635
|
+
const GetObligationsQueryParams = z$1.object({
|
|
3636
|
+
...PaginationQueryParams.shape,
|
|
3637
|
+
cursor: z$1.string().optional().meta({
|
|
3638
|
+
description: "Obligation id cursor",
|
|
3639
|
+
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
3640
|
+
}),
|
|
3641
|
+
chain: z$1.string().regex(/^[1-9]\d*$/, { message: "Chain must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).optional().meta({
|
|
3642
|
+
description: "Filter by chain ID",
|
|
3643
|
+
example: "1"
|
|
3644
|
+
}),
|
|
3645
|
+
loan_token: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Loan token must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
|
|
3646
|
+
description: "Filter by loan token address",
|
|
3647
|
+
example: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078"
|
|
3648
|
+
}),
|
|
3649
|
+
collateral_token: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Collateral token must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
|
|
3650
|
+
description: "Filter by collateral token (matches any collateral in the obligation)",
|
|
3651
|
+
example: "0x34Cf890dB685FC536E05652FB41f02090c3fb751"
|
|
3652
|
+
}),
|
|
3653
|
+
maturity: z$1.string().regex(/^[1-9]\d*$/, { message: "Maturity must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).optional().meta({
|
|
3654
|
+
description: "Filter by exact maturity timestamp (unix seconds)",
|
|
3655
|
+
example: "1761922800"
|
|
3656
|
+
})
|
|
3657
|
+
});
|
|
3658
|
+
const GetObligationParams = z$1.object({ obligation_id: z$1.string({ error: "Obligation id is required and must be a valid 32-byte hex string" }).regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).meta({
|
|
3659
|
+
description: "Obligation id",
|
|
3660
|
+
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
3661
|
+
}) });
|
|
3662
|
+
/** Validate a book cursor format: {side, lastPrice, offersCursor} */
|
|
3663
|
+
function isValidBookCursor(cursorString) {
|
|
3664
|
+
const isNumericString = (value) => typeof value === "string" && /^-?\d+$/.test(value);
|
|
3665
|
+
try {
|
|
3666
|
+
const v = JSON.parse(Buffer.from(cursorString, "base64url").toString("utf8"));
|
|
3667
|
+
return (v?.side === "buy" || v?.side === "sell") && isNumericString(v?.lastPrice) && (v?.offersCursor === null || typeof v?.offersCursor === "string");
|
|
3668
|
+
} catch {
|
|
3669
|
+
return false;
|
|
2919
3670
|
}
|
|
3671
|
+
}
|
|
3672
|
+
const BookPaginationQueryParams = z$1.object({
|
|
3673
|
+
cursor: z$1.string().optional().refine((value) => {
|
|
3674
|
+
if (!value) return true;
|
|
3675
|
+
return isValidBookCursor(value);
|
|
3676
|
+
}, { message: "Invalid cursor format. Must be a valid base64url-encoded book cursor object" }).meta({
|
|
3677
|
+
description: "Pagination cursor in base64url-encoded format for book levels",
|
|
3678
|
+
example: "eyJzaWRlIjoiYnV5IiwibGFzdFJhdGUiOiIxMDAwMDAwMDAwMDAwMDAwMDAwIiwib2ZmZXJzQ3Vyc29yIjpudWxsfQ"
|
|
3679
|
+
}),
|
|
3680
|
+
limit: z$1.string().regex(/^[1-9]\d*$/, { message: "Limit must be a positive integer" }).transform((val) => Number.parseInt(val, 10)).pipe(z$1.number().max(MAX_LIMIT, { message: `Limit cannot exceed ${MAX_LIMIT}` })).optional().default(DEFAULT_LIMIT).meta({
|
|
3681
|
+
description: `Limit maximum: ${MAX_LIMIT}. Default: ${DEFAULT_LIMIT}`,
|
|
3682
|
+
example: 10
|
|
3683
|
+
})
|
|
3684
|
+
});
|
|
3685
|
+
const HealthQueryParams = z$1.object({ strict: z$1.enum([
|
|
3686
|
+
"true",
|
|
3687
|
+
"false",
|
|
3688
|
+
"1",
|
|
3689
|
+
"0"
|
|
3690
|
+
]).transform((value) => value === "true" || value === "1").optional().meta({
|
|
3691
|
+
description: "Enable strict mode to fail health checks when initialization is incomplete.",
|
|
3692
|
+
example: "true"
|
|
3693
|
+
}) });
|
|
3694
|
+
const GetBookParams = z$1.object({
|
|
3695
|
+
...BookPaginationQueryParams.shape,
|
|
3696
|
+
obligation_id: z$1.string({ error: "Obligation id is required and must be a valid 32-byte hex string" }).regex(/^0x[a-fA-F0-9]{64}$/, { error: "Obligation id must be a valid 32-byte hex string" }).transform((val) => val.toLowerCase()).meta({
|
|
3697
|
+
description: "Obligation id",
|
|
3698
|
+
example: "0x1234567890123456789012345678901234567890123456789012345678901234"
|
|
3699
|
+
}),
|
|
3700
|
+
side: z$1.enum(["buy", "sell"]).meta({
|
|
3701
|
+
description: "Side of the book (buy or sell).",
|
|
3702
|
+
example: "buy"
|
|
3703
|
+
})
|
|
3704
|
+
});
|
|
3705
|
+
const ValidateOffersBody = z$1.object({ offers: z$1.array(z$1.unknown()).min(1, { message: "'offers' must contain at least 1 offer" }) }).strict();
|
|
3706
|
+
const GetUserPositionsParams = z$1.object({
|
|
3707
|
+
...PaginationQueryParams.shape,
|
|
3708
|
+
user_address: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "User address must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).meta({
|
|
3709
|
+
description: "User address to get positions for",
|
|
3710
|
+
example: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401"
|
|
3711
|
+
})
|
|
3712
|
+
});
|
|
3713
|
+
const schemas = {
|
|
3714
|
+
get_health: HealthQueryParams,
|
|
3715
|
+
get_health_collectors: HealthQueryParams,
|
|
3716
|
+
get_health_chains: HealthQueryParams,
|
|
3717
|
+
get_offers: GetOffersQueryParams,
|
|
3718
|
+
get_obligations: GetObligationsQueryParams,
|
|
3719
|
+
get_obligation: GetObligationParams,
|
|
3720
|
+
get_book: GetBookParams,
|
|
3721
|
+
validate_offers: ValidateOffersBody,
|
|
3722
|
+
get_user_positions: GetUserPositionsParams
|
|
2920
3723
|
};
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
* @constructor
|
|
2927
|
-
*
|
|
2928
|
-
* Creates a {@link Transfer}.
|
|
2929
|
-
* @param parameters - {@link from.Parameters}
|
|
2930
|
-
* @returns The created Transfer. {@link from.ReturnType}
|
|
2931
|
-
*
|
|
2932
|
-
* @example
|
|
2933
|
-
* ```ts
|
|
2934
|
-
* const transfer = Transfer.from({ id: "1", chainId: 1, contract: "0x123", from: "0x456", to: "0x789", value: 100n, blockNumber: 100n });
|
|
2935
|
-
* ```
|
|
2936
|
-
*/
|
|
2937
|
-
function from$1(parameters) {
|
|
2938
|
-
return {
|
|
2939
|
-
id: parameters.id,
|
|
2940
|
-
chainId: parameters.chainId,
|
|
2941
|
-
contract: parameters.contract.toLowerCase(),
|
|
2942
|
-
from: parameters.from.toLowerCase(),
|
|
2943
|
-
to: parameters.to.toLowerCase(),
|
|
2944
|
-
value: parameters.value,
|
|
2945
|
-
blockNumber: parameters.blockNumber
|
|
2946
|
-
};
|
|
3724
|
+
function parse(action, query) {
|
|
3725
|
+
return schemas[action].parse(query);
|
|
3726
|
+
}
|
|
3727
|
+
function safeParse(action, query, error) {
|
|
3728
|
+
return schemas[action].safeParse(query, { error });
|
|
2947
3729
|
}
|
|
2948
3730
|
|
|
2949
3731
|
//#endregion
|
|
2950
|
-
//#region src/
|
|
2951
|
-
|
|
3732
|
+
//#region src/api/Schema/index.ts
|
|
3733
|
+
var Schema_exports = /* @__PURE__ */ __export({
|
|
3734
|
+
BookResponse: () => BookResponse_exports,
|
|
3735
|
+
BooksController: () => BooksController,
|
|
3736
|
+
ChainHealth: () => ChainHealth,
|
|
3737
|
+
ChainsHealthResponse: () => ChainsHealthResponse,
|
|
3738
|
+
CollectorHealth: () => CollectorHealth,
|
|
3739
|
+
CollectorsHealthResponse: () => CollectorsHealthResponse,
|
|
3740
|
+
ConfigController: () => ConfigController,
|
|
3741
|
+
HealthController: () => HealthController,
|
|
3742
|
+
ObligationResponse: () => ObligationResponse_exports,
|
|
3743
|
+
ObligationsController: () => ObligationsController,
|
|
3744
|
+
OfferResponse: () => OfferResponse_exports,
|
|
3745
|
+
OffersController: () => OffersController,
|
|
3746
|
+
OpenApi: () => OpenApi,
|
|
3747
|
+
PositionResponse: () => PositionResponse_exports,
|
|
3748
|
+
RouterStatusResponse: () => RouterStatusResponse,
|
|
3749
|
+
UsersController: () => UsersController,
|
|
3750
|
+
ValidateController: () => ValidateController,
|
|
3751
|
+
parse: () => parse,
|
|
3752
|
+
safeParse: () => safeParse
|
|
3753
|
+
});
|
|
2952
3754
|
|
|
2953
3755
|
//#endregion
|
|
2954
3756
|
//#region src/client/Client.ts
|
|
@@ -3009,24 +3811,40 @@ async function getOffers(apiClient, parameters) {
|
|
|
3009
3811
|
throw new HttpGetApiFailedError(`GET request returned ${response.status}`, { details: JSON.stringify(error) });
|
|
3010
3812
|
}
|
|
3011
3813
|
const offers = data?.data.map((item) => {
|
|
3012
|
-
const { signature,
|
|
3013
|
-
return
|
|
3014
|
-
...
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3814
|
+
const { root, proof, signature, offer: offerData } = item;
|
|
3815
|
+
return {
|
|
3816
|
+
...fromSnakeCase$1({
|
|
3817
|
+
maker: offerData.maker,
|
|
3818
|
+
assets: offerData.assets,
|
|
3819
|
+
obligation_units: offerData.obligation_units,
|
|
3820
|
+
obligation_shares: offerData.obligation_shares,
|
|
3821
|
+
price: offerData.price,
|
|
3822
|
+
maturity: from$10(offerData.obligation.maturity),
|
|
3823
|
+
expiry: offerData.expiry,
|
|
3824
|
+
start: offerData.start,
|
|
3825
|
+
group: offerData.group,
|
|
3826
|
+
session: offerData.session,
|
|
3827
|
+
buy: offerData.buy,
|
|
3828
|
+
chain_id: item.chain_id,
|
|
3829
|
+
loan_token: offerData.obligation.loan_token,
|
|
3830
|
+
collaterals: offerData.obligation.collaterals.map((collateral) => ({
|
|
3831
|
+
asset: collateral.token,
|
|
3832
|
+
oracle: collateral.oracle,
|
|
3833
|
+
lltv: collateral.lltv
|
|
3834
|
+
})),
|
|
3835
|
+
callback: {
|
|
3836
|
+
address: offerData.callback,
|
|
3837
|
+
data: offerData.callback_data
|
|
3838
|
+
}
|
|
3839
|
+
}),
|
|
3840
|
+
hash: item.offer_hash,
|
|
3841
|
+
consumed: BigInt(item.consumed),
|
|
3842
|
+
takeable: BigInt(item.takeable),
|
|
3843
|
+
blockNumber: Number(item.block_number),
|
|
3844
|
+
root: root || void 0,
|
|
3845
|
+
proof: proof || void 0,
|
|
3846
|
+
signature: signature ? signature : void 0
|
|
3847
|
+
};
|
|
3030
3848
|
}) ?? [];
|
|
3031
3849
|
return {
|
|
3032
3850
|
cursor: data?.cursor ?? null,
|
|
@@ -3036,7 +3854,11 @@ async function getOffers(apiClient, parameters) {
|
|
|
3036
3854
|
async function getObligations(apiClient, parameters) {
|
|
3037
3855
|
const { data, error, response } = await apiClient.GET("/v1/obligations", { params: { query: {
|
|
3038
3856
|
cursor: parameters?.cursor,
|
|
3039
|
-
limit: parameters?.limit
|
|
3857
|
+
limit: parameters?.limit,
|
|
3858
|
+
chain: parameters?.chainId,
|
|
3859
|
+
loan_token: parameters?.loanToken,
|
|
3860
|
+
collateral_token: parameters?.collateralToken,
|
|
3861
|
+
maturity: parameters?.maturity
|
|
3040
3862
|
} } });
|
|
3041
3863
|
if (error !== void 0) {
|
|
3042
3864
|
switch (response.status) {
|
|
@@ -3051,11 +3873,11 @@ async function getObligations(apiClient, parameters) {
|
|
|
3051
3873
|
chain_id: item.chain_id,
|
|
3052
3874
|
loan_token: item.loan_token,
|
|
3053
3875
|
collaterals: item.collaterals.map((collateral) => ({
|
|
3054
|
-
asset: collateral.
|
|
3876
|
+
asset: collateral.token,
|
|
3055
3877
|
oracle: collateral.oracle,
|
|
3056
3878
|
lltv: collateral.lltv
|
|
3057
3879
|
})),
|
|
3058
|
-
maturity: from$
|
|
3880
|
+
maturity: from$10(item.maturity)
|
|
3059
3881
|
});
|
|
3060
3882
|
const { obligationId: _, ...returned } = {
|
|
3061
3883
|
id: () => id(obligation),
|
|
@@ -3217,8 +4039,8 @@ function getCallback(chain, type) {
|
|
|
3217
4039
|
* @param address - Callback contract address
|
|
3218
4040
|
* @returns The callback type when found, otherwise undefined
|
|
3219
4041
|
*/
|
|
3220
|
-
function getCallbackType(chain, address) {
|
|
3221
|
-
return configs[chain].callbacks?.find((c) => c.type !== CallbackType.BuyWithEmptyCallback && c.addresses.includes(address?.toLowerCase()))?.type;
|
|
4042
|
+
function getCallbackType(chain, address$1) {
|
|
4043
|
+
return configs[chain].callbacks?.find((c) => c.type !== CallbackType.BuyWithEmptyCallback && c.addresses.includes(address$1?.toLowerCase()))?.type;
|
|
3222
4044
|
}
|
|
3223
4045
|
/**
|
|
3224
4046
|
* Returns the callback addresses for a given chain and callback type, if it exists.
|
|
@@ -3348,9 +4170,11 @@ function create(parameters) {
|
|
|
3348
4170
|
//#endregion
|
|
3349
4171
|
//#region src/gatekeeper/Rules.ts
|
|
3350
4172
|
var Rules_exports = /* @__PURE__ */ __export({
|
|
4173
|
+
amountMutualExclusivity: () => amountMutualExclusivity,
|
|
3351
4174
|
callback: () => callback,
|
|
3352
4175
|
chains: () => chains,
|
|
3353
4176
|
maturity: () => maturity,
|
|
4177
|
+
sameMaker: () => sameMaker,
|
|
3354
4178
|
token: () => token,
|
|
3355
4179
|
validity: () => validity
|
|
3356
4180
|
});
|
|
@@ -3466,7 +4290,7 @@ const chains = ({ chains: chains$2 }) => single("chain_ids", `Validates that off
|
|
|
3466
4290
|
if (!allowedChainIds.some((id$1) => id$1 === offer.chainId)) return { message: `Chain ID ${offer.chainId} is not in the allowed chains (${allowedChainIds.join(", ")})` };
|
|
3467
4291
|
});
|
|
3468
4292
|
const maturity = ({ maturities }) => single("maturity", `Validates that offer maturity is one of: [${maturities.join(", ")}]`, (offer) => {
|
|
3469
|
-
const allowedMaturities = maturities.map((m) => from$
|
|
4293
|
+
const allowedMaturities = maturities.map((m) => from$10(m));
|
|
3470
4294
|
if (!allowedMaturities.includes(offer.maturity)) return { message: `Maturity must be end of current month (${allowedMaturities[0]}) or end of next month (${allowedMaturities[1]}). Got: ${offer.maturity}` };
|
|
3471
4295
|
});
|
|
3472
4296
|
const callback = ({ callbacks, allowedAddresses }) => single("callback", `Validates callbacks: buy empty callback is ${callbacks.includes(CallbackType.BuyWithEmptyCallback) ? "allowed" : "not allowed"}; sell offers must use a non-empty callback; non-empty callbacks must target one of [${allowedAddresses.map((a) => a.toLowerCase()).join(", ")}]`, (offer) => {
|
|
@@ -3477,32 +4301,64 @@ const callback = ({ callbacks, allowedAddresses }) => single("callback", `Valida
|
|
|
3477
4301
|
}
|
|
3478
4302
|
});
|
|
3479
4303
|
/**
|
|
3480
|
-
* A validation rule that checks if the offer's
|
|
3481
|
-
* @param
|
|
4304
|
+
* A validation rule that checks if the offer's tokens are allowed for its chain.
|
|
4305
|
+
* @param assetsByChainId - Allowed assets indexed by chain id.
|
|
3482
4306
|
* @returns The issue that was found. If the offer is valid, this will be undefined.
|
|
3483
4307
|
*/
|
|
3484
|
-
const token = ({
|
|
3485
|
-
const allowedAssets =
|
|
3486
|
-
if (!allowedAssets || allowedAssets.length === 0) return { message:
|
|
4308
|
+
const token = ({ assetsByChainId }) => single("token", "Validates that offer loan token and collateral tokens are in the allowed assets list for the offer chain", (offer) => {
|
|
4309
|
+
const allowedAssets = assetsByChainId[offer.chainId]?.map((asset) => asset.toLowerCase());
|
|
4310
|
+
if (!allowedAssets || allowedAssets.length === 0) return { message: `No allowed assets for chain ${offer.chainId}` };
|
|
3487
4311
|
if (!allowedAssets.includes(offer.loanToken.toLowerCase())) return { message: "Loan token is not allowed" };
|
|
3488
4312
|
if (offer.collaterals.some((collateral) => !allowedAssets.includes(collateral.asset.toLowerCase()))) return { message: "Collateral is not allowed" };
|
|
3489
4313
|
});
|
|
4314
|
+
/**
|
|
4315
|
+
* A batch validation rule that ensures all offers in a tree have the same maker address.
|
|
4316
|
+
* Returns an issue only for the first non-conforming offer.
|
|
4317
|
+
* This rule is signing-agnostic; signer verification is handled at the collector level.
|
|
4318
|
+
*/
|
|
4319
|
+
const sameMaker = () => batch$1("mixed_maker", "Validates that all offers in a batch have the same maker address", (offers) => {
|
|
4320
|
+
const issues = /* @__PURE__ */ new Map();
|
|
4321
|
+
if (offers.length === 0) return issues;
|
|
4322
|
+
const firstMaker = offers[0].maker.toLowerCase();
|
|
4323
|
+
for (let i = 1; i < offers.length; i++) {
|
|
4324
|
+
const offer = offers[i];
|
|
4325
|
+
if (offer.maker.toLowerCase() !== firstMaker) {
|
|
4326
|
+
issues.set(i, { message: `Offer has different maker ${offer.maker} than first offer ${offers[0].maker}` });
|
|
4327
|
+
return issues;
|
|
4328
|
+
}
|
|
4329
|
+
}
|
|
4330
|
+
return issues;
|
|
4331
|
+
});
|
|
4332
|
+
/**
|
|
4333
|
+
* A validation rule that ensures mutual exclusivity of offer amount fields.
|
|
4334
|
+
* At most one of (assets, obligationUnits, obligationShares) can be non-zero.
|
|
4335
|
+
* Matches contract requirement: `atMostOneNonZero(offer.assets, offer.obligationUnits, offer.obligationShares)`.
|
|
4336
|
+
*/
|
|
4337
|
+
const amountMutualExclusivity = () => single("amount_mutual_exclusivity", "Validates that at most one of (assets, obligationUnits, obligationShares) is non-zero", (offer) => {
|
|
4338
|
+
if (!atMostOneNonZero(offer.assets, offer.obligationUnits, offer.obligationShares)) return { message: "Inconsistent offer input: at most one of (assets, obligationUnits, obligationShares) must be non-zero" };
|
|
4339
|
+
});
|
|
3490
4340
|
|
|
3491
4341
|
//#endregion
|
|
3492
4342
|
//#region src/gatekeeper/morphoRules.ts
|
|
3493
|
-
const morphoRules = (chains$2) =>
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
4343
|
+
const morphoRules = (chains$2) => {
|
|
4344
|
+
const assetsByChainId = {};
|
|
4345
|
+
for (const chain of chains$2) assetsByChainId[chain.id] = assets[chain.id.toString()] ?? [];
|
|
4346
|
+
return [
|
|
4347
|
+
sameMaker(),
|
|
4348
|
+
amountMutualExclusivity(),
|
|
4349
|
+
chains({ chains: chains$2 }),
|
|
4350
|
+
maturity({ maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth] }),
|
|
4351
|
+
callback({
|
|
4352
|
+
callbacks: [
|
|
4353
|
+
CallbackType.BuyWithEmptyCallback,
|
|
4354
|
+
CallbackType.BuyVaultV1Callback,
|
|
4355
|
+
CallbackType.SellERC20Callback
|
|
4356
|
+
],
|
|
4357
|
+
allowedAddresses: chains$2.flatMap((c) => getCallbackAddresses(c.name))
|
|
4358
|
+
}),
|
|
4359
|
+
token({ assetsByChainId })
|
|
4360
|
+
];
|
|
4361
|
+
};
|
|
3506
4362
|
|
|
3507
4363
|
//#endregion
|
|
3508
4364
|
//#region src/mempool/MempoolEVMClient.ts
|
|
@@ -3528,25 +4384,27 @@ function from(parameters) {
|
|
|
3528
4384
|
*/
|
|
3529
4385
|
async function add(config, offers) {
|
|
3530
4386
|
if (!config.client.account) throw new WalletAccountNotSetError();
|
|
3531
|
-
const tree = from$
|
|
4387
|
+
const tree = from$8(offers.map((o) => from$7(o)));
|
|
3532
4388
|
const chainId = await getChainId(config.client);
|
|
3533
4389
|
for (const offer of tree.offers) if (chainId !== offer.chainId) throw new ChainIdMismatchError(offer.chainId, chainId);
|
|
4390
|
+
const signature = await sign(tree.offers, config.client);
|
|
4391
|
+
const encoded = await encode$1(tree, signature);
|
|
3534
4392
|
try {
|
|
3535
4393
|
return await config.client.sendTransaction({
|
|
3536
4394
|
chain: config.client.chain,
|
|
3537
4395
|
account: config.client.account,
|
|
3538
4396
|
to: config.mempoolAddress,
|
|
3539
|
-
data:
|
|
4397
|
+
data: encoded
|
|
3540
4398
|
});
|
|
3541
4399
|
} catch (error) {
|
|
3542
4400
|
throw new ViemClientError(error instanceof Error ? error.message : "Unknown error");
|
|
3543
4401
|
}
|
|
3544
4402
|
}
|
|
3545
4403
|
async function* get(config, parameters) {
|
|
3546
|
-
const { loanToken, blockNumberGte, blockNumberLte, order
|
|
4404
|
+
const { loanToken, blockNumberGte, blockNumberLte, order = "desc", options: { maxBatchSize = DEFAULT_BATCH_SIZE } = {} } = parameters || {};
|
|
3547
4405
|
yield* streamOffers(config, {
|
|
3548
4406
|
loanToken,
|
|
3549
|
-
order
|
|
4407
|
+
order,
|
|
3550
4408
|
blockNumberGte,
|
|
3551
4409
|
blockNumberLte,
|
|
3552
4410
|
options: {
|
|
@@ -3568,7 +4426,7 @@ const getChainId = async (client) => {
|
|
|
3568
4426
|
return chainId;
|
|
3569
4427
|
};
|
|
3570
4428
|
async function* streamOffers(config, parameters) {
|
|
3571
|
-
const { loanToken, blockNumberGte, blockNumberLte, order
|
|
4429
|
+
const { loanToken, blockNumberGte, blockNumberLte, order = "desc", options: { maxBatchSize = DEFAULT_BATCH_SIZE, blockWindow = config.blockWindow } = {} } = parameters;
|
|
3572
4430
|
const stream = streamLogs({
|
|
3573
4431
|
client: config.client.extend(publicActions),
|
|
3574
4432
|
contractAddress: config.mempoolAddress,
|
|
@@ -3585,13 +4443,13 @@ async function* streamOffers(config, parameters) {
|
|
|
3585
4443
|
},
|
|
3586
4444
|
blockNumberGte,
|
|
3587
4445
|
blockNumberLte,
|
|
3588
|
-
order
|
|
4446
|
+
order,
|
|
3589
4447
|
options: {
|
|
3590
4448
|
maxBatchSize,
|
|
3591
4449
|
blockWindow
|
|
3592
4450
|
}
|
|
3593
4451
|
});
|
|
3594
|
-
let blockNumber = order
|
|
4452
|
+
let blockNumber = order === "asc" ? blockNumberGte : blockNumberLte;
|
|
3595
4453
|
for await (const { logs, blockNumber: newBlockNumber } of stream) {
|
|
3596
4454
|
blockNumber = newBlockNumber;
|
|
3597
4455
|
if (logs.length === 0) continue;
|
|
@@ -3600,13 +4458,10 @@ async function* streamOffers(config, parameters) {
|
|
|
3600
4458
|
if (!log) continue;
|
|
3601
4459
|
const [payload] = decodeAbiParameters([{ type: "bytes" }], log.data);
|
|
3602
4460
|
try {
|
|
3603
|
-
const tree = decode$1(payload);
|
|
4461
|
+
const { tree } = await decode$1(payload);
|
|
3604
4462
|
for (const offer of tree.offers) {
|
|
3605
4463
|
if (loanToken && offer.loanToken.toLowerCase() !== loanToken.toLowerCase()) continue;
|
|
3606
|
-
offers.push(
|
|
3607
|
-
...offer,
|
|
3608
|
-
blockNumber: Number(log.blockNumber)
|
|
3609
|
-
});
|
|
4464
|
+
offers.push(offer);
|
|
3610
4465
|
}
|
|
3611
4466
|
} catch (_) {}
|
|
3612
4467
|
}
|
|
@@ -3685,6 +4540,20 @@ async function batchMulticall(parameters) {
|
|
|
3685
4540
|
return results;
|
|
3686
4541
|
}
|
|
3687
4542
|
|
|
4543
|
+
//#endregion
|
|
4544
|
+
//#region src/utils/Group.ts
|
|
4545
|
+
var Group_exports = /* @__PURE__ */ __export({ fromNumber: () => fromNumber });
|
|
4546
|
+
/**
|
|
4547
|
+
* Creates a bytes32 group identifier from a number.
|
|
4548
|
+
* @param n - A non-negative integer.
|
|
4549
|
+
* @throws {Error} If n is negative or not an integer.
|
|
4550
|
+
*/
|
|
4551
|
+
const fromNumber = (n) => {
|
|
4552
|
+
if (!Number.isInteger(n)) throw new Error(`Group.fromNumber: expected integer, got ${n}`);
|
|
4553
|
+
if (n < 0) throw new Error(`Group.fromNumber: expected non-negative, got ${n}`);
|
|
4554
|
+
return pad(`0x${n.toString(16)}`, { size: 32 });
|
|
4555
|
+
};
|
|
4556
|
+
|
|
3688
4557
|
//#endregion
|
|
3689
4558
|
//#region src/utils/lazy.ts
|
|
3690
4559
|
/**
|
|
@@ -3769,8 +4638,11 @@ function max() {
|
|
|
3769
4638
|
//#region src/utils/index.ts
|
|
3770
4639
|
var utils_exports = /* @__PURE__ */ __export({
|
|
3771
4640
|
BaseError: () => BaseError,
|
|
4641
|
+
Group: () => Group_exports,
|
|
4642
|
+
Random: () => Random_exports,
|
|
3772
4643
|
ReorgError: () => ReorgError,
|
|
3773
4644
|
Time: () => time_exports,
|
|
4645
|
+
atMostOneNonZero: () => atMostOneNonZero,
|
|
3774
4646
|
batch: () => batch,
|
|
3775
4647
|
batchMulticall: () => batchMulticall,
|
|
3776
4648
|
fromSnakeCase: () => fromSnakeCase$3,
|
|
@@ -3785,5 +4657,5 @@ var utils_exports = /* @__PURE__ */ __export({
|
|
|
3785
4657
|
});
|
|
3786
4658
|
|
|
3787
4659
|
//#endregion
|
|
3788
|
-
export { Abi_exports as Abi, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain,
|
|
4660
|
+
export { Abi_exports as Abi, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, ChainRegistry_exports as ChainRegistry, Collateral_exports as Collateral, ERC4626_exports as ERC4626, Errors_exports as Errors, Format_exports as Format, GateConfig_exports as GateConfig, Gatekeeper_exports as Gatekeeper, LLTV_exports as LLTV, Liquidity_exports as Liquidity, Maturity_exports as Maturity, MempoolClient_exports as Mempool, Obligation_exports as Obligation, Offer_exports as Offer, Oracle_exports as Oracle, Position_exports as Position, Quote_exports as Quote, Schema_exports as RouterApi, Client_exports as RouterClient, Rules_exports as Rules, time_exports as Time, Transfer_exports as Transfer, Tree_exports as Tree, utils_exports as Utils, Gate_exports as Validation, morphoRules };
|
|
3789
4661
|
//# sourceMappingURL=index.browser.mjs.map
|