@eco-foundation/api-schemas 0.4.1 → 0.7.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 +393 -10
- package/dist/fixtures/index.js +2 -2
- package/dist/fixtures/index.js.map +1 -1
- package/dist/fixtures/v1/intents-submit-permit2.request.quote-target.json +4 -3
- package/dist/fixtures/v1/intents-submit-permit3.request.quote-target.json +8 -3
- package/dist/fixtures/v1/quotes-create.response.all-quotes.json +6 -3
- package/dist/fixtures/v1/quotes-create.response.private-swap.json +2 -1
- package/dist/fixtures/v1/quotes-create.response.public-swap.json +2 -1
- package/dist/fixtures/v1/tokens-list.response.default.json +1 -1
- package/dist/generated/build-digest.json +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/v1/endpoints/chains.d.ts +7 -0
- package/dist/v1/endpoints/chains.js +5 -1
- package/dist/v1/endpoints/chains.js.map +1 -1
- package/dist/v1/endpoints/deposit-addresses.js +1 -1
- package/dist/v1/endpoints/deposit-addresses.js.map +1 -1
- package/dist/v1/endpoints/quotes.d.ts +7 -1
- package/dist/v1/endpoints/quotes.js +42 -6
- package/dist/v1/endpoints/quotes.js.map +1 -1
- package/dist/v1/endpoints/registry.d.ts +114 -21
- package/dist/v1/endpoints/registry.js +4 -2
- package/dist/v1/endpoints/registry.js.map +1 -1
- package/dist/v1/endpoints/status.d.ts +211 -26
- package/dist/v1/endpoints/status.js +39 -7
- package/dist/v1/endpoints/status.js.map +1 -1
- package/dist/v1/endpoints/submit.d.ts +43 -24
- package/dist/v1/endpoints/submit.js +16 -9
- package/dist/v1/endpoints/submit.js.map +1 -1
- package/dist/v1/endpoints/tokens.d.ts +7 -0
- package/dist/v1/endpoints/tokens.js +5 -1
- package/dist/v1/endpoints/tokens.js.map +1 -1
- package/dist/v1/enums.d.ts +2 -1
- package/dist/v1/enums.js +1 -1
- package/dist/v1/enums.js.map +1 -1
- package/dist/v1/errors/catalog.d.ts +14 -0
- package/dist/v1/errors/catalog.js +3 -1
- package/dist/v1/errors/catalog.js.map +1 -1
- package/dist/v1/errors/problem.d.ts +10 -0
- package/dist/v1/errors/problem.js +20 -10
- package/dist/v1/errors/problem.js.map +1 -1
- package/dist/v1/primitives.d.ts +10 -1
- package/dist/v1/primitives.js +16 -1
- package/dist/v1/primitives.js.map +1 -1
- package/dist/v1/types.d.ts +36 -1
- package/errors/catalog.lock.json +10 -0
- package/openapi/v1.json +672 -127
- package/package.json +19 -16
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Zod-first schemas, error catalog, golden fixtures, and generated OpenAPI 3.1 for
|
|
|
4
4
|
API. The Zod schemas are the source of truth; everything else (OpenAPI, fixtures, plain types)
|
|
5
5
|
is generated from or gated against them.
|
|
6
6
|
|
|
7
|
-
Today the package covers **13 endpoints across 12 paths**, **
|
|
7
|
+
Today the package covers **13 endpoints across 12 paths**, **39 error codes** (51 namespaced
|
|
8
8
|
legacy references), and **19 golden fixtures**.
|
|
9
9
|
|
|
10
10
|
## Install
|
|
@@ -14,13 +14,13 @@ While the package is 0.x, pin the patch range or the exact version:
|
|
|
14
14
|
```json
|
|
15
15
|
{
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@eco-foundation/api-schemas": "~0.
|
|
17
|
+
"@eco-foundation/api-schemas": "~0.7.0"
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
**Never write `^0`.** npm resolves `^0.x` as `>=0.0.0 <1.0.0`, so it silently accepts every
|
|
23
|
-
future breaking `0.y` — it is not a pin at all. Use `~0.
|
|
23
|
+
future breaking `0.y` — it is not a pin at all. Use `~0.7.0` or the exact `0.7.0`.
|
|
24
24
|
|
|
25
25
|
A matching version string is not evidence of a matching artifact: also compare
|
|
26
26
|
`V1_SCHEMA_DIGEST` (see [Invariants](#invariants-enforced-in-ci)). Two builds both called
|
|
@@ -30,6 +30,365 @@ A matching version string is not evidence of a matching artifact: also compare
|
|
|
30
30
|
zod-bearing entry point. Which case you are in is decided entirely by your imports; see
|
|
31
31
|
[Consumers](#consumers).
|
|
32
32
|
|
|
33
|
+
## Migrating 0.6.0 -> 0.7.0
|
|
34
|
+
|
|
35
|
+
**BREAKING under 0.x semver** (breaking bumps the minor while the major is 0). Nothing on the
|
|
36
|
+
wire that `0.6.0` accepted is rejected, and nothing `0.6.0` published is removed: two operations
|
|
37
|
+
RETURN, one response field and one error code are ADDED. Three things still break, and one of
|
|
38
|
+
them is a live-behaviour change rather than a compile error — read all three before bumping.
|
|
39
|
+
|
|
40
|
+
**`V1_SCHEMA_DIGEST` MOVES.** Both digest inputs changed (`errors/catalog.lock.json` gained one
|
|
41
|
+
code; `openapi/v1.json` gained two operations, two request schemas and one response field), so the
|
|
42
|
+
value is now `3e13c5eeb8b054f3a48a22c7694de16b0fc11e1dbf6bc3c27e8c575100225b2a` — was
|
|
43
|
+
`a6724fa4dd585e77aebe680655ac10fe5a2f4b70537930a0b4dee2612afb7c8e` on `0.6.0`. Every consumer
|
|
44
|
+
running `assertNoSkew` must move to the new value **in the same rollout**; a mixed fleet fails
|
|
45
|
+
the check by design.
|
|
46
|
+
|
|
47
|
+
**THE THREE BREAKING ITEMS FIRST.**
|
|
48
|
+
|
|
49
|
+
**1. `LaneStandard` widens back to all four standards — a compile break for anyone keying on
|
|
50
|
+
it.** `STANDARDS_BY_TARGET.quote` is `['erc-3009', 'permit2', 'permit3']` (`depositAddress` is
|
|
51
|
+
unchanged), and `LaneStandard` is derived from the matrix, so it is now
|
|
52
|
+
`'erc-3009' | 'permit2' | 'permit3' | 'erc-2612'` — the exact mirror of `0.6.0`'s narrowing.
|
|
53
|
+
`V1_SUBMIT_SCHEMAS: Record<LaneStandard, …>` regains its `permit2`/`permit3` entries, and
|
|
54
|
+
`V1_SUBMIT_SCHEMAS_BY_SERVICE.intents` has three lanes. **Your own `Record<LaneStandard, X>`,
|
|
55
|
+
and every exhaustive `switch` over a `LaneStandard`, stops compiling until it gains two arms.**
|
|
56
|
+
That is the intended signal: the alternative is a dispatcher that meets `undefined` at runtime.
|
|
57
|
+
A consumer that only indexes `V1_SUBMIT_SCHEMAS_BY_SERVICE['deposit-addresses']` is untouched.
|
|
58
|
+
|
|
59
|
+
**2. A bare dependency bump WIDENS what a server ADVERTISES.** A router that derives its
|
|
60
|
+
`/v1/tokens` `supports.quote` from `STANDARDS_BY_TARGET` advertises `permit2` and `permit3` the
|
|
61
|
+
moment this version is installed — before it can necessarily execute them. That is exactly the
|
|
62
|
+
false promise `0.6.0` closed. Ship the bump in the same release as the lane implementation
|
|
63
|
+
(quoted-salt dispatch, `execution.vault` publication, and the vault binding described under the
|
|
64
|
+
additive items), or gate discovery separately. This is the one item here that changes live
|
|
65
|
+
behaviour with no code change on your side.
|
|
66
|
+
|
|
67
|
+
**3. Consumer-side, but read it: the lock gained a 400.** `V1ProblemSchema` cross-checks a KNOWN
|
|
68
|
+
code's `status`/`type` against the catalog. `vault-mismatch` (below) is now known, so a body
|
|
69
|
+
carrying that spelling with a contradicting status or type stops parsing where `0.6.0` tolerated
|
|
70
|
+
it as "a newer server". An exhaustive `switch` over `V1ErrorCode` will not compile until it
|
|
71
|
+
handles it.
|
|
72
|
+
|
|
73
|
+
**THE ADDITIVE ITEMS.**
|
|
74
|
+
|
|
75
|
+
**Returned — `POST /v1/intents/submit/permit2` and `/permit3`.** This supersedes `0.6.0`'s
|
|
76
|
+
breaking item 4. The lanes can complete now because the two things that item named as missing
|
|
77
|
+
exist: the router dispatches the QUOTED `route.salt` unchanged (so the intent it funds is the
|
|
78
|
+
intent it quoted), and the quote response publishes the intent vault that salt produces
|
|
79
|
+
(`execution.vault`, below), so a signer can name the vault-bound counterparty before signing.
|
|
80
|
+
Both operations, both `V1_ENDPOINTS` entries (`intents.submit.permit2`, `intents.submit.permit3`),
|
|
81
|
+
both golden fixtures, and the five schema exports `Permit2PermitSingleSchema`,
|
|
82
|
+
`Permit2SubmitSchema`, `Permit3AllowanceSchema`, `Permit3PayloadSchema`, `Permit3SubmitSchema` are
|
|
83
|
+
back. Path order in the document is `erc-3009`, `permit2`, `permit3` — the matrix order — and
|
|
84
|
+
the tokens fixture advertises the same three under `supports.quote`.
|
|
85
|
+
|
|
86
|
+
**The bodies are NOT the `0.5.0` bodies.** A consumer skipping `0.6.0` (`0.5.0 -> 0.7.0`) sees
|
|
87
|
+
SIX newly-required fields, and a `0.5.0` body is a 400 at these paths. This is the material the
|
|
88
|
+
solver's DTOs require and verify, which the `0.5.0` shapes omitted:
|
|
89
|
+
|
|
90
|
+
```diff
|
|
91
|
+
// POST /v1/intents/submit/permit2
|
|
92
|
+
{
|
|
93
|
+
+ "chainId": 8453,
|
|
94
|
+
"target": { "quoteId": "quote:…" },
|
|
95
|
+
"permit2": {
|
|
96
|
+
"details": { "token": "0x…", "amount": "1043221", "expiration": 1767225600, "nonce": 0 },
|
|
97
|
+
- "spender": "<anything>",
|
|
98
|
+
+ "spender": "<execution.vault of the quote>",
|
|
99
|
+
- "sigDeadline": 1767225600
|
|
100
|
+
+ "sigDeadline": "1767225600"
|
|
101
|
+
},
|
|
102
|
+
"signature": "0x…"
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```diff
|
|
107
|
+
// POST /v1/intents/submit/permit3
|
|
108
|
+
{
|
|
109
|
+
"target": { "quoteId": "quote:…" },
|
|
110
|
+
"permit3": {
|
|
111
|
+
"owner": "0x…",
|
|
112
|
+
+ "permitContract": "0x…",
|
|
113
|
+
"salt": "0x…",
|
|
114
|
+
"deadline": 1767225600,
|
|
115
|
+
+ "timestamp": 1767222000,
|
|
116
|
+
+ "merkleRoot": "0x…",
|
|
117
|
+
"permits": [
|
|
118
|
+
- { "chainId": 8453, "token": "0x…", "amount": "1043221" }
|
|
119
|
+
+ { "chainId": 8453, "token": "0x…", "amount": "1043221",
|
|
120
|
+
+ "account": "<execution.vault of the quote>", "modeOrExpiration": 0 }
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
"signature": "0x…"
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
- **permit2 `chainId` (top-level, required)** is the EIP-712 domain chainId the signature was
|
|
128
|
+
produced under and the chain the permit executes on; the solver verifies the two agree. It
|
|
129
|
+
follows the C4 convention `erc-3009` and `erc-2612` already use.
|
|
130
|
+
- **permit3 has NO top-level `chainId`**, deliberately: its EIP-712 domain is not the source
|
|
131
|
+
chain, and each leg names its own chain. A consumer that needs one chain id for the body takes
|
|
132
|
+
`permits[0].chainId`. It also carries no `leaves` and no `tokenKey` — the solver recomputes the
|
|
133
|
+
merkle tree from the legs, and `tokenKey` is `pad(token, 32)` (ERC-20 only) by definition.
|
|
134
|
+
- **permit3 `permitContract`, `timestamp`, `merkleRoot`** are the signer's values, never
|
|
135
|
+
synthesized: the solver recomputes the root from the legs and rejects a mismatch.
|
|
136
|
+
- **permit3 leg `account` and `modeOrExpiration`**: `account` is where the leg pushes funds
|
|
137
|
+
(mode `0`, immediate transfer) or grants the allowance (any other value, read as the allowance
|
|
138
|
+
expiration in Unix seconds). On a quote target it is always the vault.
|
|
139
|
+
- **`nonce`, `expiration`, `timestamp` and `modeOrExpiration` are `Uint48`**, a new primitive
|
|
140
|
+
(with `UINT48_MAX`, `2^48 - 1`): the fields are uint48 on-chain and the ABI encoder truncates
|
|
141
|
+
rather than rejects, so the edge does. Expressed as bounds so the ceiling reaches the OpenAPI
|
|
142
|
+
document.
|
|
143
|
+
- **permit2 `sigDeadline` is a decimal STRING (`UintString`), and `details.expiration` a
|
|
144
|
+
`Uint48`** — both carry their on-chain width instead of `UnixSeconds`. The Permit2 SDK's
|
|
145
|
+
`MaxAllowanceExpiration` (`2^48-1`) and `MaxSigDeadline` (`2^256-1`) are the standard "no
|
|
146
|
+
expiry" idiom many wallets sign, and a `<=2100` bound rejected a valid signature that would
|
|
147
|
+
have funded. Same narrow exception erc-3009's `validAfter`/`validBefore` carry; a NUMBER
|
|
148
|
+
`sigDeadline` is a 400 at `permit2.sigDeadline`. Every other deadline in the module
|
|
149
|
+
(`permit3.deadline`, erc-2612's) is still `UnixSeconds` and still rejects a milliseconds value.
|
|
150
|
+
- **`Permit3PayloadSchema` stays a plain stripping `z.object`.** A `permit3.signature` sent in
|
|
151
|
+
the wrong place is dropped, so a reader has exactly one place to find the signature.
|
|
152
|
+
|
|
153
|
+
**What the schema does NOT check, and the router does.** The body carries no vault, so the vault
|
|
154
|
+
binding cannot be a refinement here (`refineDepositAddressBinding` is a no-op on quote targets by
|
|
155
|
+
construction). Before the signature pin the router asserts, per lane: the signed counterparty
|
|
156
|
+
(`permit2.spender`, every `permits[].account`) equals the quote's `execution.vault` — compared
|
|
157
|
+
CASE-INSENSITIVELY (`isSameEvmAddress`, exported here), since neither side is checksum-normalized
|
|
158
|
+
and a naive `===` turns a checksummed vault against a lowercase signature into a spurious 400 —
|
|
159
|
+
else `vault-mismatch` (400); every permit3 leg `chainId` and the permit2 `chainId` equal the quote's
|
|
160
|
+
source chain; the token equals the quote's source token and the amount is at least the reward
|
|
161
|
+
amount for it; `permit2.details.expiration`, `permit2.sigDeadline`, `permit3.deadline` and a
|
|
162
|
+
non-zero `modeOrExpiration` are all more than 60 seconds in the future (a stale authorisation is a
|
|
163
|
+
400, not a reverting funding batch). A green parse is not a green submit.
|
|
164
|
+
|
|
165
|
+
**Added — `execution.vault` on every quote object (optional, nullable, `AnyAddress`).** The
|
|
166
|
+
intent vault for THIS quote: the CREATE2 address the source-chain Portal funds the intent
|
|
167
|
+
through, derived from the quoted intent (route.salt included), so it changes whenever the salt
|
|
168
|
+
does. It is the value to sign as erc-3009 `authorization.to`, permit2 `spender` and every permit3
|
|
169
|
+
leg `account`. **Absent means the producer predates the field; `null` means the producer could
|
|
170
|
+
not derive it** — today that is any non-EVM source (an SVM vault is a PDA and is not published).
|
|
171
|
+
`AnyAddress` rather than `EvmAddress` because the same envelope carries SVM funding transactions
|
|
172
|
+
and a future SVM producer must be able to publish the PDA here without a shape break; as always,
|
|
173
|
+
never infer a VM from the branch that matched. Each ranked `quotes[]` entry carries its own. The
|
|
174
|
+
zod-free `V1Execution` alias gains `vault?: string | null`, and the parity spec pins the optional
|
|
175
|
+
member explicitly (an optional key is the one drift the mutual-assignability gate cannot see
|
|
176
|
+
through a `looseObject`'s index signature).
|
|
177
|
+
|
|
178
|
+
**Added — `vault-mismatch` (400): the signed counterparty is not the quote's intent vault.** The
|
|
179
|
+
quote-target twin of `deposit-address-mismatch`, which is the wrong NAME on a quote target (there
|
|
180
|
+
is no deposit address) — and `invalid-parameter` says nothing a caller can act on. `audience:
|
|
181
|
+
'write'` — like the twin it needs a signed counterparty, so only a submit can emit it — and
|
|
182
|
+
`legacyCodes: []` (no legacy service ever compared against a vault). A router's
|
|
183
|
+
`detail` names the field (`permit2.spender`, `permit3.permits[1].account`, `authorization.to`),
|
|
184
|
+
never the signed address. Branch on `code`: it shares 400 with `invalid-request`.
|
|
185
|
+
|
|
186
|
+
## Migrating 0.5.0 -> 0.6.0
|
|
187
|
+
|
|
188
|
+
**BREAKING under 0.x semver** (breaking bumps the minor while the major is 0). Five items REJECT
|
|
189
|
+
a request `0.5.0` accepted or remove something `0.5.0` published; four are additive. Every
|
|
190
|
+
breaking item is listed here — if you send anything named below, read its entry before bumping.
|
|
191
|
+
|
|
192
|
+
**`V1_SCHEMA_DIGEST` MOVES.** Both digest inputs changed (`errors/catalog.lock.json` gained one
|
|
193
|
+
code; `openapi/v1.json` lost two operations, gained two parameters and several descriptions), so
|
|
194
|
+
the value is now `a6724fa4dd585e77aebe680655ac10fe5a2f4b70537930a0b4dee2612afb7c8e` — was
|
|
195
|
+
`1d8e88e957795b23e1317dc1e3783fd64bf79b756e3f28bd40e02b047542d790` on `0.4.0`, `0.4.1` and
|
|
196
|
+
`0.5.0`. Every consumer running `assertNoSkew` must move to the new value **in the same
|
|
197
|
+
rollout**. Unlike `0.5.0`, this time the skew check DOES see the difference, so a mixed fleet
|
|
198
|
+
fails it by design rather than silently validating two ways.
|
|
199
|
+
|
|
200
|
+
**THE FIVE BREAKING ITEMS FIRST.**
|
|
201
|
+
|
|
202
|
+
**1. `slippage` now rejects `0` and anything below `0.0001`, and the rejection is named.**
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
// 0.5.0: parses (and then fails downstream). 0.6.0: 400, code slippage-out-of-bounds, path ['slippage'].
|
|
206
|
+
{ ..., slippage: 0 }
|
|
207
|
+
{ ..., slippage: 0.00005 }
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
The range is `0.0001`-`1` (`SLIPPAGE_MIN`/`SLIPPAGE_MAX`, both exported), a DECIMAL FRACTION of
|
|
211
|
+
the destination amount: `0.005` is 0.5%. No solver can express a tolerance below one basis
|
|
212
|
+
point, so a `0` could only ever be rejected downstream, silently clamped, or silently replaced
|
|
213
|
+
by a default; refusing it at the edge with a named code is the honest one. Zero tolerance is
|
|
214
|
+
meaningless on a swap route and ignored on a non-swap route, so nothing is lost.
|
|
215
|
+
|
|
216
|
+
**The code changes for EVERY out-of-range value, not only the new floor.** `0.5.0` enforced the
|
|
217
|
+
bound with a built-in `.min()/.max()`, which zod reports as `too_small`/`too_big` — and
|
|
218
|
+
`v1ErrorCodeFromIssues` maps only a `custom` issue carrying `v1IssueParams`, so the catalog's
|
|
219
|
+
`slippage-out-of-bounds` was promised and unreachable: `50` rendered as the generic
|
|
220
|
+
`invalid-request` with `legacyCode: eco-quotes:1003`. It now renders as
|
|
221
|
+
`slippage-out-of-bounds` (status 400 unchanged, `detail` text unchanged, no `legacyCode`
|
|
222
|
+
because that code has none). An integrator branching on `code === 'invalid-request'` for a
|
|
223
|
+
bad slippage, or reading `legacyCode` there, sees the change. The catalog TITLE names the
|
|
224
|
+
floor now; code, status and `legacyCodes` are untouched.
|
|
225
|
+
|
|
226
|
+
The published document also carries the units for the first time: both `slippage` fields have a
|
|
227
|
+
`description`, and the request field keeps `minimum`/`maximum` (via `.meta()`, since the bound
|
|
228
|
+
itself lives in a refinement that `z.toJSONSchema` drops). The response `slippage` is documented
|
|
229
|
+
as the tolerance ACTUALLY bound into `destination.minAmountOut` — when a request omits
|
|
230
|
+
`slippage`, that is the default the solver applied, not the omission.
|
|
231
|
+
|
|
232
|
+
**2. A zero `amount` is rejected on the quote request.**
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
// 0.5.0: parses, reaches a solver, comes back as a 502. 0.6.0: 400, path ['source','amount'].
|
|
236
|
+
{ ..., source: { chainId: 8453, token: '0x…', amount: '0' } }
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
`source.amount` and `destination.amount` are `PositiveUintString` (new primitive: `UintString`
|
|
240
|
+
with `'0'` excluded, message `must be greater than 0`). Every other `UintString` field is
|
|
241
|
+
unchanged — a zero `value` on a destination call or a zero fee is still legal. The bound reaches
|
|
242
|
+
the OpenAPI document as a `description` only; a string has no `minimum`.
|
|
243
|
+
|
|
244
|
+
**3. `options.maxCallDataSize` is gone.**
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
// 0.5.0: parses. 0.6.0: 400, unrecognized_keys at path ['options'].
|
|
248
|
+
{ ..., options: { maxCallDataSize: 1000 } }
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
It was published with no description and read by no service, so a caller sending it was handed
|
|
252
|
+
a 200 for a bound nobody enforced. The strict `options` object now names the key in a 400, the
|
|
253
|
+
same disposition `allowHighSlippage` has had since `0.3.0`. The zod-free `V1QuoteRequest` alias
|
|
254
|
+
drops the member too. A caller that needs a calldata cap needs one that is defined and enforced,
|
|
255
|
+
which is a different change.
|
|
256
|
+
|
|
257
|
+
**4. `POST /v1/intents/submit/permit2` and `/permit3` are WITHDRAWN.** (Superseded by `0.7.0`,
|
|
258
|
+
which returns both lanes with the fields named below — see that section.)
|
|
259
|
+
|
|
260
|
+
Neither lane can complete, and this is why. The signed Permit2 `spender` and every Permit3 leg
|
|
261
|
+
`account` must be the intent VAULT (`Portal.fundFor` pulls the funds through
|
|
262
|
+
`IPermit.transferFrom(funder, vault)`), and the vault is derived from the route salt the router
|
|
263
|
+
dispatches — a value the signer cannot know before signing until quoted-salt dispatch and vault
|
|
264
|
+
binding exist. On top of that the published bodies omitted material the solver requires (permit2
|
|
265
|
+
`chainId`; permit3 `permitContract`, `timestamp`, `merkleRoot`, per-leg `account` /
|
|
266
|
+
`modeOrExpiration`), so the first refusal was a 401 on every request. Advertising a lane whose
|
|
267
|
+
every body ends in a 4xx is a false promise. The lanes return as a follow-on once quoted-salt
|
|
268
|
+
dispatch and vault binding land; `erc-3009` is the quote-target intents standard until then.
|
|
269
|
+
|
|
270
|
+
What moved, concretely:
|
|
271
|
+
|
|
272
|
+
- `STANDARDS_BY_TARGET.quote` is `['erc-3009']`. `depositAddress` is unchanged.
|
|
273
|
+
- The two registry entries, the two operations in `openapi/v1.json`, and the two golden fixtures
|
|
274
|
+
are gone (11 endpoints over 10 paths; 17 fixtures). A router that dispatches from
|
|
275
|
+
`V1_SUBMIT_SCHEMAS_BY_SERVICE.intents` answers `invalid-parameter` on those routes by
|
|
276
|
+
construction.
|
|
277
|
+
- **Five exports are deleted:** `Permit3AllowanceSchema`, `Permit3PayloadSchema`,
|
|
278
|
+
`Permit3SubmitSchema`, `Permit2PermitSingleSchema`, `Permit2SubmitSchema`. No endpoint accepts
|
|
279
|
+
those bodies, so there is nothing for them to validate.
|
|
280
|
+
- **`V1_SUBMIT_SCHEMAS` is keyed by the new `LaneStandard` type** (`'erc-3009' | 'erc-2612'` —
|
|
281
|
+
the standards that have a lane), not by `SubmitStandard`. `V1_SUBMIT_SCHEMAS[standard]` with
|
|
282
|
+
a `SubmitStandard`-typed index no longer compiles; narrow to `LaneStandard` first. That is the
|
|
283
|
+
intended signal — the alternative was an `undefined` a dispatcher trips over at runtime.
|
|
284
|
+
- **`SUBMIT_STANDARDS` and `SubmitStandard` KEEP all four spellings.** That enum is also the
|
|
285
|
+
discovery vocabulary a token advertises under `supports`, and narrowing it would make a
|
|
286
|
+
consumer hard-fail on a token list from a server still spelling `permit3`. The vocabulary is
|
|
287
|
+
what a token MAY advertise; the matrix is what has a lane. The tokens fixture advertises
|
|
288
|
+
`quote: ['erc-3009']`.
|
|
289
|
+
|
|
290
|
+
**5. Consumer-side only, but read it: the lock gained a 502.** `V1ProblemSchema` cross-checks a
|
|
291
|
+
KNOWN code's `status`/`type` against the catalog. `solver-error` (below) is now known, so a body
|
|
292
|
+
carrying that spelling with a contradicting status or type stops parsing where `0.5.0` tolerated
|
|
293
|
+
it as "a newer server". An exhaustive `switch` over `V1ErrorCode` will not compile until it
|
|
294
|
+
handles it.
|
|
295
|
+
|
|
296
|
+
**THE FOUR ADDITIVE ITEMS.**
|
|
297
|
+
|
|
298
|
+
**Added — `solver-error` (502): an upstream solver rejected or failed the quote request.**
|
|
299
|
+
`solver-timeout` was the only 502, so a router had to label a solver answering 400 in six
|
|
300
|
+
milliseconds with a title that says "timed out". `solver-error` is the code for every upstream
|
|
301
|
+
failure that is NOT a deadline expiry — a solver 4xx/5xx, a network error, an unparseable body.
|
|
302
|
+
It is 502 rather than 4xx/422 on purpose: the gateway built the RFQ, so a solver rejection is a
|
|
303
|
+
gateway/contract fault, never the caller's, and a 422 mapping would hide a contract bug as "no
|
|
304
|
+
route". `legacyCodes` is EMPTY by construction: `eco-quotes:1025` (Failed) is the ref that would
|
|
305
|
+
belong here, but it was published on `solver-timeout` and the lock is append-only, so it stays
|
|
306
|
+
there. Branch on `code`, not on `status`, to tell the two 502s apart.
|
|
307
|
+
|
|
308
|
+
**Added — `?chainId=` on `GET /v1/chains` and `GET /v1/tokens`.** OPTIONAL on both (the
|
|
309
|
+
unfiltered document is unchanged and stays legal), a single value only. A malformed value —
|
|
310
|
+
`abc`, `0`, `-1`, `1.5`, or a repeated `?chainId=1&chainId=8453` — is a 400 at the field; a
|
|
311
|
+
syntactically valid chain id that matches nothing is a 200 with `chains: []` /
|
|
312
|
+
`tokens: [], nextCursor: null`, never a 404. New exports: `CHAINS_LIST_QUERY_SHAPE` /
|
|
313
|
+
`ChainsListQuerySchema`, `TOKENS_LIST_QUERY_SHAPE` / `TokensListQuerySchema`, and `ChainIdParam`
|
|
314
|
+
(the coercing query-string twin of the body `ChainId`, which all three `chainId` query params —
|
|
315
|
+
these two and the deposit-address lookup's — now wrap, so the accepted set cannot differ between
|
|
316
|
+
endpoints publishing the same parameter name). Query-side only: never coerce a chain id in a
|
|
317
|
+
JSON body.
|
|
318
|
+
|
|
319
|
+
**Added — `renderIssuesAsProblemParts(issues, opts?) -> { code, detail?, errors? }`, THE one
|
|
320
|
+
sanctioned path from a `ZodError` to a problem body.** Two services rendered the same validation
|
|
321
|
+
failure with a cap of 4 and a cap of 10, a `(+N more issues)` suffix and an `N issues, first M:`
|
|
322
|
+
prefix, a bare root message and a `(root)` placeholder, and only one of them emitted `errors[]`.
|
|
323
|
+
This function is the single set of conventions: cap `MAX_DETAIL_ISSUES` (8, now exported) for
|
|
324
|
+
both `detail` and `errors`; overflow is ONE trailing `(+N more issues)`; a root-level issue is
|
|
325
|
+
its bare message; `errors` carries bare dotted fields and is omitted when nothing survives.
|
|
326
|
+
Absent keys are absent, so the result spreads straight into `problem(code, rest)` or your own
|
|
327
|
+
builder. `problemFromZodError` is built on it and a test pins that the two produce byte-identical
|
|
328
|
+
bodies. A service with its own problem type should route every `ZodError` through here and
|
|
329
|
+
delete its local cap and overflow constants.
|
|
330
|
+
|
|
331
|
+
**Added — execution detail on a status entry.** `StatusEntrySchema` and `statusEntrySchemaFor`
|
|
332
|
+
gain three OPTIONAL members: `sourceTx` and `destinationTx` as
|
|
333
|
+
`{ chainId, txHash, token, amount }`, and `steps[]` as
|
|
334
|
+
`{ type: 'SWAP' | 'BRIDGE', status, from, to, transactions: { created?, fulfilled?, refunded? } }`
|
|
335
|
+
with `{ token, amount, chainId }` legs and `{ chainId, txHash }` transaction refs. The shape
|
|
336
|
+
mirrors the solver's step facts verbatim; the step `type` is the producer's vocabulary (not the
|
|
337
|
+
quote-response `StepKind`) and the step `status` is the producer's raw per-step state beneath the
|
|
338
|
+
C1 entry-level vocabulary, deliberately unmapped. **Absent means unknown; `null` is rejected** —
|
|
339
|
+
a null would read as "known to be none" on a lane whose upstream simply has no token/amount.
|
|
340
|
+
Today the quote-status lane can populate them; the general intent-status lane omits them.
|
|
341
|
+
`chainId` is a JSON number (the solver spells it as a string; the producer converts), amounts
|
|
342
|
+
are uint strings, `token` is a bare string because the native asset may be a sentinel. New
|
|
343
|
+
schema exports `StatusTxRefSchema`, `StatusTokenAmountSchema`, `StatusTxDetailSchema`,
|
|
344
|
+
`StatusStepSchema`, `StatusStepType` / `STATUS_STEP_TYPES`; new zod-free aliases `V1StatusTxRef`,
|
|
345
|
+
`V1StatusTokenAmount`, `V1StatusTxDetail`, `V1StatusStep`, `V1StatusStepType`.
|
|
346
|
+
|
|
347
|
+
## Migrating 0.4.1 -> 0.5.0
|
|
348
|
+
|
|
349
|
+
**BREAKING under 0.x semver** (breaking bumps the minor while the major is 0): this release
|
|
350
|
+
REJECTS a request body `0.4.1` accepted. Nothing else moved — no code, status, `legacyCodes`
|
|
351
|
+
mapping, or response shape changed.
|
|
352
|
+
|
|
353
|
+
**`V1_SCHEMA_DIGEST` DOES NOT MOVE, and that is the caveat to read before rolling out.** The new
|
|
354
|
+
rule is a `superRefine`, and `z.toJSONSchema` drops refinements, so neither digest input changed:
|
|
355
|
+
`openapi/v1.json` is byte-identical and `assertNoSkew` cannot see the difference. A fleet running
|
|
356
|
+
`0.4.1` and `0.5.0` side by side therefore passes the skew check while VALIDATING DIFFERENTLY —
|
|
357
|
+
the same body is a 400 on one instance and a 200 on another. Roll every consumer together, or
|
|
358
|
+
accept that inconsistency knowingly.
|
|
359
|
+
|
|
360
|
+
**Rejected — a `funder` that cannot share a chain with `source.token`.**
|
|
361
|
+
|
|
362
|
+
```ts
|
|
363
|
+
// 0.4.1: parses. 0.5.0: 400, path ['funder'].
|
|
364
|
+
{ source: { chainId: 1399811149, token: '<a Solana mint>' }, funder: '0x3333…3333' }
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Both fields live on the SOURCE chain, so an EVM funder beside a Solana source token describes no
|
|
368
|
+
chain that exists. It used to parse, get quoted, and then fail wherever a service classified the
|
|
369
|
+
funder against the source VM — and a service that read a malformed funder as ITS OWN material
|
|
370
|
+
answered `500 internal-error` for a field the caller sent.
|
|
371
|
+
|
|
372
|
+
**What this rule deliberately does NOT do: bind `funder` to `source.chainId`.** That needs a
|
|
373
|
+
chain-ID-to-VM table, and this package holds none by design — `ChainId` is any positive integer,
|
|
374
|
+
and `ADDRESS_BY_CHAIN_TYPE` exists for the caller that already knows the chain type. A table here
|
|
375
|
+
would make every published version an allow-list of chains: a newly launched SVM chain would be
|
|
376
|
+
misclassified by every consumer still on an older pin, and its valid base58 funder rejected, so
|
|
377
|
+
this package would have to be re-released and rolled out before a chain could launch. Comparing
|
|
378
|
+
two addresses from the same request needs no table and cannot go stale.
|
|
379
|
+
|
|
380
|
+
So the check is a NECESSARY condition, not a sufficient one, in two specific ways:
|
|
381
|
+
|
|
382
|
+
- **Two EVM addresses agree with each other whatever `chainId` says**, including a Solana chain id.
|
|
383
|
+
A green parse is not evidence the funder is right for the chain.
|
|
384
|
+
- **SVM and TVM are not separated.** A Tron base58check address also satisfies `SvmAddress`'s
|
|
385
|
+
32-44 character range (see the `AnyAddress` docblock), so shape cannot decide between them and
|
|
386
|
+
the rule lets that pair through rather than guessing.
|
|
387
|
+
|
|
388
|
+
A service that knows the chain's VM must still check each address against it. Two new exports help:
|
|
389
|
+
`addressFamilies(value)` returns every family a value is consistent with, and
|
|
390
|
+
`addressFamiliesCanAgree(a, b)` is the pairwise predicate the refinement uses.
|
|
391
|
+
|
|
33
392
|
## Migrating 0.4.0 -> 0.4.1
|
|
34
393
|
|
|
35
394
|
Purely additive; no schema, wire, or digest change. `V1_SCHEMA_DIGEST` is UNCHANGED, so this is
|
|
@@ -550,10 +909,10 @@ which needs no server.
|
|
|
550
909
|
build → lint:check → test → catalog:check → openapi:check → digest:check
|
|
551
910
|
```
|
|
552
911
|
|
|
553
|
-
Both `.github/workflows/ci.yml` (every PR) and `.github/workflows/publish
|
|
912
|
+
Both `.github/workflows/ci.yml` (every PR) and `.github/workflows/publish.yml`
|
|
554
913
|
(every release tag) run exactly that one command.
|
|
555
914
|
|
|
556
|
-
**The `verify`-before-`
|
|
915
|
+
**The `verify`-before-`stage` step in the release workflow is load-bearing — do not
|
|
557
916
|
streamline it away.** `build` uses `tsconfig.build.json`, which excludes `src/**/*.spec.ts`, so
|
|
558
917
|
the compile-time gates that live in spec files — most importantly the `v1/types` parity gate —
|
|
559
918
|
cannot fail `build`. They fail `test`. Publishing without running `verify` would therefore ship
|
|
@@ -577,13 +936,37 @@ Two `catalog:check` outcomes are NOT failures and must not be confused with each
|
|
|
577
936
|
|
|
578
937
|
## Publishing
|
|
579
938
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
939
|
+
Publishing is **two steps, and CI only does the first one.**
|
|
940
|
+
|
|
941
|
+
**1. Tag `v<version>`** (must equal `package.json` version). The `Stage release` workflow
|
|
942
|
+
verifies and then runs `npm stage publish`, which uploads the tarball to npm in a pending state.
|
|
943
|
+
It fails with `::error::tag version <x> != package version <y>` if the two drift, so a stale tag
|
|
944
|
+
can never stage a mismatched artifact. It needs the `NPM_TOKEN` repo secret: a granular token
|
|
945
|
+
scoped to `@eco-foundation` with **"Read and write (stage only)"** rights.
|
|
946
|
+
|
|
947
|
+
**A green run means the version is QUEUED, not released.** Nobody can install it yet.
|
|
948
|
+
|
|
949
|
+
**2. A maintainer promotes it**, which costs a 2FA challenge:
|
|
950
|
+
|
|
951
|
+
```
|
|
952
|
+
npm stage list @eco-foundation/api-schemas
|
|
953
|
+
npm stage approve <stage-id> # or: npm stage reject <stage-id>
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
The queue is also visible on npmjs.com, and the workflow's run summary repeats these commands.
|
|
957
|
+
|
|
958
|
+
Why the split: npm removes direct publish from granular access tokens in **January 2027**, and
|
|
959
|
+
an approval cannot be satisfied by any CI credential — token or OIDC — by design. A stolen
|
|
960
|
+
runner token can queue a release; it can never ship one. `npm stage approve` needs npm ≥
|
|
961
|
+
`11.15.0` locally, same as CI.
|
|
962
|
+
|
|
963
|
+
Two staging rules worth knowing before you tag. The dist-tag is **immutable once staged** — it
|
|
964
|
+
cannot be changed on the way to approval, only rejected and re-staged — and a version that is
|
|
965
|
+
already staged cannot be staged again, so a re-tag of a queued version fails until the queued
|
|
966
|
+
one is approved or rejected.
|
|
584
967
|
|
|
585
968
|
Semver: breaking schema change = major, additive = minor; consumers pin minor. **While the
|
|
586
|
-
package is 0.x, "pin minor" means `~0.
|
|
969
|
+
package is 0.x, "pin minor" means `~0.7.0` or the exact `0.7.0` — never `^0`** (see
|
|
587
970
|
[Install](#install)). Consumers additionally compare `V1_SCHEMA_DIGEST`: a matching version
|
|
588
971
|
string is not evidence of a matching artifact. `/v1/routes` is draft-tagged and exempt until its
|
|
589
972
|
stability flips.
|
package/dist/fixtures/index.js
CHANGED
|
@@ -29,9 +29,9 @@ const FIXTURE_BINDINGS = [
|
|
|
29
29
|
bind('quotes.create', 'response', 'public-swap', quotes_create_response_public_swap_json_1.default),
|
|
30
30
|
bind('quotes.create', 'response', 'private-swap', quotes_create_response_private_swap_json_1.default),
|
|
31
31
|
bind('quotes.create', 'response', 'all-quotes', quotes_create_response_all_quotes_json_1.default),
|
|
32
|
-
bind('intents.submit.permit3', 'request', 'quote-target', intents_submit_permit3_request_quote_target_json_1.default),
|
|
33
|
-
bind('intents.submit.permit2', 'request', 'quote-target', intents_submit_permit2_request_quote_target_json_1.default),
|
|
34
32
|
bind('intents.submit.erc-3009', 'response', 'job', intents_submit_erc_3009_response_job_json_1.default),
|
|
33
|
+
bind('intents.submit.permit2', 'request', 'quote-target', intents_submit_permit2_request_quote_target_json_1.default),
|
|
34
|
+
bind('intents.submit.permit3', 'request', 'quote-target', intents_submit_permit3_request_quote_target_json_1.default),
|
|
35
35
|
bind('deposit-addresses.submit.erc-3009', 'request', 'deposit-address-target', deposit_addresses_submit_erc_3009_request_deposit_address_target_json_1.default),
|
|
36
36
|
bind('deposit-addresses.submit.erc-2612', 'request', 'deposit-address-target', deposit_addresses_submit_erc_2612_request_deposit_address_target_json_1.default),
|
|
37
37
|
bind('intents.status', 'response', 'intent-filled', intents_status_response_intent_filled_json_1.default),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":";;;;;;AACA,+GAAgE;AAChE,mJAAuF;AACvF,qJAAyF;AACzF,yIAA2E;AAC3E,uLAAsG;AACtG,uLAAsG;AACtG,qIAA8E;AAC9E,iIAA2E;AAC3E,qHAAsE;AACtE,6HAAuE;AACvE,+HAA2E;AAC3E,6IAAkF;AAClF,6IAAkF;AAClF,yHAA8E;AAC9E,yHAA0E;AAC1E,6HAA0E;AAC1E,2HAAwE;AACxE,+GAAgE;AAChE,+GAAgE;AA0ChE,MAAM,IAAI,GAAG,CACX,UAAwB,EACxB,SAAiC,EACjC,OAAe,EACf,IAAa,EACb,OAA+E,EAAE,EACjF,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;AAezD,MAAM,gBAAgB,GAAG;IACvB,IAAI,CAAC,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,gDAAmB,CAAC;IACpE,IAAI,CAAC,eAAe,EAAE,UAAU,EAAE,aAAa,EAAE,iDAAY,CAAC;IAC9D,IAAI,CAAC,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,kDAAa,CAAC;IAChE,IAAI,CAAC,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,gDAAe,CAAC;IAChE,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,18 +7,19 @@
|
|
|
7
7
|
"expectedStatus": 202,
|
|
8
8
|
"sideEffect": true,
|
|
9
9
|
"payload": {
|
|
10
|
+
"chainId": 8453,
|
|
10
11
|
"target": {
|
|
11
12
|
"quoteId": "quote:8f14e45f-ea3c-4c2d-9b6e-1a2b3c4d5e6f"
|
|
12
13
|
},
|
|
13
14
|
"permit2": {
|
|
14
15
|
"details": {
|
|
15
|
-
"token": "
|
|
16
|
+
"token": "0x1111111111111111111111111111111111111111",
|
|
16
17
|
"amount": "1043221",
|
|
17
18
|
"expiration": 1767225600,
|
|
18
19
|
"nonce": 0
|
|
19
20
|
},
|
|
20
|
-
"spender": "
|
|
21
|
-
"sigDeadline": 1767225600
|
|
21
|
+
"spender": "0x5555555555555555555555555555555555555555",
|
|
22
|
+
"sigDeadline": "1767225600"
|
|
22
23
|
},
|
|
23
24
|
"signature": "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
|
|
24
25
|
}
|
|
@@ -11,14 +11,19 @@
|
|
|
11
11
|
"quoteId": "quote:8f14e45f-ea3c-4c2d-9b6e-1a2b3c4d5e6f"
|
|
12
12
|
},
|
|
13
13
|
"permit3": {
|
|
14
|
-
"owner": "
|
|
14
|
+
"owner": "0x3333333333333333333333333333333333333333",
|
|
15
|
+
"permitContract": "0x6666666666666666666666666666666666666666",
|
|
15
16
|
"salt": "0xabababababababababababababababababababababababababababababababab",
|
|
16
17
|
"deadline": 1767225600,
|
|
18
|
+
"timestamp": 1767222000,
|
|
19
|
+
"merkleRoot": "0x7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a",
|
|
17
20
|
"permits": [
|
|
18
21
|
{
|
|
19
22
|
"chainId": 8453,
|
|
20
|
-
"token": "
|
|
21
|
-
"amount": "1043221"
|
|
23
|
+
"token": "0x1111111111111111111111111111111111111111",
|
|
24
|
+
"amount": "1043221",
|
|
25
|
+
"account": "0x5555555555555555555555555555555555555555",
|
|
26
|
+
"modeOrExpiration": 0
|
|
22
27
|
}
|
|
23
28
|
]
|
|
24
29
|
},
|
|
@@ -149,7 +149,8 @@
|
|
|
149
149
|
}
|
|
150
150
|
},
|
|
151
151
|
"encodedRoute": "0xdead",
|
|
152
|
-
"encodedReward": "0xbeef"
|
|
152
|
+
"encodedReward": "0xbeef",
|
|
153
|
+
"vault": "0x5555555555555555555555555555555555555555"
|
|
153
154
|
},
|
|
154
155
|
"expiresAt": 1767225600,
|
|
155
156
|
"signature": "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
|
|
@@ -297,7 +298,8 @@
|
|
|
297
298
|
}
|
|
298
299
|
},
|
|
299
300
|
"encodedRoute": "0xdead",
|
|
300
|
-
"encodedReward": "0xbeef"
|
|
301
|
+
"encodedReward": "0xbeef",
|
|
302
|
+
"vault": "0x5555555555555555555555555555555555555555"
|
|
301
303
|
},
|
|
302
304
|
"expiresAt": 1767225600,
|
|
303
305
|
"signature": "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
|
|
@@ -445,7 +447,8 @@
|
|
|
445
447
|
}
|
|
446
448
|
},
|
|
447
449
|
"encodedRoute": "0xdead",
|
|
448
|
-
"encodedReward": "0xbeef"
|
|
450
|
+
"encodedReward": "0xbeef",
|
|
451
|
+
"vault": "0x7777777777777777777777777777777777777777"
|
|
449
452
|
},
|
|
450
453
|
"expiresAt": 1767225600,
|
|
451
454
|
"signature": "0x9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a"
|
|
@@ -143,7 +143,8 @@
|
|
|
143
143
|
}
|
|
144
144
|
},
|
|
145
145
|
"encodedRoute": null,
|
|
146
|
-
"encodedReward": null
|
|
146
|
+
"encodedReward": null,
|
|
147
|
+
"vault": "0x5555555555555555555555555555555555555555"
|
|
147
148
|
},
|
|
148
149
|
"expiresAt": 1767225600,
|
|
149
150
|
"signature": "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
|
|
@@ -149,7 +149,8 @@
|
|
|
149
149
|
}
|
|
150
150
|
},
|
|
151
151
|
"encodedRoute": "0xdead",
|
|
152
|
-
"encodedReward": "0xbeef"
|
|
152
|
+
"encodedReward": "0xbeef",
|
|
153
|
+
"vault": "0x5555555555555555555555555555555555555555"
|
|
153
154
|
},
|
|
154
155
|
"expiresAt": 1767225600,
|
|
155
156
|
"signature": "0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
|
package/dist/index.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ export { generateOpenApiDocument, STABLE_TAG } from './openapi';
|
|
|
3
3
|
export type { V1Fixture } from './testing';
|
|
4
4
|
export { assertMatchesV1Schema, loadV1Fixtures } from './testing';
|
|
5
5
|
export * as v1 from './v1';
|
|
6
|
-
export type { LegacyCodeRef, V1Chain, V1ChainType, V1DepositAddress, V1DepositAddressChainStatus, V1DepositAddressCreateRequest, V1DepositAddressCreateResponse, V1DepositAddressKind, V1DestinationCall, V1ErrorCode, V1ErrorDefinition, V1Execution, V1Fee, V1FeeKind, V1FeeToken, V1FundingTransaction, V1GaslessJob, V1GaslessJobStatus, V1GaslessSubState, V1GaslessSubStatus, V1Guarantee, V1IntentCall, V1IntentReward, V1IntentRoute, V1IntentTokenAmount, V1ProblemBody, V1QuoteCore, V1QuoteRequest, V1QuoteResponse, V1RankedQuoteEntry, V1RelatedIntent, V1RelatedIntentRole, V1SolverIdentity, V1StatusEntry, V1StatusType, V1Step, V1StepKind, V1StepLeg, V1SvmAccountMeta, V1SvmInstruction, V1SwapType, V1TokenEntry, V1Visibility, } from './v1/types';
|
|
6
|
+
export type { LegacyCodeRef, V1Chain, V1ChainType, V1DepositAddress, V1DepositAddressChainStatus, V1DepositAddressCreateRequest, V1DepositAddressCreateResponse, V1DepositAddressKind, V1DestinationCall, V1ErrorCode, V1ErrorDefinition, V1Execution, V1Fee, V1FeeKind, V1FeeToken, V1FundingTransaction, V1GaslessJob, V1GaslessJobStatus, V1GaslessSubState, V1GaslessSubStatus, V1Guarantee, V1IntentCall, V1IntentReward, V1IntentRoute, V1IntentTokenAmount, V1ProblemBody, V1QuoteCore, V1QuoteRequest, V1QuoteResponse, V1RankedQuoteEntry, V1RelatedIntent, V1RelatedIntentRole, V1SolverIdentity, V1StatusEntry, V1StatusStep, V1StatusStepType, V1StatusTokenAmount, V1StatusTxDetail, V1StatusTxRef, V1StatusType, V1Step, V1StepKind, V1StepLeg, V1SvmAccountMeta, V1SvmInstruction, V1SwapType, V1TokenEntry, V1Visibility, } from './v1/types';
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
export declare const CHAINS_LIST_QUERY_SHAPE: {
|
|
3
|
+
chainId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
4
|
+
};
|
|
5
|
+
export declare const ChainsListQuerySchema: z.ZodObject<{
|
|
6
|
+
chainId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
export type ChainsListQuery = z.infer<typeof ChainsListQuerySchema>;
|
|
2
9
|
export declare const ChainContractsSchema: z.ZodObject<{
|
|
3
10
|
portal: z.ZodUnion<readonly [z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodString]>, z.ZodString]>;
|
|
4
11
|
executor: z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodString]>, z.ZodString]>>;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ChainsResponseSchema = exports.V1LimitsSchema = exports.ChainSchema = exports.ChainContractsSchema = void 0;
|
|
3
|
+
exports.ChainsResponseSchema = exports.V1LimitsSchema = exports.ChainSchema = exports.ChainContractsSchema = exports.ChainsListQuerySchema = exports.CHAINS_LIST_QUERY_SHAPE = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const enums_1 = require("../enums");
|
|
6
6
|
const primitives_1 = require("../primitives");
|
|
7
7
|
const status_1 = require("./status");
|
|
8
|
+
exports.CHAINS_LIST_QUERY_SHAPE = {
|
|
9
|
+
chainId: primitives_1.ChainIdParam.optional(),
|
|
10
|
+
};
|
|
11
|
+
exports.ChainsListQuerySchema = zod_1.z.object(exports.CHAINS_LIST_QUERY_SHAPE);
|
|
8
12
|
exports.ChainContractsSchema = zod_1.z.looseObject({
|
|
9
13
|
portal: primitives_1.AnyAddress,
|
|
10
14
|
executor: primitives_1.AnyAddress.nullable(),
|