@morpho-dev/router 0.10.0 → 0.12.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.
Files changed (60) hide show
  1. package/README.md +20 -5
  2. package/dist/cli.js +14944 -8994
  3. package/dist/drizzle/migrations/0031_sell-takeable-reindex.sql +254 -0
  4. package/dist/drizzle/migrations/0032_callback-type.sql +3 -0
  5. package/dist/drizzle/migrations/0033_obligation-id-bytes20.sql +255 -0
  6. package/dist/drizzle/migrations/0034_chain-checkpoints.sql +1 -0
  7. package/dist/drizzle/migrations/0035_chain-tip-hash-cas.sql +1 -0
  8. package/dist/drizzle/migrations/0036_pending-links.sql +22 -0
  9. package/dist/drizzle/migrations/0037_chain-finalized-anchor.sql +2 -0
  10. package/dist/drizzle/migrations/0038_add-obligation-rcf-threshold.sql +2 -0
  11. package/dist/drizzle/migrations/0039_add-offers-composite-indexes.sql +2 -0
  12. package/dist/drizzle/migrations/0040_drop-redundant-offers-indexes.sql +2 -0
  13. package/dist/drizzle/migrations/0041_add-group-winner-expression-index.sql +10 -0
  14. package/dist/drizzle/migrations/0042_contract-sync-v1.14.sql +284 -0
  15. package/dist/drizzle/migrations/0043_add-obligation-side-tick-index.sql +1 -0
  16. package/dist/drizzle/migrations/0044_index-audit-cleanup.sql +27 -0
  17. package/dist/drizzle/migrations/0045_add-lots-offsets-availability-indexes.sql +5 -0
  18. package/dist/drizzle/migrations/0046_add-offers-active-tick-index.sql +1 -0
  19. package/dist/drizzle/migrations/0047_add-offers-book-winners-index.sql +1 -0
  20. package/dist/drizzle/migrations/0048_covering-indexes-for-winners-queries.sql +34 -0
  21. package/dist/drizzle/migrations/0049_contract-sync-v1.15.sql +305 -0
  22. package/dist/drizzle/migrations/meta/0031_snapshot.json +1652 -0
  23. package/dist/drizzle/migrations/meta/0033_snapshot.json +1658 -0
  24. package/dist/drizzle/migrations/meta/0036_snapshot.json +1864 -0
  25. package/dist/drizzle/migrations/meta/0037_snapshot.json +1876 -0
  26. package/dist/drizzle/migrations/meta/0038_snapshot.json +1882 -0
  27. package/dist/drizzle/migrations/meta/0039_snapshot.json +1960 -0
  28. package/dist/drizzle/migrations/meta/0040_snapshot.json +1912 -0
  29. package/dist/drizzle/migrations/meta/0041_snapshot.json +1912 -0
  30. package/dist/drizzle/migrations/meta/0042_snapshot.json +1882 -0
  31. package/dist/drizzle/migrations/meta/0043_snapshot.json +1909 -0
  32. package/dist/drizzle/migrations/meta/0044_snapshot.json +1853 -0
  33. package/dist/drizzle/migrations/meta/0045_snapshot.json +1921 -0
  34. package/dist/drizzle/migrations/meta/0046_snapshot.json +1966 -0
  35. package/dist/drizzle/migrations/meta/0047_snapshot.json +2005 -0
  36. package/dist/drizzle/migrations/meta/0048_snapshot.json +2035 -0
  37. package/dist/drizzle/migrations/meta/0049_snapshot.json +2035 -0
  38. package/dist/drizzle/migrations/meta/_journal.json +133 -0
  39. package/dist/evm/bytecode/morpho.txt +1 -1
  40. package/dist/index.browser.d.mts +784 -282
  41. package/dist/index.browser.d.mts.map +1 -1
  42. package/dist/index.browser.mjs +1516 -675
  43. package/dist/index.browser.mjs.map +1 -1
  44. package/dist/index.node.d.mts +1676 -602
  45. package/dist/index.node.d.mts.map +1 -1
  46. package/dist/index.node.mjs +10121 -5251
  47. package/dist/index.node.mjs.map +1 -1
  48. package/dist/register-otel-hook.js +7 -0
  49. package/dist/server-D4xxddev.js +9573 -0
  50. package/dist/server.js +9617 -0
  51. package/docs/integrator.md +14 -24
  52. package/package.json +36 -29
  53. package/dist/index.browser.d.ts +0 -5007
  54. package/dist/index.browser.d.ts.map +0 -1
  55. package/dist/index.browser.js +0 -5825
  56. package/dist/index.browser.js.map +0 -1
  57. package/dist/index.node.d.ts +0 -8263
  58. package/dist/index.node.d.ts.map +0 -1
  59. package/dist/index.node.js +0 -12566
  60. package/dist/index.node.js.map +0 -1
@@ -1,35 +1,25 @@
1
- # Documentation
1
+ # Router
2
2
 
3
- This document is intended for **technical integrators** and **product/design teams**. It explains how the router works end-to-end, how to integrate with it, and what the main user-facing implications are.
3
+ The router improves the discoverability of offers made by **makers** for **takers**. Because offers are published to a **public**, **uncensored mempool**, the router ensures malicious or invalid offers are filtered out before they reach takers, acting as an opinionated infrastructure that lets applications be built without needing custom offer validation or anti-spam logic.
4
4
 
5
- At a high level, the router indexes and exposes offers published to the on-chain mempool and computes the *takeable* amount for each offer. In practice, this means the router aims to surface offers with a takeable amount that can be executed without reverting at take time, minimizing execution failures for takers.
5
+ It follows a set of rules managed by an external service, the **gatekeeper**, exposed at **`GET /v1/config/rules`**. Those rules determine which offers are fully excluded, based on criteria such as offer format, tokens, maturity, callback, and more. Any maker that wants to comply with these rules can call **`POST /v1/validate`** to confirm that their offers are supported by the router.
6
6
 
7
- ## Forge a supported offer
7
+ ### The mempool
8
8
 
9
- Not every offer published to the mempool will be indexed by the router. The router applies a **gatekeeper** that validates both **offer validity** (e.g., the offer is not expired) and the **supported format** (e.g., the callback type is supported by the router).
9
+ Although the mempool is unrestricted, the router supports only a specific offer format. The best way for a maker to stay router-compatible is to call **`POST /v1/validate`** to get the **encoded offer payload**, sign the returned **root**, and publish the payload with the **signature appended** (`data = payload + signature`).
10
10
 
11
- These checks serve the same goal: **minimize take-time failures**. Validity checks eliminate offers that are expected to revert on-chain. Supported-format checks further reduce failure risk by restricting the full set of protocol possibilities to a subset the router understands and can reason about, providing a more controlled integration surface and fewer unpredictable execution paths.
12
-
13
- To run these checks and validate your offers, call **`POST /v1/validate`**. If validation fails, the response includes `data.issues` describing what needs to be fixed.
14
-
15
- ## Discover supported rules
16
-
17
- The router publishes configured rules (maturities, loan tokens, and oracles) by chain. These rules are enforced by the gatekeeper when validating offers.
18
-
19
- Call **`GET /v1/config/rules`** to retrieve the current rules (with pagination). Use the `types` and `chains` query params to filter which rules are returned. The response includes `meta.checksum` so integrators can detect updates.
20
-
21
- ## Push offers to the mempool
22
-
23
- Once your offer is valid, you must **publish it on-chain** to make it available to all mempool consumers. The router is one consumer of the mempool, but anyone can publish to it or listen to it.
11
+ The maker can then be confident their offers will be indexed correctly when queried.
24
12
 
13
+ ```text
14
+ POST /v1/validate --data "{ chainId, offers: [...] }"
15
+ → { payload, root }
16
+ → sign(root)
17
+ → publish(payload + signature)
25
18
  ```
26
- POST /v1/validate → { payload, root } → sign(root) → publish(payload + sig)
27
- { offers: [...] }
28
- ```
29
-
30
- Offers are published as a *batch* using a Merkle tree so that a single signature can cover a whole group of offers. The Merkle **root** is a compact commitment to the full set: changing any offer changes the root, which makes the signature invalid. To keep calldata (and therefore gas costs) low, the offer set is embedded in the `payload` as a **gzipped** representation rather than being sent as plain JSON.
31
19
 
32
- Use **`POST /v1/validate`** to obtain `payload` (the encoded representation of your offers, with the root already embedded) and `root` (the Merkle root to sign). To publish, append your signature to the payload: `data = payload + signature`.
20
+ Offers are submitted as a batch using a Merkle tree, so one signature can cover multiple offers. The Merkle root is a compact
21
+ commitment to the whole set: any change to any offer changes the root, invalidating the signature. To reduce calldata (and gas)
22
+ usage, the full offer set is embedded in the payload as gzipped data instead of plain JSON.
33
23
 
34
24
  ## Router takeable computation
35
25
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morpho-dev/router",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Router package for Morpho protocol",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -16,23 +16,23 @@
16
16
  "dist/*",
17
17
  "docs/*"
18
18
  ],
19
- "main": "./dist/index.node.js",
19
+ "main": "./dist/index.node.mjs",
20
20
  "module": "./dist/index.node.mjs",
21
- "types": "./dist/index.node.d.ts",
21
+ "types": "./dist/index.node.d.mts",
22
22
  "bin": {
23
23
  "router": "./dist/cli.js"
24
24
  },
25
25
  "exports": {
26
26
  ".": {
27
27
  "node": {
28
- "types": "./dist/index.node.d.ts",
28
+ "types": "./dist/index.node.d.mts",
29
29
  "import": "./dist/index.node.mjs",
30
- "require": "./dist/index.node.js"
30
+ "require": "./dist/index.node.mjs"
31
31
  },
32
32
  "default": {
33
- "types": "./dist/index.browser.d.ts",
33
+ "types": "./dist/index.browser.d.mts",
34
34
  "import": "./dist/index.browser.mjs",
35
- "require": "./dist/index.browser.js"
35
+ "require": "./dist/index.browser.mjs"
36
36
  }
37
37
  }
38
38
  },
@@ -40,6 +40,10 @@
40
40
  "#core": "./src/core/index.ts",
41
41
  "#*": "./src/*"
42
42
  },
43
+ "engines": {
44
+ "node": ">=22.22.0",
45
+ "pnpm": ">=10.30.1 <11"
46
+ },
43
47
  "devDependencies": {
44
48
  "@types/pako": "^2.0.4",
45
49
  "@types/pg": "^8.15.5",
@@ -50,55 +54,58 @@
50
54
  },
51
55
  "dependencies": {
52
56
  "@electric-sql/pglite": "^0.3.1",
53
- "@hono/node-server": "^1.19.9",
57
+ "@hono/node-server": "^1.19.10",
54
58
  "@opentelemetry/api": "^1.9.0",
55
- "@opentelemetry/exporter-trace-otlp-proto": "^0.208.0",
56
- "@opentelemetry/id-generator-aws-xray": "^2.0.3",
57
- "@opentelemetry/instrumentation": "^0.208.0",
58
- "@opentelemetry/instrumentation-http": "^0.208.0",
59
- "@opentelemetry/instrumentation-pg": "^0.61.1",
60
- "@opentelemetry/propagator-aws-xray": "^2.0.3",
61
- "@opentelemetry/resources": "^2.2.0",
62
- "@opentelemetry/sdk-trace-node": "^2.2.0",
63
- "@opentelemetry/semantic-conventions": "^1.38.0",
59
+ "@opentelemetry/exporter-trace-otlp-proto": "^0.212.0",
60
+ "@opentelemetry/instrumentation": "^0.212.0",
61
+ "@opentelemetry/instrumentation-http": "^0.212.0",
62
+ "@opentelemetry/instrumentation-pg": "^0.64.0",
63
+ "@opentelemetry/resources": "^2.5.1",
64
+ "@opentelemetry/sdk-trace-node": "^2.5.1",
65
+ "@opentelemetry/semantic-conventions": "^1.39.0",
64
66
  "@openzeppelin/merkle-tree": "^1.0.8",
65
67
  "commander": "^13.1.0",
66
68
  "dotenv": "^17.2.1",
67
69
  "drizzle-orm": "^0.43.1",
68
- "hono": "^4.11.5",
69
- "js-base64": "^3.7.8",
70
+ "hono": "^4.12.7",
70
71
  "marked": "^17.0.1",
71
72
  "openapi-fetch": "^0.15.0",
72
73
  "openapi-metadata": "^0.2.2",
73
74
  "pako": "^2.1.0",
75
+ "prom-client": "^15.1.3",
74
76
  "pg": "^8.16.0",
75
77
  "reflect-metadata": "^0.2.2",
76
78
  "smol-toml": "^1.6.0",
77
79
  "viem": "^2.37.13",
78
- "zod": "^4.1.12",
79
- "zod-openapi": "^5.4.3"
80
+ "zod": "^4.1.12"
80
81
  },
81
82
  "scripts": {
82
83
  "bench": "vitest bench",
83
84
  "build": "pnpm openapi:generate && tsdown --config tsdown.config.ts",
84
- "container:build": "docker build -f Dockerfile -t morpho-router ../../",
85
+ "container:build": "docker buildx build -f Dockerfile -t morpho-router --load ../../",
85
86
  "container:run": "docker run -p 7891:7891 -e OTEL_EXPORTER_OTLP_ENDPOINT=http://host.docker.internal:4318/v1/traces --rm -it morpho-router",
86
- "cli": "pnpm build && node --experimental-loader=@opentelemetry/instrumentation/hook.mjs ./dist/cli.js",
87
+ "cli": "pnpm build && node --import ./dist/register-otel-hook.js ./dist/cli.js",
87
88
  "dev": "tsdown --config tsdown.config.ts --watch --onSuccess 'echo \"Router package rebuilt\"'",
88
89
  "docs:cli": "node ./scripts/generate-readme.mjs",
89
- "format": "biome format --write src/",
90
+ "format": "oxfmt src/",
90
91
  "lint": "bash ./scripts/lint.sh",
91
- "lint:ci": "biome ci src/",
92
+ "lint:fix": "oxlint --fix src/",
93
+ "lint:ci": "bash ./scripts/lint.sh",
92
94
  "migrations:create": "drizzle-kit generate --config src/database/drizzle/drizzle.config.ts --name",
95
+ "migrations:verify": "node ./scripts/verify-migration-artifacts.mjs",
93
96
  "migrations:run": "drizzle-kit migrate --config src/database/drizzle/drizzle.config.ts",
94
- "openapi:generate": "node --import tsx src/cli/dump-swagger.ts && pnpm openapi-typescript src/api/Schema/generated/swagger.json -o src/api/Schema/generated/swagger.d.ts && biome check --write src/api/Schema/generated",
95
- "test": "vitest run",
97
+ "openapi:generate": "node --import tsx src/cli/dump-swagger.ts && pnpm openapi-typescript src/api/Schema/generated/swagger.json -o src/api/Schema/generated/swagger.d.ts && oxfmt src/api/Schema/generated",
98
+ "test": "vitest --config vitest.config.ts run",
99
+ "test:guard:classification": "node --import tsx ./scripts/verify-test-classification.ts",
100
+ "test:integration": "vitest --config vitest.integration.config.ts run",
101
+ "test:unit": "pnpm test:guard:classification && vitest --config vitest.config.ts run",
96
102
  "test:e2e": "./scripts/e2e-run.sh",
97
103
  "test:tenderly": "vitest --config vitest.e2e.config.ts run",
98
- "test:ui": "vitest --ui",
99
- "test:watch": "vitest watch",
104
+ "test:ui": "vitest --config vitest.config.ts --ui",
105
+ "test:watch": "vitest --config vitest.config.ts watch",
100
106
  "e2e:setup": "./scripts/e2e-setup.sh",
101
107
  "e2e:teardown": "./scripts/e2e-teardown.sh",
108
+ "load:test": "node --import tsx scripts/load-test.ts",
102
109
  "typecheck": "pnpm openapi:generate && tsc --project tsconfig.json --noEmit --incremental"
103
110
  }
104
111
  }