@anywalletkit/protocol-swap2-relay 0.1.1 → 0.1.2
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 +1 -1
- package/dist/{chunk-WRIKAUWI.js → chunk-C3I2XYSW.js} +92 -84
- package/dist/chunk-C3I2XYSW.js.map +1 -0
- package/dist/{chunk-CCMNAZZB.js → chunk-JTPYU26F.js} +72 -29
- package/dist/chunk-JTPYU26F.js.map +1 -0
- package/dist/{chunk-UVHDMGM5.js → chunk-MDXHT7HY.js} +5 -3
- package/dist/chunk-MDXHT7HY.js.map +1 -0
- package/dist/{chunk-7LPLU3MB.js → chunk-TBFD7BPZ.js} +2 -2
- package/dist/index.cjs +163 -110
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -4
- package/dist/order.cjs +4 -2
- package/dist/order.cjs.map +1 -1
- package/dist/order.d.cts +9 -1
- package/dist/order.d.ts +9 -1
- package/dist/order.js +1 -1
- package/dist/protocol.cjs +163 -110
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.js +4 -4
- package/dist/provider.cjs +163 -110
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.js +3 -3
- package/dist/verify.cjs +94 -84
- package/dist/verify.cjs.map +1 -1
- package/dist/verify.d.cts +2 -1
- package/dist/verify.d.ts +2 -1
- package/dist/verify.js +2 -2
- package/package.json +5 -5
- package/dist/chunk-CCMNAZZB.js.map +0 -1
- package/dist/chunk-UVHDMGM5.js.map +0 -1
- package/dist/chunk-WRIKAUWI.js.map +0 -1
- /package/dist/{chunk-7LPLU3MB.js.map → chunk-TBFD7BPZ.js.map} +0 -0
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
relayClearOrder,
|
|
8
8
|
relayRequestOf,
|
|
9
9
|
verifyRelayOrder
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-C3I2XYSW.js";
|
|
11
11
|
import {
|
|
12
12
|
RelayRefusal
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-MDXHT7HY.js";
|
|
14
14
|
import {
|
|
15
15
|
describeRelayActivity
|
|
16
16
|
} from "./chunk-K5F3BEUO.js";
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
|
|
23
23
|
// src/provider.ts
|
|
24
24
|
import { anySignal, redactUrls, timeoutSignal } from "@anywalletkit/protocol-swap2-core/util";
|
|
25
|
+
import { httpRefusal, refusal, refusalOf } from "@anywalletkit/protocol-swap2-core/errors";
|
|
25
26
|
var EVM_PLACEHOLDER = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";
|
|
26
27
|
var DEFAULT_QUOTE_TTL_MS = 6e4;
|
|
27
28
|
var QUOTE_TIMEOUT_MS = 2e4;
|
|
@@ -42,28 +43,69 @@ var RELAY_STATUS_MAP = Object.freeze({
|
|
|
42
43
|
refunded: "refunded",
|
|
43
44
|
failure: "refund-pending"
|
|
44
45
|
});
|
|
46
|
+
var RELAY_ERROR_REASONS = Object.freeze(Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
47
|
+
AMOUNT_TOO_LOW: "amount_too_small",
|
|
48
|
+
AMOUNT_TOO_HIGH: "amount_too_large",
|
|
49
|
+
INSUFFICIENT_LIQUIDITY: "insufficient_liquidity",
|
|
50
|
+
NO_QUOTES: "no_route",
|
|
51
|
+
NO_SWAP_ROUTES_FOUND: "no_route",
|
|
52
|
+
NO_INTERNAL_SWAP_ROUTES_FOUND: "no_route",
|
|
53
|
+
// Relay's own failures: a third-party pricing failure, and the transient codes it says to retry with backoff.
|
|
54
|
+
SWAP_QUOTE_FAILED: "upstream_unavailable",
|
|
55
|
+
REQUEST_TIMED_OUT: "upstream_unavailable",
|
|
56
|
+
RPC_HTTP_ERROR: "upstream_unavailable",
|
|
57
|
+
PRICE_FETCH_FAILED: "upstream_unavailable",
|
|
58
|
+
SERVICE_UNAVAILABLE: "upstream_unavailable",
|
|
59
|
+
// The recipient resolves to a token contract, which cannot receive.
|
|
60
|
+
INVALID_RECIPIENT: "recipient_mismatch",
|
|
61
|
+
UNSUPPORTED_CHAIN: "unsupported_pair",
|
|
62
|
+
UNSUPPORTED_CURRENCY: "unsupported_pair",
|
|
63
|
+
UNSUPPORTED_ROUTE: "unsupported_pair",
|
|
64
|
+
UNSUPPORTED_EXECUTION_TYPE: "unsupported_pair",
|
|
65
|
+
INVALID_INPUT_CURRENCY: "unsupported_pair",
|
|
66
|
+
INVALID_OUTPUT_CURRENCY: "unsupported_pair",
|
|
67
|
+
CHAIN_DISABLED: "chain_halted",
|
|
68
|
+
ROUTE_TEMPORARILY_RESTRICTED: "chain_halted",
|
|
69
|
+
SWAP_IMPACT_TOO_HIGH: "price_check_failed",
|
|
70
|
+
UNAUTHORIZED: "key_rejected",
|
|
71
|
+
UNAUTHORIZED_QUOTE: "key_rejected",
|
|
72
|
+
FORBIDDEN: "key_rejected"
|
|
73
|
+
}));
|
|
74
|
+
function quoteHttpRefusal(res, parsed, aborted) {
|
|
75
|
+
const code = parsed?.errorCode;
|
|
76
|
+
const byCode = typeof code === "string" && Object.prototype.hasOwnProperty.call(RELAY_ERROR_REASONS, code) ? RELAY_ERROR_REASONS[code] : void 0;
|
|
77
|
+
const byStatus = httpRefusal(res.status, res.headers?.get?.("retry-after"));
|
|
78
|
+
if (byStatus?.reason === "rate_limited") return byStatus;
|
|
79
|
+
if (byCode) {
|
|
80
|
+
if (byStatus?.reason === byCode) return byStatus;
|
|
81
|
+
return byCode === "upstream_unavailable" || byCode === "key_rejected" ? { reason: byCode, httpStatus: res.status } : { reason: byCode };
|
|
82
|
+
}
|
|
83
|
+
if (byStatus) return byStatus;
|
|
84
|
+
if (parsed !== null && typeof parsed === "object") return { reason: "no_route" };
|
|
85
|
+
return aborted ? void 0 : { reason: "upstream_unavailable", httpStatus: res.status };
|
|
86
|
+
}
|
|
45
87
|
function clip(text, max = 240) {
|
|
46
88
|
const t = redactUrls(text).replace(/\s+/g, " ").trim();
|
|
47
89
|
return t.length > max ? `${t.slice(0, max)}\u2026` : t;
|
|
48
90
|
}
|
|
49
91
|
function depositStep(body) {
|
|
50
92
|
const steps = body.steps;
|
|
51
|
-
if (!Array.isArray(steps) || steps.length === 0 || steps.length > 8) throw new RelayRefusal("quote-steps", "the quote has no steps");
|
|
93
|
+
if (!Array.isArray(steps) || steps.length === 0 || steps.length > 8) throw new RelayRefusal("quote-steps", "the quote has no steps", "upstream_unavailable");
|
|
52
94
|
let found = null;
|
|
53
95
|
for (const s of steps) {
|
|
54
|
-
if (s === null || typeof s !== "object") throw new RelayRefusal("quote-steps", "the quote has a malformed step");
|
|
96
|
+
if (s === null || typeof s !== "object") throw new RelayRefusal("quote-steps", "the quote has a malformed step", "upstream_unavailable");
|
|
55
97
|
if (s.id === "approve") continue;
|
|
56
|
-
if (s.id !== "deposit") throw new RelayRefusal("quote-steps", `the quote needs a "${clip(String(s.id), 40)}" step, only a single deposit is signed
|
|
57
|
-
if (found) throw new RelayRefusal("quote-steps", "the quote has more than one deposit step");
|
|
98
|
+
if (s.id !== "deposit") throw new RelayRefusal("quote-steps", `the quote needs a "${clip(String(s.id), 40)}" step, only a single deposit is signed`, "unsupported_pair");
|
|
99
|
+
if (found) throw new RelayRefusal("quote-steps", "the quote has more than one deposit step", "unsupported_pair");
|
|
58
100
|
found = s;
|
|
59
101
|
}
|
|
60
|
-
if (!found) throw new RelayRefusal("quote-steps", "the quote has no deposit step");
|
|
102
|
+
if (!found) throw new RelayRefusal("quote-steps", "the quote has no deposit step", "upstream_unavailable");
|
|
61
103
|
const items = found.items;
|
|
62
|
-
if (!Array.isArray(items) || items.length !== 1) throw new RelayRefusal("quote-steps", "the deposit step is not a single transaction");
|
|
104
|
+
if (!Array.isArray(items) || items.length !== 1) throw new RelayRefusal("quote-steps", "the deposit step is not a single transaction", "unsupported_pair");
|
|
63
105
|
const data = items[0]?.data;
|
|
64
|
-
if (data === null || typeof data !== "object") throw new RelayRefusal("quote-steps", "the deposit step has no transaction");
|
|
106
|
+
if (data === null || typeof data !== "object") throw new RelayRefusal("quote-steps", "the deposit step has no transaction", "upstream_unavailable");
|
|
65
107
|
const requestId = typeof found.requestId === "string" ? found.requestId.toLowerCase() : "";
|
|
66
|
-
if (!REQUEST_ID.test(requestId)) throw new RelayRefusal("quote-steps", "the quote has no request id to track the deposit by");
|
|
108
|
+
if (!REQUEST_ID.test(requestId)) throw new RelayRefusal("quote-steps", "the quote has no request id to track the deposit by", "upstream_unavailable");
|
|
67
109
|
return { requestId, tx: data };
|
|
68
110
|
}
|
|
69
111
|
function relayProvider(config = {}) {
|
|
@@ -99,12 +141,12 @@ function relayProvider(config = {}) {
|
|
|
99
141
|
.../^\d{1,5}$/.test(pd.slippageBps ?? "") ? { slippageBps: Number(pd.slippageBps) } : {}
|
|
100
142
|
};
|
|
101
143
|
if (sealed.depositor.toLowerCase() === EVM_PLACEHOLDER.toLowerCase() || sealed.recipient.toLowerCase() === EVM_PLACEHOLDER.toLowerCase()) {
|
|
102
|
-
throw new RelayRefusal("request-invalid", "a quote priced without the real addresses is never built or signed \u2014 quote again with them");
|
|
144
|
+
throw new RelayRefusal("request-invalid", "a quote priced without the real addresses is never built or signed \u2014 quote again with them", "policy_refused");
|
|
103
145
|
}
|
|
104
146
|
const mine = issued.get(quote.intentId);
|
|
105
147
|
if (!mine) return sealed;
|
|
106
148
|
const same = mine.sourceChain === sealed.sourceChain && mine.destChain === sealed.destChain && mine.amount === sealed.amount && mine.sourceToken.toLowerCase() === sealed.sourceToken.toLowerCase() && mine.destToken.toLowerCase() === sealed.destToken.toLowerCase() && mine.depositor.toLowerCase() === sealed.depositor.toLowerCase() && mine.recipient.toLowerCase() === sealed.recipient.toLowerCase();
|
|
107
|
-
if (!same) throw new RelayRefusal("request-invalid", "the quote no longer says what was asked when it was issued \u2014 quote again");
|
|
149
|
+
if (!same) throw new RelayRefusal("request-invalid", "the quote no longer says what was asked when it was issued \u2014 quote again", "policy_refused");
|
|
108
150
|
return mine;
|
|
109
151
|
}
|
|
110
152
|
async function readJson(res) {
|
|
@@ -120,8 +162,8 @@ function relayProvider(config = {}) {
|
|
|
120
162
|
supportsChainPair: (from, to) => relay.supports(from, to),
|
|
121
163
|
supportsRoute: (from, to) => relay.supports(from.chain, to.chain),
|
|
122
164
|
async getQuote(params, signal) {
|
|
123
|
-
const refuse = (reason) => {
|
|
124
|
-
params.onRefusal?.(reason);
|
|
165
|
+
const refuse = (reason, info) => {
|
|
166
|
+
params.onRefusal?.(reason, info);
|
|
125
167
|
return null;
|
|
126
168
|
};
|
|
127
169
|
const dry = params.dry !== false;
|
|
@@ -130,7 +172,7 @@ function relayProvider(config = {}) {
|
|
|
130
172
|
try {
|
|
131
173
|
request = relayRequestOf(params, dry ? { placeholder: EVM_PLACEHOLDER } : {});
|
|
132
174
|
} catch (err) {
|
|
133
|
-
if (err instanceof RelayRefusal) return refuse(err.message);
|
|
175
|
+
if (err instanceof RelayRefusal) return refuse(err.message, refusalOf(err));
|
|
134
176
|
throw err;
|
|
135
177
|
}
|
|
136
178
|
const src = relayChain(request.sourceChain);
|
|
@@ -165,20 +207,21 @@ function relayProvider(config = {}) {
|
|
|
165
207
|
if (!res.ok) {
|
|
166
208
|
const e = parsed ?? {};
|
|
167
209
|
const why = typeof e.message === "string" ? clip(e.message) : `HTTP ${res.status}`;
|
|
168
|
-
return refuse(`relay: no quote \u2014 ${typeof e.errorCode === "string" ? `${clip(e.errorCode, 60)}: ` : ""}${why}
|
|
210
|
+
return refuse(`relay: no quote \u2014 ${typeof e.errorCode === "string" ? `${clip(e.errorCode, 60)}: ` : ""}${why}`, quoteHttpRefusal(res, parsed, signal?.aborted === true));
|
|
169
211
|
}
|
|
170
|
-
if (parsed === null || typeof parsed !== "object") return refuse("relay: the quote response is not JSON");
|
|
212
|
+
if (parsed === null || typeof parsed !== "object") return refuse("relay: the quote response is not JSON", signal?.aborted ? void 0 : { reason: "upstream_unavailable" });
|
|
171
213
|
body = parsed;
|
|
172
214
|
} catch (err) {
|
|
173
|
-
|
|
215
|
+
const info = refusalOf(err) ?? (signal?.aborted ? void 0 : { reason: "upstream_unavailable" });
|
|
216
|
+
return refuse(`relay: quote request failed \u2014 ${clip(err instanceof Error ? err.message : String(err))}`, info);
|
|
174
217
|
}
|
|
175
218
|
try {
|
|
176
219
|
const step = depositStep(body);
|
|
177
220
|
const proto = body.protocol?.v2 ?? null;
|
|
178
221
|
const v = verifyRelayOrder(request, proto, step.tx);
|
|
179
222
|
const extra = (x) => x !== void 0 && x !== null && x !== "0" && x !== 0;
|
|
180
|
-
if (extra(body.fees?.app?.amount)) throw new RelayRefusal("app-fee", "the quote charges an app fee this module did not ask for");
|
|
181
|
-
if (extra(body.details?.currencyGasTopup?.amount)) throw new RelayRefusal("gas-topup", "the quote converts part of the output into a gas top-up this module did not ask for");
|
|
223
|
+
if (extra(body.fees?.app?.amount)) throw new RelayRefusal("app-fee", "the quote charges an app fee this module did not ask for", "policy_refused");
|
|
224
|
+
if (extra(body.details?.currencyGasTopup?.amount)) throw new RelayRefusal("gas-topup", "the quote converts part of the output into a gas top-up this module did not ask for", "policy_refused");
|
|
182
225
|
const native = v.deposit.approvalAddress === void 0;
|
|
183
226
|
const floor = native ? RELAY_GAS_FLOOR_NATIVE : RELAY_GAS_FLOOR_ERC20;
|
|
184
227
|
const apiGas = typeof step.tx.gas === "string" && /^[1-9]\d{0,9}$/.test(step.tx.gas) ? BigInt(step.tx.gas) * 2n : 0n;
|
|
@@ -233,15 +276,15 @@ function relayProvider(config = {}) {
|
|
|
233
276
|
}
|
|
234
277
|
};
|
|
235
278
|
} catch (err) {
|
|
236
|
-
if (err instanceof RelayRefusal) return refuse(err.message);
|
|
237
|
-
return refuse(`relay: unreadable quote \u2014 ${clip(err instanceof Error ? err.message : String(err))}
|
|
279
|
+
if (err instanceof RelayRefusal) return refuse(err.message, refusalOf(err));
|
|
280
|
+
return refuse(`relay: unreadable quote \u2014 ${clip(err instanceof Error ? err.message : String(err))}`, refusalOf(err) ?? { reason: "upstream_unavailable" });
|
|
238
281
|
}
|
|
239
282
|
},
|
|
240
283
|
/** The quote's own transaction — after the order it carries has been verified once more. */
|
|
241
284
|
async buildDeposit(quote) {
|
|
242
285
|
const tx = quote.txRequest;
|
|
243
|
-
if (!tx || !quote.intentId.startsWith(INTENT_PREFIX)) throw
|
|
244
|
-
if (quote.providerData?.placeholder === "1") throw new RelayRefusal("request-invalid", "a quote priced without the real addresses is never built \u2014 quote again with them");
|
|
286
|
+
if (!tx || !quote.intentId.startsWith(INTENT_PREFIX)) throw refusal("policy_refused", "swap2: Relay quote has no transaction request");
|
|
287
|
+
if (quote.providerData?.placeholder === "1") throw new RelayRefusal("request-invalid", "a quote priced without the real addresses is never built \u2014 quote again with them", "policy_refused");
|
|
245
288
|
const request = requestOf(quote);
|
|
246
289
|
const v = checkRelayQuote(request, quote);
|
|
247
290
|
return {
|
|
@@ -259,15 +302,15 @@ function relayProvider(config = {}) {
|
|
|
259
302
|
* and the exact transaction about to be signed — and each order is cleared for one deposit only.
|
|
260
303
|
*/
|
|
261
304
|
async preflightDeposit(quote, tx) {
|
|
262
|
-
if (quote.providerData?.placeholder === "1") throw new RelayRefusal("request-invalid", "a quote priced without the real addresses is never signed");
|
|
305
|
+
if (quote.providerData?.placeholder === "1") throw new RelayRefusal("request-invalid", "a quote priced without the real addresses is never signed", "policy_refused");
|
|
263
306
|
const request = requestOf(quote);
|
|
264
|
-
if (tx.chain !== request.sourceChain) throw new RelayRefusal("tx-chain", `the deposit is for ${tx.chain}, not ${request.sourceChain}
|
|
307
|
+
if (tx.chain !== request.sourceChain) throw new RelayRefusal("tx-chain", `the deposit is for ${tx.chain}, not ${request.sourceChain}`, "vault_mismatch");
|
|
265
308
|
if (tx.serializedTx !== void 0 || tx.memo !== void 0 || tx.typedData !== void 0 || tx.bodyBoc !== void 0) {
|
|
266
|
-
throw new RelayRefusal("quote-shape", "a Relay deposit is one EVM call");
|
|
309
|
+
throw new RelayRefusal("quote-shape", "a Relay deposit is one EVM call", "policy_refused");
|
|
267
310
|
}
|
|
268
311
|
const v = checkRelayQuote(request, quote, tx);
|
|
269
312
|
const store = config.clearedStore;
|
|
270
|
-
if (store && await store.has(v.id)) throw new RelayRefusal("order-reused", `order ${v.id} was already cleared for a deposit \u2014 quote again
|
|
313
|
+
if (store && await store.has(v.id)) throw new RelayRefusal("order-reused", `order ${v.id} was already cleared for a deposit \u2014 quote again`, "policy_refused");
|
|
271
314
|
relayClearOrder(v.id, "sign");
|
|
272
315
|
if (store) await store.add(v.id, v.order.output.deadline * 1e3);
|
|
273
316
|
},
|
|
@@ -304,4 +347,4 @@ export {
|
|
|
304
347
|
RELAY_STATUS_MAP,
|
|
305
348
|
relayProvider
|
|
306
349
|
};
|
|
307
|
-
//# sourceMappingURL=chunk-
|
|
350
|
+
//# sourceMappingURL=chunk-JTPYU26F.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/provider.ts"],"sourcesContent":["import {anySignal, redactUrls, timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentState, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {httpRefusal, refusal, refusalOf, type Swap2RefusalInfo, type Swap2RefusalReason} from \"@anywalletkit/protocol-swap2-core/errors\";\nimport {describeRelayActivity} from \"./activity.js\";\nimport {RELAY_API, relay as relayCfg, relayChain} from \"./config.js\";\nimport {RelayRefusal} from \"./order.js\";\nimport {RELAY_DEFAULT_SLIPPAGE_BPS, RELAY_GAS_CAP as GAS_CAP, RELAY_GAS_FLOOR_ERC20 as GAS_FLOOR_ERC20, RELAY_GAS_FLOOR_NATIVE as GAS_FLOOR_NATIVE, checkRelayQuote, relayClearOrder, relayRequestOf, verifyRelayOrder, type RelayRequest} from \"./verify.js\";\n\n/**\n * Relay (relay.link) — a solver network. ONE source transaction: a deposit into the chain's RelayDepository that names\n * an order by its hash; Relay's solver then pays the recipient on the destination chain, or the deposit is refunded.\n *\n * - Quote = `POST /quote/v2` with `includeProtocolData: true`, which returns the order itself next to the deposit.\n * The answer is only an input to `verify.ts`: the order is parsed, hashed and attributed on the device, compared\n * with the request, and the deposit this module builds from its own pins must be byte-for-byte the one offered.\n * What a quote carries afterwards is that own-built call; the amounts it shows are the order's (`expectedAmount`\n * as the estimate, `minimumAmount` as the enforced minimum).\n * - The API's `approve` step is never used: an ERC-20 input sets `approvalAddress` to the pinned depository and the\n * engine approves exactly the input amount.\n * - `baseUrl` may be the app's own proxy that adds the API key. It cannot get a deposit signed for another\n * recipient, chain, token, minimum or refund address than the request's. It CAN make the quote worse: the solver\n * signs whatever request reaches Relay, so a proxy that adds an app fee or a gas top-up gets a genuine order with\n * a lower expected amount. The response's own account of such extras is refused (`app-fee`, `gas-topup`), but a\n * proxy can strip that too — the amounts shown are always the order's, and what bounds the price is the caller's\n * `minAmountOut` or the other quotes of the router, not this module.\n * - Routes Relay serves by first swapping on the source chain call a router, not the depository, and are refused\n * by name (`tx-target`); so are non-EVM chains and any chain without a pin.\n * - Status: `GET /intents/status/v3?requestId=` — display only, nothing is signed on its word.\n */\n\nconst EVM_PLACEHOLDER = \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\";\nconst DEFAULT_QUOTE_TTL_MS = 60_000;\nconst QUOTE_TIMEOUT_MS = 20_000;\nconst STATUS_TIMEOUT_MS = 12_000;\nconst INTENT_PREFIX = \"relay:\";\nconst REQUEST_ID = /^0x[0-9a-f]{64}$/;\nconst MAX_BODY = 512 * 1024;\nconst MAX_REMEMBERED = 256;\n\nexport interface RelayProviderConfig {\n enabled?: boolean;\n /**\n * Relay's API (default https://api.relay.link) or the app's own proxy in front of it. Untrusted either way:\n * every answer is verified on the device.\n */\n baseUrl?: string;\n /** Sent as `x-api-key` when set. Prefer a proxy that adds it — a key shipped in an app is public. */\n apiKey?: string;\n /** Local lifetime of a quote (default 60 s, at most 5 min). The order itself is refused once older than 10 min. */\n quoteTtlMs?: number;\n /** Injectable for tests and for runtimes that bring their own. */\n fetchImpl?: typeof fetch;\n /**\n * Where cleared order ids are also kept, so that \"one deposit per order\" survives an app restart (the built-in\n * record lives in memory). `has` is asked and `add` awaited right before a signature; either throwing refuses.\n */\n clearedStore?: RelayClearedStore;\n}\n\n/** A durable record of order ids a deposit was cleared for. `expiresAtMs` is when an entry may be dropped. */\nexport interface RelayClearedStore {\n has(orderId: string): boolean | Promise<boolean>;\n add(orderId: string, expiresAtMs: number): void | Promise<void>;\n}\n\ninterface RelayStep {id?: unknown; requestId?: unknown; items?: unknown}\ninterface RelayQuoteBody {\n steps?: unknown;\n fees?: {relayer?: {currency?: {address?: unknown}; amount?: unknown; amountUsd?: unknown}; app?: {amount?: unknown}};\n details?: {timeEstimate?: unknown; currencyGasTopup?: {amount?: unknown}};\n protocol?: {v2?: unknown};\n message?: unknown;\n errorCode?: unknown;\n}\n\n/** Relay's request states → swap2 states. `failure` is read together with `refundFailReason` (see `trackIntent`). */\nexport const RELAY_STATUS_MAP: Readonly<Record<string, IntentState>> = Object.freeze({\n waiting: \"pending\", depositing: \"pending\", pending: \"pending\", submitted: \"pending\", delayed: \"pending\", unknown: \"pending\",\n success: \"completed\", refund: \"refunded\", refunded: \"refunded\", failure: \"refund-pending\",\n});\n\n/**\n * Relay's error codes that say why there is no quote (`errorCode` of a non-2xx answer, as docs.relay.link lists them\n * under \"handling errors\"). They win over the HTTP status except a 429, which keeps its Retry-After; a code not\n * listed here is read from the status, and failing that a JSON refusal is `no_route`.\n */\nconst RELAY_ERROR_REASONS: Readonly<Record<string, Swap2RefusalReason>> = Object.freeze(Object.assign(Object.create(null) as Record<string, Swap2RefusalReason>, {\n AMOUNT_TOO_LOW: \"amount_too_small\",\n AMOUNT_TOO_HIGH: \"amount_too_large\",\n INSUFFICIENT_LIQUIDITY: \"insufficient_liquidity\",\n NO_QUOTES: \"no_route\",\n NO_SWAP_ROUTES_FOUND: \"no_route\",\n NO_INTERNAL_SWAP_ROUTES_FOUND: \"no_route\",\n // Relay's own failures: a third-party pricing failure, and the transient codes it says to retry with backoff.\n SWAP_QUOTE_FAILED: \"upstream_unavailable\",\n REQUEST_TIMED_OUT: \"upstream_unavailable\",\n RPC_HTTP_ERROR: \"upstream_unavailable\",\n PRICE_FETCH_FAILED: \"upstream_unavailable\",\n SERVICE_UNAVAILABLE: \"upstream_unavailable\",\n // The recipient resolves to a token contract, which cannot receive.\n INVALID_RECIPIENT: \"recipient_mismatch\",\n UNSUPPORTED_CHAIN: \"unsupported_pair\",\n UNSUPPORTED_CURRENCY: \"unsupported_pair\",\n UNSUPPORTED_ROUTE: \"unsupported_pair\",\n UNSUPPORTED_EXECUTION_TYPE: \"unsupported_pair\",\n INVALID_INPUT_CURRENCY: \"unsupported_pair\",\n INVALID_OUTPUT_CURRENCY: \"unsupported_pair\",\n CHAIN_DISABLED: \"chain_halted\",\n ROUTE_TEMPORARILY_RESTRICTED: \"chain_halted\",\n SWAP_IMPACT_TOO_HIGH: \"price_check_failed\",\n UNAUTHORIZED: \"key_rejected\",\n UNAUTHORIZED_QUOTE: \"key_rejected\",\n FORBIDDEN: \"key_rejected\",\n}));\n\n/**\n * Why a non-2xx quote answer refused: a 429 first (its wait), then Relay's own code, then the status, then the body's\n * shape. `aborted`: the caller's own signal fired, so a body that could not be read is not Relay's failure.\n */\nfunction quoteHttpRefusal(res: Response, parsed: unknown, aborted: boolean): Swap2RefusalInfo | undefined {\n const code = (parsed as RelayQuoteBody | null)?.errorCode;\n const byCode = typeof code === \"string\" && Object.prototype.hasOwnProperty.call(RELAY_ERROR_REASONS, code) ? RELAY_ERROR_REASONS[code] : undefined;\n const byStatus = httpRefusal(res.status, res.headers?.get?.(\"retry-after\"));\n if (byStatus?.reason === \"rate_limited\") return byStatus;\n if (byCode) {\n if (byStatus?.reason === byCode) return byStatus;\n // The reasons that carry the status keep it whatever the status was.\n return byCode === \"upstream_unavailable\" || byCode === \"key_rejected\" ? {reason: byCode, httpStatus: res.status} : {reason: byCode};\n }\n if (byStatus) return byStatus;\n // A JSON refusal Relay did not name is a quote it does not have; anything else is an answer of another shape.\n if (parsed !== null && typeof parsed === \"object\") return {reason: \"no_route\"};\n return aborted ? undefined : {reason: \"upstream_unavailable\", httpStatus: res.status};\n}\n\nfunction clip(text: string, max = 240): string {\n const t = redactUrls(text).replace(/\\s+/g, \" \").trim();\n return t.length > max ? `${t.slice(0, max)}…` : t;\n}\n\n/** The single deposit step of a quote response; an `approve` step is ignored, anything else refuses the quote. */\nfunction depositStep(body: RelayQuoteBody): {requestId: string; tx: {to?: unknown; data?: unknown; value?: unknown; chainId?: unknown; gas?: unknown}} {\n const steps = body.steps;\n if (!Array.isArray(steps) || steps.length === 0 || steps.length > 8) throw new RelayRefusal(\"quote-steps\", \"the quote has no steps\", \"upstream_unavailable\");\n let found: RelayStep | null = null;\n for (const s of steps as RelayStep[]) {\n if (s === null || typeof s !== \"object\") throw new RelayRefusal(\"quote-steps\", \"the quote has a malformed step\", \"upstream_unavailable\");\n if (s.id === \"approve\") continue; // never used: the approval is built here, for the exact amount, to the pinned depository\n if (s.id !== \"deposit\") throw new RelayRefusal(\"quote-steps\", `the quote needs a \"${clip(String(s.id), 40)}\" step, only a single deposit is signed`, \"unsupported_pair\");\n if (found) throw new RelayRefusal(\"quote-steps\", \"the quote has more than one deposit step\", \"unsupported_pair\");\n found = s;\n }\n if (!found) throw new RelayRefusal(\"quote-steps\", \"the quote has no deposit step\", \"upstream_unavailable\");\n const items = found.items;\n if (!Array.isArray(items) || items.length !== 1) throw new RelayRefusal(\"quote-steps\", \"the deposit step is not a single transaction\", \"unsupported_pair\");\n const data = (items[0] as {data?: unknown} | null)?.data;\n if (data === null || typeof data !== \"object\") throw new RelayRefusal(\"quote-steps\", \"the deposit step has no transaction\", \"upstream_unavailable\");\n const requestId = typeof found.requestId === \"string\" ? found.requestId.toLowerCase() : \"\";\n if (!REQUEST_ID.test(requestId)) throw new RelayRefusal(\"quote-steps\", \"the quote has no request id to track the deposit by\", \"upstream_unavailable\");\n return {requestId, tx: data as never};\n}\n\nexport function relayProvider(config: RelayProviderConfig = {}): CrossChainProvider {\n config = Object.freeze({...config});\n const base = (config.baseUrl ?? RELAY_API).replace(/\\/+$/, \"\");\n if (!/^https?:\\/\\//.test(base)) throw new Error(\"relay: baseUrl must use http or https\");\n const quoteTtlMs = config.quoteTtlMs ?? DEFAULT_QUOTE_TTL_MS;\n if (!Number.isInteger(quoteTtlMs) || quoteTtlMs <= 0 || quoteTtlMs > 300_000) throw new Error(\"relay: quoteTtlMs must be an integer between 1 and 300000\");\n if (config.apiKey !== undefined && (typeof config.apiKey !== \"string\" || !/^[\\x21-\\x7e]{1,256}$/.test(config.apiKey))) throw new Error(\"relay: apiKey must be a printable string\");\n const doFetch: typeof fetch = (input, init) => (config.fetchImpl ?? fetch)(input, init);\n const headers = (json: boolean): Record<string, string> => ({\n accept: \"application/json\",\n ...(json ? {\"content-type\": \"application/json\"} : {}),\n ...(config.apiKey ? {\"x-api-key\": config.apiKey} : {}),\n });\n\n // The request each live quote answered, kept on this side: a deposit is checked against what was asked here, not\n // against what the quote object says was asked.\n const issued = new Map<string, RelayRequest>();\n const remember = <K, V>(m: Map<K, V>, k: K, v: V): void => {\n m.delete(k);\n m.set(k, v);\n if (m.size > MAX_REMEMBERED) m.delete(m.keys().next().value as K);\n };\n\n /** The request a quote is checked against before a build or a signature. */\n function requestOf(quote: Quote): RelayRequest {\n const pd = quote.providerData ?? {};\n const sealed: RelayRequest = {\n sourceChain: pd.sourceChain ?? \"\", destChain: pd.destChain ?? \"\", sourceToken: pd.sourceToken ?? \"\", destToken: pd.destToken ?? \"\",\n amount: /^[1-9]\\d{0,77}$/.test(pd.amount ?? \"\") ? BigInt(pd.amount!) : 0n,\n depositor: pd.depositor ?? \"\", recipient: pd.recipient ?? \"\",\n ...(/^\\d{1,78}$/.test(pd.minAmountOut ?? \"\") ? {minAmountOut: BigInt(pd.minAmountOut!)} : {}),\n ...(/^\\d{1,5}$/.test(pd.slippageBps ?? \"\") ? {slippageBps: Number(pd.slippageBps)} : {}),\n };\n // The pricing placeholder is never a party to a deposit, whatever flags the quote object carries.\n if (sealed.depositor.toLowerCase() === EVM_PLACEHOLDER.toLowerCase() || sealed.recipient.toLowerCase() === EVM_PLACEHOLDER.toLowerCase()) {\n throw new RelayRefusal(\"request-invalid\", \"a quote priced without the real addresses is never built or signed — quote again with them\", \"policy_refused\");\n }\n const mine = issued.get(quote.intentId);\n if (!mine) return sealed;\n const same = mine.sourceChain === sealed.sourceChain && mine.destChain === sealed.destChain && mine.amount === sealed.amount\n && mine.sourceToken.toLowerCase() === sealed.sourceToken.toLowerCase() && mine.destToken.toLowerCase() === sealed.destToken.toLowerCase()\n && mine.depositor.toLowerCase() === sealed.depositor.toLowerCase() && mine.recipient.toLowerCase() === sealed.recipient.toLowerCase();\n if (!same) throw new RelayRefusal(\"request-invalid\", \"the quote no longer says what was asked when it was issued — quote again\", \"policy_refused\");\n return mine;\n }\n\n async function readJson(res: Response): Promise<unknown> {\n const text = await res.text();\n if (text.length > MAX_BODY) throw new Error(\"relay: response too large\");\n return JSON.parse(text) as unknown;\n }\n\n return {\n name: \"relay\",\n describeActivity: describeRelayActivity,\n enabled: () => config.enabled ?? true,\n supportsChain: (chain: string) => relayCfg.supportsChain(chain),\n supportsChainPair: (from: string, to: string) => relayCfg.supports(from, to),\n supportsRoute: (from: Asset, to: Asset) => relayCfg.supports(from.chain, to.chain),\n\n async getQuote(params: QuoteParams, signal?: AbortSignal): Promise<Quote | null> {\n const refuse = (reason: string, info?: Swap2RefusalInfo) => { params.onRefusal?.(reason, info); return null; };\n const dry = params.dry !== false;\n // Only a quote priced with the placeholder is unbuildable; one asked with real addresses is a real order.\n const placeholder = dry && (!params.destAddress || !params.refundAddress);\n let request: RelayRequest;\n try {\n // The placeholder prices a dry quote; a live one without addresses is refused.\n request = relayRequestOf(params, dry ? {placeholder: EVM_PLACEHOLDER} : {});\n } catch (err) {\n if (err instanceof RelayRefusal) return refuse(err.message, refusalOf(err));\n throw err;\n }\n const src = relayChain(request.sourceChain)!;\n const dst = relayChain(request.destChain)!;\n let body: RelayQuoteBody;\n try {\n const res = await doFetch(`${base}/quote/v2`, {\n method: \"POST\",\n headers: headers(true),\n body: JSON.stringify({\n user: request.depositor,\n recipient: request.recipient,\n refundTo: request.depositor,\n originChainId: src.chainId,\n destinationChainId: dst.chainId,\n originCurrency: request.sourceToken.toLowerCase(),\n destinationCurrency: request.destToken.toLowerCase(),\n amount: request.amount.toString(10),\n tradeType: \"EXACT_INPUT\",\n includeProtocolData: true,\n // Always named: Relay's \"auto\" would leave the distance between expected and minimum to the answering side.\n slippageTolerance: String(request.slippageBps ?? RELAY_DEFAULT_SLIPPAGE_BPS),\n }),\n signal: signal ? anySignal([signal, timeoutSignal(QUOTE_TIMEOUT_MS)]) : timeoutSignal(QUOTE_TIMEOUT_MS),\n });\n let parsed: unknown;\n try { parsed = await readJson(res); } catch { parsed = null; }\n if (!res.ok) {\n const e = (parsed ?? {}) as RelayQuoteBody;\n const why = typeof e.message === \"string\" ? clip(e.message) : `HTTP ${res.status}`;\n return refuse(`relay: no quote — ${typeof e.errorCode === \"string\" ? `${clip(e.errorCode, 60)}: ` : \"\"}${why}`, quoteHttpRefusal(res, parsed, signal?.aborted === true));\n }\n // A body cut off by the caller's own abort is not Relay's failure.\n if (parsed === null || typeof parsed !== \"object\") return refuse(\"relay: the quote response is not JSON\", signal?.aborted ? undefined : {reason: \"upstream_unavailable\"});\n body = parsed as RelayQuoteBody;\n } catch (err) {\n // The network, or this module's own timeout; the caller's own abort is not Relay's failure.\n const info = refusalOf(err) ?? (signal?.aborted ? undefined : {reason: \"upstream_unavailable\" as const});\n return refuse(`relay: quote request failed — ${clip(err instanceof Error ? err.message : String(err))}`, info);\n }\n\n try {\n const step = depositStep(body);\n const proto = (body.protocol?.v2 ?? null) as Record<string, unknown> | null;\n const v = verifyRelayOrder(request, proto, step.tx);\n // Extras this module never asks for. Each lowers the output inside a genuine order; the response's own account\n // of them is only a hint (an answering side that adds one can also hide it), so this refuses the honest case.\n const extra = (x: unknown): boolean => x !== undefined && x !== null && x !== \"0\" && x !== 0;\n if (extra(body.fees?.app?.amount)) throw new RelayRefusal(\"app-fee\", \"the quote charges an app fee this module did not ask for\", \"policy_refused\");\n if (extra(body.details?.currencyGasTopup?.amount)) throw new RelayRefusal(\"gas-topup\", \"the quote converts part of the output into a gas top-up this module did not ask for\", \"policy_refused\");\n const native = v.deposit.approvalAddress === undefined;\n const floor = native ? GAS_FLOOR_NATIVE : GAS_FLOOR_ERC20;\n const apiGas = typeof step.tx.gas === \"string\" && /^[1-9]\\d{0,9}$/.test(step.tx.gas) ? BigInt(step.tx.gas) * 2n : 0n;\n const gasLimit = apiGas > GAS_CAP ? GAS_CAP : apiGas > floor ? apiGas : floor;\n\n // Fees are Relay's own account of the quote: shown, never used in a check. They are already inside the output.\n const relayer = body.fees?.relayer;\n const usd = typeof relayer?.amountUsd === \"string\" && /^\\d{1,12}(?:\\.\\d{1,18})?$/.test(relayer.amountUsd) ? parseFloat(relayer.amountUsd) : 0;\n const feeToken = relayer?.currency?.address;\n const fees = typeof relayer?.amount === \"string\" && /^[1-9]\\d{0,77}$/.test(relayer.amount) && typeof feeToken === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(feeToken)\n ? [{type: \"protocol\" as const, amount: relayer.amount, token: feeToken.toLowerCase(), included: true, description: \"Relay fee\"}]\n : [];\n const eta = body.details?.timeEstimate;\n const etaSeconds = typeof eta === \"number\" && Number.isFinite(eta) && eta > 0 ? Math.min(Math.ceil(eta), 86_400) : 60;\n\n const intentId = `${INTENT_PREFIX}${step.requestId}`;\n if (!placeholder) remember(issued, intentId, request);\n return {\n provider: \"relay\",\n intentId,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {\n to: v.deposit.to,\n data: v.deposit.data,\n value: v.deposit.value,\n chainId: v.deposit.chainId,\n gasLimit: gasLimit.toString(10),\n ...(v.deposit.approvalAddress ? {approvalAddress: v.deposit.approvalAddress} : {}),\n },\n sourceAmount: request.amount.toString(10),\n destAmount: v.expectedAmount.toString(10),\n minDestAmount: v.minimumAmount.toString(10),\n feeUsd: usd,\n fees,\n etaSeconds,\n reliability: 0.97,\n validUntilMs: Date.now() + quoteTtlMs,\n providerData: {\n requestId: step.requestId,\n orderId: v.id,\n hubType: \"onchain\",\n // The order as received, re-read by the same parser before a build and before a signature.\n orderData: JSON.stringify(proto!.orderData),\n orderSignature: String(proto!.orderSignature).toLowerCase(),\n paymentDetails: JSON.stringify(proto!.paymentDetails),\n sourceChain: request.sourceChain,\n destChain: request.destChain,\n sourceToken: request.sourceToken.toLowerCase(),\n destToken: request.destToken.toLowerCase(),\n amount: request.amount.toString(10),\n depositor: request.depositor.toLowerCase(),\n recipient: request.recipient.toLowerCase(),\n ...(request.minAmountOut !== undefined ? {minAmountOut: request.minAmountOut.toString(10)} : {}),\n ...(request.slippageBps !== undefined ? {slippageBps: String(request.slippageBps)} : {}),\n ...(placeholder ? {placeholder: \"1\"} : {}),\n },\n };\n } catch (err) {\n if (err instanceof RelayRefusal) return refuse(err.message, refusalOf(err));\n return refuse(`relay: unreadable quote — ${clip(err instanceof Error ? err.message : String(err))}`, refusalOf(err) ?? {reason: \"upstream_unavailable\"});\n }\n },\n\n /** The quote's own transaction — after the order it carries has been verified once more. */\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest;\n if (!tx || !quote.intentId.startsWith(INTENT_PREFIX)) throw refusal(\"policy_refused\", \"swap2: Relay quote has no transaction request\");\n if (quote.providerData?.placeholder === \"1\") throw new RelayRefusal(\"request-invalid\", \"a quote priced without the real addresses is never built — quote again with them\", \"policy_refused\");\n const request = requestOf(quote);\n const v = checkRelayQuote(request, quote);\n return {\n chain: request.sourceChain,\n to: v.deposit.to,\n value: v.deposit.value,\n data: v.deposit.data,\n chainId: v.deposit.chainId,\n ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {}),\n ...(v.deposit.approvalAddress ? {approvalAddress: v.deposit.approvalAddress} : {}),\n };\n },\n\n /**\n * Right before signing: the whole verification again, against the request this instance issued the quote for\n * and the exact transaction about to be signed — and each order is cleared for one deposit only.\n */\n async preflightDeposit(quote: Quote, tx: UnsignedTx): Promise<void> {\n if (quote.providerData?.placeholder === \"1\") throw new RelayRefusal(\"request-invalid\", \"a quote priced without the real addresses is never signed\", \"policy_refused\");\n const request = requestOf(quote);\n if (tx.chain !== request.sourceChain) throw new RelayRefusal(\"tx-chain\", `the deposit is for ${tx.chain}, not ${request.sourceChain}`, \"vault_mismatch\");\n if (tx.serializedTx !== undefined || tx.memo !== undefined || tx.typedData !== undefined || tx.bodyBoc !== undefined) {\n throw new RelayRefusal(\"quote-shape\", \"a Relay deposit is one EVM call\", \"policy_refused\");\n }\n const v = checkRelayQuote(request, quote, tx);\n const store = config.clearedStore;\n if (store && await store.has(v.id)) throw new RelayRefusal(\"order-reused\", `order ${v.id} was already cleared for a deposit — quote again`, \"policy_refused\");\n relayClearOrder(v.id, \"sign\");\n // Kept until the order's own deadline: a deposit for it is never signed twice, restart or not.\n if (store) await store.add(v.id, v.order.output.deadline * 1000);\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (typeof ref.intentId !== \"string\" || !ref.intentId.startsWith(INTENT_PREFIX)) return {state: \"failed\"};\n const requestId = ref.intentId.slice(INTENT_PREFIX.length);\n if (!REQUEST_ID.test(requestId)) return {state: \"failed\"};\n // Nothing was sent yet: Relay answers \"waiting\" for a request it has seen no deposit for.\n if (!ref.sourceTxHash) return {state: \"pending\"};\n try {\n const res = await doFetch(`${base}/intents/status/v3?requestId=${requestId}`, {headers: headers(false), signal: timeoutSignal(STATUS_TIMEOUT_MS)});\n if (!res.ok) return {state: \"pending\"};\n const s = (await readJson(res)) as {status?: unknown; txHashes?: unknown; refundFailReason?: unknown} | null;\n const status = typeof s?.status === \"string\" ? s.status.toLowerCase() : \"\";\n const state = Object.prototype.hasOwnProperty.call(RELAY_STATUS_MAP, status) ? RELAY_STATUS_MAP[status]! : \"pending\";\n const seen = status !== \"waiting\" && status !== \"unknown\" && status !== \"\";\n if (state === \"completed\") {\n const hashes = Array.isArray(s?.txHashes) ? s.txHashes.filter((h): h is string => typeof h === \"string\" && /^0x[0-9a-fA-F]{64}$/.test(h)) : [];\n const dest = hashes[hashes.length - 1] ?? ref.destTxHash ?? undefined;\n return {state, depositReceived: true, ...(dest ? {destTxHash: dest} : {})};\n }\n if (status === \"failure\") {\n // A failed fill is refunded by Relay on its own. Only when the refund itself failed is there nothing\n // more coming without Relay's support.\n const why = typeof s?.refundFailReason === \"string\" ? s.refundFailReason.trim() : \"\";\n return {state: why !== \"\" && why.toUpperCase() !== \"N/A\" ? \"failed\" : \"refund-pending\", depositReceived: true};\n }\n return {state, ...(seen ? {depositReceived: true} : {})};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
// src/order.ts
|
|
2
2
|
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
3
|
+
import { withReason } from "@anywalletkit/protocol-swap2-core/errors";
|
|
3
4
|
import { hashMessage, hashStruct, hexToBytes, keccak256 } from "viem";
|
|
4
5
|
var RelayRefusal = class extends Error {
|
|
5
6
|
code;
|
|
6
|
-
constructor(code, detail) {
|
|
7
|
+
constructor(code, detail, reason) {
|
|
7
8
|
super(`relay: ${detail} [${code}]`);
|
|
8
9
|
this.name = "RelayRefusal";
|
|
9
10
|
this.code = code;
|
|
11
|
+
if (reason !== void 0) withReason(this, reason);
|
|
10
12
|
}
|
|
11
13
|
};
|
|
12
14
|
var RELAY_ORDER_TYPES = {
|
|
@@ -63,7 +65,7 @@ var MAX_BYTES_HEX = 2 + 2 * 1024;
|
|
|
63
65
|
var MAX_TEXT = 64;
|
|
64
66
|
var U256_MAX = (1n << 256n) - 1n;
|
|
65
67
|
var bad = (what) => {
|
|
66
|
-
throw new RelayRefusal("order-malformed", `the order's ${what}
|
|
68
|
+
throw new RelayRefusal("order-malformed", `the order's ${what}`, "upstream_unavailable");
|
|
67
69
|
};
|
|
68
70
|
function rec(v, what) {
|
|
69
71
|
if (v === null || typeof v !== "object" || Array.isArray(v)) bad(`${what} is not an object`);
|
|
@@ -187,4 +189,4 @@ export {
|
|
|
187
189
|
relayOrderId,
|
|
188
190
|
relayOrderSigner
|
|
189
191
|
};
|
|
190
|
-
//# sourceMappingURL=chunk-
|
|
192
|
+
//# sourceMappingURL=chunk-MDXHT7HY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/order.ts"],"sourcesContent":["/**\n * A Relay order, read strictly, hashed and attributed here.\n *\n * - The order id is the EIP-712 `hashStruct` of the order under {@link RELAY_ORDER_TYPES} (no domain separator), as\n * github.com/relayprotocol/relay-protocol-sdk (src/order/index.ts) computes it. Chain ids are STRINGS (Relay's own\n * chain names), addresses and currencies are `bytes` (20 raw bytes on an EVM chain).\n * - `orderSignature` is the solver's EIP-191 `personal_sign` over the 32 raw bytes of that id.\n *\n * The id a deposit names is a commitment to everything in the order — recipient, chain, token, minimum, refunds — so\n * recomputing it from the order the API hands over, and reading that same parsed order, is what binds the deposit\n * to terms the device has seen.\n */\nimport {secp256k1} from \"@noble/curves/secp256k1.js\";\nimport {withReason, type Swap2RefusalReason} from \"@anywalletkit/protocol-swap2-core/errors\";\nimport {hashMessage, hashStruct, hexToBytes, keccak256, type Hex} from \"viem\";\n\n/** Why an order, a quote or a deposit was refused. One code per check; the message says what was found. */\nexport type RelayRefusalCode =\n | \"request-invalid\"\n | \"chain-unsupported\"\n | \"protocol-data-missing\"\n | \"hub-type\"\n | \"order-malformed\"\n | \"order-version\"\n | \"order-inputs\"\n | \"order-payments\"\n | \"order-calls\"\n | \"order-fees\"\n | \"solver-not-pinned\"\n | \"input-chain\"\n | \"input-currency\"\n | \"input-amount\"\n | \"input-weight\"\n | \"output-chain\"\n | \"output-recipient\"\n | \"output-currency\"\n | \"output-minimum\"\n | \"output-expected\"\n | \"output-deadline\"\n | \"refund-missing\"\n | \"refund-chain\"\n | \"refund-recipient\"\n | \"refund-currency\"\n | \"refund-deadline\"\n | \"order-id-mismatch\"\n | \"signature-invalid\"\n | \"payment-details\"\n | \"tx-chain\"\n | \"tx-target\"\n | \"tx-selector\"\n | \"tx-calldata\"\n | \"tx-depositor\"\n | \"tx-token\"\n | \"tx-amount\"\n | \"tx-id\"\n | \"tx-value\"\n | \"order-reused\"\n | \"app-fee\"\n | \"gas-topup\"\n | \"quote-gas\"\n | \"quote-expiry\"\n | \"quote-steps\"\n | \"quote-amounts\"\n | \"quote-approval\"\n | \"quote-shape\";\n\n/**\n * `code` names the check; `reason` (a `Swap2RefusalReason` from `@anywalletkit/protocol-swap2-core`) is the stable\n * classification an app switches on. It is set where the refusal is raised, so one code can carry different reasons\n * (an order deadline too far ahead is `policy_refused`, one already used up is `quote_expired`); a malformed request\n * from the caller (a programming error) carries none.\n */\nexport class RelayRefusal extends Error {\n readonly code: RelayRefusalCode;\n declare readonly reason?: Swap2RefusalReason;\n constructor(code: RelayRefusalCode, detail: string, reason?: Swap2RefusalReason) {\n super(`relay: ${detail} [${code}]`);\n this.name = \"RelayRefusal\";\n this.code = code;\n if (reason !== undefined) withReason(this, reason);\n }\n}\n\nexport const RELAY_ORDER_TYPES = {\n Order: [\n {name: \"version\", type: \"string\"},\n {name: \"solverChainId\", type: \"string\"},\n {name: \"solver\", type: \"address\"},\n {name: \"salt\", type: \"uint256\"},\n {name: \"inputs\", type: \"Input[]\"},\n {name: \"output\", type: \"Output\"},\n {name: \"fees\", type: \"Fee[]\"},\n ],\n Input: [\n {name: \"payment\", type: \"InputPayment\"},\n {name: \"refunds\", type: \"InputRefund[]\"},\n ],\n InputPayment: [\n {name: \"chainId\", type: \"string\"},\n {name: \"currency\", type: \"bytes\"},\n {name: \"amount\", type: \"uint256\"},\n {name: \"weight\", type: \"uint256\"},\n ],\n InputRefund: [\n {name: \"chainId\", type: \"string\"},\n {name: \"recipient\", type: \"bytes\"},\n {name: \"currency\", type: \"bytes\"},\n {name: \"minimumAmount\", type: \"uint256\"},\n {name: \"deadline\", type: \"uint32\"},\n {name: \"extraData\", type: \"bytes\"},\n ],\n Output: [\n {name: \"chainId\", type: \"string\"},\n {name: \"payments\", type: \"OutputPayment[]\"},\n {name: \"deadline\", type: \"uint32\"},\n {name: \"calls\", type: \"bytes[]\"},\n {name: \"extraData\", type: \"bytes\"},\n ],\n OutputPayment: [\n {name: \"recipient\", type: \"bytes\"},\n {name: \"currency\", type: \"bytes\"},\n {name: \"minimumAmount\", type: \"uint256\"},\n {name: \"expectedAmount\", type: \"uint256\"},\n ],\n Fee: [\n {name: \"recipientChainId\", type: \"string\"},\n {name: \"recipient\", type: \"bytes\"},\n {name: \"currencyChainId\", type: \"string\"},\n {name: \"currency\", type: \"bytes\"},\n {name: \"amount\", type: \"uint256\"},\n ],\n} as const;\n\nexport interface RelayInputRefund {chainId: string; recipient: Hex; currency: Hex; minimumAmount: bigint; deadline: number; extraData: Hex}\nexport interface RelayInput {payment: {chainId: string; currency: Hex; amount: bigint; weight: bigint}; refunds: RelayInputRefund[]}\nexport interface RelayOutputPayment {recipient: Hex; currency: Hex; minimumAmount: bigint; expectedAmount: bigint}\nexport interface RelayFee {recipientChainId: string; recipient: Hex; currencyChainId: string; currency: Hex; amount: bigint}\n/** An order after {@link parseRelayOrder}: hex lowercased, integers exact. Every field below is hashed into the id. */\nexport interface RelayOrder {\n version: string;\n solverChainId: string;\n solver: Hex;\n salt: bigint;\n inputs: RelayInput[];\n output: {chainId: string; payments: RelayOutputPayment[]; deadline: number; calls: Hex[]; extraData: Hex};\n fees: RelayFee[];\n}\n\nconst MAX_LIST = 8;\nconst MAX_BYTES_HEX = 2 + 2 * 1024;\nconst MAX_TEXT = 64;\nconst U256_MAX = (1n << 256n) - 1n;\n\n// The answer is not the documented shape.\nconst bad = (what: string): never => { throw new RelayRefusal(\"order-malformed\", `the order's ${what}`, \"upstream_unavailable\"); };\n\nfunction rec(v: unknown, what: string): Record<string, unknown> {\n if (v === null || typeof v !== \"object\" || Array.isArray(v)) bad(`${what} is not an object`);\n return v as Record<string, unknown>;\n}\nfunction list(v: unknown, what: string): unknown[] {\n if (!Array.isArray(v)) bad(`${what} is not a list`);\n if ((v as unknown[]).length > MAX_LIST) bad(`${what} has more than ${MAX_LIST} entries`);\n return v as unknown[];\n}\n/** Own property only: a field missing from the JSON is never read off a prototype. */\nfunction own(o: Record<string, unknown>, key: string): unknown {\n return Object.prototype.hasOwnProperty.call(o, key) ? o[key] : undefined;\n}\nfunction text(v: unknown, what: string): string {\n if (typeof v !== \"string\" || v.length === 0 || v.length > MAX_TEXT) bad(`${what} is not a short string`);\n return v as string;\n}\n/** `bytes`: 0x-hex of whole bytes, lowercased. */\nfunction bytes(v: unknown, what: string): Hex {\n if (typeof v !== \"string\" || v.length > MAX_BYTES_HEX || !/^0x(?:[0-9a-fA-F]{2})*$/.test(v)) bad(`${what} is not hex bytes`);\n return (v as string).toLowerCase() as Hex;\n}\n/** `uint256`: a decimal string, a 0x-hex string (Relay writes the salt that way) or a safe non-negative integer. */\nfunction uint(v: unknown, what: string, max: bigint = U256_MAX): bigint {\n let n: bigint | null = null;\n if (typeof v === \"string\" && (/^(?:0|[1-9]\\d{0,77})$/.test(v) || /^0x[0-9a-fA-F]{1,64}$/.test(v))) n = BigInt(v);\n else if (typeof v === \"number\" && Number.isSafeInteger(v) && v >= 0) n = BigInt(v);\n if (n === null || n > max) bad(`${what} is not an unsigned integer in range`);\n return n as bigint;\n}\nfunction uint32(v: unknown, what: string): number {\n // Below 2^32, so the conversion is exact.\n return parseInt(uint(v, what, 0xffff_ffffn).toString(10), 10);\n}\nfunction address(v: unknown, what: string): Hex {\n if (typeof v !== \"string\" || !/^0x[0-9a-fA-F]{40}$/.test(v)) bad(`${what} is not an address`);\n return (v as string).toLowerCase() as Hex;\n}\n\n/**\n * Read an order as the API gives it (`protocol.v2.orderData`, already JSON-parsed) into the one typed form the id,\n * the signature and every check are computed from. Anything that is not exactly the documented shape is refused\n * (`order-malformed`); keys the type does not have are ignored — they are outside the hash, and nothing reads them.\n */\nexport function parseRelayOrder(raw: unknown): RelayOrder {\n const o = rec(raw, \"body\");\n const output = rec(own(o, \"output\"), \"output\");\n return {\n version: text(own(o, \"version\"), \"version\"),\n solverChainId: text(own(o, \"solverChainId\"), \"solver chain\"),\n solver: address(own(o, \"solver\"), \"solver\"),\n salt: uint(own(o, \"salt\"), \"salt\"),\n inputs: list(own(o, \"inputs\"), \"inputs\").map((x, i) => {\n const input = rec(x, `input ${i}`);\n const p = rec(own(input, \"payment\"), `input ${i} payment`);\n return {\n payment: {\n chainId: text(own(p, \"chainId\"), `input ${i} chain`),\n currency: bytes(own(p, \"currency\"), `input ${i} currency`),\n amount: uint(own(p, \"amount\"), `input ${i} amount`),\n weight: uint(own(p, \"weight\"), `input ${i} weight`),\n },\n refunds: list(own(input, \"refunds\"), `input ${i} refunds`).map((y, j) => {\n const r = rec(y, `refund ${j}`);\n return {\n chainId: text(own(r, \"chainId\"), `refund ${j} chain`),\n recipient: bytes(own(r, \"recipient\"), `refund ${j} recipient`),\n currency: bytes(own(r, \"currency\"), `refund ${j} currency`),\n minimumAmount: uint(own(r, \"minimumAmount\"), `refund ${j} minimum`),\n deadline: uint32(own(r, \"deadline\"), `refund ${j} deadline`),\n extraData: bytes(own(r, \"extraData\"), `refund ${j} extra data`),\n };\n }),\n };\n }),\n output: {\n chainId: text(own(output, \"chainId\"), \"output chain\"),\n payments: list(own(output, \"payments\"), \"output payments\").map((x, i) => {\n const p = rec(x, `output payment ${i}`);\n return {\n recipient: bytes(own(p, \"recipient\"), `output payment ${i} recipient`),\n currency: bytes(own(p, \"currency\"), `output payment ${i} currency`),\n minimumAmount: uint(own(p, \"minimumAmount\"), `output payment ${i} minimum`),\n expectedAmount: uint(own(p, \"expectedAmount\"), `output payment ${i} expected amount`),\n };\n }),\n deadline: uint32(own(output, \"deadline\"), \"output deadline\"),\n calls: list(own(output, \"calls\"), \"output calls\").map((x, i) => bytes(x, `output call ${i}`)),\n extraData: bytes(own(output, \"extraData\"), \"output extra data\"),\n },\n fees: list(own(o, \"fees\"), \"fees\").map((x, i) => {\n const f = rec(x, `fee ${i}`);\n return {\n recipientChainId: text(own(f, \"recipientChainId\"), `fee ${i} recipient chain`),\n recipient: bytes(own(f, \"recipient\"), `fee ${i} recipient`),\n currencyChainId: text(own(f, \"currencyChainId\"), `fee ${i} currency chain`),\n currency: bytes(own(f, \"currency\"), `fee ${i} currency`),\n amount: uint(own(f, \"amount\"), `fee ${i} amount`),\n };\n }),\n };\n}\n\n/** The order id: `hashStruct(Order)`, no domain. */\nexport function relayOrderId(order: RelayOrder): Hex {\n return hashStruct({types: RELAY_ORDER_TYPES, primaryType: \"Order\", data: order as never});\n}\n\n/**\n * The address whose `personal_sign` over the id's 32 bytes this signature is (lowercase), or null when it is not a\n * 65-byte secp256k1 signature that recovers at all. Synchronous on purpose: the same check runs wherever the order\n * is read, with nothing left for a later asynchronous step.\n */\nexport function relayOrderSigner(id: Hex, signature: unknown): Hex | null {\n if (typeof signature !== \"string\" || !/^0x[0-9a-fA-F]{130}$/.test(signature)) return null;\n const sig = hexToBytes(signature as Hex);\n const v = sig[64]!;\n const recovery = v === 27 || v === 28 ? v - 27 : v === 0 || v === 1 ? v : -1;\n if (recovery < 0) return null;\n try {\n const recoverable = new Uint8Array(65);\n recoverable[0] = recovery;\n recoverable.set(sig.subarray(0, 64), 1);\n const digest = hexToBytes(hashMessage({raw: id}));\n const key = secp256k1.recoverPublicKey(recoverable, digest, {prehash: false});\n // The recovery must also verify: a malformed (r, s) never passes as a signer.\n if (!secp256k1.verify(sig.subarray(0, 64), digest, key, {prehash: false})) return null;\n const uncompressed = secp256k1.Point.fromBytes(key).toBytes(false);\n return `0x${keccak256(uncompressed.subarray(1)).slice(-40)}`.toLowerCase() as Hex;\n } catch {\n return null;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
relayProvider
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JTPYU26F.js";
|
|
4
4
|
import {
|
|
5
5
|
relay
|
|
6
6
|
} from "./chunk-JQAN7HB5.js";
|
|
@@ -24,4 +24,4 @@ var RelaySwap2Protocol = class extends SingleProviderSwap2 {
|
|
|
24
24
|
export {
|
|
25
25
|
RelaySwap2Protocol
|
|
26
26
|
};
|
|
27
|
-
//# sourceMappingURL=chunk-
|
|
27
|
+
//# sourceMappingURL=chunk-TBFD7BPZ.js.map
|