@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
@@ -4,61 +4,16 @@ exports.buildHyperliquidAuthorizationRequest = exports.buildHyperliquidAuthoriza
4
4
  const url_1 = require("@gibs/common/url");
5
5
  const viem_1 = require("viem");
6
6
  const relay_quote_js_1 = require("./relay-quote.js");
7
- /**
8
- * Executing a Hyperliquid deposit, as pure data.
9
- *
10
- * Hyperliquid is the one origin whose deposit is never broadcast to a chain.
11
- * The user signs a typed-data ACTION and that signed action is posted to
12
- * Hyperliquid's own exchange API; Relay then observes the transfer and fills the
13
- * route. Two details make this impossible to derive from the quote alone, and
14
- * both are encoded here rather than rediscovered at a call site:
15
- *
16
- * 1. Relay's quote supplies `eip712Types`, `eip712PrimaryType` and the action,
17
- * but NOT the signing domain. The domain is fixed by Hyperliquid and is
18
- * reconstructed by {@link buildHyperliquidTypedData}.
19
- * 2. Hyperliquid wants the signature split into `r`/`s`/`v` components, not the
20
- * concatenated hex string a wallet returns.
21
- *
22
- * Kept free of transport so it is fully testable: nothing here signs, fetches,
23
- * or reads a clock. The caller supplies the signature and performs the request.
24
- *
25
- * The shape mirrors Relay's own client, which is the only reference
26
- * implementation of this exchange — their public documentation covers the
27
- * generic `signature` step but not this action-bearing `transaction` step.
28
- */
29
- /** Where a signed Hyperliquid action is submitted. Hyperliquid's API, not Relay's. */
30
7
  exports.hyperliquidExchangeUrl = 'https://api.hyperliquid.xyz/exchange';
31
- /** The signing domain Hyperliquid requires. Fixed; never supplied by the quote. */
32
8
  exports.hyperliquidDomainName = 'HyperliquidSignTransaction';
33
- /** The signing domain's version. Fixed alongside {@link hyperliquidDomainName}. */
34
9
  exports.hyperliquidDomainVersion = '1';
35
- /**
36
- * The domain's `verifyingContract`. Hyperliquid actions are verified off-chain,
37
- * so no contract is involved and the field is the all-zero address.
38
- */
39
10
  exports.hyperliquidVerifyingContract = '0x0000000000000000000000000000000000000000';
40
- /** The standard typed-data domain type, which the action's type table must include. */
41
11
  const eip712DomainType = [
42
12
  { name: 'name', type: 'string' },
43
13
  { name: 'version', type: 'string' },
44
14
  { name: 'chainId', type: 'uint256' },
45
15
  { name: 'verifyingContract', type: 'address' },
46
16
  ];
47
- /**
48
- * Builds the typed-data payload for a Hyperliquid deposit.
49
- *
50
- * The message is the action's parameters plus the action `type` and a
51
- * `signatureChainId`; the latter is the signing chain in hex and MUST agree
52
- * with `domain.chainId`, because Hyperliquid recovers the signer using both.
53
- * They are derived from the single `signatureChainId` argument so they cannot
54
- * disagree.
55
- *
56
- * @param deposit - the parsed Hyperliquid origin deposit
57
- * @param options.signatureChainId - the chain id the connected wallet signs
58
- * under. Not the Relay origin chain id: it identifies the signing domain, and
59
- * Relay's own client uses the wallet's active chain here.
60
- * @returns the payload to sign, whose `message` doubles as the submitted action
61
- */
62
17
  const buildHyperliquidTypedData = (deposit, { signatureChainId }) => ({
63
18
  domain: {
64
19
  name: exports.hyperliquidDomainName,
@@ -78,47 +33,19 @@ const buildHyperliquidTypedData = (deposit, { signatureChainId }) => ({
78
33
  },
79
34
  });
80
35
  exports.buildHyperliquidTypedData = buildHyperliquidTypedData;
81
- /**
82
- * Builds the exchange request for an action the user has signed.
83
- *
84
- * The nonce is read back out of the signed message rather than passed in: it is
85
- * covered by the signature, so any independently supplied value could disagree
86
- * with what was signed and be rejected.
87
- *
88
- * @param options.typedData - the payload that was signed
89
- * @param options.signature - the wallet's signature over it
90
- * @returns the request body, or null when the signed action carries no usable nonce
91
- */
92
36
  const buildHyperliquidExchangeRequest = ({ typedData, signature, }) => {
93
- // Hyperliquid names it `nonce`; the older action shapes name it `time`.
94
37
  const rawNonce = typedData.message.nonce ?? typedData.message.time;
95
38
  if (typeof rawNonce !== 'number' && typeof rawNonce !== 'bigint') {
96
39
  return null;
97
40
  }
98
41
  const { r, s, v, yParity } = (0, viem_1.parseSignature)(signature);
99
42
  return {
100
- // The exchange wants the 27/28 form. A signature whose final byte is the
101
- // PARITY form (0 or 1) — which some hardware wallets and smart-account flows
102
- // produce — parses with `v` absent and the parity carried separately, so
103
- // reading `v` alone and defaulting would send recovery value 0: not a value
104
- // the exchange accepts, and the deposit dies for those wallets only. The
105
- // parity is the same fact in the other encoding, so shift it rather than
106
- // guess.
107
43
  signature: { r, s, v: v === undefined ? yParity + 27 : Number(v) },
108
44
  nonce: Number(rawNonce),
109
45
  action: typedData.message,
110
46
  };
111
47
  };
112
48
  exports.buildHyperliquidExchangeRequest = buildHyperliquidExchangeRequest;
113
- /**
114
- * Whether an exchange response reports success. Hyperliquid answers with HTTP
115
- * 200 even for a rejected action, so the body's own status is the only reliable
116
- * signal — treating the status code as the outcome would report a failed
117
- * transfer as a completed one.
118
- *
119
- * @param payload - the parsed response body
120
- * @returns true only when the body explicitly reports success
121
- */
122
49
  const isHyperliquidExchangeSuccess = (payload) => {
123
50
  if (typeof payload !== 'object' || payload === null) {
124
51
  return false;
@@ -126,21 +53,6 @@ const isHyperliquidExchangeSuccess = (payload) => {
126
53
  return payload.status === 'ok';
127
54
  };
128
55
  exports.isHyperliquidExchangeSuccess = isHyperliquidExchangeSuccess;
129
- /**
130
- * The typed-data payload for the authorization that must be completed BEFORE
131
- * the action is submitted.
132
- *
133
- * Relay builds the authorization against a chain it picks when quoting, but the
134
- * signature is produced by whichever chain the wallet is actually on. Both the
135
- * domain here and `signatureChainId` in {@link buildHyperliquidAuthorizationRequest}
136
- * are therefore overridden with the active wallet chain; leaving Relay's value in
137
- * place makes the recovered signer disagree with the submitted one and the
138
- * authorization is rejected.
139
- *
140
- * @param authorization - the authorization carried by the deposit
141
- * @param options.signatureChainId - the chain id the connected wallet signs under
142
- * @returns the payload to sign
143
- */
144
56
  const buildHyperliquidAuthorizationTypedData = (authorization, { signatureChainId }) => ({
145
57
  domain: {
146
58
  ...authorization.sign.domain,
@@ -151,16 +63,6 @@ const buildHyperliquidAuthorizationTypedData = (authorization, { signatureChainI
151
63
  message: authorization.sign.value,
152
64
  });
153
65
  exports.buildHyperliquidAuthorizationTypedData = buildHyperliquidAuthorizationTypedData;
154
- /**
155
- * Builds the authorization submission for a signed authorization.
156
- *
157
- * @param options.authorization - the authorization that was signed
158
- * @param options.signature - the wallet's signature over its typed data
159
- * @param options.signatureChainId - the chain id the wallet signed under, which
160
- * replaces the value Relay quoted so the body agrees with the signature
161
- * @param options.baseUrl - Relay's API root; the step's endpoint is relative
162
- * @returns the request to perform, or null when the endpoint is not a usable path
163
- */
164
66
  const buildHyperliquidAuthorizationRequest = ({ authorization, signature, signatureChainId, baseUrl = relay_quote_js_1.relayApiBaseUrl, }) => {
165
67
  const { endpoint, method, body } = authorization.post;
166
68
  if (!endpoint.startsWith('/')) {
@@ -5,101 +5,30 @@ const viem_1 = require("viem");
5
5
  const chain_names_js_1 = require("./chain-names.js");
6
6
  const ecosystems_js_1 = require("./ecosystems.js");
7
7
  let imageRoot = 'https://gib.show';
8
- /**
9
- * Sets the image root for the bridge
10
- * @param root - the root
11
- */
12
8
  const setImageRoot = (root) => {
13
9
  imageRoot = root;
14
10
  };
15
11
  exports.setImageRoot = setImageRoot;
16
- /**
17
- * Returns the image root for the bridge
18
- * @returns the image root
19
- */
20
12
  const getImageRoot = () => imageRoot;
21
13
  exports.getImageRoot = getImageRoot;
22
- /**
23
- * Returns the list image for the given path
24
- * @param path - the path
25
- * @returns the list image
26
- */
27
14
  const list = (path) => {
28
15
  return `${imageRoot}/list${path}`;
29
16
  };
30
17
  exports.list = list;
31
- /**
32
- * Returns the network image for the given chain id
33
- * @param chainId - the chain id
34
- * @returns the network image
35
- */
36
18
  const network = (chainId) => `${imageRoot}/image/${Number(chainId)}`;
37
19
  exports.network = network;
38
- /**
39
- * gib.show's own key for a chain this package can only name by a LOCAL,
40
- * INVENTED identifier — a pay-by-hand origin (see `depositAddressChainIds`)
41
- * rather than a real chain id gib.show's numeric endpoint recognizes.
42
- * `network(chainId)` 404s for one of these, and the browser draws that 404 as
43
- * a broken image on every chain badge and route mark drawn through it.
44
- *
45
- * Every route producer that draws a chain badge for a token needs this, not
46
- * only the deposit-address ones: a route can START on a deposit-address chain
47
- * and cross through ordinary Ethereum-Virtual-Machine chains after, so the
48
- * predicate has to run on every chain id a route touches, not only the one
49
- * the reader picked. Kept beside `network` rather than in the client that also
50
- * resolves Relay's pseudo chains (`@gibs/bridge-client/image`'s
51
- * `chainLogoUrl`) because that client sits ABOVE this package — it imports
52
- * FROM `bridge-sdk` — so this package importing back from it would be a
53
- * cycle. `chainLogoUrl` still adds a Relay-icon fallback for chains gib.show
54
- * does not carry at ALL (Eclipse, Hyperliquid); this table is only the
55
- * chains gib.show DOES carry, under a key other than their numeric id.
56
- *
57
- * EXPORTED, and this is the ONLY place a pay-by-hand chain's gib.show key is
58
- * declared. `@gibs/bridge-client`'s `image.ts` used to hard-code its own copy
59
- * of the same `zcash → 'bip122-133'` entry; it now spreads this map into its
60
- * own icon table instead, because the dependency runs one way — the client
61
- * already imports from this package — so there was never a cycle stopping it.
62
- */
63
20
  exports.pseudoChainGibShowIdentifierByChain = {
64
21
  zcash: 'bip122-133',
65
22
  };
66
- /** {@link pseudoChainGibShowIdentifierByChain}, keyed by chain id for lookup. */
67
23
  exports.pseudoChainGibShowIdentifier = Object.fromEntries(Object.keys(chain_names_js_1.depositAddressChainIds).map((chain) => [
68
24
  chain_names_js_1.depositAddressChainIds[chain],
69
25
  exports.pseudoChainGibShowIdentifierByChain[chain],
70
26
  ]));
71
- /**
72
- * The network image for a chain id, honouring a pseudo chain's own gib.show
73
- * key when its numeric id is not one gib.show's `/image/<id>` endpoint knows.
74
- *
75
- * @param chainId - the chain id, a deposit-address chain's local identifier included
76
- * @returns a working network/chain-badge image url
77
- */
78
27
  const networkOrPseudo = (chainId) => {
79
28
  const identifier = exports.pseudoChainGibShowIdentifier[chainId];
80
29
  return identifier !== undefined ? `${imageRoot}/image/${identifier}` : (0, exports.network)(chainId);
81
30
  };
82
31
  exports.networkOrPseudo = networkOrPseudo;
83
- /**
84
- * Returns the image url for the given token info.
85
- *
86
- * The gas token is asked for by BOTH of its keys, because the service keys it
87
- * two ways and each chain carries only one of them. `<chain>/<zero address>` is
88
- * a dedicated picture — Ethereum's ether diamond, PulseChain's mark — and
89
- * Binance Smart Chain has none, so asking for it there returns a 404 the browser
90
- * draws as a broken image. The empty-address form `<chain>/` is the chain's own
91
- * mark, which every chain has.
92
- *
93
- * The order is NOT interchangeable. The service serves the first source that
94
- * resolves, so a chain with a dedicated picture keeps it; reversed, Ethereum
95
- * would show the network logo where the ether logo belongs (the two are
96
- * genuinely different files). The pair is for the gas token alone: pairing an
97
- * ordinary contract address with the chain mark would hide a missing token logo
98
- * behind the network's, showing the wrong token rather than an honest fallback.
99
- *
100
- * @param t - the token info
101
- * @returns the image url
102
- */
103
32
  const image = (t) => {
104
33
  if (t.logoURI)
105
34
  return t.logoURI;
@@ -109,45 +38,8 @@ const image = (t) => {
109
38
  return `${(0, exports.network)(t.chainId)}/${(0, viem_1.getAddress)(t.address)}`;
110
39
  };
111
40
  exports.image = image;
112
- /**
113
- * Whether `address` is a real Ethereum-Virtual-Machine address {@link image}
114
- * can ask the service about — the zero address included, since that is
115
- * {@link isNativeAsset}'s own case and {@link image} handles it without
116
- * `getAddress` ever running.
117
- *
118
- * @param address - the address to check
119
- * @returns true when `getAddress` can checksum it without throwing
120
- */
121
41
  const isResolvableEvmAddress = (address) => /^0x[0-9a-fA-F]{40}$/.test(address);
122
- /**
123
- * {@link image}, but falling back to the token's own CHAIN mark rather than
124
- * throwing or asking the service for a picture that was never going to exist,
125
- * when the token carries no address a picture can be resolved from yet.
126
- *
127
- * WHY THIS EXISTS SEPARATELY FROM `image`. A route producer can reach the
128
- * moment it draws a DELIVERED token's picture before that token's exact
129
- * on-chain address is known — a not-yet-bridged token's `assetOutAddress` is
130
- * documented to arrive `null` (see the repository's own "Not-Yet-Bridged
131
- * Tokens" gotcha), and a deferred crossing's landing token is exactly this
132
- * case: the reader has not yet signed the leg that would settle it. `image`
133
- * either throws (`getAddress` refuses a malformed or empty string) or, for a
134
- * caller that swallows the throw, silently draws nothing — the same "blank
135
- * disc" defect the carrier marks were fixed for, one token lower. The chain's
136
- * own mark is a real, recognisable picture that is honest about what is
137
- * known: THIS chain, a token not yet resolved on it — the same trade
138
- * `trackerView.ts`'s `depositAddressChainLogoFallback` already makes for a
139
- * pay-by-hand ORIGIN with no address of its own.
140
- *
141
- * @param t - the token to draw
142
- * @returns the token's own picture, or its chain's mark when the token's
143
- * address cannot be resolved into one
144
- */
145
42
  const tokenImageOrChainFallback = (t) => isResolvableEvmAddress(t.address) ? (0, exports.image)(t) : (0, exports.networkOrPseudo)(t.chainId);
146
43
  exports.tokenImageOrChainFallback = tokenImageOrChainFallback;
147
- /**
148
- * Returns a url that will lookup all sources for the given array
149
- * @param sources - the sources
150
- * @returns the images
151
- */
152
44
  const images = (sources) => `${imageRoot}/image/?${sources.map((s) => `i=${s}`).join('&')}`;
153
45
  exports.images = images;
@@ -2,16 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.verifyLifiEvmExecution = exports.lifiDiamondAddressByChainId = exports.LifiExecutionRefusedError = void 0;
4
4
  const viem_1 = require("viem");
5
- /**
6
- * Thrown by {@link verifyLifiEvmExecution} instead of returning a deposit a
7
- * wallet could sign.
8
- *
9
- * NAMED AND TYPED SO A REFUSAL IS NEVER A SILENT DROP. Every caller that
10
- * catches this can read `refusal.reason` and show, or log, exactly which
11
- * check failed — the same discipline `@gibs/quotes`'s `ProviderQuoteError`
12
- * applies to a provider declining a quote, applied here to a provider's
13
- * ANSWER disagreeing with itself.
14
- */
15
5
  class LifiExecutionRefusedError extends Error {
16
6
  refusal;
17
7
  constructor(refusal) {
@@ -24,102 +14,72 @@ exports.LifiExecutionRefusedError = LifiExecutionRefusedError;
24
14
  const refuse = (reason, detail) => {
25
15
  throw new LifiExecutionRefusedError({ reason, detail });
26
16
  };
27
- /**
28
- * LI.FI's Diamond entryway contract address, by chain id.
29
- *
30
- * SOURCE. `lifinance/contracts` (https://github.com/lifinance/contracts),
31
- * commit `025989955bb373739737ee78ddff01620638ae3b` (2026-09-23): the
32
- * `LiFiDiamond` address in `deployments/<network>.json`, matched to its
33
- * chain id in `config/networks.json`, for every network whose `status` is
34
- * `"active"` and `"type"` is `"mainnet"`. LI.FI's own documentation
35
- * (https://docs.li.fi/introduction/lifi-architecture/smart-contract-addresses)
36
- * states the address is `0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE` "on most
37
- * supported networks" but differs on some — confirmed here directly against
38
- * the deployment records rather than assumed: 39 of the 65 active mainnet
39
- * networks use a DIFFERENT address, almost all of them newer or lower-volume
40
- * chains (0G, Abstract, ApeChain, Arbitrum Nova, Berachain, Flare, zkSync
41
- * Era, and more).
42
- *
43
- * DELIBERATELY A FIXED, BAKED-IN TABLE, NEVER A LIVE LOOKUP. LI.FI's own
44
- * `/v1/chains` endpoint carries a `diamondAddress` per chain, and this
45
- * codebase already fetches it for other purposes — but that endpoint is
46
- * reached through the SAME configurable, potentially-compromised host this
47
- * module exists to distrust. Trusting it here would make the whole guard
48
- * circular: a compromised proxy could simply report its own malicious
49
- * address as the "correct" one. This table is real code, reviewed and
50
- * shipped with the application, and can only change through a new release.
51
- *
52
- * UNKNOWN CHAIN, UNKNOWN ADDRESS. A chain id absent from this table refuses
53
- * rather than falling back to the common address — LI.FI adds networks
54
- * continuously, and assuming a newly-added chain shares the common address
55
- * would be exactly the kind of guess this module exists to avoid making.
56
- */
57
17
  exports.lifiDiamondAddressByChainId = new Map([
58
- [1, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // mainnet
59
- [10, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // optimism
60
- [14, '0x198FC70Dfe05E755C81e54bd67Bff3F729344B9b'], // flare
61
- [25, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // cronos
62
- [30, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // rootstock
63
- [40, '0xa7cd44521903C65915648385E3FE881E49171582'], // telos
64
- [50, '0x055d4612Ec74aD799C6cB4dF72C0Ab8dbDBCBAfa'], // xdc
65
- [56, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // bsc
66
- [88, '0x198FC70Dfe05E755C81e54bd67Bff3F729344B9b'], // viction
67
- [100, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // gnosis
68
- [122, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // fuse
69
- [130, '0x864b314D4C5a0399368609581d3E8933a63b9232'], // unichain
70
- [137, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // polygon
71
- [143, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'], // monad
72
- [146, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // sonic
73
- [196, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // xlayer
74
- [204, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // opbnb
75
- [232, '0xF3B20515d9B193531c48E47c18aF16d1e5d28f9a'], // lens
76
- [252, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // fraxtal
77
- [288, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // boba
78
- [324, '0x341e94069f53234fE6DabeF707aD424830525715'], // zksync
79
- [480, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // worldchain
80
- [747, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'], // flow
81
- [988, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'], // stable
82
- [1088, '0x24ca98fB6972F5eE05f0dB00595c7f68D9FaFd68'], // metis
83
- [1135, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // lisk
84
- [1329, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // sei
85
- [1480, '0x198FC70Dfe05E755C81e54bd67Bff3F729344B9b'], // vana
86
- [1625, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // gravity
87
- [1672, '0xFf70F4A1d11995621854F3692acF286d8aCd04b2'], // pharos
88
- [1776, '0xeCeC3970Ca674278DA8D9B1c484ACaF6B20181F5'], // injective
89
- [1868, '0x864b314D4C5a0399368609581d3E8933a63b9232'], // soneium
90
- [2020, '0x452Cf1B8597E6319Cd21abd847312bF17E26d8d1'], // ronin
91
- [2741, '0x4f8C9056bb8A3616693a76922FA35d53C056E5b3'], // abstract
92
- [2818, '0xF7aB42D00D2399f8A4Fba2F15466Be40709fe307'], // morph
93
- [4217, '0x2cAcAE8e22418E65dcf7651c67aEbe6288EB8243'], // tempo
94
- [4326, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'], // megaeth
95
- [4663, '0xB477751B76CF82d00a686A1232f5fCD772414Af3'], // robinhood
96
- [5000, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // mantle
97
- [5031, '0x0bc413CAe89C5b3Ba3AA87FB98dCA23425E1828f'], // somnia
98
- [5042, '0xA4072583658Fae592A3506A42431cb6316a8d40b'], // arc
99
- [5734951, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'], // jovay
100
- [6900, '0x926c22Dc753E543Cf9CaB75CeEB46ecf865d006a'], // nibiru
101
- [8217, '0x1255d17c1BC2f764d087536410879F2d0D8772fD'], // kaia
102
- [8453, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // base
103
- [9745, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'], // plasma
104
- [13371, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // immutablezkevm
105
- [16661, '0x213A83c67E1Fc0334eF684571ABCB820708A6536'], // 0g
106
- [33139, '0x2dea447e7dc6cd2f10b31bF10dCB30F87E838417'], // apechain
107
- [34443, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // mode
108
- [42161, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // arbitrum
109
- [42170, '0xFf70F4A1d11995621854F3692acF286d8aCd04b2'], // arbitrumnova
110
- [42220, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // celo
111
- [42793, '0x977474593c982cFa8b197cAE302e6d01f789435b'], // etherlink
112
- [43111, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'], // hemi
113
- [43114, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // avalanche
114
- [57073, '0x864b314D4C5a0399368609581d3E8933a63b9232'], // ink
115
- [59144, '0xDE1E598b81620773454588B85D6b5D4eEC32573e'], // linea
116
- [60808, '0x452Cf1B8597E6319Cd21abd847312bF17E26d8d1'], // bob
117
- [80094, '0xf909c4Ae16622898b885B89d7F839E0244851c66'], // berachain
118
- [81457, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // blast
119
- [98866, '0x6f5C8Bb0C5Fe4ECeAC40EE1C238EaB6bbb29761c'], // plume
120
- [534352, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'], // scroll
121
- [747474, '0xC59fe32C9549e3E8B5dCcdAbC45BD287Bd5bA2bc'], // katana
122
- [999, '0x0a0758d937d1059c356D4714e57F5df0239bce1A'], // hyperevm
18
+ [1, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
19
+ [10, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
20
+ [14, '0x198FC70Dfe05E755C81e54bd67Bff3F729344B9b'],
21
+ [25, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
22
+ [30, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
23
+ [40, '0xa7cd44521903C65915648385E3FE881E49171582'],
24
+ [50, '0x055d4612Ec74aD799C6cB4dF72C0Ab8dbDBCBAfa'],
25
+ [56, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
26
+ [88, '0x198FC70Dfe05E755C81e54bd67Bff3F729344B9b'],
27
+ [100, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
28
+ [122, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
29
+ [130, '0x864b314D4C5a0399368609581d3E8933a63b9232'],
30
+ [137, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
31
+ [143, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'],
32
+ [146, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
33
+ [196, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
34
+ [204, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
35
+ [232, '0xF3B20515d9B193531c48E47c18aF16d1e5d28f9a'],
36
+ [252, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
37
+ [288, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
38
+ [324, '0x341e94069f53234fE6DabeF707aD424830525715'],
39
+ [480, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
40
+ [747, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'],
41
+ [988, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'],
42
+ [1088, '0x24ca98fB6972F5eE05f0dB00595c7f68D9FaFd68'],
43
+ [1135, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
44
+ [1329, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
45
+ [1480, '0x198FC70Dfe05E755C81e54bd67Bff3F729344B9b'],
46
+ [1625, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
47
+ [1672, '0xFf70F4A1d11995621854F3692acF286d8aCd04b2'],
48
+ [1776, '0xeCeC3970Ca674278DA8D9B1c484ACaF6B20181F5'],
49
+ [1868, '0x864b314D4C5a0399368609581d3E8933a63b9232'],
50
+ [2020, '0x452Cf1B8597E6319Cd21abd847312bF17E26d8d1'],
51
+ [2741, '0x4f8C9056bb8A3616693a76922FA35d53C056E5b3'],
52
+ [2818, '0xF7aB42D00D2399f8A4Fba2F15466Be40709fe307'],
53
+ [4217, '0x2cAcAE8e22418E65dcf7651c67aEbe6288EB8243'],
54
+ [4326, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'],
55
+ [4663, '0xB477751B76CF82d00a686A1232f5fCD772414Af3'],
56
+ [5000, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
57
+ [5031, '0x0bc413CAe89C5b3Ba3AA87FB98dCA23425E1828f'],
58
+ [5042, '0xA4072583658Fae592A3506A42431cb6316a8d40b'],
59
+ [5734951, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'],
60
+ [6900, '0x926c22Dc753E543Cf9CaB75CeEB46ecf865d006a'],
61
+ [8217, '0x1255d17c1BC2f764d087536410879F2d0D8772fD'],
62
+ [8453, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
63
+ [9745, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'],
64
+ [13371, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
65
+ [16661, '0x213A83c67E1Fc0334eF684571ABCB820708A6536'],
66
+ [33139, '0x2dea447e7dc6cd2f10b31bF10dCB30F87E838417'],
67
+ [34443, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
68
+ [42161, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
69
+ [42170, '0xFf70F4A1d11995621854F3692acF286d8aCd04b2'],
70
+ [42220, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
71
+ [42793, '0x977474593c982cFa8b197cAE302e6d01f789435b'],
72
+ [43111, '0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37'],
73
+ [43114, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
74
+ [57073, '0x864b314D4C5a0399368609581d3E8933a63b9232'],
75
+ [59144, '0xDE1E598b81620773454588B85D6b5D4eEC32573e'],
76
+ [60808, '0x452Cf1B8597E6319Cd21abd847312bF17E26d8d1'],
77
+ [80094, '0xf909c4Ae16622898b885B89d7F839E0244851c66'],
78
+ [81457, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
79
+ [98866, '0x6f5C8Bb0C5Fe4ECeAC40EE1C238EaB6bbb29761c'],
80
+ [534352, '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE'],
81
+ [747474, '0xC59fe32C9549e3E8B5dCcdAbC45BD287Bd5bA2bc'],
82
+ [999, '0x0a0758d937d1059c356D4714e57F5df0239bce1A'],
123
83
  ]);
124
84
  const bridgeDataAbiType = {
125
85
  type: 'tuple',
@@ -148,32 +108,14 @@ const swapDataArrayAbiType = {
148
108
  { name: 'requiresDeposit', type: 'bool' },
149
109
  ],
150
110
  };
151
- /** Decodes `BridgeData` and the leading `SwapData` entry, shared by every verified decoder. */
152
111
  const decodeBridgeDataAndLeadingSwap = (encodedTail) => {
153
112
  const [bridgeData, swapData] = (0, viem_1.decodeAbiParameters)([bridgeDataAbiType, swapDataArrayAbiType], encodedTail);
154
- // EVERY VERIFIED SELECTOR IS A `swapAndStartBridgeTokensViaX` FUNCTION,
155
- // whose `containsSourceSwaps` modifier requires a non-empty `SwapData[]`
156
- // on a genuine call. An empty array here — whether from `hasSourceSwaps`
157
- // being forged false or the array itself being emptied — means this
158
- // module cannot identify what was actually pulled from the depositor, so
159
- // it refuses rather than reading past the end of the array.
160
113
  const leadingSwap = swapData[0];
161
114
  if (!bridgeData.hasSourceSwaps || leadingSwap === undefined) {
162
115
  return null;
163
116
  }
164
117
  return { bridgeData, leadingSwap };
165
118
  };
166
- /**
167
- * `swapAndStartBridgeTokensViaAcrossV4((BridgeData),(SwapData[]),(AcrossV4Data))`.
168
- *
169
- * Selector `0x1794958f`, verified against
170
- * `packages/bridge-sdk/src/__fixtures__/lifi/contract-quote-success-eth-to-base-usdc.json`
171
- * (a real `GET /v1/quote` response) — signature and struct layout read from
172
- * `lifinance/contracts/src/Facets/AcrossFacetV4.sol`. `AcrossV4Data` carries
173
- * no native-fee field, so {@link DecodedLifiFacetCall.extraNativeFee} is
174
- * always `0n`. `outputAmount` is Across's own destination-side guarantee —
175
- * confirmed equal to the SAME response's `estimate.toAmountMin`.
176
- */
177
119
  const decodeAcrossV4SwapAndStart = (data) => {
178
120
  const acrossV4DataAbiType = {
179
121
  type: 'tuple',
@@ -206,19 +148,6 @@ const decodeAcrossV4SwapAndStart = (data) => {
206
148
  destinationMinimum: acrossData.outputAmount,
207
149
  };
208
150
  };
209
- /**
210
- * `swapAndStartBridgeTokensViaLayerSwap((BridgeData),(SwapData[]),(LayerSwapData))`.
211
- *
212
- * Selector `0x4c279d6b`, verified against
213
- * `packages/bridge-sdk/src/__fixtures__/lifi/quote-plain-base-to-polygon.json`
214
- * (a real `GET /v1/quote` response) — signature and struct layout read from
215
- * `lifinance/contracts/src/Facets/LayerSwapFacet.sol`. `LayerSwapData`
216
- * carries no native-fee field ({@link DecodedLifiFacetCall.extraNativeFee}
217
- * is always `0n`) and, unlike Across or Stargate, NO destination-amount
218
- * field at all — LayerSwap's delivered amount is attested off-chain by an
219
- * EIP-712 signature over `requestId`, not provable from this calldata, so
220
- * {@link DecodedLifiFacetCall.destinationMinimum} is always `null`.
221
- */
222
151
  const decodeLayerSwapSwapAndStart = (data) => {
223
152
  const layerSwapDataAbiType = {
224
153
  type: 'tuple',
@@ -245,22 +174,6 @@ const decodeLayerSwapSwapAndStart = (data) => {
245
174
  destinationMinimum: null,
246
175
  };
247
176
  };
248
- /**
249
- * `swapAndStartBridgeTokensViaStargate((BridgeData),(SwapData[]),(StargateData))`.
250
- *
251
- * Selector `0xa6010a66`, verified against two live captures of
252
- * `POST /v1/quote/contractCalls`
253
- * (`packages/bridge-sdk/src/__fixtures__/lifi/contract-calls-native-base-to-eth-mediator.json`
254
- * and its `-erc20-` sibling) — signature and struct layout read from
255
- * `lifinance/contracts/src/Facets/StargateFacetV2.sol` and
256
- * `src/Interfaces/IStargate.sol`. `StargateData.fee.nativeFee` is a
257
- * LayerZero messaging fee that rides in `msg.value` ON TOP of any deposited
258
- * native amount — confirmed by both fixtures: `transactionRequest.value`
259
- * equalled `originAmount + fee.nativeFee` exactly (origin ETH) and
260
- * `fee.nativeFee` alone when the origin amount was an ERC20 (USD Coin, no
261
- * native component). `sendParams.minAmountLD` is Stargate's own
262
- * destination-side guarantee.
263
- */
264
177
  const decodeStargateSwapAndStart = (data) => {
265
178
  const stargateDataAbiType = {
266
179
  type: 'tuple',
@@ -305,32 +218,12 @@ const decodeStargateSwapAndStart = (data) => {
305
218
  destinationMinimum: stargateData.sendParams.minAmountLD,
306
219
  };
307
220
  };
308
- /**
309
- * Every LI.FI facet function this module can decode, keyed by its four-byte
310
- * selector. AN UNKNOWN SELECTOR IS NEVER DECODED — {@link verifyLifiEvmExecution}
311
- * refuses it outright. Extending this table means capturing a real fixture
312
- * for the new tool first; see this module's top-of-file doc comment.
313
- */
314
221
  const lifiFacetDecoders = {
315
222
  '0x1794958f': decodeAcrossV4SwapAndStart,
316
223
  '0x4c279d6b': decodeLayerSwapSwapAndStart,
317
224
  '0xa6010a66': decodeStargateSwapAndStart,
318
225
  };
319
226
  const sameAddress = (a, b) => a.toLowerCase() === b.toLowerCase();
320
- /**
321
- * Verifies a LI.FI EVM execution transaction against what this application
322
- * asked for, throwing {@link LifiExecutionRefusedError} on any disagreement.
323
- * Returns normally — carrying nothing, since the caller already holds the
324
- * transaction it validated — when every check passes.
325
- *
326
- * See this module's top-of-file doc comment for what is checked and why.
327
- *
328
- * @param transactionRequest - the parsed `to`/`data`/`value`/`chainId` this
329
- * application is about to hand to a wallet
330
- * @param approvalAddress - `estimate.approvalAddress` from the same
331
- * response, or `null` when the route needs no token approval
332
- * @param expectation - what this application actually asked for
333
- */
334
227
  const verifyLifiEvmExecution = (transactionRequest, approvalAddress, expectation) => {
335
228
  const router = exports.lifiDiamondAddressByChainId.get(transactionRequest.chainId);
336
229
  if (router === undefined) {