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