@gibs/bridge-sdk 1.19.0 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/abis.js +0 -2
  2. package/dist/bridge-limits.js +0 -38
  3. package/dist/chain-info.js +0 -116
  4. package/dist/chain-names.js +0 -151
  5. package/dist/chains.js +0 -198
  6. package/dist/cjs/abis.js +0 -2
  7. package/dist/cjs/bridge-limits.js +0 -38
  8. package/dist/cjs/chain-info.js +0 -116
  9. package/dist/cjs/chain-names.js +0 -151
  10. package/dist/cjs/chains.js +0 -198
  11. package/dist/cjs/claims.js +0 -60
  12. package/dist/cjs/config.js +1 -208
  13. package/dist/cjs/consolidated-quote.js +0 -465
  14. package/dist/cjs/destination-calldata.js +0 -71
  15. package/dist/cjs/ecosystems.js +0 -183
  16. package/dist/cjs/execution.js +0 -92
  17. package/dist/cjs/fee-type.js +0 -1
  18. package/dist/cjs/hyperliquid-execution.js +0 -98
  19. package/dist/cjs/image-links.js +0 -108
  20. package/dist/cjs/lifi-execution-guard.js +65 -172
  21. package/dist/cjs/near-intents-conformance.js +0 -110
  22. package/dist/cjs/near-intents-route.js +0 -149
  23. package/dist/cjs/near-intents.js +0 -562
  24. package/dist/cjs/origin-deposit.js +0 -56
  25. package/dist/cjs/pre-quote.js +0 -80
  26. package/dist/cjs/prices.js +0 -113
  27. package/dist/cjs/providers.js +0 -83
  28. package/dist/cjs/quote-fees.js +0 -80
  29. package/dist/cjs/referral.js +0 -75
  30. package/dist/cjs/relay-currencies.js +0 -31
  31. package/dist/cjs/relay-depository.js +52 -77
  32. package/dist/cjs/relay-quote.js +0 -394
  33. package/dist/cjs/route-steps.js +0 -100
  34. package/dist/cjs/routing/amounts.js +0 -83
  35. package/dist/cjs/routing/candidate-route.js +0 -73
  36. package/dist/cjs/routing/candidate.js +0 -46
  37. package/dist/cjs/routing/carrier-provider-key.js +0 -27
  38. package/dist/cjs/routing/carriers/omnibridge.js +0 -120
  39. package/dist/cjs/routing/carriers/pulsex-paths.js +0 -57
  40. package/dist/cjs/routing/carriers/pulsex-split.js +0 -92
  41. package/dist/cjs/routing/carriers/pulsex.js +0 -279
  42. package/dist/cjs/routing/carriers/wrap.js +0 -57
  43. package/dist/cjs/routing/composed-route-quality.js +0 -95
  44. package/dist/cjs/routing/entry-chain-anchor.js +0 -27
  45. package/dist/cjs/routing/format.js +0 -50
  46. package/dist/cjs/routing/index.js +0 -28
  47. package/dist/cjs/routing/producers.js +0 -854
  48. package/dist/cjs/routing/providers.js +0 -27
  49. package/dist/cjs/routing/search/compose.js +0 -56
  50. package/dist/cjs/routing/search/graph.js +0 -364
  51. package/dist/cjs/routing/search/plan-route-data.js +0 -508
  52. package/dist/cjs/routing/search/score.js +0 -344
  53. package/dist/cjs/routing/swap-transactions.js +0 -74
  54. package/dist/cjs/routing/usd-value.js +0 -12
  55. package/dist/cjs/settings.js +1 -456
  56. package/dist/cjs/swap-venues.js +0 -17
  57. package/dist/cjs/ton-connect.js +0 -82
  58. package/dist/cjs/ton-execution.js +0 -6
  59. package/dist/cjs/ton.js +0 -42
  60. package/dist/cjs/tron-execution.js +0 -145
  61. package/dist/claims.js +0 -60
  62. package/dist/config.js +1 -211
  63. package/dist/consolidated-quote.js +0 -465
  64. package/dist/destination-calldata.js +0 -71
  65. package/dist/ecosystems.js +0 -183
  66. package/dist/execution.js +0 -92
  67. package/dist/fee-type.js +0 -2
  68. package/dist/hyperliquid-execution.js +0 -98
  69. package/dist/image-links.js +0 -108
  70. package/dist/lifi-execution-guard.js +65 -172
  71. package/dist/near-intents-conformance.js +0 -110
  72. package/dist/near-intents-route.js +0 -149
  73. package/dist/near-intents.js +0 -562
  74. package/dist/origin-deposit.js +0 -56
  75. package/dist/pre-quote.js +0 -80
  76. package/dist/prices.js +0 -113
  77. package/dist/providers.js +0 -83
  78. package/dist/quote-fees.js +0 -80
  79. package/dist/referral.js +0 -75
  80. package/dist/relay-currencies.js +0 -31
  81. package/dist/relay-depository.js +52 -77
  82. package/dist/relay-quote.js +0 -394
  83. package/dist/route-steps.js +0 -100
  84. package/dist/routing/amounts.js +0 -83
  85. package/dist/routing/candidate-route.js +0 -73
  86. package/dist/routing/candidate.js +0 -46
  87. package/dist/routing/carrier-provider-key.js +0 -27
  88. package/dist/routing/carriers/omnibridge.js +0 -120
  89. package/dist/routing/carriers/pulsex-paths.js +0 -57
  90. package/dist/routing/carriers/pulsex-split.js +0 -92
  91. package/dist/routing/carriers/pulsex.js +0 -279
  92. package/dist/routing/carriers/wrap.js +0 -57
  93. package/dist/routing/composed-route-quality.js +0 -95
  94. package/dist/routing/entry-chain-anchor.js +0 -27
  95. package/dist/routing/format.js +0 -50
  96. package/dist/routing/index.js +0 -28
  97. package/dist/routing/producers.js +0 -854
  98. package/dist/routing/providers.js +0 -27
  99. package/dist/routing/search/compose.js +0 -56
  100. package/dist/routing/search/graph.js +0 -364
  101. package/dist/routing/search/plan-route-data.js +0 -508
  102. package/dist/routing/search/score.js +0 -344
  103. package/dist/routing/swap-transactions.js +0 -74
  104. package/dist/routing/usd-value.js +0 -12
  105. package/dist/settings.js +1 -456
  106. package/dist/swap-venues.js +0 -17
  107. package/dist/ton-connect.js +0 -82
  108. package/dist/ton-execution.js +0 -6
  109. package/dist/ton.js +0 -42
  110. package/dist/tron-execution.js +0 -145
  111. package/package.json +3 -3
@@ -7,43 +7,9 @@ import { lifiQuoteFees } from './quote-fees.js';
7
7
  import { referralIntegrator, resolveAttribution } from './referral.js';
8
8
  import { normalizeLifiSteps } from './route-steps.js';
9
9
  import { relayDepositoryByChainId } from './relay-depository.js';
10
- /**
11
- * Gibs Finance's own LI.FI `integrator` label.
12
- *
13
- * NOT A DEFAULT. A request that leaves
14
- * {@link ConsolidatedQuoteRequest.lifiIntegrator} out sends no `integrator`
15
- * at all. An integrator label is attribution: LI.FI records the traffic under
16
- * it, and pays any `fee` to the account behind it. A wallet that builds on this
17
- * package must not attribute its users' routes to Gibs Finance without
18
- * choosing to. The Gibs interface passes this value explicitly.
19
- */
20
10
  export const lifiIntegrator = referralIntegrator;
21
- /**
22
- * The referral fee Gibs Finance charges on its own LI.FI routes (0.001 = 0.1%).
23
- * No builder applies it. A request carries a fee only when it sets `lifiFee`.
24
- */
25
11
  export const lifiReferralFeePercent = 0.001;
26
- /**
27
- * LI.FI's HTTP origin when the interface's `PUBLIC_LIFI_API_URL` build flag is
28
- * unset. Points straight at LI.FI rather than through the server-side proxy,
29
- * so local development and the anonymous IPFS build still get real quotes —
30
- * at LI.FI's shared, unauthenticated tier — with no configuration at all.
31
- */
32
12
  export const lifiDefaultApiOrigin = 'https://li.quest';
33
- /**
34
- * Builds every LI.FI endpoint address from one origin — THE ONE PLACE the
35
- * `/v1/...` paths are spelled, so a caller pointed at a different origin (the
36
- * server-side proxy at `https://lifi.gibs.finance`, or LI.FI itself) never
37
- * duplicates them by hand.
38
- *
39
- * `apiOrigin` is the scheme-plus-host ONLY (e.g. `https://lifi.gibs.finance`),
40
- * never a path — a trailing slash is trimmed, but this throws for anything
41
- * that is not an absolute `http:`/`https:` URL, so a malformed configuration
42
- * fails at startup rather than silently building a broken address.
43
- *
44
- * @param apiOrigin - the scheme-plus-host to reach LI.FI's `/v1` interface through
45
- * @returns a frozen object of every endpoint this codebase calls
46
- */
47
13
  export const lifiEndpoints = (apiOrigin) => {
48
14
  if (!isHttpUrl(apiOrigin)) {
49
15
  throw new Error(`lifiEndpoints: "${apiOrigin}" is not an absolute http(s) origin`);
@@ -62,72 +28,12 @@ export const lifiEndpoints = (apiOrigin) => {
62
28
  });
63
29
  };
64
30
  const defaultLifiEndpoints = lifiEndpoints(lifiDefaultApiOrigin);
65
- /** Quote endpoint that accepts destination contract calls, at {@link lifiDefaultApiOrigin}. */
66
31
  export const lifiContractCallsQuoteUrl = defaultLifiEndpoints.contractCallsQuote;
67
- /**
68
- * The plain quote endpoint, at {@link lifiDefaultApiOrigin}: carry funds and stop.
69
- *
70
- * WHICH ENDPOINT A ROUTE USES IS DECIDED BY WHETHER ANYTHING RUNS ON ARRIVAL,
71
- * not by which chains the provider covers. A crossing into the omnibridge needs
72
- * a call made on the entry chain, so it goes to
73
- * {@link lifiContractCallsQuoteUrl} and arrives as one signature. A route the
74
- * omnibridge does not touch has nothing to run on arrival, so it asks here.
75
- *
76
- * A GET, unlike its sibling — the parameters are a query string.
77
- */
78
32
  export const lifiQuoteUrl = defaultLifiEndpoints.quote;
79
- /**
80
- * Builds the headers for a LI.FI request.
81
- *
82
- * CARRIES NO API KEY. LI.FI's own documentation forbids setting
83
- * `x-lifi-api-key` in a browser — "Never expose your x-lifi-api-key in
84
- * client-side environments such as browser-based JavaScript" — so this
85
- * codebase never attaches one here. The key lives on the server-side proxy
86
- * (`https://lifi.gibs.finance`) that fronts `lifiApiOrigin`, added to the
87
- * outbound request there, never in this bundle. LI.FI answers every endpoint
88
- * with no key at a lower, shared rate limit, so a request built from this is a
89
- * normal operating state, not a degraded one.
90
- *
91
- * ONE HELPER FOR EVERY LI.FI ENDPOINT — the plain quote, the contract-calls
92
- * quote, `/v1/chains`, `/v1/tokens`, and `/v1/status` all build their headers
93
- * through this, rather than each call site duplicating the content-type.
94
- */
95
33
  export const lifiRequestHeaders = () => ({
96
34
  'Content-Type': 'application/json',
97
35
  });
98
- /**
99
- * Whether a consolidated quote request originates on a non-Ethereum-Virtual-
100
- * Machine chain. A missing `originVmType` is treated as Ethereum Virtual
101
- * Machine, so existing callers are never classified non-Ethereum.
102
- *
103
- * Deliberately expressed as "anything that is not Ethereum" rather than as a
104
- * list of the non-Ethereum families. The two behaviors this gates — excluding a
105
- * route from LI.FI, and refunding on the ORIGIN chain instead of to an Ethereum
106
- * fallback address — are both wrong by default for an unlisted ecosystem, and a
107
- * positive list fails open: a newly registered family would be handed to LI.FI
108
- * with a non-Ethereum address cast to `Hex`, and would name an Ethereum address
109
- * as its origin-chain refund target. Inverting the test makes every future
110
- * ecosystem safe on arrival.
111
- *
112
- * Hyperliquid counts as non-Ethereum here despite using Ethereum-style account
113
- * addresses: Relay's origin for it is HyperCore, whose deposit is a signed
114
- * typed-data action posted to an API rather than a broadcast transaction, and
115
- * which LI.FI does not carry.
116
- *
117
- * @param request - the consolidated quote request to classify
118
- * @returns true when the origin is any ecosystem other than Ethereum
119
- */
120
36
  export const isNonEthereumVirtualMachineOrigin = (request) => (request.originVmType ?? 'evm') !== 'evm';
121
- /**
122
- * The attribution fields of a LI.FI request: the `integrator` label and, when
123
- * one is charged, the referral `fee`. Shared by both LI.FI builders so the two
124
- * endpoints can never attribute or charge differently.
125
- *
126
- * @param request - the consolidated request's attribution fields
127
- * @returns the fields to merge into the request; empty when none apply
128
- * @throws when a positive `lifiFee` arrives without an explicit `lifiIntegrator`
129
- * string — LI.FI would have nobody of yours to pay it to
130
- */
131
37
  export const lifiAttribution = (request) => {
132
38
  const integrator = resolveAttribution(request.lifiIntegrator, undefined);
133
39
  const chargesFee = request.lifiFee !== undefined && request.lifiFee > 0;
@@ -139,38 +45,6 @@ export const lifiAttribution = (request) => {
139
45
  }
140
46
  return { integrator: request.lifiIntegrator, fee: request.lifiFee };
141
47
  };
142
- /**
143
- * Builds the LI.FI contract-calls quote request from a provider-agnostic
144
- * consolidated request. LI.FI quotes backwards from `toAmount` (the guaranteed
145
- * minimum arriving on Ethereum), which is what makes the fixed amount inside
146
- * the destination calldata safe.
147
- *
148
- * @returns the request body, or null when the inputs cannot form a valid call
149
- */
150
- /**
151
- * Builds the query string for LI.FI's plain `GET /v1/quote`.
152
- *
153
- * THE ROUTE THIS EXISTS FOR. A crossing with no omnibridge leg had exactly one
154
- * bidder — Relay — because our only LI.FI endpoint was the contract-calls one,
155
- * which cannot express a route that calls nothing. Every any-to-any quote was
156
- * therefore a price with nothing to rank it against.
157
- *
158
- * SOLVED FORWARDS, WHICH IS THE OPPOSITE OF ITS SIBLING. An omnibridge route is
159
- * asked for an exact OUTPUT, because the entry call must receive an exact
160
- * amount. Here the reader names what they spend and the delivered amount is
161
- * whatever the market gives, so `fromAmount` is the input and the answer's
162
- * `toAmount` is the thing that differs between providers. Ranking two forward
163
- * quotes on what they cost compares two identical numbers — see
164
- * `orderQuotesByCost` in the interface, which ranks these on what ARRIVES.
165
- *
166
- * Returns null for a request carrying a `destinationCall`: that route belongs
167
- * to the other endpoint, and sending it here would quote a crossing that stops
168
- * on the entry chain and never enters the bridge.
169
- *
170
- * @param request - the consolidated request to express
171
- * @returns the query string, or null when this endpoint cannot express it
172
- * @throws when `lifiFee` is positive and `lifiIntegrator` is not a string — see {@link lifiAttribution}
173
- */
174
48
  export const buildLifiQuoteRequest = (request) => {
175
49
  const { destinationCall, fromAmount, toChainId } = request;
176
50
  if (destinationCall !== undefined) {
@@ -182,13 +56,9 @@ export const buildLifiQuoteRequest = (request) => {
182
56
  if (toChainId === undefined) {
183
57
  return null;
184
58
  }
185
- // LI.FI quotes Ethereum-Virtual-Machine origins only, and a non-Ethereum
186
- // origin address would be rejected as malformed rather than declined.
187
59
  if ((request.originVmType ?? 'evm') !== 'evm') {
188
60
  return null;
189
61
  }
190
- // Same attribution as the contract-calls builder, so a fee the reader agreed
191
- // to is charged on both endpoints, not only on one.
192
62
  const { integrator, fee } = lifiAttribution(request);
193
63
  return buildQuery({
194
64
  fromChain: request.fromChainId.toString(),
@@ -197,11 +67,7 @@ export const buildLifiQuoteRequest = (request) => {
197
67
  toToken: request.toTokenAddress,
198
68
  fromAmount: fromAmount.toString(),
199
69
  fromAddress: request.fromAddress,
200
- // WHERE THE FUNDS LAND, stated separately from who is paying. They are the
201
- // same account for an ordinary transfer and are NOT when a reader has named
202
- // a delivery address, which is exactly the case a bridge has to get right.
203
70
  toAddress: request.recipient,
204
- // Each optional parameter is left out when it is undefined.
205
71
  integrator,
206
72
  fee: fee?.toString(),
207
73
  slippage: request.slippage?.toString(),
@@ -209,26 +75,15 @@ export const buildLifiQuoteRequest = (request) => {
209
75
  };
210
76
  export const buildLifiContractCallsRequest = (request) => {
211
77
  const { destinationCall, toAmount } = request;
212
- // THIS ENDPOINT EXISTS TO DELIVER AND THEN CALL SOMETHING. A route with no
213
- // omnibridge leg has nothing to call, so it is not a request this builder can
214
- // express — LI.FI's plain quote is the right endpoint for that shape, and
215
- // wiring it is separate work. Refusing here leaves the route to Relay rather
216
- // than sending LI.FI a contract-call request with no contract call in it.
217
78
  if (destinationCall === undefined) {
218
79
  return null;
219
80
  }
220
81
  if (toAmount <= 0n) {
221
82
  return null;
222
83
  }
223
- // contract-call entries carry no native value; native-entry calls
224
- // (wrapAndRelayTokens) stay out of scope until value support is verified
225
84
  if (destinationCall.value > 0n) {
226
85
  return null;
227
86
  }
228
- // LI.FI cannot bridge across virtual-machine ecosystems. The provider gate
229
- // (`providerSupportsOrigin`) already keeps non-Ethereum origins away from
230
- // LI.FI; this guard makes the boundary explicit so the origin fields below are
231
- // genuinely Ethereum `Hex` addresses, not merely the widened `string` shape.
232
87
  if (isNonEthereumVirtualMachineOrigin(request)) {
233
88
  return null;
234
89
  }
@@ -256,11 +111,6 @@ export const buildLifiContractCallsRequest = (request) => {
256
111
  ],
257
112
  };
258
113
  };
259
- /**
260
- * Narrows a quote's origin deposit to the Ethereum-Virtual-Machine variant.
261
- * Throws when the deposit is not Ethereum, because the Ethereum-only execute
262
- * path must never silently proceed on a Solana or Bitcoin payload.
263
- */
264
114
  export const evmDepositOf = (quote) => {
265
115
  if (!isEvmDeposit(quote.originDeposit)) {
266
116
  throw new Error(`expected an Ethereum-Virtual-Machine origin deposit, received "${depositFamilyOf(quote.originDeposit)}"`);
@@ -269,43 +119,18 @@ export const evmDepositOf = (quote) => {
269
119
  };
270
120
  const refuseOrigin = (refusal) => ({ kind: 'refused', refusal });
271
121
  const sameHexAddress = (a, b) => a.toLowerCase() === b.toLowerCase();
272
- /**
273
- * The amount of the origin token the reader sends, in base units.
274
- *
275
- * THE REQUEST IS THE AUTHORITY. A route with no omnibridge entry call is
276
- * solved forwards: the reader names the input and the request carries it as
277
- * `fromAmount`. {@link aggregatorOriginCalls} refuses a quote whose own
278
- * `fromAmount` differs from it.
279
- *
280
- * A route WITH an entry call is solved backwards from an exact output, so the
281
- * request names no input at all and the provider works one out. For that
282
- * route the quote's `fromAmount` is the only figure there is. The deposit, the
283
- * approval and the quote must still agree with each other, but no figure of
284
- * the reader's exists to compare them with.
285
- */
286
122
  const amountToSendOf = ({ quote, request }) => request.fromAmount ?? quote.fromAmount;
287
123
  const refuseAmount = ({ provider, field, expected, actual, }) => refuseVerdict({ reason: 'amount-mismatch', provider, field, expected, actual });
288
124
  const refuseRecipient = ({ provider, field, expected, actual, }) => refuseVerdict({ reason: 'recipient-mismatch', provider, field, expected, actual });
289
125
  const refuseVerdict = (refusal) => ({ kind: 'refused', refusal });
290
- /**
291
- * The spender a provider allows, given the one contract it trusts on this
292
- * chain: no approval when the quote asks for none, the trusted contract when
293
- * the quote names it, and a refusal for any other address.
294
- */
295
126
  const spenderVerdict = ({ provider, requested, trusted, }) => {
296
127
  if (requested === null)
297
128
  return { kind: 'verified', spender: null };
298
129
  if (trusted === null || !sameHexAddress(requested, trusted)) {
299
130
  return refuseVerdict({ reason: 'spender-not-allowed', provider, spender: requested });
300
131
  }
301
- // The one place a spender is branded verified: the trusted table entry.
302
132
  return { kind: 'verified', spender: trusted };
303
133
  };
304
- /**
305
- * LI.FI: the deposit and the spender must be LI.FI's Diamond, and the calldata
306
- * must say what was asked: the receiver, the asset, and (through
307
- * `originAmount`) the exact amount pulled from the reader.
308
- */
309
134
  const lifiOriginVerdict = ({ request, quote, deposit, amountToSend }) => {
310
135
  const diamond = lifiDiamondAddressByChainId.get(deposit.chainId);
311
136
  if (diamond === undefined)
@@ -323,17 +148,6 @@ const lifiOriginVerdict = ({ request, quote, deposit, amountToSend }) => {
323
148
  }
324
149
  return spenderVerdict({ provider: 'lifi', requested: quote.approvalAddress, trusted: diamond });
325
150
  };
326
- /**
327
- * The two deposit functions Relay's depository exposes, as observed in live
328
- * `POST /quote/v2` answers on 2026-10-07 (Ethereum to Base):
329
- *
330
- * - `depositNative(address depositor, bytes32 id)` (selector `0x49290c1c`):
331
- * the amount is `msg.value`; the calldata carries NO amount.
332
- * - `depositErc20(address depositor, address token, uint256 amount, bytes32 id)`
333
- * (selector `0xe8017952`): the calldata carries the token and the amount.
334
- *
335
- * Any other selector is refused rather than guessed at.
336
- */
337
151
  const relayDepositoryAbi = parseAbi([
338
152
  'function depositNative(address depositor, bytes32 id) payable',
339
153
  'function depositErc20(address depositor, address token, uint256 amount, bytes32 id)',
@@ -346,7 +160,6 @@ const decodeRelayDeposit = (data) => {
346
160
  return null;
347
161
  }
348
162
  };
349
- /** The native half of Relay's deposit: `depositNative`, with the amount as `msg.value`. */
350
163
  const relayNativeVerdict = ({ deposit, amountToSend }) => {
351
164
  const provider = 'relay';
352
165
  if (deposit.value !== amountToSend) {
@@ -358,7 +171,6 @@ const relayNativeVerdict = ({ deposit, amountToSend }) => {
358
171
  }
359
172
  return null;
360
173
  };
361
- /** The token half of Relay's deposit: no value, and `depositErc20` naming the request's token and amount. */
362
174
  const relayTokenVerdict = ({ request, deposit, amountToSend }) => {
363
175
  const provider = 'relay';
364
176
  if (deposit.value !== 0n) {
@@ -377,18 +189,6 @@ const relayTokenVerdict = ({ request, deposit, amountToSend }) => {
377
189
  }
378
190
  return null;
379
191
  };
380
- /**
381
- * Relay: the deposit and the spender must be Relay's depository on the
382
- * deposit's chain, and the deposit must move exactly the amount to send.
383
- *
384
- * - A native origin: `value` equals the amount, and the calldata is
385
- * `depositNative`, which carries no amount of its own.
386
- * - A token origin: `value` is 0, and the calldata is `depositErc20` for the
387
- * request's token and the amount, decoded with {@link relayDepositoryAbi}.
388
- *
389
- * The depositor and the order identifier inside the calldata are NOT checked.
390
- * The identifier is Relay's own, and nothing in the request predicts it.
391
- */
392
192
  const relayOriginVerdict = (inputs) => {
393
193
  const { quote, request, deposit } = inputs;
394
194
  const depository = relayDepositoryByChainId.get(deposit.chainId);
@@ -412,24 +212,8 @@ const decodeTransfer = (data) => {
412
212
  return null;
413
213
  }
414
214
  };
415
- /**
416
- * NEAR Intents: no contract pulls anything. The deposit is a plain payment to
417
- * the quote's own deposit address, so the check is on its SHAPE and on the two
418
- * figures that matter: who is paid and how much.
419
- *
420
- * - No approval.
421
- * - A native origin: no calldata, `to` is the quote's deposit address
422
- * (`quote.quoteId`, which `parseNearIntentsQuote` sets to it), and `value`
423
- * is the amount to send.
424
- * - A token origin: no value, `to` is the origin token, and the calldata is the
425
- * token's own `transfer(depositAddress, amount)` for the same two figures.
426
- *
427
- * The deposit address itself is per quote and cannot be checked against a
428
- * fixed table; the checks bind the payment to the address the quote names.
429
- */
430
215
  const nearIntentsOriginVerdict = ({ quote, request, deposit, amountToSend }) => {
431
216
  const provider = 'near-intents';
432
- // NEAR Intents trusts no spender at all.
433
217
  const spender = spenderVerdict({ provider, requested: quote.approvalAddress, trusted: null });
434
218
  if (spender.kind === 'refused')
435
219
  return spender;
@@ -467,35 +251,6 @@ const originVerdictByProvider = {
467
251
  relay: relayOriginVerdict,
468
252
  'near-intents': nearIntentsOriginVerdict,
469
253
  };
470
- /**
471
- * Reads the approval and the deposit off an aggregator quote with an Ethereum
472
- * origin, after checking both against what this code knows about the
473
- * provider. The interface's aggregator press (`stores/consolidated-execute.ts`)
474
- * and the SDK's execution planner both read them here, so neither can sign a
475
- * call the other would refuse.
476
- *
477
- * WHAT IS CHECKED, BEFORE ANYTHING IS APPROVED OR SENT:
478
- * - Every provider: when the request names the amount to send
479
- * (`request.fromAmount`), the quote's own `fromAmount` must equal it.
480
- * - LI.FI: `verifyLifiEvmExecution`: the Diamond for the chain, a known
481
- * facet call, calldata that matches the request, and the decoded amount
482
- * pulled from the reader equal to the amount to send.
483
- * - Relay: the deposit target and the spender are Relay's depository for the
484
- * chain (`relayDepositoryByChainId`). A native deposit carries the amount
485
- * as `value` through `depositNative`; a token deposit carries no value and
486
- * is `depositErc20` for the request's token and the amount.
487
- * - NEAR Intents: no spender, and a plain payment of the amount to send to the
488
- * quote's own deposit address (`quote.quoteId`), native or `transfer`.
489
- * - Any other provider is refused. Its spender is unknown.
490
- *
491
- * The approval is for exactly the amount to send (the request's, else the
492
- * quote's when the route is solved backwards and the request names none), on
493
- * the request's origin chain. The native coin needs none.
494
- *
495
- * @param options.quote - the live quote to sign
496
- * @param options.request - the request it answered
497
- * @returns the checked approval and deposit, or why they are refused
498
- */
499
254
  export const aggregatorOriginCalls = ({ quote, request, }) => {
500
255
  const { originDeposit } = quote;
501
256
  if (!isEvmDeposit(originDeposit)) {
@@ -524,9 +279,6 @@ export const aggregatorOriginCalls = ({ quote, request, }) => {
524
279
  const verdict = check({ quote, request, deposit: originDeposit, amountToSend });
525
280
  if (verdict.kind === 'refused')
526
281
  return refuseOrigin(verdict.refusal);
527
- // THE SPENDER COMES FROM THE VERDICT, never from `quote.approvalAddress`:
528
- // only an address the provider check took from its own table can be
529
- // approved, so no provider path can forget the check.
530
282
  if (request.fromTokenAddress === zeroAddress || verdict.spender === null) {
531
283
  return { kind: 'calls', approval: null, deposit: originDeposit };
532
284
  }
@@ -534,8 +286,6 @@ export const aggregatorOriginCalls = ({ quote, request, }) => {
534
286
  kind: 'calls',
535
287
  approval: {
536
288
  chainId: request.fromChainId,
537
- // An Ethereum origin; the request widens the address to `string` only
538
- // for non-Ethereum origins, which were refused above.
539
289
  token: request.fromTokenAddress,
540
290
  spender: verdict.spender,
541
291
  minimum: amountToSend,
@@ -544,12 +294,6 @@ export const aggregatorOriginCalls = ({ quote, request, }) => {
544
294
  };
545
295
  };
546
296
  const isHexString = (value) => typeof value === 'string' && value.startsWith('0x');
547
- /**
548
- * Parses the ecosystem-independent part of a LI.FI quote.
549
- *
550
- * @param payload - the raw JSON body from either LI.FI quote endpoint
551
- * @returns the envelope, or null when a required field is missing or malformed
552
- */
553
297
  const parseLifiQuoteEnvelope = (payload) => {
554
298
  if (typeof payload !== 'object' || payload === null) {
555
299
  return null;
@@ -588,27 +332,9 @@ const parseLifiQuoteEnvelope = (payload) => {
588
332
  };
589
333
  }
590
334
  catch {
591
- // a BigInt conversion failed on a malformed numeric string
592
335
  return null;
593
336
  }
594
337
  };
595
- /**
596
- * Normalizes a quote response from the contract-calls endpoint.
597
- *
598
- * A present but malformed `transactionRequest.value` fails the parse — silently
599
- * sending zero native value would produce a transaction that under-pays the
600
- * provider's bridging fee.
601
- *
602
- * REQUIRES `context.request` — see {@link lifiEvmDeposit}. Every live caller
603
- * (`providers.ts`'s registry entry, the interface's `consolidated-quote.ts`
604
- * store) supplies it; a caller that omits it gets a thrown
605
- * {@link LifiExecutionRefusedError} rather than a silently unchecked
606
- * execution transaction.
607
- *
608
- * @returns the normalized quote, or null when the payload shape is unexpected
609
- * @throws {LifiExecutionRefusedError} when the response's execution
610
- * transaction disagrees with `context.request` — see `lifi-execution-guard.ts`
611
- */
612
338
  export const parseLifiContractCallsQuote = (payload, context) => {
613
339
  const envelope = parseLifiQuoteEnvelope(payload);
614
340
  if (envelope === null) {
@@ -621,16 +347,6 @@ export const parseLifiContractCallsQuote = (payload, context) => {
621
347
  const { transactionRequest: _request, fromChainId: _fromChainId, ...quote } = envelope;
622
348
  return { ...quote, originDeposit, fees: lifiQuoteFees(payload) };
623
349
  };
624
- /**
625
- * Builds what THIS APPLICATION expects a LI.FI execution transaction to
626
- * contain, from the request that produced it — the only thing
627
- * {@link verifyLifiEvmExecution} is allowed to check a response against.
628
- *
629
- * `receiver` and `minimumAmount` differ by whether `destinationCall` is
630
- * present, because the two LI.FI endpoints populate `BridgeData.receiver`
631
- * with DIFFERENT fields and only one endpoint accepts a requested minimum at
632
- * all — see the field-semantics note atop `lifi-execution-guard.ts`.
633
- */
634
350
  const lifiExecutionExpectation = (request) => {
635
351
  const hasDestinationCall = request.destinationCall !== undefined;
636
352
  return {
@@ -642,28 +358,6 @@ const lifiExecutionExpectation = (request) => {
642
358
  originAmount: request.fromAmount ?? null,
643
359
  };
644
360
  };
645
- /**
646
- * Reads LI.FI's Ethereum `transactionRequest` into an Ethereum origin deposit.
647
- *
648
- * A present but malformed `value` fails the parse — silently sending zero
649
- * native value would produce a transaction that under-pays the provider's
650
- * bridging fee.
651
- *
652
- * VERIFIES THE TRANSACTION BEFORE RETURNING IT. `lifiApi.quote` and
653
- * `lifiApi.contractCallsQuote` are fetched through a configurable, possibly
654
- * compromised host — see `lifi-execution-guard.ts`'s top-of-file doc comment
655
- * for the full threat model. `request` is REQUIRED, not optional: a caller
656
- * with no request to check against gets a thrown
657
- * {@link LifiExecutionRefusedError} (`missing-request-context`) rather than
658
- * an origin deposit nothing has verified. This is the one gap a type
659
- * signature alone could not close — `ProviderQuoteContext.request` is
660
- * optional on every OTHER provider, so this function still accepts
661
- * `undefined` in its parameter type and refuses at the call boundary
662
- * instead, keeping it assignable to `ProviderDescriptor.executionQuote.parse`.
663
- *
664
- * @throws {LifiExecutionRefusedError} when `request` is absent, or when the
665
- * transaction disagrees with it
666
- */
667
361
  const lifiEvmDeposit = (transactionRequest, approvalAddress, request) => {
668
362
  if (!isHexString(transactionRequest.to) ||
669
363
  !isHexString(transactionRequest.data) ||
@@ -695,17 +389,7 @@ const lifiEvmDeposit = (transactionRequest, approvalAddress, request) => {
695
389
  gasLimit: isHexString(transactionRequest.gasLimit) ? BigInt(transactionRequest.gasLimit) : null,
696
390
  };
697
391
  };
698
- // A partially-signed Bitcoin transaction always begins with the five-byte magic
699
- // "psbt\xff". Checking it keeps a base64 payload, or an Ethereum `0x` string,
700
- // from being handed to a Bitcoin wallet as though it were a transaction.
701
392
  const partiallySignedBitcoinMagic = '70736274ff';
702
- /**
703
- * Reads LI.FI's Bitcoin `transactionRequest` into a Bitcoin origin deposit.
704
- *
705
- * LI.FI and Relay happen to agree on the encoding here — an unprefixed
706
- * hexadecimal partially-signed transaction — so this lands on the same
707
- * {@link BitcoinDeposit} the Relay parser produces and needs no signer change.
708
- */
709
393
  const lifiBitcoinDeposit = (transactionRequest, chainId) => {
710
394
  const { to, data, value } = transactionRequest;
711
395
  if (typeof to !== 'string' || to.length === 0) {
@@ -719,27 +403,10 @@ const lifiBitcoinDeposit = (transactionRequest, chainId) => {
719
403
  }
720
404
  return { ecosystem: 'bvm', psbt: data, depositAddress: to, amountSats: BigInt(value), chainId };
721
405
  };
722
- // Base64 without whitespace. Necessary but nowhere near sufficient on its own:
723
- // the hexadecimal alphabet is a SUBSET of base64's, so a Bitcoin
724
- // partially-signed transaction matches this pattern happily.
725
406
  const base64Pattern = /^[A-Za-z0-9+/]+={0,2}$/;
726
- // A single-byte compact-u16 tops out below this, and no real transaction needs
727
- // anything near this many signatures.
728
407
  const maxPlausibleSignatureCount = 19;
729
408
  const solanaSignatureByteLength = 64;
730
- // A versioned message's first byte sets the high bit; version 0 is the only one
731
- // that exists, so the byte is exactly 0x80.
732
409
  const solanaVersionZeroPrefix = 0x80;
733
- /**
734
- * Checks that a base64 payload really is a serialized Solana transaction, by
735
- * walking its wire layout: a compact-u16 signature count, that many 64-byte
736
- * signatures, then a message whose leading byte is either the version-0 marker
737
- * or (for a legacy message) the same signature count again.
738
- *
739
- * An alphabet check alone is not enough. Hexadecimal is a subset of base64, so
740
- * a Bitcoin partially-signed transaction passes a pure pattern test and would
741
- * be handed to a Solana wallet as a transaction.
742
- */
743
410
  const isSerializedSolanaTransaction = (value) => {
744
411
  if (!base64Pattern.test(value)) {
745
412
  return false;
@@ -765,13 +432,6 @@ const isSerializedSolanaTransaction = (value) => {
765
432
  }
766
433
  return header === solanaVersionZeroPrefix || header === signatureCount;
767
434
  };
768
- /**
769
- * Reads LI.FI's Solana `transactionRequest` into a Solana origin deposit.
770
- *
771
- * The whole payload is a single base64 compiled transaction under `data`, with
772
- * no `to`, `value` or `chainId` beside it, so the chain id comes from the
773
- * quote's action rather than the request.
774
- */
775
435
  const lifiSolanaDeposit = (transactionRequest, chainId) => {
776
436
  const { data } = transactionRequest;
777
437
  if (typeof data !== 'string' || !isSerializedSolanaTransaction(data)) {
@@ -779,73 +439,6 @@ const lifiSolanaDeposit = (transactionRequest, chainId) => {
779
439
  }
780
440
  return { ecosystem: 'svm', form: 'serialized', transaction: data, chainId };
781
441
  };
782
- /**
783
- * INTENTIONALLY UNWIRED at runtime — retained as tested, parked capability.
784
- *
785
- * Nothing in the app calls this; the live LI.FI path is `parseLifiContractCallsQuote`
786
- * (the contract-calls endpoint), which only ever produces an Ethereum deposit.
787
- * This parser is the ONE piece that can decode a NON-Ethereum LI.FI origin
788
- * deposit, and it exists for a provider path that is deliberately NOT built:
789
- * adding LI.FI as a competing provider for non-Ethereum origins was analysed and
790
- * rejected (LI.FI can produce only leg one of the consolidated route, and every
791
- * way to execute leg two is strictly worse than Relay, which already serves those
792
- * origins in a single signature — see docs/consolidated-bridge-route-design.md).
793
- * Do not delete this while that decision could still be revisited; its test block
794
- * (`parseLifiQuote across origin ecosystems`) is its executable spec.
795
- *
796
- * Normalizes a quote response from LI.FI's plain `GET /v1/quote`.
797
- *
798
- * Unlike the contract-calls endpoint, this one accepts a non-Ethereum origin,
799
- * and the shape of `transactionRequest` then varies by ecosystem: Ethereum
800
- * returns the familiar `to`/`data`/`value`/`chainId`, Bitcoin returns a deposit
801
- * address plus a partially-signed transaction, and Solana returns nothing but a
802
- * compiled transaction. Reading the Ethereum fields off the others would
803
- * produce a deposit that is structurally valid and completely wrong, so the
804
- * caller states the origin ecosystem and only that reader runs.
805
- *
806
- * The origin ecosystem is a parameter rather than something sniffed from the
807
- * payload because the caller already knows it — it decided which chain to quote
808
- * — and guessing from field presence would make a malformed Ethereum response
809
- * look like a valid Solana one.
810
- *
811
- * Note that `approvalAddress` is dropped for a non-Ethereum origin. LI.FI
812
- * returns its Ethereum router there regardless of where the route starts, and
813
- * that address is meaningless to a Solana or Bitcoin wallet; passing it on
814
- * invites a caller to build an approval for a chain that has no such concept.
815
- *
816
- * @param payload - the raw JSON body from `GET /v1/quote`
817
- * @param options.originEcosystem - the virtual-machine family the route starts from
818
- * @returns the normalized quote, or null when the payload does not match that ecosystem
819
- */
820
- /**
821
- * What a plain LI.FI quote says arrives, and what LI.FI says it is worth.
822
- *
823
- * ONLY THE PLAIN ENDPOINT CARRIES THESE ONTO THE QUOTE, and that is not a
824
- * convenience. A route through this endpoint is solved FORWARDS: the reader
825
- * names what they spend, so every provider is handed the same `fromAmount` and
826
- * the delivered amount is the ONE figure that differs. Without it:
827
- *
828
- * - ranking cannot engage its forward rule — it requires every quote to carry
829
- * `toAmount` — and falls back to comparing each provider's own dollar
830
- * figure, which come from different price feeds. Measured: LI.FI $122.00
831
- * against Relay $123.71 on the same 0.05 ether, so LI.FI won on a feed.
832
- * - the route then shows the winner's delivered amount as ZERO, because the
833
- * direct candidate reads `quote.toAmount ?? 0n`.
834
- *
835
- * Both happened: Relay's parser set these, LI.FI's never did, and a route test
836
- * built its quotes by hand with `toAmount` already filled in — so it passed.
837
- * It took a live round trip to see the gap.
838
- *
839
- * NOT added to the shared envelope. The contract-calls endpoint uses that too,
840
- * and on an omnibridge route the provider's delivered side is the ENTRY chain's
841
- * tokens rather than what lands on PulseChain — see `ConsolidatedQuote.toAmount`.
842
- *
843
- * `estimate.toAmount` is the expected amount, matching Relay's
844
- * `currencyOut.amount`, so the two rank on the same kind of figure.
845
- *
846
- * @param payload - the raw JSON body from `GET /v1/quote`
847
- * @returns the delivered amount and its dollar value, each only when present
848
- */
849
442
  const lifiDeliveredAmount = (payload) => {
850
443
  const estimate = payload?.estimate;
851
444
  const delivered = {};
@@ -854,8 +447,6 @@ const lifiDeliveredAmount = (payload) => {
854
447
  delivered.toAmount = BigInt(estimate.toAmount);
855
448
  }
856
449
  catch {
857
- // A malformed amount leaves the field absent rather than zero: zero is a
858
- // real quantity and would read as "this route delivers nothing".
859
450
  }
860
451
  }
861
452
  if (typeof estimate?.toAmountUSD === 'string') {
@@ -863,22 +454,6 @@ const lifiDeliveredAmount = (payload) => {
863
454
  }
864
455
  return delivered;
865
456
  };
866
- /**
867
- * Normalizes a quote response from LI.FI's plain `GET /v1/quote`.
868
- *
869
- * `request` IS REQUIRED FOR AN ETHEREUM ORIGIN, though its type stays
870
- * optional — omitting it there throws {@link LifiExecutionRefusedError}
871
- * rather than returning an unverified deposit; see `lifiEvmDeposit`'s doc
872
- * comment for why the type cannot say so directly. It is genuinely optional
873
- * for a Solana or Bitcoin origin, which never reach the execution guard.
874
- *
875
- * @param payload - the raw JSON body from `GET /v1/quote`
876
- * @param options.originEcosystem - the virtual-machine family the route starts from
877
- * @param options.request - the consolidated request this response answers
878
- * @returns the normalized quote, or null when the payload does not match that ecosystem
879
- * @throws {LifiExecutionRefusedError} for an Ethereum origin, when `request`
880
- * is absent or the execution transaction disagrees with it
881
- */
882
457
  export const parseLifiQuote = (payload, { originEcosystem, request }) => {
883
458
  const envelope = parseLifiQuoteEnvelope(payload);
884
459
  if (envelope === null) {
@@ -904,27 +479,10 @@ export const parseLifiQuote = (payload, { originEcosystem, request }) => {
904
479
  return { ...quote, originDeposit, approvalAddress: null };
905
480
  };
906
481
  const consolidatedStatusValues = ['NOT_FOUND', 'INVALID', 'PENDING', 'DONE', 'FAILED'];
907
- /**
908
- * Builds the status-poll address for an origin transaction, at
909
- * {@link lifiDefaultApiOrigin}. Chain hints narrow the provider's lookup and
910
- * are recommended when known. `txHash` is typed as `string` rather than `Hex`
911
- * because a non-Ethereum origin (Solana base58 signature, Bitcoin transaction
912
- * id) is not `0x`-prefixed.
913
- */
914
482
  export const lifiStatusUrl = ({ txHash, fromChainId, toChainId, }) => {
915
483
  return defaultLifiEndpoints.status({ txHash, fromChainId, toChainId });
916
484
  };
917
485
  const isTransactionHash = (value) => typeof value === 'string' && /^0x[0-9a-fA-F]{64}$/.test(value);
918
- /**
919
- * Normalizes a status response for an in-flight consolidated bridge.
920
- *
921
- * The receiving hash gates the handover from provider polling to the
922
- * omnibridge indexer, so it must be a full 32-byte transaction hash — an
923
- * empty or malformed value collapses to null rather than masquerading as a
924
- * real transaction.
925
- *
926
- * @returns the normalized status, or null when the payload shape is unexpected
927
- */
928
486
  export const parseLifiStatus = (payload) => {
929
487
  if (typeof payload !== 'object' || payload === null) {
930
488
  return null;
@@ -941,18 +499,7 @@ export const parseLifiStatus = (payload) => {
941
499
  receivingTxHash: isTransactionHash(receiving?.txHash) ? receiving.txHash : null,
942
500
  };
943
501
  };
944
- /**
945
- * Chain listing endpoint, at {@link lifiDefaultApiOrigin}. Deliberately
946
- * carries no query parameters: the `chainTypes` filter requires an API key on
947
- * the anonymous tier (verified live 2026-06-12, error code 1010), and the
948
- * default response is EVM-only.
949
- */
950
502
  export const lifiChainsUrl = defaultLifiEndpoints.chains;
951
- /**
952
- * Normalizes a `GET /v1/chains` response body to mainnet EVM chains.
953
- *
954
- * @returns the chain list, or null when the payload shape is unexpected
955
- */
956
503
  export const parseLifiChains = (payload) => {
957
504
  if (typeof payload !== 'object' || payload === null) {
958
505
  return null;
@@ -981,16 +528,7 @@ export const parseLifiChains = (payload) => {
981
528
  }
982
529
  return parsed;
983
530
  };
984
- /** Builds the per-chain token listing URL, at {@link lifiDefaultApiOrigin}. */
985
531
  export const lifiTokensUrl = defaultLifiEndpoints.tokens;
986
- /**
987
- * Normalizes a `GET /v1/tokens?chains=<id>` response body into the shared
988
- * token shape used across the bridge frontend. Malformed entries are skipped
989
- * rather than failing the whole list; `logoURI` is optional on the live
990
- * interface.
991
- *
992
- * @returns the token list, or null when the payload shape is unexpected
993
- */
994
532
  export const parseLifiTokens = (payload, chainId) => {
995
533
  if (typeof payload !== 'object' || payload === null) {
996
534
  return null;
@@ -1022,10 +560,7 @@ export const parseLifiTokens = (payload, chainId) => {
1022
560
  name: entry.name,
1023
561
  decimals: entry.decimals,
1024
562
  logoURI: typeof entry.logoURI === 'string' ? entry.logoURI : null,
1025
- // Preserve the inline spot price the LI.FI list carries — it is the USD
1026
- // price source for aggregator chains (the dapp image lists carry none).
1027
563
  priceUSD: typeof entry.priceUSD === 'string' ? entry.priceUSD : null,
1028
- // Additive: kept only when LI.FI sends them, so a token without them has the same shape as before.
1029
564
  ...(typeof entry.coinKey === 'string' ? { coinKey: entry.coinKey } : {}),
1030
565
  ...(typeof entry.verificationStatus === 'string' ? { verificationStatus: entry.verificationStatus } : {}),
1031
566
  });