@gibs/bridge-sdk 1.12.0 → 1.13.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 (117) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +234 -432
  3. package/dist/abis.d.ts +1 -0
  4. package/dist/bridge-limits.d.ts +103 -0
  5. package/dist/bridge-limits.js +84 -0
  6. package/dist/chain-info.d.ts +169 -0
  7. package/dist/chain-info.js +410 -0
  8. package/dist/chain-names.d.ts +160 -0
  9. package/dist/chain-names.js +200 -0
  10. package/dist/chains.d.ts +65 -0
  11. package/dist/chains.js +284 -0
  12. package/dist/config.d.ts +216 -0
  13. package/dist/config.js +493 -0
  14. package/dist/consolidated-quote.d.ts +554 -0
  15. package/dist/consolidated-quote.js +773 -0
  16. package/dist/destination-calldata.d.ts +118 -0
  17. package/dist/destination-calldata.js +152 -0
  18. package/dist/ecosystems.d.ts +217 -0
  19. package/dist/ecosystems.js +288 -0
  20. package/dist/fee-type.d.ts +10 -0
  21. package/dist/fee-type.js +9 -0
  22. package/dist/hyperliquid-execution.d.ts +152 -0
  23. package/dist/hyperliquid-execution.js +168 -0
  24. package/dist/image-links.d.ts +117 -0
  25. package/dist/image-links.js +142 -0
  26. package/dist/index.d.ts +20 -0
  27. package/dist/index.js +20 -0
  28. package/dist/lifi-execution-guard.d.ts +199 -0
  29. package/dist/lifi-execution-guard.js +400 -0
  30. package/dist/near-intents-conformance.d.ts +85 -0
  31. package/dist/near-intents-conformance.js +329 -0
  32. package/dist/near-intents-route.d.ts +47 -0
  33. package/dist/near-intents-route.js +265 -0
  34. package/dist/near-intents.d.ts +524 -0
  35. package/dist/near-intents.js +1055 -0
  36. package/dist/origin-deposit.d.ts +326 -0
  37. package/dist/origin-deposit.js +68 -0
  38. package/dist/pre-quote.d.ts +198 -0
  39. package/dist/pre-quote.js +175 -0
  40. package/dist/prices.d.ts +107 -0
  41. package/dist/prices.js +162 -0
  42. package/dist/providers.d.ts +221 -0
  43. package/dist/providers.js +157 -0
  44. package/dist/quote-fees.d.ts +102 -0
  45. package/dist/quote-fees.js +195 -0
  46. package/dist/referral.d.ts +77 -0
  47. package/dist/referral.js +72 -0
  48. package/dist/relay-currencies.d.ts +47 -0
  49. package/dist/relay-currencies.js +89 -0
  50. package/dist/relay-quote.d.ts +301 -0
  51. package/dist/relay-quote.js +983 -0
  52. package/dist/route-steps.d.ts +138 -0
  53. package/dist/route-steps.js +305 -0
  54. package/dist/routing/amounts.d.ts +80 -0
  55. package/dist/routing/amounts.js +120 -0
  56. package/dist/routing/candidate-route.d.ts +43 -0
  57. package/dist/routing/candidate-route.js +45 -0
  58. package/dist/routing/candidate.d.ts +237 -0
  59. package/dist/routing/candidate.js +96 -0
  60. package/dist/routing/carriers/ask-answer.d.ts +58 -0
  61. package/dist/routing/carriers/ask-answer.js +1 -0
  62. package/dist/routing/carriers/omnibridge.d.ts +137 -0
  63. package/dist/routing/carriers/omnibridge.js +419 -0
  64. package/dist/routing/carriers/pulsex.d.ts +111 -0
  65. package/dist/routing/carriers/pulsex.js +404 -0
  66. package/dist/routing/carriers/wrap.d.ts +25 -0
  67. package/dist/routing/carriers/wrap.js +115 -0
  68. package/dist/routing/composed-route-quality.d.ts +103 -0
  69. package/dist/routing/composed-route-quality.js +108 -0
  70. package/dist/routing/entry-chain-anchor.d.ts +88 -0
  71. package/dist/routing/entry-chain-anchor.js +55 -0
  72. package/dist/routing/format.d.ts +31 -0
  73. package/dist/routing/format.js +58 -0
  74. package/dist/routing/index.d.ts +34 -0
  75. package/dist/routing/index.js +42 -0
  76. package/dist/routing/producers.d.ts +770 -0
  77. package/dist/routing/producers.js +1564 -0
  78. package/dist/routing/providers.d.ts +26 -0
  79. package/dist/routing/providers.js +38 -0
  80. package/dist/routing/route-data.d.ts +355 -0
  81. package/dist/routing/route-data.js +1 -0
  82. package/dist/routing/search/compose.d.ts +168 -0
  83. package/dist/routing/search/compose.js +98 -0
  84. package/dist/routing/search/graph.d.ts +639 -0
  85. package/dist/routing/search/graph.js +445 -0
  86. package/dist/routing/search/plan-route-data.d.ts +244 -0
  87. package/dist/routing/search/plan-route-data.js +767 -0
  88. package/dist/routing/search/score.d.ts +324 -0
  89. package/dist/routing/search/score.js +400 -0
  90. package/dist/routing/usd-value.d.ts +17 -0
  91. package/dist/routing/usd-value.js +25 -0
  92. package/dist/settings.d.ts +692 -0
  93. package/dist/settings.js +909 -0
  94. package/dist/ton-execution.d.ts +117 -0
  95. package/dist/ton-execution.js +247 -0
  96. package/dist/tron-execution.d.ts +146 -0
  97. package/dist/tron-execution.js +239 -0
  98. package/dist/types.d.ts +51 -0
  99. package/dist/types.js +1 -0
  100. package/package.json +203 -23
  101. package/src/chain-info.test.ts +0 -968
  102. package/src/chain-info.ts +0 -498
  103. package/src/chains.test.ts +0 -123
  104. package/src/chains.ts +0 -88
  105. package/src/config.test.ts +0 -679
  106. package/src/config.ts +0 -500
  107. package/src/fee-type.test.ts +0 -45
  108. package/src/fee-type.ts +0 -14
  109. package/src/image-links.test.ts +0 -160
  110. package/src/image-links.ts +0 -65
  111. package/src/index.ts +0 -8
  112. package/src/settings.test.ts +0 -2754
  113. package/src/settings.ts +0 -875
  114. package/src/types.ts +0 -48
  115. package/tsconfig.json +0 -17
  116. package/vitest.config.ts +0 -13
  117. /package/{src/abis.ts → dist/abis.js} +0 -0
@@ -0,0 +1,117 @@
1
+ import { type DepositAddressChain } from './chain-names.js';
2
+ /**
3
+ * Sets the image root for the bridge
4
+ * @param root - the root
5
+ */
6
+ export declare const setImageRoot: (root: string) => void;
7
+ /**
8
+ * Returns the image root for the bridge
9
+ * @returns the image root
10
+ */
11
+ export declare const getImageRoot: () => string;
12
+ /** The minimal token info */
13
+ interface MinimalTokenInfo {
14
+ chainId: number;
15
+ address: string;
16
+ logoURI?: string | null;
17
+ }
18
+ /**
19
+ * Returns the list image for the given path
20
+ * @param path - the path
21
+ * @returns the list image
22
+ */
23
+ export declare const list: (path: string) => string;
24
+ /**
25
+ * Returns the network image for the given chain id
26
+ * @param chainId - the chain id
27
+ * @returns the network image
28
+ */
29
+ export declare const network: (chainId: number) => string;
30
+ /**
31
+ * gib.show's own key for a chain this package can only name by a LOCAL,
32
+ * INVENTED identifier — a pay-by-hand origin (see `depositAddressChainIds`)
33
+ * rather than a real chain id gib.show's numeric endpoint recognizes.
34
+ * `network(chainId)` 404s for one of these, and the browser draws that 404 as
35
+ * a broken image on every chain badge and route mark drawn through it.
36
+ *
37
+ * Every route producer that draws a chain badge for a token needs this, not
38
+ * only the deposit-address ones: a route can START on a deposit-address chain
39
+ * and cross through ordinary Ethereum-Virtual-Machine chains after, so the
40
+ * predicate has to run on every chain id a route touches, not only the one
41
+ * the reader picked. Kept beside `network` rather than in the client that also
42
+ * resolves Relay's pseudo chains (`@gibs/bridge-client/image`'s
43
+ * `chainLogoUrl`) because that client sits ABOVE this package — it imports
44
+ * FROM `bridge-sdk` — so this package importing back from it would be a
45
+ * cycle. `chainLogoUrl` still adds a Relay-icon fallback for chains gib.show
46
+ * does not carry at ALL (Eclipse, Hyperliquid); this table is only the
47
+ * chains gib.show DOES carry, under a key other than their numeric id.
48
+ *
49
+ * EXPORTED, and this is the ONLY place a pay-by-hand chain's gib.show key is
50
+ * declared. `@gibs/bridge-client`'s `image.ts` used to hard-code its own copy
51
+ * of the same `zcash → 'bip122-133'` entry; it now spreads this map into its
52
+ * own icon table instead, because the dependency runs one way — the client
53
+ * already imports from this package — so there was never a cycle stopping it.
54
+ */
55
+ export declare const pseudoChainGibShowIdentifierByChain: Record<DepositAddressChain, string>;
56
+ /** {@link pseudoChainGibShowIdentifierByChain}, keyed by chain id for lookup. */
57
+ export declare const pseudoChainGibShowIdentifier: Readonly<Record<number, string>>;
58
+ /**
59
+ * The network image for a chain id, honouring a pseudo chain's own gib.show
60
+ * key when its numeric id is not one gib.show's `/image/<id>` endpoint knows.
61
+ *
62
+ * @param chainId - the chain id, a deposit-address chain's local identifier included
63
+ * @returns a working network/chain-badge image url
64
+ */
65
+ export declare const networkOrPseudo: (chainId: number) => string;
66
+ /**
67
+ * Returns the image url for the given token info.
68
+ *
69
+ * The gas token is asked for by BOTH of its keys, because the service keys it
70
+ * two ways and each chain carries only one of them. `<chain>/<zero address>` is
71
+ * a dedicated picture — Ethereum's ether diamond, PulseChain's mark — and
72
+ * Binance Smart Chain has none, so asking for it there returns a 404 the browser
73
+ * draws as a broken image. The empty-address form `<chain>/` is the chain's own
74
+ * mark, which every chain has.
75
+ *
76
+ * The order is NOT interchangeable. The service serves the first source that
77
+ * resolves, so a chain with a dedicated picture keeps it; reversed, Ethereum
78
+ * would show the network logo where the ether logo belongs (the two are
79
+ * genuinely different files). The pair is for the gas token alone: pairing an
80
+ * ordinary contract address with the chain mark would hide a missing token logo
81
+ * behind the network's, showing the wrong token rather than an honest fallback.
82
+ *
83
+ * @param t - the token info
84
+ * @returns the image url
85
+ */
86
+ export declare const image: (t: MinimalTokenInfo) => string;
87
+ /**
88
+ * {@link image}, but falling back to the token's own CHAIN mark rather than
89
+ * throwing or asking the service for a picture that was never going to exist,
90
+ * when the token carries no address a picture can be resolved from yet.
91
+ *
92
+ * WHY THIS EXISTS SEPARATELY FROM `image`. A route producer can reach the
93
+ * moment it draws a DELIVERED token's picture before that token's exact
94
+ * on-chain address is known — a not-yet-bridged token's `assetOutAddress` is
95
+ * documented to arrive `null` (see the repository's own "Not-Yet-Bridged
96
+ * Tokens" gotcha), and a deferred crossing's landing token is exactly this
97
+ * case: the reader has not yet signed the leg that would settle it. `image`
98
+ * either throws (`getAddress` refuses a malformed or empty string) or, for a
99
+ * caller that swallows the throw, silently draws nothing — the same "blank
100
+ * disc" defect the carrier marks were fixed for, one token lower. The chain's
101
+ * own mark is a real, recognisable picture that is honest about what is
102
+ * known: THIS chain, a token not yet resolved on it — the same trade
103
+ * `trackerView.ts`'s `depositAddressChainLogoFallback` already makes for a
104
+ * pay-by-hand ORIGIN with no address of its own.
105
+ *
106
+ * @param t - the token to draw
107
+ * @returns the token's own picture, or its chain's mark when the token's
108
+ * address cannot be resolved into one
109
+ */
110
+ export declare const tokenImageOrChainFallback: (t: MinimalTokenInfo) => string;
111
+ /**
112
+ * Returns a url that will lookup all sources for the given array
113
+ * @param sources - the sources
114
+ * @returns the images
115
+ */
116
+ export declare const images: (sources: string[]) => string;
117
+ export {};
@@ -0,0 +1,142 @@
1
+ import { getAddress, zeroAddress } from 'viem';
2
+ import { depositAddressChainIds } from './chain-names.js';
3
+ import { isNativeAsset } from './ecosystems.js';
4
+ let imageRoot = 'https://gib.show';
5
+ /**
6
+ * Sets the image root for the bridge
7
+ * @param root - the root
8
+ */
9
+ export const setImageRoot = (root) => {
10
+ imageRoot = root;
11
+ };
12
+ /**
13
+ * Returns the image root for the bridge
14
+ * @returns the image root
15
+ */
16
+ export const getImageRoot = () => imageRoot;
17
+ /**
18
+ * Returns the list image for the given path
19
+ * @param path - the path
20
+ * @returns the list image
21
+ */
22
+ export const list = (path) => {
23
+ return `${imageRoot}/list${path}`;
24
+ };
25
+ /**
26
+ * Returns the network image for the given chain id
27
+ * @param chainId - the chain id
28
+ * @returns the network image
29
+ */
30
+ export const network = (chainId) => `${imageRoot}/image/${Number(chainId)}`;
31
+ /**
32
+ * gib.show's own key for a chain this package can only name by a LOCAL,
33
+ * INVENTED identifier — a pay-by-hand origin (see `depositAddressChainIds`)
34
+ * rather than a real chain id gib.show's numeric endpoint recognizes.
35
+ * `network(chainId)` 404s for one of these, and the browser draws that 404 as
36
+ * a broken image on every chain badge and route mark drawn through it.
37
+ *
38
+ * Every route producer that draws a chain badge for a token needs this, not
39
+ * only the deposit-address ones: a route can START on a deposit-address chain
40
+ * and cross through ordinary Ethereum-Virtual-Machine chains after, so the
41
+ * predicate has to run on every chain id a route touches, not only the one
42
+ * the reader picked. Kept beside `network` rather than in the client that also
43
+ * resolves Relay's pseudo chains (`@gibs/bridge-client/image`'s
44
+ * `chainLogoUrl`) because that client sits ABOVE this package — it imports
45
+ * FROM `bridge-sdk` — so this package importing back from it would be a
46
+ * cycle. `chainLogoUrl` still adds a Relay-icon fallback for chains gib.show
47
+ * does not carry at ALL (Eclipse, Hyperliquid); this table is only the
48
+ * chains gib.show DOES carry, under a key other than their numeric id.
49
+ *
50
+ * EXPORTED, and this is the ONLY place a pay-by-hand chain's gib.show key is
51
+ * declared. `@gibs/bridge-client`'s `image.ts` used to hard-code its own copy
52
+ * of the same `zcash → 'bip122-133'` entry; it now spreads this map into its
53
+ * own icon table instead, because the dependency runs one way — the client
54
+ * already imports from this package — so there was never a cycle stopping it.
55
+ */
56
+ export const pseudoChainGibShowIdentifierByChain = {
57
+ zcash: 'bip122-133',
58
+ };
59
+ /** {@link pseudoChainGibShowIdentifierByChain}, keyed by chain id for lookup. */
60
+ export const pseudoChainGibShowIdentifier = Object.fromEntries(Object.keys(depositAddressChainIds).map((chain) => [
61
+ depositAddressChainIds[chain],
62
+ pseudoChainGibShowIdentifierByChain[chain],
63
+ ]));
64
+ /**
65
+ * The network image for a chain id, honouring a pseudo chain's own gib.show
66
+ * key when its numeric id is not one gib.show's `/image/<id>` endpoint knows.
67
+ *
68
+ * @param chainId - the chain id, a deposit-address chain's local identifier included
69
+ * @returns a working network/chain-badge image url
70
+ */
71
+ export const networkOrPseudo = (chainId) => {
72
+ const identifier = pseudoChainGibShowIdentifier[chainId];
73
+ return identifier !== undefined ? `${imageRoot}/image/${identifier}` : network(chainId);
74
+ };
75
+ /**
76
+ * Returns the image url for the given token info.
77
+ *
78
+ * The gas token is asked for by BOTH of its keys, because the service keys it
79
+ * two ways and each chain carries only one of them. `<chain>/<zero address>` is
80
+ * a dedicated picture — Ethereum's ether diamond, PulseChain's mark — and
81
+ * Binance Smart Chain has none, so asking for it there returns a 404 the browser
82
+ * draws as a broken image. The empty-address form `<chain>/` is the chain's own
83
+ * mark, which every chain has.
84
+ *
85
+ * The order is NOT interchangeable. The service serves the first source that
86
+ * resolves, so a chain with a dedicated picture keeps it; reversed, Ethereum
87
+ * would show the network logo where the ether logo belongs (the two are
88
+ * genuinely different files). The pair is for the gas token alone: pairing an
89
+ * ordinary contract address with the chain mark would hide a missing token logo
90
+ * behind the network's, showing the wrong token rather than an honest fallback.
91
+ *
92
+ * @param t - the token info
93
+ * @returns the image url
94
+ */
95
+ export const image = (t) => {
96
+ if (t.logoURI)
97
+ return t.logoURI;
98
+ if (isNativeAsset(t.address, 'evm')) {
99
+ return images([`${Number(t.chainId)}/${zeroAddress}`, `${Number(t.chainId)}/`]);
100
+ }
101
+ return `${network(t.chainId)}/${getAddress(t.address)}`;
102
+ };
103
+ /**
104
+ * Whether `address` is a real Ethereum-Virtual-Machine address {@link image}
105
+ * can ask the service about — the zero address included, since that is
106
+ * {@link isNativeAsset}'s own case and {@link image} handles it without
107
+ * `getAddress` ever running.
108
+ *
109
+ * @param address - the address to check
110
+ * @returns true when `getAddress` can checksum it without throwing
111
+ */
112
+ const isResolvableEvmAddress = (address) => /^0x[0-9a-fA-F]{40}$/.test(address);
113
+ /**
114
+ * {@link image}, but falling back to the token's own CHAIN mark rather than
115
+ * throwing or asking the service for a picture that was never going to exist,
116
+ * when the token carries no address a picture can be resolved from yet.
117
+ *
118
+ * WHY THIS EXISTS SEPARATELY FROM `image`. A route producer can reach the
119
+ * moment it draws a DELIVERED token's picture before that token's exact
120
+ * on-chain address is known — a not-yet-bridged token's `assetOutAddress` is
121
+ * documented to arrive `null` (see the repository's own "Not-Yet-Bridged
122
+ * Tokens" gotcha), and a deferred crossing's landing token is exactly this
123
+ * case: the reader has not yet signed the leg that would settle it. `image`
124
+ * either throws (`getAddress` refuses a malformed or empty string) or, for a
125
+ * caller that swallows the throw, silently draws nothing — the same "blank
126
+ * disc" defect the carrier marks were fixed for, one token lower. The chain's
127
+ * own mark is a real, recognisable picture that is honest about what is
128
+ * known: THIS chain, a token not yet resolved on it — the same trade
129
+ * `trackerView.ts`'s `depositAddressChainLogoFallback` already makes for a
130
+ * pay-by-hand ORIGIN with no address of its own.
131
+ *
132
+ * @param t - the token to draw
133
+ * @returns the token's own picture, or its chain's mark when the token's
134
+ * address cannot be resolved into one
135
+ */
136
+ export const tokenImageOrChainFallback = (t) => isResolvableEvmAddress(t.address) ? image(t) : networkOrPseudo(t.chainId);
137
+ /**
138
+ * Returns a url that will lookup all sources for the given array
139
+ * @param sources - the sources
140
+ * @returns the images
141
+ */
142
+ export const images = (sources) => `${imageRoot}/image/?${sources.map((s) => `i=${s}`).join('&')}`;
@@ -0,0 +1,20 @@
1
+ export * from './abis.js';
2
+ export * from './bridge-limits.js';
3
+ export * from './chain-info.js';
4
+ export * from './chains.js';
5
+ export * from './config.js';
6
+ export * from './consolidated-quote.js';
7
+ export * from './relay-quote.js';
8
+ export * from './relay-currencies.js';
9
+ export * from './destination-calldata.js';
10
+ export * from './ecosystems.js';
11
+ export * from './fee-type.js';
12
+ export * from './image-links.js';
13
+ export * from './lifi-execution-guard.js';
14
+ export * from './origin-deposit.js';
15
+ export * from './providers.js';
16
+ export * from './referral.js';
17
+ export * from './route-steps.js';
18
+ export * from './routing/index.js';
19
+ export * from './settings.js';
20
+ export * from './types.js';
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ export * from './abis.js';
2
+ export * from './bridge-limits.js';
3
+ export * from './chain-info.js';
4
+ export * from './chains.js';
5
+ export * from './config.js';
6
+ export * from './consolidated-quote.js';
7
+ export * from './relay-quote.js';
8
+ export * from './relay-currencies.js';
9
+ export * from './destination-calldata.js';
10
+ export * from './ecosystems.js';
11
+ export * from './fee-type.js';
12
+ export * from './image-links.js';
13
+ export * from './lifi-execution-guard.js';
14
+ export * from './origin-deposit.js';
15
+ export * from './providers.js';
16
+ export * from './referral.js';
17
+ export * from './route-steps.js';
18
+ export * from './routing/index.js';
19
+ export * from './settings.js';
20
+ export * from './types.js';
@@ -0,0 +1,199 @@
1
+ import { type Hex } from 'viem';
2
+ /**
3
+ * Verifies a LI.FI EVM execution transaction before a wallet ever signs it.
4
+ *
5
+ * WHY THIS EXISTS. `lifiApi.quote` and `lifiApi.contractCallsQuote` are fetched
6
+ * through a configurable base URL — today `lifi.gibs.finance`, a server-side
7
+ * proxy; the interface may point at a different host in the future. Whichever
8
+ * host answers, this codebase used to sign whatever `transactionRequest` came
9
+ * back after checking only that `to` and `data` were hexadecimal strings (see
10
+ * `lifiEvmDeposit` in `consolidated-quote.ts`). A COMPROMISED PROXY could
11
+ * return ANY `to`/`data`/`value` and a connected wallet would sign it,
12
+ * moving the reader's funds wherever the proxy chose.
13
+ *
14
+ * WHAT THIS MODULE PROVES INSTEAD, before signing:
15
+ *
16
+ * 1. `to` (and, when present, `estimate.approvalAddress`) is LI.FI's own
17
+ * Diamond entryway contract for the chain the transaction runs on — a
18
+ * fixed table, not something the response gets to assert about itself.
19
+ * See {@link lifiDiamondAddressByChainId}.
20
+ * 2. The calldata's selector is one of a small, explicitly verified set of
21
+ * LI.FI facet functions whose ABI this module carries in full. An unknown
22
+ * selector is refused rather than guessed at.
23
+ * 3. The decoded `BridgeData` and leading `SwapData` entry agree with what
24
+ * THIS APPLICATION asked for — not with other fields of the same,
25
+ * potentially compromised, response. See {@link LifiExecutionExpectation}.
26
+ * 4. `transactionRequest.value` equals exactly the native currency the
27
+ * decoded calldata implies (the amount being deposited, when that amount
28
+ * is native, plus any protocol messaging fee the tool's own data
29
+ * declares) — never more, never less.
30
+ *
31
+ * WHERE THE FIELD SEMANTICS CAME FROM. Every fact this module relies on —
32
+ * which struct field means what, and how the three verified facet functions
33
+ * actually populate `BridgeData` and `SwapData` — was read from REAL
34
+ * responses captured live from `https://li.quest`, decoded with this exact
35
+ * machinery, and cross-checked against the deployed contracts' Solidity
36
+ * source (`lifinance/contracts`, commit `025989955bb373739737ee78ddff01620638ae3b`,
37
+ * 2026-09-23). Two assumptions a first reading of LI.FI's own field
38
+ * descriptions would suggest turned out to be wrong, and are recorded here so
39
+ * nobody reintroduces them:
40
+ *
41
+ * - `BridgeData.receiver` is NOT "the final recipient" in general. For the
42
+ * contract-calls endpoint (`hasDestinationCall: true`) it decoded to the
43
+ * REQUEST'S `toFallbackAddress` — the address that receives the bridged
44
+ * asset if the destination call reverts — not the destination call's own
45
+ * contract or the reader's recipient. Only for the plain endpoint
46
+ * (`hasDestinationCall: false`) does it equal the recipient (`toAddress`).
47
+ * Verified against three independently captured quotes; see the fixtures
48
+ * this module's test file reads.
49
+ * - `BridgeData.minAmount` is NOT the destination-side guaranteed amount for
50
+ * any of the three verified tools. It is the amount of `sendingAssetId`
51
+ * pulled from the depositor on the ORIGIN chain (`LibAsset.depositAsset`
52
+ * in every facet's Solidity), reassigned at runtime to the real swap
53
+ * output when `hasSourceSwaps` is true — a fact this module's calldata
54
+ * never carries. The genuine destination-side guarantee lives in each
55
+ * tool's own trailing struct (`AcrossV4Data.outputAmount`,
56
+ * `StargateData.sendParams.minAmountLD`) and is read from there instead.
57
+ * LayerSwap's own struct carries no on-chain amount field at all — its
58
+ * guarantee is an off-chain, backend-signed attestation — so this module
59
+ * cannot verify a destination minimum for it and refuses to try; see
60
+ * {@link DecodedLifiFacetCall.destinationMinimum}.
61
+ *
62
+ * SCOPE, DELIBERATELY NARROW. Only the exact facet-function shapes seen in a
63
+ * REAL captured LI.FI response are decoded; every other selector refuses.
64
+ * Adding a new tool means capturing a fixture for it first — see
65
+ * `packages/bridge-sdk/src/__fixtures__/lifi/README.md` — and extending
66
+ * {@link lifiFacetDecoders} from that fixture, never from documentation
67
+ * alone (per the hand-built-quotes-hide-parser-gaps lesson: a decoder written
68
+ * from a guess passes its own hand-built test and nothing else).
69
+ */
70
+ /**
71
+ * Every reason this module can refuse a LI.FI execution transaction.
72
+ *
73
+ * Each maps to one property of the response this module distrusts by
74
+ * default: `unknown-chain` and `router-mismatch` distrust `to`;
75
+ * `approval-address-mismatch` distrusts `estimate.approvalAddress`;
76
+ * `unknown-selector` and `calldata-undecodable` distrust `data`'s shape;
77
+ * `receiver-mismatch`, `destination-chain-mismatch`, `sending-asset-mismatch`,
78
+ * `destination-call-flag-mismatch` and `minimum-amount-below-requested`
79
+ * distrust `data`'s DECODED fields against what this application asked for;
80
+ * `native-value-mismatch` distrusts `value`. `missing-request-context` is
81
+ * different in kind: it means the CALLER never supplied what this
82
+ * application expected, so none of the above could even be checked — see
83
+ * `parseLifiContractCallsQuote` and `parseLifiQuote` in `consolidated-quote.ts`.
84
+ */
85
+ export type LifiExecutionRefusalReason = 'unknown-chain' | 'router-mismatch' | 'approval-address-mismatch' | 'unknown-selector' | 'calldata-undecodable' | 'receiver-mismatch' | 'destination-chain-mismatch' | 'sending-asset-mismatch' | 'destination-call-flag-mismatch' | 'minimum-amount-below-requested' | 'native-value-mismatch' | 'missing-request-context';
86
+ /** Why a LI.FI execution transaction was refused before signing. */
87
+ export type LifiExecutionRefusal = {
88
+ readonly reason: LifiExecutionRefusalReason;
89
+ /** A short, specific explanation naming the values that disagreed. */
90
+ readonly detail: string;
91
+ };
92
+ /**
93
+ * Thrown by {@link verifyLifiEvmExecution} instead of returning a deposit a
94
+ * wallet could sign.
95
+ *
96
+ * NAMED AND TYPED SO A REFUSAL IS NEVER A SILENT DROP. Every caller that
97
+ * catches this can read `refusal.reason` and show, or log, exactly which
98
+ * check failed — the same discipline `@gibs/quotes`'s `ProviderQuoteError`
99
+ * applies to a provider declining a quote, applied here to a provider's
100
+ * ANSWER disagreeing with itself.
101
+ */
102
+ export declare class LifiExecutionRefusedError extends Error {
103
+ readonly refusal: LifiExecutionRefusal;
104
+ constructor(refusal: LifiExecutionRefusal);
105
+ }
106
+ /**
107
+ * LI.FI's Diamond entryway contract address, by chain id.
108
+ *
109
+ * SOURCE. `lifinance/contracts` (https://github.com/lifinance/contracts),
110
+ * commit `025989955bb373739737ee78ddff01620638ae3b` (2026-09-23): the
111
+ * `LiFiDiamond` address in `deployments/<network>.json`, matched to its
112
+ * chain id in `config/networks.json`, for every network whose `status` is
113
+ * `"active"` and `"type"` is `"mainnet"`. LI.FI's own documentation
114
+ * (https://docs.li.fi/introduction/lifi-architecture/smart-contract-addresses)
115
+ * states the address is `0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE` "on most
116
+ * supported networks" but differs on some — confirmed here directly against
117
+ * the deployment records rather than assumed: 39 of the 65 active mainnet
118
+ * networks use a DIFFERENT address, almost all of them newer or lower-volume
119
+ * chains (0G, Abstract, ApeChain, Arbitrum Nova, Berachain, Flare, zkSync
120
+ * Era, and more).
121
+ *
122
+ * DELIBERATELY A FIXED, BAKED-IN TABLE, NEVER A LIVE LOOKUP. LI.FI's own
123
+ * `/v1/chains` endpoint carries a `diamondAddress` per chain, and this
124
+ * codebase already fetches it for other purposes — but that endpoint is
125
+ * reached through the SAME configurable, potentially-compromised host this
126
+ * module exists to distrust. Trusting it here would make the whole guard
127
+ * circular: a compromised proxy could simply report its own malicious
128
+ * address as the "correct" one. This table is real code, reviewed and
129
+ * shipped with the application, and can only change through a new release.
130
+ *
131
+ * UNKNOWN CHAIN, UNKNOWN ADDRESS. A chain id absent from this table refuses
132
+ * rather than falling back to the common address — LI.FI adds networks
133
+ * continuously, and assuming a newly-added chain shares the common address
134
+ * would be exactly the kind of guess this module exists to avoid making.
135
+ */
136
+ export declare const lifiDiamondAddressByChainId: ReadonlyMap<number, Hex>;
137
+ /** LI.FI's `ILiFi.BridgeData` struct — identical across every facet function. */
138
+ export type LifiBridgeData = {
139
+ readonly transactionId: Hex;
140
+ readonly bridge: string;
141
+ readonly integrator: string;
142
+ readonly referrer: Hex;
143
+ readonly sendingAssetId: Hex;
144
+ readonly receiver: Hex;
145
+ readonly minAmount: bigint;
146
+ readonly destinationChainId: bigint;
147
+ readonly hasSourceSwaps: boolean;
148
+ readonly hasDestinationCall: boolean;
149
+ };
150
+ /**
151
+ * What THIS APPLICATION asked LI.FI for, independent of anything the
152
+ * response itself claims — the only thing a decoded transaction is allowed
153
+ * to be checked against.
154
+ */
155
+ export type LifiExecutionExpectation = {
156
+ /**
157
+ * Where the bridged asset lands if the route needs no destination call
158
+ * (the plain endpoint's recipient), or where it lands if the destination
159
+ * call reverts (the contract-calls endpoint's fallback address) — see the
160
+ * `BridgeData.receiver` note at the top of this file for why these two are
161
+ * NOT the same field despite the shared name.
162
+ */
163
+ readonly receiver: Hex;
164
+ /** The chain the entry call (or the plain delivery) must land on. */
165
+ readonly destinationChainId: number;
166
+ /** The token this application is paying with on the origin chain. */
167
+ readonly sendingAssetId: Hex;
168
+ /** Whether this application attached an omnibridge entry call. */
169
+ readonly hasDestinationCall: boolean;
170
+ /**
171
+ * The guaranteed minimum this application asked LI.FI to deliver, or
172
+ * `null` for the plain (forward-solved) endpoint, which names no such
173
+ * minimum — the delivered amount is read back from the response instead
174
+ * of constrained by the request. See `ConsolidatedQuote.toAmount`.
175
+ */
176
+ readonly minimumAmount: bigint | null;
177
+ };
178
+ /** The transaction fields {@link verifyLifiEvmExecution} reads off the raw response. */
179
+ export type LifiExecutionTransactionRequest = {
180
+ readonly to: Hex;
181
+ readonly data: Hex;
182
+ readonly value: bigint;
183
+ readonly chainId: number;
184
+ };
185
+ /**
186
+ * Verifies a LI.FI EVM execution transaction against what this application
187
+ * asked for, throwing {@link LifiExecutionRefusedError} on any disagreement.
188
+ * Returns normally — carrying nothing, since the caller already holds the
189
+ * transaction it validated — when every check passes.
190
+ *
191
+ * See this module's top-of-file doc comment for what is checked and why.
192
+ *
193
+ * @param transactionRequest - the parsed `to`/`data`/`value`/`chainId` this
194
+ * application is about to hand to a wallet
195
+ * @param approvalAddress - `estimate.approvalAddress` from the same
196
+ * response, or `null` when the route needs no token approval
197
+ * @param expectation - what this application actually asked for
198
+ */
199
+ export declare const verifyLifiEvmExecution: (transactionRequest: LifiExecutionTransactionRequest, approvalAddress: Hex | null, expectation: LifiExecutionExpectation) => void;