@anywalletkit/protocol-swap2-relay 0.1.1 → 0.1.3

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 CHANGED
@@ -29,7 +29,7 @@ Standalone: `new RelaySwap2Protocol(account, {fromChain: "eip155:42161"})`.
29
29
 
30
30
  ## What is checked
31
31
 
32
- Every check has a code; a refusal reads `relay: <what was found> [<code>]` and reaches `onRefusal`. Nothing returns a silent null.
32
+ Every check has a code; a refusal reads `relay: <what was found> [<code>]` and reaches `onRefusal`. Nothing returns a silent null. Next to the text, a refusal carries `reason`, a stable `Swap2RefusalReason` from `@anywalletkit/protocol-swap2-core` (on the thrown error, as `onRefusal`'s second argument, and through `relayPins.reasonOf` for the pins' texts): for example `recipient_mismatch` for an order paying or refunding someone else, `vault_mismatch` for a deposit or approval off the pinned depository, `price_check_failed` for a minimum under the floor or the slippage, `quote_expired` for an order older than ten minutes, and Relay's own answers by its `errorCode` or the HTTP status (`rate_limited` with `retryAfterMs`, `key_rejected`, `upstream_unavailable`). A malformed request from the caller carries none.
33
33
 
34
34
  **The order is the one the deposit names**
35
35
 
@@ -3,7 +3,7 @@ import {
3
3
  parseRelayOrder,
4
4
  relayOrderId,
5
5
  relayOrderSigner
6
- } from "./chunk-UVHDMGM5.js";
6
+ } from "./chunk-MDXHT7HY.js";
7
7
  import {
8
8
  RELAY_CLOCK_SKEW_S,
9
9
  RELAY_DEPOSIT_ERC20,
@@ -19,6 +19,7 @@ import {
19
19
 
20
20
  // src/verify.ts
21
21
  import { encodeFunctionData, parseAbi } from "viem";
22
+ import { refusalNotes, refusalOf } from "@anywalletkit/protocol-swap2-core/errors";
22
23
  import { sourceAssetOf } from "@anywalletkit/protocol-swap2-core/util";
23
24
 
24
25
  // src/cleared.ts
@@ -28,10 +29,10 @@ var clearedOrders = /* @__PURE__ */ new Map();
28
29
  function relayClearOrder(id, stage, nowMs = Date.now()) {
29
30
  const key = `${stage}:${id.toLowerCase()}`;
30
31
  const until = clearedOrders.get(key);
31
- if (until !== void 0 && until > nowMs) throw new RelayRefusal("order-reused", `order ${id} was already cleared for a deposit \u2014 quote again`);
32
+ if (until !== void 0 && until > nowMs) throw new RelayRefusal("order-reused", `order ${id} was already cleared for a deposit \u2014 quote again`, "policy_refused");
32
33
  if (clearedOrders.size >= CLEARED_MAX) {
33
34
  for (const [k, t] of clearedOrders) if (t <= nowMs) clearedOrders.delete(k);
34
- if (clearedOrders.size >= CLEARED_MAX) throw new RelayRefusal("order-reused", "too many deposits cleared in the last minutes \u2014 try again later");
35
+ if (clearedOrders.size >= CLEARED_MAX) throw new RelayRefusal("order-reused", "too many deposits cleared in the last minutes \u2014 try again later", "policy_refused");
35
36
  }
36
37
  clearedOrders.set(key, nowMs + CLEARED_TTL_MS);
37
38
  }
@@ -73,24 +74,24 @@ function buildRelayDeposit(source, depositor, token, amount, id) {
73
74
  };
74
75
  }
75
76
  function checkRequest(r) {
76
- const invalid = (what) => {
77
- throw new RelayRefusal("request-invalid", what);
77
+ const invalid = (what, reason) => {
78
+ throw new RelayRefusal("request-invalid", what, reason);
78
79
  };
79
80
  if (r === null || typeof r !== "object") invalid("no request to check the order against");
80
81
  const source = relayChain(r.sourceChain);
81
82
  const dest = relayChain(r.destChain);
82
- if (!source) throw new RelayRefusal("chain-unsupported", `source chain ${String(r.sourceChain)} is not a pinned Relay chain`);
83
- if (!dest) throw new RelayRefusal("chain-unsupported", `destination chain ${String(r.destChain)} is not a pinned Relay chain`);
84
- if (source === dest) throw new RelayRefusal("chain-unsupported", "source and destination are the same chain");
83
+ if (!source) throw new RelayRefusal("chain-unsupported", `source chain ${String(r.sourceChain)} is not a pinned Relay chain`, "unsupported_pair");
84
+ if (!dest) throw new RelayRefusal("chain-unsupported", `destination chain ${String(r.destChain)} is not a pinned Relay chain`, "unsupported_pair");
85
+ if (source === dest) throw new RelayRefusal("chain-unsupported", "source and destination are the same chain", "unsupported_pair");
85
86
  for (const [what, v] of [["input token", r.sourceToken], ["output token", r.destToken], ["depositor", r.depositor], ["recipient", r.recipient]]) {
86
87
  if (typeof v !== "string" || !ADDRESS.test(v)) invalid(`the ${what} is not an address`);
87
88
  }
88
- if (/^0x0{40}$/.test(r.depositor)) invalid("the depositor is the zero address");
89
- if (/^0x0{40}$/.test(r.recipient)) invalid("the recipient is the zero address");
89
+ if (/^0x0{40}$/.test(r.depositor)) invalid("the depositor is the zero address", "recipient_mismatch");
90
+ if (/^0x0{40}$/.test(r.recipient)) invalid("the recipient is the zero address", "recipient_mismatch");
90
91
  if (typeof r.amount !== "bigint" || r.amount <= 0n || r.amount > U256_MAX) invalid("the amount is not a positive integer");
91
92
  if (r.minAmountOut !== void 0 && (typeof r.minAmountOut !== "bigint" || r.minAmountOut < 0n)) invalid("the output floor is not an unsigned integer");
92
93
  if (r.slippageBps !== void 0 && (!Number.isInteger(r.slippageBps) || r.slippageBps < 0 || r.slippageBps > RELAY_MAX_SLIPPAGE_BPS)) {
93
- invalid(`slippage must be a whole number of basis points up to ${RELAY_MAX_SLIPPAGE_BPS}`);
94
+ invalid(`slippage must be a whole number of basis points up to ${RELAY_MAX_SLIPPAGE_BPS}`, "policy_refused");
94
95
  }
95
96
  const nowMs = r.nowMs ?? Date.now();
96
97
  if (!Number.isFinite(nowMs) || nowMs <= 0) invalid("the clock is not a time");
@@ -100,143 +101,143 @@ var isAddr = (bytes, addr) => bytes.length === 42 && bytes === lower(addr);
100
101
  function checkDeadline(code, what, deadline, nowS) {
101
102
  const left = deadline - nowS;
102
103
  if (left > RELAY_ORDER_LIFETIME_S + RELAY_CLOCK_SKEW_S) {
103
- throw new RelayRefusal(code, `${what} is ${left} s away, past the ${RELAY_ORDER_LIFETIME_S} s an order lives`);
104
+ throw new RelayRefusal(code, `${what} is ${left} s away, past the ${RELAY_ORDER_LIFETIME_S} s an order lives`, "policy_refused");
104
105
  }
105
106
  if (left < RELAY_ORDER_LIFETIME_S - RELAY_MAX_ORDER_AGE_S) {
106
- throw new RelayRefusal(code, `${what} is ${left} s away: the order is older than ${RELAY_MAX_ORDER_AGE_S} s or already past it`);
107
+ throw new RelayRefusal(code, `${what} is ${left} s away: the order is older than ${RELAY_MAX_ORDER_AGE_S} s or already past it`, "quote_expired");
107
108
  }
108
109
  }
109
110
  function wordAddress(word) {
110
111
  return /^0{24}/.test(word) ? `0x${word.slice(24)}` : null;
111
112
  }
112
113
  function checkDepositTarget(tx, source) {
113
- if (tx === null || typeof tx !== "object") throw new RelayRefusal("tx-calldata", "there is no deposit transaction");
114
+ if (tx === null || typeof tx !== "object") throw new RelayRefusal("tx-calldata", "there is no deposit transaction", "policy_refused");
114
115
  if (tx.chainId !== source.chainId) {
115
- throw new RelayRefusal("tx-chain", `the deposit is for chain ${String(tx.chainId)}, not ${source.chainId}`);
116
+ throw new RelayRefusal("tx-chain", `the deposit is for chain ${String(tx.chainId)}, not ${source.chainId}`, "vault_mismatch");
116
117
  }
117
118
  if (typeof tx.to !== "string" || !ADDRESS.test(tx.to) || lower(tx.to) !== source.depository) {
118
- throw new RelayRefusal("tx-target", `the deposit calls ${String(tx.to)}, not the ${source.name} depository ${source.depository} \u2014 routes that first swap on the source chain go through a router and are not signed by this module`);
119
+ throw new RelayRefusal("tx-target", `the deposit calls ${String(tx.to)}, not the ${source.name} depository ${source.depository} \u2014 routes that first swap on the source chain go through a router and are not signed by this module`, "vault_mismatch");
119
120
  }
120
121
  }
121
122
  function checkDepositTx(tx, source, request, order, id) {
122
123
  checkDepositTarget(tx, source);
123
124
  if (typeof tx.data !== "string" || !/^0x(?:[0-9a-fA-F]{2})*$/.test(tx.data) || tx.data.length < 10) {
124
- throw new RelayRefusal("tx-calldata", "the deposit has no calldata");
125
+ throw new RelayRefusal("tx-calldata", "the deposit has no calldata", "policy_refused");
125
126
  }
126
127
  const data = lower(tx.data);
127
128
  const selector = data.slice(0, 10);
128
129
  const input = order.inputs[0].payment;
129
130
  const native = isNative(input.currency);
130
131
  if (selector === RELAY_DEPOSIT_ERC20_ALLOWANCE) {
131
- throw new RelayRefusal("tx-selector", "the deposit uses depositErc20 without an amount, which takes the whole allowance");
132
+ throw new RelayRefusal("tx-selector", "the deposit uses depositErc20 without an amount, which takes the whole allowance", "policy_refused");
132
133
  }
133
134
  if (selector !== RELAY_DEPOSIT_NATIVE && selector !== RELAY_DEPOSIT_ERC20) {
134
- throw new RelayRefusal("tx-selector", `the deposit calls ${selector}, not a known deposit function`);
135
+ throw new RelayRefusal("tx-selector", `the deposit calls ${selector}, not a known deposit function`, "policy_refused");
135
136
  }
136
137
  if (selector === RELAY_DEPOSIT_NATIVE !== native) {
137
- throw new RelayRefusal("tx-selector", `the deposit calls ${native ? "depositErc20" : "depositNative"} for an order whose input is ${native ? "the native coin" : "a token"}`);
138
+ throw new RelayRefusal("tx-selector", `the deposit calls ${native ? "depositErc20" : "depositNative"} for an order whose input is ${native ? "the native coin" : "a token"}`, "policy_refused");
138
139
  }
139
140
  const words = native ? 2 : 4;
140
141
  if (data.length !== 10 + 64 * words) {
141
- throw new RelayRefusal("tx-calldata", `the deposit calldata is ${(data.length - 2) / 2} bytes, not ${4 + 32 * words}`);
142
+ throw new RelayRefusal("tx-calldata", `the deposit calldata is ${(data.length - 2) / 2} bytes, not ${4 + 32 * words}`, "policy_refused");
142
143
  }
143
144
  const word = (i) => data.slice(10 + 64 * i, 74 + 64 * i);
144
145
  const depositor = wordAddress(word(0));
145
- if (depositor === null) throw new RelayRefusal("tx-calldata", "the depositor argument is not a padded address");
146
+ if (depositor === null) throw new RelayRefusal("tx-calldata", "the depositor argument is not a padded address", "policy_refused");
146
147
  if (depositor !== lower(request.depositor)) {
147
- throw new RelayRefusal("tx-depositor", `the deposit is credited to ${depositor}, not to the sender ${lower(request.depositor)}`);
148
+ throw new RelayRefusal("tx-depositor", `the deposit is credited to ${depositor}, not to the sender ${lower(request.depositor)}`, "recipient_mismatch");
148
149
  }
149
150
  if (!native) {
150
151
  const token = wordAddress(word(1));
151
- if (token === null) throw new RelayRefusal("tx-calldata", "the token argument is not a padded address");
152
- if (token !== input.currency) throw new RelayRefusal("tx-token", `the deposit moves ${token}, the order's input is ${input.currency}`);
152
+ if (token === null) throw new RelayRefusal("tx-calldata", "the token argument is not a padded address", "policy_refused");
153
+ if (token !== input.currency) throw new RelayRefusal("tx-token", `the deposit moves ${token}, the order's input is ${input.currency}`, "policy_refused");
153
154
  const amount = BigInt(`0x${word(2)}`);
154
- if (amount !== input.amount) throw new RelayRefusal("tx-amount", `the deposit moves ${amount}, the order's input is ${input.amount}`);
155
+ if (amount !== input.amount) throw new RelayRefusal("tx-amount", `the deposit moves ${amount}, the order's input is ${input.amount}`, "policy_refused");
155
156
  }
156
157
  const txId = `0x${word(native ? 1 : 3)}`;
157
- if (txId !== id) throw new RelayRefusal("tx-id", `the deposit names order ${txId}, the order received hashes to ${id}`);
158
+ if (txId !== id) throw new RelayRefusal("tx-id", `the deposit names order ${txId}, the order received hashes to ${id}`, "recipient_unverifiable");
158
159
  const value = typeof tx.value === "string" && /^(?:0|[1-9]\d{0,77})$/.test(tx.value) ? BigInt(tx.value) : null;
159
160
  const wantValue = native ? input.amount : 0n;
160
161
  if (value === null || value !== wantValue) {
161
- throw new RelayRefusal("tx-value", `the deposit sends ${String(tx.value)} wei, it must send ${wantValue}`);
162
+ throw new RelayRefusal("tx-value", `the deposit sends ${String(tx.value)} wei, it must send ${wantValue}`, "policy_refused");
162
163
  }
163
164
  }
164
165
  function verifyRelayOrder(request, protocol, deposit) {
165
166
  const { source, dest, nowS } = checkRequest(request);
166
167
  if (deposit !== void 0) checkDepositTarget(deposit, source);
167
168
  if (protocol === null || typeof protocol !== "object") {
168
- throw new RelayRefusal("protocol-data-missing", "the quote carries no order (protocol.v2) \u2014 nothing to check the deposit against");
169
+ throw new RelayRefusal("protocol-data-missing", "the quote carries no order (protocol.v2) \u2014 nothing to check the deposit against", "upstream_unavailable");
169
170
  }
170
171
  if (protocol.orderData === void 0 || protocol.orderData === null) {
171
- throw new RelayRefusal("protocol-data-missing", "the quote carries no order data \u2014 nothing to check the deposit against");
172
+ throw new RelayRefusal("protocol-data-missing", "the quote carries no order data \u2014 nothing to check the deposit against", "upstream_unavailable");
172
173
  }
173
174
  if (protocol.hubType !== "onchain") {
174
- throw new RelayRefusal("hub-type", `the order settles through a "${String(protocol.hubType)}" hub, only "onchain" is read`);
175
+ throw new RelayRefusal("hub-type", `the order settles through a "${String(protocol.hubType)}" hub, only "onchain" is read`, "unsupported_pair");
175
176
  }
176
177
  const order = parseRelayOrder(protocol.orderData);
177
- if (order.version !== RELAY_ORDER_VERSION) throw new RelayRefusal("order-version", `order version "${order.version}" is not ${RELAY_ORDER_VERSION}`);
178
- if (order.inputs.length !== 1) throw new RelayRefusal("order-inputs", `the order has ${order.inputs.length} inputs, exactly one is signed for`);
179
- if (order.output.payments.length !== 1) throw new RelayRefusal("order-payments", `the order pays ${order.output.payments.length} outputs, exactly one is accepted`);
180
- if (order.output.calls.length !== 0) throw new RelayRefusal("order-calls", "the order runs calls on the destination \u2014 only plain payments are accepted");
181
- if (order.fees.length !== 0) throw new RelayRefusal("order-fees", "the order carries order-level fees, which this module does not show and does not accept");
178
+ if (order.version !== RELAY_ORDER_VERSION) throw new RelayRefusal("order-version", `order version "${order.version}" is not ${RELAY_ORDER_VERSION}`, "upstream_unavailable");
179
+ if (order.inputs.length !== 1) throw new RelayRefusal("order-inputs", `the order has ${order.inputs.length} inputs, exactly one is signed for`, "policy_refused");
180
+ if (order.output.payments.length !== 1) throw new RelayRefusal("order-payments", `the order pays ${order.output.payments.length} outputs, exactly one is accepted`, "policy_refused");
181
+ if (order.output.calls.length !== 0) throw new RelayRefusal("order-calls", "the order runs calls on the destination \u2014 only plain payments are accepted", "policy_refused");
182
+ if (order.fees.length !== 0) throw new RelayRefusal("order-fees", "the order carries order-level fees, which this module does not show and does not accept", "policy_refused");
182
183
  const input = order.inputs[0];
183
184
  const pay = order.output.payments[0];
184
- if (input.payment.weight === 0n) throw new RelayRefusal("input-weight", "the order's input has zero weight");
185
+ if (input.payment.weight === 0n) throw new RelayRefusal("input-weight", "the order's input has zero weight", "policy_refused");
185
186
  if (!RELAY_SOLVERS.some((s) => s.address === order.solver && s.chainId === order.solverChainId)) {
186
- throw new RelayRefusal("solver-not-pinned", `solver ${order.solver} on "${order.solverChainId}" is not a pinned Relay solver`);
187
+ throw new RelayRefusal("solver-not-pinned", `solver ${order.solver} on "${order.solverChainId}" is not a pinned Relay solver`, "recipient_unverifiable");
187
188
  }
188
- if (order.output.chainId !== dest.slug) throw new RelayRefusal("output-chain", `the order pays on "${order.output.chainId}", the request is for ${dest.name} ("${dest.slug}")`);
189
- if (!isAddr(pay.recipient, request.recipient)) throw new RelayRefusal("output-recipient", `the order pays ${pay.recipient}, not the recipient ${lower(request.recipient)}`);
190
- if (!isAddr(pay.currency, request.destToken)) throw new RelayRefusal("output-currency", `the order pays in ${pay.currency}, the request is for ${lower(request.destToken)}`);
191
- if (pay.minimumAmount <= 0n) throw new RelayRefusal("output-minimum", "the order's minimum output is zero");
189
+ if (order.output.chainId !== dest.slug) throw new RelayRefusal("output-chain", `the order pays on "${order.output.chainId}", the request is for ${dest.name} ("${dest.slug}")`, "recipient_mismatch");
190
+ if (!isAddr(pay.recipient, request.recipient)) throw new RelayRefusal("output-recipient", `the order pays ${pay.recipient}, not the recipient ${lower(request.recipient)}`, "recipient_mismatch");
191
+ if (!isAddr(pay.currency, request.destToken)) throw new RelayRefusal("output-currency", `the order pays in ${pay.currency}, the request is for ${lower(request.destToken)}`, "price_check_failed");
192
+ if (pay.minimumAmount <= 0n) throw new RelayRefusal("output-minimum", "the order's minimum output is zero", "price_check_failed");
192
193
  if (request.minAmountOut !== void 0 && pay.minimumAmount < request.minAmountOut) {
193
- throw new RelayRefusal("output-minimum", `the order's minimum output ${pay.minimumAmount} is under the caller's floor ${request.minAmountOut}`);
194
+ throw new RelayRefusal("output-minimum", `the order's minimum output ${pay.minimumAmount} is under the caller's floor ${request.minAmountOut}`, "price_check_failed");
194
195
  }
195
- if (pay.expectedAmount < pay.minimumAmount) throw new RelayRefusal("output-expected", `the order expects ${pay.expectedAmount}, less than its own minimum ${pay.minimumAmount}`);
196
+ if (pay.expectedAmount < pay.minimumAmount) throw new RelayRefusal("output-expected", `the order expects ${pay.expectedAmount}, less than its own minimum ${pay.minimumAmount}`, "price_check_failed");
196
197
  const slippage = BigInt(request.slippageBps ?? RELAY_DEFAULT_SLIPPAGE_BPS);
197
198
  const floor = pay.expectedAmount * (10000n - slippage) / 10000n;
198
199
  if (pay.minimumAmount < floor) {
199
- throw new RelayRefusal("output-minimum", `the order's minimum output ${pay.minimumAmount} is more than ${slippage} bps under its expected ${pay.expectedAmount}`);
200
+ throw new RelayRefusal("output-minimum", `the order's minimum output ${pay.minimumAmount} is more than ${slippage} bps under its expected ${pay.expectedAmount}`, "price_check_failed");
200
201
  }
201
202
  checkDeadline("output-deadline", "the output deadline", order.output.deadline, nowS);
202
- if (input.payment.chainId !== source.slug) throw new RelayRefusal("input-chain", `the order is funded on "${input.payment.chainId}", the request sends on ${source.name} ("${source.slug}")`);
203
- if (!isAddr(input.payment.currency, request.sourceToken)) throw new RelayRefusal("input-currency", `the order is funded in ${input.payment.currency}, the request sends ${lower(request.sourceToken)}`);
204
- if (input.payment.amount !== request.amount) throw new RelayRefusal("input-amount", `the order is funded with ${input.payment.amount}, the request sends ${request.amount}`);
203
+ if (input.payment.chainId !== source.slug) throw new RelayRefusal("input-chain", `the order is funded on "${input.payment.chainId}", the request sends on ${source.name} ("${source.slug}")`, "policy_refused");
204
+ if (!isAddr(input.payment.currency, request.sourceToken)) throw new RelayRefusal("input-currency", `the order is funded in ${input.payment.currency}, the request sends ${lower(request.sourceToken)}`, "policy_refused");
205
+ if (input.payment.amount !== request.amount) throw new RelayRefusal("input-amount", `the order is funded with ${input.payment.amount}, the request sends ${request.amount}`, "policy_refused");
205
206
  let originRefund = false;
206
207
  for (const refund of input.refunds) {
207
208
  if (refund.chainId === source.slug) {
208
- if (!isAddr(refund.recipient, request.depositor)) throw new RelayRefusal("refund-recipient", `a source-chain refund goes to ${refund.recipient}, not the sender ${lower(request.depositor)}`);
209
- if (refund.currency !== input.payment.currency) throw new RelayRefusal("refund-currency", `a source-chain refund is in ${refund.currency}, not the token sent`);
209
+ if (!isAddr(refund.recipient, request.depositor)) throw new RelayRefusal("refund-recipient", `a source-chain refund goes to ${refund.recipient}, not the sender ${lower(request.depositor)}`, "recipient_mismatch");
210
+ if (refund.currency !== input.payment.currency) throw new RelayRefusal("refund-currency", `a source-chain refund is in ${refund.currency}, not the token sent`, "policy_refused");
210
211
  originRefund = true;
211
212
  } else if (refund.chainId === dest.slug) {
212
213
  if (!isAddr(refund.recipient, request.recipient) && !isAddr(refund.recipient, request.depositor)) {
213
- throw new RelayRefusal("refund-recipient", `a destination-chain refund goes to ${refund.recipient}, neither the recipient nor the sender`);
214
+ throw new RelayRefusal("refund-recipient", `a destination-chain refund goes to ${refund.recipient}, neither the recipient nor the sender`, "recipient_mismatch");
214
215
  }
215
- if (refund.currency.length !== 42) throw new RelayRefusal("refund-currency", "a destination-chain refund names no token");
216
+ if (refund.currency.length !== 42) throw new RelayRefusal("refund-currency", "a destination-chain refund names no token", "policy_refused");
216
217
  } else {
217
- throw new RelayRefusal("refund-chain", `a refund is payable on "${refund.chainId}", neither the source nor the destination chain`);
218
+ throw new RelayRefusal("refund-chain", `a refund is payable on "${refund.chainId}", neither the source nor the destination chain`, "recipient_mismatch");
218
219
  }
219
220
  checkDeadline("refund-deadline", "a refund deadline", refund.deadline, nowS);
220
221
  }
221
- if (!originRefund) throw new RelayRefusal("refund-missing", "the order has no refund to the sender on the source chain");
222
+ if (!originRefund) throw new RelayRefusal("refund-missing", "the order has no refund to the sender on the source chain", "policy_refused");
222
223
  const id = relayOrderId(order);
223
224
  if (typeof protocol.orderId !== "string" || lower(protocol.orderId) !== id) {
224
- throw new RelayRefusal("order-id-mismatch", `the quote names order ${String(protocol.orderId)}, the order data hashes to ${id}`);
225
+ throw new RelayRefusal("order-id-mismatch", `the quote names order ${String(protocol.orderId)}, the order data hashes to ${id}`, "recipient_unverifiable");
225
226
  }
226
227
  const signer = relayOrderSigner(id, protocol.orderSignature);
227
228
  if (signer === null || signer !== order.solver) {
228
- throw new RelayRefusal("signature-invalid", signer === null ? "the order signature is not a valid signature" : `the order is signed by ${signer}, not by its solver ${order.solver}`);
229
+ throw new RelayRefusal("signature-invalid", signer === null ? "the order signature is not a valid signature" : `the order is signed by ${signer}, not by its solver ${order.solver}`, "recipient_unverifiable");
229
230
  }
230
231
  const pd = protocol.paymentDetails;
231
- if (pd === null || typeof pd !== "object") throw new RelayRefusal("payment-details", "the quote has no payment details");
232
+ if (pd === null || typeof pd !== "object") throw new RelayRefusal("payment-details", "the quote has no payment details", "upstream_unavailable");
232
233
  if (pd.chainId !== source.slug || typeof pd.depository !== "string" || lower(pd.depository) !== source.depository || typeof pd.currency !== "string" || lower(pd.currency) !== input.payment.currency || typeof pd.amount !== "string" || pd.amount !== input.payment.amount.toString(10)) {
233
- throw new RelayRefusal("payment-details", "the quote's payment details do not describe the order's input on the pinned depository");
234
+ throw new RelayRefusal("payment-details", "the quote's payment details do not describe the order's input on the pinned depository", "vault_mismatch");
234
235
  }
235
236
  const built = buildRelayDeposit(source, request.depositor, input.payment.currency, input.payment.amount, id);
236
237
  if (deposit !== void 0) {
237
238
  checkDepositTx(deposit, source, request, order, id);
238
239
  if (lower(deposit.data) !== built.data || lower(deposit.to) !== built.to || deposit.value !== built.value) {
239
- throw new RelayRefusal("tx-calldata", "the deposit is not the call this module builds for the order");
240
+ throw new RelayRefusal("tx-calldata", "the deposit is not the call this module builds for the order", "policy_refused");
240
241
  }
241
242
  }
242
243
  return { order, id, deposit: built, expectedAmount: pay.expectedAmount, minimumAmount: pay.minimumAmount, source, dest };
@@ -246,22 +247,22 @@ function relayRefusalReason(err) {
246
247
  throw err;
247
248
  }
248
249
  function relayRequestOf(params, opts = {}) {
249
- const invalid = (what) => {
250
- throw new RelayRefusal("request-invalid", what);
250
+ const invalid = (what, reason) => {
251
+ throw new RelayRefusal("request-invalid", what, reason);
251
252
  };
252
- if (params.flex) invalid("the amount is sealed into the order (no flexible deposits)");
253
- if (!relayChain(params.sourceChain)) throw new RelayRefusal("chain-unsupported", `source chain ${params.sourceChain} is not a pinned Relay chain`);
254
- if (!relayChain(params.destChain)) throw new RelayRefusal("chain-unsupported", `destination chain ${params.destChain} is not a pinned Relay chain`);
255
- if (params.sourceChain === params.destChain) throw new RelayRefusal("chain-unsupported", "same-chain swaps are not served through the depository");
253
+ if (params.flex) invalid("the amount is sealed into the order (no flexible deposits)", "unsupported_pair");
254
+ if (!relayChain(params.sourceChain)) throw new RelayRefusal("chain-unsupported", `source chain ${params.sourceChain} is not a pinned Relay chain`, "unsupported_pair");
255
+ if (!relayChain(params.destChain)) throw new RelayRefusal("chain-unsupported", `destination chain ${params.destChain} is not a pinned Relay chain`, "unsupported_pair");
256
+ if (params.sourceChain === params.destChain) throw new RelayRefusal("chain-unsupported", "same-chain swaps are not served through the depository", "unsupported_pair");
256
257
  let sourceToken;
257
258
  if (typeof params.sourceToken === "string" && ADDRESS.test(params.sourceToken)) sourceToken = params.sourceToken;
258
259
  else {
259
260
  const asset = sourceAssetOf(params);
260
- if (!asset) invalid(`source token ${String(params.sourceToken)} is not known on ${params.sourceChain}`);
261
+ if (!asset) invalid(`source token ${String(params.sourceToken)} is not known on ${params.sourceChain}`, "unsupported_pair");
261
262
  sourceToken = asset.contract ?? RELAY_NATIVE;
262
- if (!ADDRESS.test(sourceToken)) invalid(`source token ${String(params.sourceToken)} has no EVM contract`);
263
+ if (!ADDRESS.test(sourceToken)) invalid(`source token ${String(params.sourceToken)} has no EVM contract`, "unsupported_pair");
263
264
  }
264
- if (typeof params.destToken !== "string" || !ADDRESS.test(params.destToken)) invalid("the destination token must be an EVM address (zero for the native coin)");
265
+ if (typeof params.destToken !== "string" || !ADDRESS.test(params.destToken)) invalid("the destination token must be an EVM address (zero for the native coin)", "unsupported_pair");
265
266
  if (typeof params.amountIn !== "string" || !/^[1-9]\d{0,77}$/.test(params.amountIn)) invalid("amount must be a positive base-unit integer");
266
267
  if (params.minAmountOut !== void 0 && !/^(?:0|[1-9]\d{0,77})$/.test(params.minAmountOut)) invalid("the output floor must be a base-unit integer");
267
268
  const recipient = params.destAddress || opts.placeholder || "";
@@ -297,57 +298,63 @@ function relayProtocolOf(quote) {
297
298
  return { orderId: pd.orderId, hubType: pd.hubType, orderData, orderSignature: pd.orderSignature, paymentDetails };
298
299
  }
299
300
  function checkRelayQuote(request, quote, tx) {
300
- if (quote === null || typeof quote !== "object" || quote.provider !== "relay") throw new RelayRefusal("quote-shape", "not a Relay quote");
301
+ if (quote === null || typeof quote !== "object" || quote.provider !== "relay") throw new RelayRefusal("quote-shape", "not a Relay quote", "policy_refused");
301
302
  const t = tx ?? quote.txRequest;
302
- if (!t) throw new RelayRefusal("quote-shape", "the quote has no transaction");
303
- if (quote.depositAddress) throw new RelayRefusal("quote-shape", "a Relay quote pays the depository through its calldata, never a deposit address");
303
+ if (!t) throw new RelayRefusal("quote-shape", "the quote has no transaction", "policy_refused");
304
+ if (quote.depositAddress) throw new RelayRefusal("quote-shape", "a Relay quote pays the depository through its calldata, never a deposit address", "vault_mismatch");
304
305
  if (quote.txRequest?.serializedTx !== void 0 || quote.txRequest?.nativeFee !== void 0) {
305
- throw new RelayRefusal("quote-shape", "a Relay deposit carries no extra native fee and no serialized transaction");
306
+ throw new RelayRefusal("quote-shape", "a Relay deposit carries no extra native fee and no serialized transaction", "policy_refused");
306
307
  }
307
308
  const v = verifyRelayOrder(request, relayProtocolOf(quote), t);
308
309
  const approval = t.approvalAddress;
309
310
  if (v.deposit.approvalAddress === void 0 ? approval !== void 0 && approval !== "" : typeof approval !== "string" || lower(approval) !== v.deposit.approvalAddress) {
310
- throw new RelayRefusal("quote-approval", `the quote approves ${String(approval)}, the order needs ${v.deposit.approvalAddress ?? "no approval"}`);
311
+ throw new RelayRefusal("quote-approval", `the quote approves ${String(approval)}, the order needs ${v.deposit.approvalAddress ?? "no approval"}`, "vault_mismatch");
311
312
  }
312
313
  if (quote.sourceAmount !== request.amount.toString(10) || quote.minDestAmount !== v.minimumAmount.toString(10) || quote.destAmount !== v.expectedAmount.toString(10)) {
313
- throw new RelayRefusal("quote-amounts", "the amounts the quote shows are not the order's");
314
+ throw new RelayRefusal("quote-amounts", "the amounts the quote shows are not the order's", "price_check_failed");
314
315
  }
315
316
  const gas = t.gasLimit;
316
317
  if (gas !== void 0) {
317
318
  const floor = v.deposit.approvalAddress === void 0 ? RELAY_GAS_FLOOR_NATIVE : RELAY_GAS_FLOOR_ERC20;
318
319
  if (typeof gas !== "string" || !/^[1-9]\d{0,10}$/.test(gas) || BigInt(gas) < floor || BigInt(gas) > RELAY_GAS_CAP) {
319
- throw new RelayRefusal("quote-gas", `the gas limit ${String(gas).slice(0, 40)} is outside ${floor}\u2013${RELAY_GAS_CAP}`);
320
+ throw new RelayRefusal("quote-gas", `the gas limit ${String(gas).slice(0, 40)} is outside ${floor}\u2013${RELAY_GAS_CAP}`, "policy_refused");
320
321
  }
321
322
  }
322
323
  const now = request.nowMs ?? Date.now();
323
324
  if (typeof quote.validUntilMs !== "number" || !Number.isFinite(quote.validUntilMs) || quote.validUntilMs > now + RELAY_MAX_QUOTE_LIFE_MS) {
324
- throw new RelayRefusal("quote-expiry", "the quote claims to live longer than a Relay quote may");
325
+ throw new RelayRefusal("quote-expiry", "the quote claims to live longer than a Relay quote may", "policy_refused");
325
326
  }
326
327
  if (typeof quote.intentId !== "string" || quote.intentId !== `relay:${String(quote.providerData?.requestId)}` || !/^relay:0x[0-9a-f]{64}$/.test(quote.intentId)) {
327
- throw new RelayRefusal("quote-shape", "the quote's id is not its Relay request id");
328
+ throw new RelayRefusal("quote-shape", "the quote's id is not its Relay request id", "policy_refused");
328
329
  }
329
330
  return v;
330
331
  }
332
+ var pinNotes = refusalNotes();
333
+ function notedReason(err) {
334
+ const text = relayRefusalReason(err);
335
+ const info = refusalOf(err);
336
+ return info ? pinNotes.note(text, info) : text;
337
+ }
331
338
  function relayVerifyQuote(params, quote) {
332
339
  try {
333
340
  checkRelayQuote(relayRequestOf(params), quote);
334
341
  return null;
335
342
  } catch (err) {
336
- return relayRefusalReason(err);
343
+ return notedReason(err);
337
344
  }
338
345
  }
339
346
  function relayVerifyBuild(quote, tx, params) {
340
347
  try {
341
- if (!params) throw new RelayRefusal("request-invalid", "the request this quote answered is not known on this side \u2014 quote again");
342
- if (tx.chain !== params.sourceChain) throw new RelayRefusal("tx-chain", `the build is for ${tx.chain}, not ${params.sourceChain}`);
348
+ if (!params) throw new RelayRefusal("request-invalid", "the request this quote answered is not known on this side \u2014 quote again", "policy_refused");
349
+ if (tx.chain !== params.sourceChain) throw new RelayRefusal("tx-chain", `the build is for ${tx.chain}, not ${params.sourceChain}`, "vault_mismatch");
343
350
  if (tx.serializedTx !== void 0 || tx.memo !== void 0 || tx.typedData !== void 0 || tx.bodyBoc !== void 0) {
344
- throw new RelayRefusal("quote-shape", "a Relay deposit is one EVM call");
351
+ throw new RelayRefusal("quote-shape", "a Relay deposit is one EVM call", "policy_refused");
345
352
  }
346
353
  const v = checkRelayQuote(relayRequestOf(params), quote, tx);
347
354
  relayClearOrder(v.id, "build");
348
355
  return null;
349
356
  } catch (err) {
350
- return relayRefusalReason(err);
357
+ return notedReason(err);
351
358
  }
352
359
  }
353
360
  var relayPins = Object.freeze({
@@ -360,7 +367,8 @@ var relayPins = Object.freeze({
360
367
  return c ? [c.depository] : [];
361
368
  },
362
369
  verifyQuote: relayVerifyQuote,
363
- verifyBuild: relayVerifyBuild
370
+ verifyBuild: relayVerifyBuild,
371
+ reasonOf: pinNotes.reasonOf
364
372
  });
365
373
 
366
374
  export {
@@ -381,4 +389,4 @@ export {
381
389
  relayVerifyBuild,
382
390
  relayPins
383
391
  };
384
- //# sourceMappingURL=chunk-WRIKAUWI.js.map
392
+ //# sourceMappingURL=chunk-C3I2XYSW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/verify.ts","../src/cleared.ts"],"sourcesContent":["/**\n * The device-side check of a Relay order and of the deposit that funds it.\n *\n * A Relay deposit is `depositNative(depositor, id)` / `depositErc20(depositor, token, amount, id)` on the chain's\n * RelayDepository: the calldata names no recipient, no destination and no minimum — only `id`, the hash of an order\n * that lives off chain. Signing such a deposit is safe exactly when the device holds the order behind the id and that\n * order says what the user asked for. {@link verifyRelayOrder} establishes that, from nothing but the user's own\n * request, the pins in `config.ts`, and the bytes the API (or an app's proxy — equally untrusted) returned:\n *\n * 1. the order is the documented shape, one input, one output payment, no destination calls, no order-level fees;\n * 2. its content is the request: recipient, destination chain and token, a minimum no lower than the caller's, a\n * deadline one order lifetime away, the input chain / token / amount, refunds only to the user;\n * 3. its solver is the pinned one and the solver signed this very id;\n * 4. the id recomputed here (EIP-712 `hashStruct`) is the id in the calldata;\n * 5. the transaction is a known deposit call on the pinned depository, depositing exactly the order's input from the\n * user's own address — and is byte-for-byte the call this module would build itself.\n *\n * Every refusal is a {@link RelayRefusal} with its own code. Nothing here is asynchronous and nothing reads the\n * network, so the same function runs at quote time, again right before signing, and on the client of a remote\n * provider (`relayPins.verifyQuote`).\n */\nimport {encodeFunctionData, parseAbi, type Hex} from \"viem\";\nimport type {Quote, QuoteParams, RemotePins, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {refusalNotes, refusalOf, type Swap2RefusalReason} from \"@anywalletkit/protocol-swap2-core/errors\";\nimport {sourceAssetOf} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {\n RELAY_CLOCK_SKEW_S, RELAY_DEPOSIT_ERC20, RELAY_DEPOSIT_ERC20_ALLOWANCE, RELAY_DEPOSIT_NATIVE, RELAY_MAX_ORDER_AGE_S,\n RELAY_NATIVE, RELAY_ORDER_LIFETIME_S, RELAY_ORDER_VERSION, RELAY_SOLVERS, relayChain, type RelayChain,\n} from \"./config.js\";\nimport {RelayRefusal, parseRelayOrder, relayOrderId, relayOrderSigner, type RelayOrder} from \"./order.js\";\n\nconst DEPOSITORY_ABI = parseAbi([\n \"function depositNative(address depositor, bytes32 id) payable\",\n \"function depositErc20(address depositor, address token, uint256 amount, bytes32 id)\",\n]);\n\n/** Widest slippage a request may ask for. */\nexport const RELAY_MAX_SLIPPAGE_BPS = 5_000;\n/**\n * The slippage this module asks Relay for, and holds the order to, when the caller names none (Relay's own default\n * on 2026-11-10). Without it the answering side would choose how far the minimum may sit under the expected amount.\n */\nexport const RELAY_DEFAULT_SLIPPAGE_BPS = 200;\n\n/** A direct deposit used ~33k (native) and ~76k (ERC-20) gas in Relay's own estimates (2026-11-10). */\nexport const RELAY_GAS_FLOOR_NATIVE = 90_000n;\nexport const RELAY_GAS_FLOOR_ERC20 = 180_000n;\n/** Chains that meter gas differently (Mantle, zkSync) estimate far higher; an estimate is taken up to this. */\nexport const RELAY_GAS_CAP = 60_000_000n;\n/** The longest a quote may claim to live: the provider's own upper bound plus the tolerated clock difference. */\nexport const RELAY_MAX_QUOTE_LIFE_MS = 300_000 + RELAY_CLOCK_SKEW_S * 1000;\n\nexport {relayClearOrder} from \"./cleared.js\";\nimport {relayClearOrder} from \"./cleared.js\";\n\nconst ADDRESS = /^0x[0-9a-fA-F]{40}$/;\nconst U256_MAX = (1n << 256n) - 1n;\n\n/** What the user asked for — the only thing an order is compared against. Addresses in any casing. */\nexport interface RelayRequest {\n /** CAIP-2 of the chain the deposit is sent on. */\n sourceChain: string;\n /** CAIP-2 of the chain the output is paid on. */\n destChain: string;\n /** Input token contract; the zero address is the native coin. */\n sourceToken: string;\n /** Output token contract; the zero address is the native coin. */\n destToken: string;\n /** Exact input, base units. */\n amount: bigint;\n /** The account that signs the deposit: the `depositor` argument and the origin-chain refund recipient. */\n depositor: string;\n /** Who receives the output. */\n recipient: string;\n /** The caller's own floor on the output, base units. */\n minAmountOut?: bigint;\n /** The slippage the caller asked for: the order's minimum may sit at most this far under its expected amount. */\n slippageBps?: number;\n /** The clock (ms) deadlines are judged against; defaults to `Date.now()`. */\n nowMs?: number;\n}\n\n/** `protocol.v2` of a quote response, as received. */\nexport interface RelayProtocolData {\n orderId?: unknown;\n hubType?: unknown;\n orderData?: unknown;\n orderSignature?: unknown;\n paymentDetails?: unknown;\n}\n\n/** The deposit transaction under check: what the API proposed, or what is about to be signed. */\nexport interface RelayDepositTx {\n to?: unknown;\n data?: unknown;\n value?: unknown;\n chainId?: unknown;\n}\n\n/** A deposit this module built: the only bytes a Relay quote ever carries. */\nexport interface RelayDeposit {\n to: string;\n data: Hex;\n /** Wei, decimal. */\n value: string;\n chainId: number;\n /** ERC-20 input: the spender to approve for exactly the input amount — the pinned depository. */\n approvalAddress?: string;\n}\n\nexport interface VerifiedRelayOrder {\n order: RelayOrder;\n /** The order id, recomputed. */\n id: Hex;\n /** The deposit built here from the pins and the order. */\n deposit: RelayDeposit;\n /** `expectedAmount` of the single output payment. */\n expectedAmount: bigint;\n /** `minimumAmount` of the single output payment: the least the solver may pay for the order to count as filled. */\n minimumAmount: bigint;\n source: RelayChain;\n dest: RelayChain;\n}\n\nconst lower = (s: string): string => s.toLowerCase();\nconst isNative = (token: string): boolean => lower(token) === RELAY_NATIVE;\n\n/** The deposit call for an order: built from pinned and verified values only. */\nexport function buildRelayDeposit(source: RelayChain, depositor: string, token: string, amount: bigint, id: Hex): RelayDeposit {\n if (!ADDRESS.test(depositor) || /^0x0{40}$/.test(depositor)) throw new RelayRefusal(\"request-invalid\", \"the depositor is not an address\");\n if (!ADDRESS.test(token)) throw new RelayRefusal(\"request-invalid\", \"the input token is not an address\");\n if (amount <= 0n || amount > U256_MAX) throw new RelayRefusal(\"request-invalid\", \"the amount is not a positive integer\");\n if (!/^0x[0-9a-f]{64}$/.test(id)) throw new RelayRefusal(\"order-id-mismatch\", \"the order id is not 32 bytes\");\n if (isNative(token)) {\n return {\n to: source.depository,\n data: encodeFunctionData({abi: DEPOSITORY_ABI, functionName: \"depositNative\", args: [lower(depositor) as Hex, id]}),\n value: amount.toString(10),\n chainId: source.chainId,\n };\n }\n return {\n to: source.depository,\n data: encodeFunctionData({abi: DEPOSITORY_ABI, functionName: \"depositErc20\", args: [lower(depositor) as Hex, lower(token) as Hex, amount, id]}),\n value: \"0\",\n chainId: source.chainId,\n approvalAddress: source.depository,\n };\n}\n\nfunction checkRequest(r: RelayRequest): {source: RelayChain; dest: RelayChain; nowS: number} {\n // A malformed request is the caller's own bug and carries no reason; the zero-address parties and the slippage cap\n // are refusals.\n const invalid = (what: string, reason?: Swap2RefusalReason): never => { throw new RelayRefusal(\"request-invalid\", what, reason); };\n if (r === null || typeof r !== \"object\") invalid(\"no request to check the order against\");\n const source = relayChain(r.sourceChain);\n const dest = relayChain(r.destChain);\n if (!source) throw new RelayRefusal(\"chain-unsupported\", `source chain ${String(r.sourceChain)} is not a pinned Relay chain`, \"unsupported_pair\");\n if (!dest) throw new RelayRefusal(\"chain-unsupported\", `destination chain ${String(r.destChain)} is not a pinned Relay chain`, \"unsupported_pair\");\n if (source === dest) throw new RelayRefusal(\"chain-unsupported\", \"source and destination are the same chain\", \"unsupported_pair\");\n for (const [what, v] of [[\"input token\", r.sourceToken], [\"output token\", r.destToken], [\"depositor\", r.depositor], [\"recipient\", r.recipient]] as const) {\n if (typeof v !== \"string\" || !ADDRESS.test(v)) invalid(`the ${what} is not an address`);\n }\n if (/^0x0{40}$/.test(r.depositor)) invalid(\"the depositor is the zero address\", \"recipient_mismatch\");\n if (/^0x0{40}$/.test(r.recipient)) invalid(\"the recipient is the zero address\", \"recipient_mismatch\");\n if (typeof r.amount !== \"bigint\" || r.amount <= 0n || r.amount > U256_MAX) invalid(\"the amount is not a positive integer\");\n if (r.minAmountOut !== undefined && (typeof r.minAmountOut !== \"bigint\" || r.minAmountOut < 0n)) invalid(\"the output floor is not an unsigned integer\");\n if (r.slippageBps !== undefined && (!Number.isInteger(r.slippageBps) || r.slippageBps < 0 || r.slippageBps > RELAY_MAX_SLIPPAGE_BPS)) {\n invalid(`slippage must be a whole number of basis points up to ${RELAY_MAX_SLIPPAGE_BPS}`, \"policy_refused\");\n }\n const nowMs = r.nowMs ?? Date.now();\n if (!Number.isFinite(nowMs) || nowMs <= 0) invalid(\"the clock is not a time\");\n return {source, dest, nowS: Math.floor(nowMs / 1000)};\n}\n\n/** Twenty raw bytes equal to an address. `bytes` fields are lowercased by the parser. */\nconst isAddr = (bytes: Hex, addr: string): boolean => bytes.length === 42 && bytes === lower(addr);\n\nfunction checkDeadline(code: \"output-deadline\" | \"refund-deadline\", what: string, deadline: number, nowS: number): void {\n const left = deadline - nowS;\n if (left > RELAY_ORDER_LIFETIME_S + RELAY_CLOCK_SKEW_S) {\n throw new RelayRefusal(code, `${what} is ${left} s away, past the ${RELAY_ORDER_LIFETIME_S} s an order lives`, \"policy_refused\");\n }\n if (left < RELAY_ORDER_LIFETIME_S - RELAY_MAX_ORDER_AGE_S) {\n throw new RelayRefusal(code, `${what} is ${left} s away: the order is older than ${RELAY_MAX_ORDER_AGE_S} s or already past it`, \"quote_expired\");\n }\n}\n\n/** A 32-byte calldata word that is a left-padded address. */\nfunction wordAddress(word: string): string | null {\n return /^0{24}/.test(word) ? `0x${word.slice(24)}` : null;\n}\n\n/** Where the deposit goes: the pinned depository of the source chain, and nothing else. Checked before the order is read. */\nfunction checkDepositTarget(tx: RelayDepositTx, source: RelayChain): void {\n if (tx === null || typeof tx !== \"object\") throw new RelayRefusal(\"tx-calldata\", \"there is no deposit transaction\", \"policy_refused\");\n if (tx.chainId !== source.chainId) {\n throw new RelayRefusal(\"tx-chain\", `the deposit is for chain ${String(tx.chainId)}, not ${source.chainId}`, \"vault_mismatch\");\n }\n if (typeof tx.to !== \"string\" || !ADDRESS.test(tx.to) || lower(tx.to) !== source.depository) {\n throw new RelayRefusal(\"tx-target\", `the deposit calls ${String(tx.to)}, not the ${source.name} depository ${source.depository} — routes that first swap on the source chain go through a router and are not signed by this module`, \"vault_mismatch\");\n }\n}\n\nfunction checkDepositTx(tx: RelayDepositTx, source: RelayChain, request: RelayRequest, order: RelayOrder, id: Hex): void {\n checkDepositTarget(tx, source);\n if (typeof tx.data !== \"string\" || !/^0x(?:[0-9a-fA-F]{2})*$/.test(tx.data) || tx.data.length < 10) {\n throw new RelayRefusal(\"tx-calldata\", \"the deposit has no calldata\", \"policy_refused\");\n }\n const data = lower(tx.data);\n const selector = data.slice(0, 10);\n const input = order.inputs[0]!.payment;\n const native = isNative(input.currency);\n if (selector === RELAY_DEPOSIT_ERC20_ALLOWANCE) {\n throw new RelayRefusal(\"tx-selector\", \"the deposit uses depositErc20 without an amount, which takes the whole allowance\", \"policy_refused\");\n }\n if (selector !== RELAY_DEPOSIT_NATIVE && selector !== RELAY_DEPOSIT_ERC20) {\n throw new RelayRefusal(\"tx-selector\", `the deposit calls ${selector}, not a known deposit function`, \"policy_refused\");\n }\n if ((selector === RELAY_DEPOSIT_NATIVE) !== native) {\n throw new RelayRefusal(\"tx-selector\", `the deposit calls ${native ? \"depositErc20\" : \"depositNative\"} for an order whose input is ${native ? \"the native coin\" : \"a token\"}`, \"policy_refused\");\n }\n const words = native ? 2 : 4;\n if (data.length !== 10 + 64 * words) {\n throw new RelayRefusal(\"tx-calldata\", `the deposit calldata is ${(data.length - 2) / 2} bytes, not ${4 + 32 * words}`, \"policy_refused\");\n }\n const word = (i: number): string => data.slice(10 + 64 * i, 74 + 64 * i);\n const depositor = wordAddress(word(0));\n if (depositor === null) throw new RelayRefusal(\"tx-calldata\", \"the depositor argument is not a padded address\", \"policy_refused\");\n if (depositor !== lower(request.depositor)) {\n throw new RelayRefusal(\"tx-depositor\", `the deposit is credited to ${depositor}, not to the sender ${lower(request.depositor)}`, \"recipient_mismatch\");\n }\n if (!native) {\n const token = wordAddress(word(1));\n if (token === null) throw new RelayRefusal(\"tx-calldata\", \"the token argument is not a padded address\", \"policy_refused\");\n if (token !== input.currency) throw new RelayRefusal(\"tx-token\", `the deposit moves ${token}, the order's input is ${input.currency}`, \"policy_refused\");\n const amount = BigInt(`0x${word(2)}`);\n if (amount !== input.amount) throw new RelayRefusal(\"tx-amount\", `the deposit moves ${amount}, the order's input is ${input.amount}`, \"policy_refused\");\n }\n const txId = `0x${word(native ? 1 : 3)}`;\n if (txId !== id) throw new RelayRefusal(\"tx-id\", `the deposit names order ${txId}, the order received hashes to ${id}`, \"recipient_unverifiable\");\n const value = typeof tx.value === \"string\" && /^(?:0|[1-9]\\d{0,77})$/.test(tx.value) ? BigInt(tx.value) : null;\n const wantValue = native ? input.amount : 0n;\n if (value === null || value !== wantValue) {\n throw new RelayRefusal(\"tx-value\", `the deposit sends ${String(tx.value)} wei, it must send ${wantValue}`, \"policy_refused\");\n }\n}\n\n/**\n * Check an order against the user's request and — when given — a deposit transaction against the order. Returns the\n * parsed order, its id and the deposit this module builds for it; throws {@link RelayRefusal} otherwise.\n *\n * `deposit` is what the API proposed (at quote time) or what is about to be signed (before signing). Without it the\n * order alone is checked and the caller uses the returned `deposit`.\n */\nexport function verifyRelayOrder(request: RelayRequest, protocol: RelayProtocolData | null | undefined, deposit?: RelayDepositTx): VerifiedRelayOrder {\n const {source, dest, nowS} = checkRequest(request);\n // A deposit that does not call the pinned depository is refused for that, whatever order comes with it.\n if (deposit !== undefined) checkDepositTarget(deposit, source);\n\n // The envelope.\n if (protocol === null || typeof protocol !== \"object\") {\n throw new RelayRefusal(\"protocol-data-missing\", \"the quote carries no order (protocol.v2) — nothing to check the deposit against\", \"upstream_unavailable\");\n }\n if (protocol.orderData === undefined || protocol.orderData === null) {\n throw new RelayRefusal(\"protocol-data-missing\", \"the quote carries no order data — nothing to check the deposit against\", \"upstream_unavailable\");\n }\n if (protocol.hubType !== \"onchain\") {\n throw new RelayRefusal(\"hub-type\", `the order settles through a \"${String(protocol.hubType)}\" hub, only \"onchain\" is read`, \"unsupported_pair\");\n }\n const order = parseRelayOrder(protocol.orderData);\n\n // The shape.\n if (order.version !== RELAY_ORDER_VERSION) throw new RelayRefusal(\"order-version\", `order version \"${order.version}\" is not ${RELAY_ORDER_VERSION}`, \"upstream_unavailable\");\n if (order.inputs.length !== 1) throw new RelayRefusal(\"order-inputs\", `the order has ${order.inputs.length} inputs, exactly one is signed for`, \"policy_refused\");\n if (order.output.payments.length !== 1) throw new RelayRefusal(\"order-payments\", `the order pays ${order.output.payments.length} outputs, exactly one is accepted`, \"policy_refused\");\n if (order.output.calls.length !== 0) throw new RelayRefusal(\"order-calls\", \"the order runs calls on the destination — only plain payments are accepted\", \"policy_refused\");\n if (order.fees.length !== 0) throw new RelayRefusal(\"order-fees\", \"the order carries order-level fees, which this module does not show and does not accept\", \"policy_refused\");\n const input = order.inputs[0]!;\n const pay = order.output.payments[0]!;\n if (input.payment.weight === 0n) throw new RelayRefusal(\"input-weight\", \"the order's input has zero weight\", \"policy_refused\");\n\n // The solver.\n if (!RELAY_SOLVERS.some((s) => s.address === order.solver && s.chainId === order.solverChainId)) {\n throw new RelayRefusal(\"solver-not-pinned\", `solver ${order.solver} on \"${order.solverChainId}\" is not a pinned Relay solver`, \"recipient_unverifiable\");\n }\n\n // The output: who is paid, where, in what, and at least how much.\n if (order.output.chainId !== dest.slug) throw new RelayRefusal(\"output-chain\", `the order pays on \"${order.output.chainId}\", the request is for ${dest.name} (\"${dest.slug}\")`, \"recipient_mismatch\");\n if (!isAddr(pay.recipient, request.recipient)) throw new RelayRefusal(\"output-recipient\", `the order pays ${pay.recipient}, not the recipient ${lower(request.recipient)}`, \"recipient_mismatch\");\n if (!isAddr(pay.currency, request.destToken)) throw new RelayRefusal(\"output-currency\", `the order pays in ${pay.currency}, the request is for ${lower(request.destToken)}`, \"price_check_failed\");\n if (pay.minimumAmount <= 0n) throw new RelayRefusal(\"output-minimum\", \"the order's minimum output is zero\", \"price_check_failed\");\n if (request.minAmountOut !== undefined && pay.minimumAmount < request.minAmountOut) {\n throw new RelayRefusal(\"output-minimum\", `the order's minimum output ${pay.minimumAmount} is under the caller's floor ${request.minAmountOut}`, \"price_check_failed\");\n }\n if (pay.expectedAmount < pay.minimumAmount) throw new RelayRefusal(\"output-expected\", `the order expects ${pay.expectedAmount}, less than its own minimum ${pay.minimumAmount}`, \"price_check_failed\");\n const slippage = BigInt(request.slippageBps ?? RELAY_DEFAULT_SLIPPAGE_BPS);\n const floor = (pay.expectedAmount * (10_000n - slippage)) / 10_000n;\n if (pay.minimumAmount < floor) {\n throw new RelayRefusal(\"output-minimum\", `the order's minimum output ${pay.minimumAmount} is more than ${slippage} bps under its expected ${pay.expectedAmount}`, \"price_check_failed\");\n }\n checkDeadline(\"output-deadline\", \"the output deadline\", order.output.deadline, nowS);\n\n // The input: exactly what is sent.\n if (input.payment.chainId !== source.slug) throw new RelayRefusal(\"input-chain\", `the order is funded on \"${input.payment.chainId}\", the request sends on ${source.name} (\"${source.slug}\")`, \"policy_refused\");\n if (!isAddr(input.payment.currency, request.sourceToken)) throw new RelayRefusal(\"input-currency\", `the order is funded in ${input.payment.currency}, the request sends ${lower(request.sourceToken)}`, \"policy_refused\");\n if (input.payment.amount !== request.amount) throw new RelayRefusal(\"input-amount\", `the order is funded with ${input.payment.amount}, the request sends ${request.amount}`, \"policy_refused\");\n\n // Refunds: on the source chain back to the sender in the token sent; on the destination to the recipient or the\n // sender; nowhere else. An unfilled order must have a way back on the source chain.\n let originRefund = false;\n for (const refund of input.refunds) {\n if (refund.chainId === source.slug) {\n if (!isAddr(refund.recipient, request.depositor)) throw new RelayRefusal(\"refund-recipient\", `a source-chain refund goes to ${refund.recipient}, not the sender ${lower(request.depositor)}`, \"recipient_mismatch\");\n if (refund.currency !== input.payment.currency) throw new RelayRefusal(\"refund-currency\", `a source-chain refund is in ${refund.currency}, not the token sent`, \"policy_refused\");\n originRefund = true;\n } else if (refund.chainId === dest.slug) {\n if (!isAddr(refund.recipient, request.recipient) && !isAddr(refund.recipient, request.depositor)) {\n throw new RelayRefusal(\"refund-recipient\", `a destination-chain refund goes to ${refund.recipient}, neither the recipient nor the sender`, \"recipient_mismatch\");\n }\n if (refund.currency.length !== 42) throw new RelayRefusal(\"refund-currency\", \"a destination-chain refund names no token\", \"policy_refused\");\n } else {\n throw new RelayRefusal(\"refund-chain\", `a refund is payable on \"${refund.chainId}\", neither the source nor the destination chain`, \"recipient_mismatch\");\n }\n checkDeadline(\"refund-deadline\", \"a refund deadline\", refund.deadline, nowS);\n }\n if (!originRefund) throw new RelayRefusal(\"refund-missing\", \"the order has no refund to the sender on the source chain\", \"policy_refused\");\n\n // The id and who signed it.\n const id = relayOrderId(order);\n if (typeof protocol.orderId !== \"string\" || lower(protocol.orderId) !== id) {\n throw new RelayRefusal(\"order-id-mismatch\", `the quote names order ${String(protocol.orderId)}, the order data hashes to ${id}`, \"recipient_unverifiable\");\n }\n const signer = relayOrderSigner(id, protocol.orderSignature);\n if (signer === null || signer !== order.solver) {\n throw new RelayRefusal(\"signature-invalid\", signer === null ? \"the order signature is not a valid signature\" : `the order is signed by ${signer}, not by its solver ${order.solver}`, \"recipient_unverifiable\");\n }\n\n // What the API says the payment is: it must describe the same deposit.\n const pd = protocol.paymentDetails as {chainId?: unknown; depository?: unknown; currency?: unknown; amount?: unknown} | null | undefined;\n if (pd === null || typeof pd !== \"object\") throw new RelayRefusal(\"payment-details\", \"the quote has no payment details\", \"upstream_unavailable\");\n if (pd.chainId !== source.slug || typeof pd.depository !== \"string\" || lower(pd.depository) !== source.depository\n || typeof pd.currency !== \"string\" || lower(pd.currency) !== input.payment.currency\n || typeof pd.amount !== \"string\" || pd.amount !== input.payment.amount.toString(10)) {\n throw new RelayRefusal(\"payment-details\", \"the quote's payment details do not describe the order's input on the pinned depository\", \"vault_mismatch\");\n }\n\n const built = buildRelayDeposit(source, request.depositor, input.payment.currency, input.payment.amount, id);\n if (deposit !== undefined) {\n checkDepositTx(deposit, source, request, order, id);\n // Whatever the field checks above let through, the bytes signed are the bytes built here.\n if (lower(deposit.data as string) !== built.data || lower(deposit.to as string) !== built.to || deposit.value !== built.value) {\n throw new RelayRefusal(\"tx-calldata\", \"the deposit is not the call this module builds for the order\", \"policy_refused\");\n }\n }\n return {order, id, deposit: built, expectedAmount: pay.expectedAmount, minimumAmount: pay.minimumAmount, source, dest};\n}\n\n/** A refusal's text for a caller that wants a string (`onRefusal`, remote pins); rethrows anything else. */\nexport function relayRefusalReason(err: unknown): string {\n if (err instanceof RelayRefusal) return err.message;\n throw err;\n}\n\n/**\n * The request a `QuoteParams` describes, for the verifier. `dry` fills a missing address with `placeholder` (pricing\n * only). The sender is `refundAddress` — the engine sets it to the account that signs.\n */\nexport function relayRequestOf(params: QuoteParams, opts: {placeholder?: string; nowMs?: number} = {}): RelayRequest {\n const invalid = (what: string, reason?: Swap2RefusalReason): never => { throw new RelayRefusal(\"request-invalid\", what, reason); };\n if (params.flex) invalid(\"the amount is sealed into the order (no flexible deposits)\", \"unsupported_pair\");\n if (!relayChain(params.sourceChain)) throw new RelayRefusal(\"chain-unsupported\", `source chain ${params.sourceChain} is not a pinned Relay chain`, \"unsupported_pair\");\n if (!relayChain(params.destChain)) throw new RelayRefusal(\"chain-unsupported\", `destination chain ${params.destChain} is not a pinned Relay chain`, \"unsupported_pair\");\n if (params.sourceChain === params.destChain) throw new RelayRefusal(\"chain-unsupported\", \"same-chain swaps are not served through the depository\", \"unsupported_pair\");\n let sourceToken: string;\n if (typeof params.sourceToken === \"string\" && ADDRESS.test(params.sourceToken)) sourceToken = params.sourceToken;\n else {\n const asset = sourceAssetOf(params);\n if (!asset) invalid(`source token ${String(params.sourceToken)} is not known on ${params.sourceChain}`, \"unsupported_pair\");\n sourceToken = asset!.contract ?? RELAY_NATIVE;\n if (!ADDRESS.test(sourceToken)) invalid(`source token ${String(params.sourceToken)} has no EVM contract`, \"unsupported_pair\");\n }\n if (typeof params.destToken !== \"string\" || !ADDRESS.test(params.destToken)) invalid(\"the destination token must be an EVM address (zero for the native coin)\", \"unsupported_pair\");\n if (typeof params.amountIn !== \"string\" || !/^[1-9]\\d{0,77}$/.test(params.amountIn)) invalid(\"amount must be a positive base-unit integer\");\n if (params.minAmountOut !== undefined && !/^(?:0|[1-9]\\d{0,77})$/.test(params.minAmountOut)) invalid(\"the output floor must be a base-unit integer\");\n const recipient = params.destAddress || opts.placeholder || \"\";\n if (!recipient) invalid(\"a live quote needs a recipient\");\n if (!ADDRESS.test(recipient)) invalid(\"the recipient must be an EVM address\");\n const depositor = params.refundAddress || opts.placeholder || \"\";\n if (!depositor) invalid(\"a live quote needs the sender's address (refundAddress)\");\n if (!ADDRESS.test(depositor)) invalid(\"the sender's address must be an EVM address\");\n return {\n sourceChain: params.sourceChain,\n destChain: params.destChain,\n sourceToken,\n destToken: params.destToken,\n amount: BigInt(params.amountIn),\n depositor,\n recipient,\n ...(params.minAmountOut !== undefined ? {minAmountOut: BigInt(params.minAmountOut)} : {}),\n ...(params.slippageBps !== undefined ? {slippageBps: params.slippageBps} : {}),\n ...(opts.nowMs !== undefined ? {nowMs: opts.nowMs} : {}),\n };\n}\n\n/** The order a quote of this provider carries (`providerData`), back in the form the verifier reads. */\nexport function relayProtocolOf(quote: Quote): RelayProtocolData | null {\n const pd = quote.providerData;\n if (!pd || typeof pd.orderData !== \"string\") return null;\n let orderData: unknown;\n let paymentDetails: unknown;\n try {\n orderData = JSON.parse(pd.orderData);\n paymentDetails = typeof pd.paymentDetails === \"string\" ? JSON.parse(pd.paymentDetails) : undefined;\n } catch {\n return null;\n }\n return {orderId: pd.orderId, hubType: pd.hubType, orderData, orderSignature: pd.orderSignature, paymentDetails};\n}\n\n/**\n * A quote of this provider against the request it answers: the order it carries is verified, its transaction is\n * that order's deposit, its approval names the pinned depository, and the amounts it shows are the order's. Throws\n * {@link RelayRefusal}. Used on the client of a remote provider and again before signing.\n */\nexport function checkRelayQuote(request: RelayRequest, quote: Quote, tx?: RelayDepositTx & {approvalAddress?: unknown}): VerifiedRelayOrder {\n if (quote === null || typeof quote !== \"object\" || quote.provider !== \"relay\") throw new RelayRefusal(\"quote-shape\", \"not a Relay quote\", \"policy_refused\");\n const t = tx ?? quote.txRequest;\n if (!t) throw new RelayRefusal(\"quote-shape\", \"the quote has no transaction\", \"policy_refused\");\n if (quote.depositAddress) throw new RelayRefusal(\"quote-shape\", \"a Relay quote pays the depository through its calldata, never a deposit address\", \"vault_mismatch\");\n if ((quote.txRequest as {serializedTx?: unknown; nativeFee?: unknown} | undefined)?.serializedTx !== undefined || (quote.txRequest as {nativeFee?: unknown} | undefined)?.nativeFee !== undefined) {\n throw new RelayRefusal(\"quote-shape\", \"a Relay deposit carries no extra native fee and no serialized transaction\", \"policy_refused\");\n }\n const v = verifyRelayOrder(request, relayProtocolOf(quote), t);\n const approval = (t as {approvalAddress?: unknown}).approvalAddress;\n if (v.deposit.approvalAddress === undefined ? approval !== undefined && approval !== \"\" : typeof approval !== \"string\" || lower(approval) !== v.deposit.approvalAddress) {\n throw new RelayRefusal(\"quote-approval\", `the quote approves ${String(approval)}, the order needs ${v.deposit.approvalAddress ?? \"no approval\"}`, \"vault_mismatch\");\n }\n if (quote.sourceAmount !== request.amount.toString(10) || quote.minDestAmount !== v.minimumAmount.toString(10) || quote.destAmount !== v.expectedAmount.toString(10)) {\n throw new RelayRefusal(\"quote-amounts\", \"the amounts the quote shows are not the order's\", \"price_check_failed\");\n }\n // Gas is the one number of the call that no order binds: held to the band this module itself would set, so a\n // backend can neither starve the deposit (a paid revert) nor name an absurd limit. Absent = the wallet estimates.\n const gas = (t as {gasLimit?: unknown}).gasLimit;\n if (gas !== undefined) {\n const floor = v.deposit.approvalAddress === undefined ? RELAY_GAS_FLOOR_NATIVE : RELAY_GAS_FLOOR_ERC20;\n if (typeof gas !== \"string\" || !/^[1-9]\\d{0,10}$/.test(gas) || BigInt(gas) < floor || BigInt(gas) > RELAY_GAS_CAP) {\n throw new RelayRefusal(\"quote-gas\", `the gas limit ${String(gas).slice(0, 40)} is outside ${floor}–${RELAY_GAS_CAP}`, \"policy_refused\");\n }\n }\n const now = request.nowMs ?? Date.now();\n if (typeof quote.validUntilMs !== \"number\" || !Number.isFinite(quote.validUntilMs) || quote.validUntilMs > now + RELAY_MAX_QUOTE_LIFE_MS) {\n throw new RelayRefusal(\"quote-expiry\", \"the quote claims to live longer than a Relay quote may\", \"policy_refused\");\n }\n if (typeof quote.intentId !== \"string\" || quote.intentId !== `relay:${String(quote.providerData?.requestId)}` || !/^relay:0x[0-9a-f]{64}$/.test(quote.intentId)) {\n throw new RelayRefusal(\"quote-shape\", \"the quote's id is not its Relay request id\", \"policy_refused\");\n }\n return v;\n}\n\n// The reason behind each text the pins return (`relayPins.reasonOf`), bounded.\nconst pinNotes = refusalNotes();\n/** The refusal's text, its reason noted for `relayPins.reasonOf`; rethrows anything that is not a refusal. */\nfunction notedReason(err: unknown): string {\n const text = relayRefusalReason(err);\n const info = refusalOf(err);\n return info ? pinNotes.note(text, info) : text;\n}\n\n/** `RemotePins.verifyQuote`: the reason a remote Relay quote fails against the user's own request, or null. */\nexport function relayVerifyQuote(params: QuoteParams, quote: Quote): string | null {\n try {\n checkRelayQuote(relayRequestOf(params), quote);\n return null;\n } catch (err) {\n return notedReason(err);\n }\n}\n\n/** `RemotePins.verifyBuild`: a remote build must be the quote's own (verified) transaction, and is verified again. */\nexport function relayVerifyBuild(quote: Quote, tx: UnsignedTx, params?: QuoteParams): string | null {\n try {\n if (!params) throw new RelayRefusal(\"request-invalid\", \"the request this quote answered is not known on this side — quote again\", \"policy_refused\");\n if (tx.chain !== params.sourceChain) throw new RelayRefusal(\"tx-chain\", `the build is for ${tx.chain}, not ${params.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(relayRequestOf(params), quote, tx);\n // The remote path has no client-side step after this one: an order is built for once.\n relayClearOrder(v.id, \"build\");\n return null;\n } catch (err) {\n return notedReason(err);\n }\n}\n\n/**\n * The app's pins for a remote Relay provider (`remoteProvider({name: \"relay\", ...relayPins})`): the only contract a\n * build may call or approve is the chain's depository, and every quote and build is verified on the client against\n * the user's own request. `reasonOf` classifies a text `verifyQuote` / `verifyBuild` returned.\n */\nexport const relayPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => { const c = relayChain(chain); return c ? [c.depository] : []; },\n spenders: (chain: string): readonly string[] => { const c = relayChain(chain); return c ? [c.depository] : []; },\n verifyQuote: relayVerifyQuote,\n verifyBuild: relayVerifyBuild,\n reasonOf: pinNotes.reasonOf,\n});\n","/**\n * One deposit per order: the ids already cleared, for the whole JS realm — every provider instance and every remote\n * stub share it, so a second instance cannot be handed the order the first one already signed for.\n */\nimport {RELAY_CLOCK_SKEW_S, RELAY_MAX_ORDER_AGE_S} from \"./config.js\";\nimport {RelayRefusal} from \"./order.js\";\n\n// Order ids already cleared, per stage, for the whole JS realm (every provider instance and every remote stub): the\n// same order is never built or signed for twice while it could still pass the age check. An entry outlives the\n// order's own acceptance window (age + skew), after which the order is stale anyway.\nconst CLEARED_TTL_MS = (RELAY_MAX_ORDER_AGE_S + 2 * RELAY_CLOCK_SKEW_S) * 1000;\nconst CLEARED_MAX = 4096;\nconst clearedOrders = new Map<string, number>();\n\n/**\n * Record that `id` is being used at `stage` (\"build\" on the client of a remote provider, \"sign\" right before a\n * signature); throws `order-reused` when it already was. Fail-closed when the record is full of live entries.\n */\nexport function relayClearOrder(id: string, stage: \"build\" | \"sign\", nowMs: number = Date.now()): void {\n const key = `${stage}:${id.toLowerCase()}`;\n const until = clearedOrders.get(key);\n if (until !== undefined && until > nowMs) throw new RelayRefusal(\"order-reused\", `order ${id} was already cleared for a deposit — quote again`, \"policy_refused\");\n if (clearedOrders.size >= CLEARED_MAX) {\n for (const [k, t] of clearedOrders) if (t <= nowMs) clearedOrders.delete(k);\n if (clearedOrders.size >= CLEARED_MAX) throw new RelayRefusal(\"order-reused\", \"too many deposits cleared in the last minutes — try again later\", \"policy_refused\");\n }\n clearedOrders.set(key, nowMs + CLEARED_TTL_MS);\n}\n\n/** Tests only; the package index leaves it out. */\nexport function forgetClearedOrders(): void {\n clearedOrders.clear();\n}\n"],"mappings":"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","names":[]}