@gibs/bridge-sdk 1.19.0 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/abis.js +0 -2
  2. package/dist/bridge-limits.js +0 -38
  3. package/dist/chain-info.js +0 -116
  4. package/dist/chain-names.js +0 -151
  5. package/dist/chains.js +0 -198
  6. package/dist/cjs/abis.js +0 -2
  7. package/dist/cjs/bridge-limits.js +0 -38
  8. package/dist/cjs/chain-info.js +0 -116
  9. package/dist/cjs/chain-names.js +0 -151
  10. package/dist/cjs/chains.js +0 -198
  11. package/dist/cjs/claims.js +0 -60
  12. package/dist/cjs/config.js +1 -208
  13. package/dist/cjs/consolidated-quote.js +0 -465
  14. package/dist/cjs/destination-calldata.js +0 -71
  15. package/dist/cjs/ecosystems.js +0 -183
  16. package/dist/cjs/execution.js +0 -92
  17. package/dist/cjs/fee-type.js +0 -1
  18. package/dist/cjs/hyperliquid-execution.js +0 -98
  19. package/dist/cjs/image-links.js +0 -108
  20. package/dist/cjs/lifi-execution-guard.js +65 -172
  21. package/dist/cjs/near-intents-conformance.js +0 -110
  22. package/dist/cjs/near-intents-route.js +0 -149
  23. package/dist/cjs/near-intents.js +0 -562
  24. package/dist/cjs/origin-deposit.js +0 -56
  25. package/dist/cjs/pre-quote.js +0 -80
  26. package/dist/cjs/prices.js +0 -113
  27. package/dist/cjs/providers.js +0 -83
  28. package/dist/cjs/quote-fees.js +0 -80
  29. package/dist/cjs/referral.js +0 -75
  30. package/dist/cjs/relay-currencies.js +0 -31
  31. package/dist/cjs/relay-depository.js +52 -77
  32. package/dist/cjs/relay-quote.js +0 -394
  33. package/dist/cjs/route-steps.js +0 -100
  34. package/dist/cjs/routing/amounts.js +0 -83
  35. package/dist/cjs/routing/candidate-route.js +0 -73
  36. package/dist/cjs/routing/candidate.js +0 -46
  37. package/dist/cjs/routing/carrier-provider-key.js +0 -27
  38. package/dist/cjs/routing/carriers/omnibridge.js +0 -120
  39. package/dist/cjs/routing/carriers/pulsex-paths.js +0 -57
  40. package/dist/cjs/routing/carriers/pulsex-split.js +0 -92
  41. package/dist/cjs/routing/carriers/pulsex.js +0 -279
  42. package/dist/cjs/routing/carriers/wrap.js +0 -57
  43. package/dist/cjs/routing/composed-route-quality.js +0 -95
  44. package/dist/cjs/routing/entry-chain-anchor.js +0 -27
  45. package/dist/cjs/routing/format.js +0 -50
  46. package/dist/cjs/routing/index.js +0 -28
  47. package/dist/cjs/routing/producers.js +0 -854
  48. package/dist/cjs/routing/providers.js +0 -27
  49. package/dist/cjs/routing/search/compose.js +0 -56
  50. package/dist/cjs/routing/search/graph.js +0 -364
  51. package/dist/cjs/routing/search/plan-route-data.js +0 -508
  52. package/dist/cjs/routing/search/score.js +0 -344
  53. package/dist/cjs/routing/swap-transactions.js +0 -74
  54. package/dist/cjs/routing/usd-value.js +0 -12
  55. package/dist/cjs/settings.js +1 -456
  56. package/dist/cjs/swap-venues.js +0 -17
  57. package/dist/cjs/ton-connect.js +0 -82
  58. package/dist/cjs/ton-execution.js +0 -6
  59. package/dist/cjs/ton.js +0 -42
  60. package/dist/cjs/tron-execution.js +0 -145
  61. package/dist/claims.js +0 -60
  62. package/dist/config.js +1 -211
  63. package/dist/consolidated-quote.js +0 -465
  64. package/dist/destination-calldata.js +0 -71
  65. package/dist/ecosystems.js +0 -183
  66. package/dist/execution.js +0 -92
  67. package/dist/fee-type.js +0 -2
  68. package/dist/hyperliquid-execution.js +0 -98
  69. package/dist/image-links.js +0 -108
  70. package/dist/lifi-execution-guard.js +65 -172
  71. package/dist/near-intents-conformance.js +0 -110
  72. package/dist/near-intents-route.js +0 -149
  73. package/dist/near-intents.js +0 -562
  74. package/dist/origin-deposit.js +0 -56
  75. package/dist/pre-quote.js +0 -80
  76. package/dist/prices.js +0 -113
  77. package/dist/providers.js +0 -83
  78. package/dist/quote-fees.js +0 -80
  79. package/dist/referral.js +0 -75
  80. package/dist/relay-currencies.js +0 -31
  81. package/dist/relay-depository.js +52 -77
  82. package/dist/relay-quote.js +0 -394
  83. package/dist/route-steps.js +0 -100
  84. package/dist/routing/amounts.js +0 -83
  85. package/dist/routing/candidate-route.js +0 -73
  86. package/dist/routing/candidate.js +0 -46
  87. package/dist/routing/carrier-provider-key.js +0 -27
  88. package/dist/routing/carriers/omnibridge.js +0 -120
  89. package/dist/routing/carriers/pulsex-paths.js +0 -57
  90. package/dist/routing/carriers/pulsex-split.js +0 -92
  91. package/dist/routing/carriers/pulsex.js +0 -279
  92. package/dist/routing/carriers/wrap.js +0 -57
  93. package/dist/routing/composed-route-quality.js +0 -95
  94. package/dist/routing/entry-chain-anchor.js +0 -27
  95. package/dist/routing/format.js +0 -50
  96. package/dist/routing/index.js +0 -28
  97. package/dist/routing/producers.js +0 -854
  98. package/dist/routing/providers.js +0 -27
  99. package/dist/routing/search/compose.js +0 -56
  100. package/dist/routing/search/graph.js +0 -364
  101. package/dist/routing/search/plan-route-data.js +0 -508
  102. package/dist/routing/search/score.js +0 -344
  103. package/dist/routing/swap-transactions.js +0 -74
  104. package/dist/routing/usd-value.js +0 -12
  105. package/dist/settings.js +1 -456
  106. package/dist/swap-venues.js +0 -17
  107. package/dist/ton-connect.js +0 -82
  108. package/dist/ton-execution.js +0 -6
  109. package/dist/ton.js +0 -42
  110. package/dist/tron-execution.js +0 -145
  111. package/package.json +3 -3
package/dist/chains.js CHANGED
@@ -1,99 +1,8 @@
1
- // Relative, not through this package's own name. A self-reference resolves
2
- // through the `exports` map, which now points at the compiled `dist` — so the
3
- // same module would be loaded twice, once as source and once as build output,
4
- // and `Chains.PLS` from one would not be the same object as from the other.
5
1
  import { chainDisplayName } from './chain-names.js';
6
2
  import { Chains, toChain } from './config.js';
7
3
  import * as imageLinks from './image-links.js';
8
- // Chain definitions come from viem, not from a wallet-connection library. These
9
- // five objects are identical in `@reown/appkit/networks`, which is where they used
10
- // to be imported from — but that made a package with no user interface depend on a
11
- // wallet modal, and it was never declared in `dependencies`, so the root entry
12
- // point of this package could not be loaded by anyone outside this repository.
13
4
  import { bsc, mainnet, pulsechain, pulsechainV4, sepolia } from 'viem/chains';
14
- /**
15
- * Builds an endpoint on valve.city, which proxies four of this dapp's chains.
16
- *
17
- * DEMO ONLY. These endpoints live in {@link demoRpcUrls}, never in
18
- * {@link chainsMetadata}. A third party that hands `chainsMetadata` to viem with
19
- * a bare `http()` gets the public endpoints below, not this shared key. The Gibs
20
- * interface asks for the demo list by name (`@gibs/bridge-client`'s
21
- * `clientFromChain`). Any other caller should pass its own clients.
22
- *
23
- * The key in this URL is `vk_demo`, and it is MEANT to be here. It is the
24
- * proxy's published demo key — it is already listed on chainlist.org, so it is
25
- * public knowledge and shipping it in a browser bundle discloses nothing. The
26
- * proxy reflects any `Origin` back, which is what makes it usable at all from
27
- * an IPFS build: the same bundle is served from gib.show, from ipfs.io, from
28
- * dweb.link, and from a local node, so an origin-locked key would break every
29
- * gateway but one.
30
- *
31
- * NEVER replace this with the unlimited key from 1Password. That one is a
32
- * bearer credential, this file compiles into the public bundle, and the two
33
- * facts together would hand an unmetered proxy to every visitor.
34
- *
35
- * Only chains 1, 369, 943 and 11155111 are proxied; the service lists them at
36
- * its root. Binance Smart Chain is not, which is why it keeps a public endpoint
37
- * alone. Every chain below keeps its previous endpoints after this one, so a
38
- * valve.city outage falls through to where it used to go rather than breaking.
39
- *
40
- * IT LEADS EVERY LIST IT APPEARS IN, and the measurement that says it may is
41
- * not a burst — it is the shape this interface actually produces.
42
- *
43
- * MEASURED 2026-08-29, against the real cadence rather than a synthetic flood:
44
- *
45
- * steady, 1 request per 4 seconds for 3 minutes 45 of 45 answered 200
46
- * bursts, 8 concurrent, four rounds 30 of 32 answered 200
47
- * 20 requests at concurrency 1, 2, 4, 6 and 8 20 of 20 every time
48
- * 20 requests at concurrency 12 19 of 20
49
- *
50
- * Four seconds is not arbitrary: `watchBlocks` runs on viem's default poll, one
51
- * per watched chain, and `clientFromChain` coalesces up to 32 JSON-RPC calls
52
- * made within 10ms into ONE HTTP POST. So the interface's request rate is about
53
- * a quarter of a request per second per chain, and the key handles four times
54
- * that without a single refusal.
55
- *
56
- * AN EARLIER READING SAID THE OPPOSITE AND WAS MEASURING SOMETHING ELSE. On
57
- * 2026-08-27 this key answered 429 for four requests in five — from 40 requests
58
- * at 12 concurrent, fired four times back to back across four chains, roughly
59
- * 160 requests with no pause. That exhausts a windowed budget. No browser does
60
- * it. The reading before THAT one was 40 CONSECUTIVE requests, which cannot see
61
- * a rate limit at all because it paces itself. Both were honest measurements of
62
- * the wrong thing.
63
- *
64
- * THE PROBE STORM WAS THE REAL CULPRIT. `fallback` used to run `rank: true`,
65
- * which pings every url on every chain every few seconds forever — on an idle
66
- * page, every outbound request was one of those. That is what spent the key's
67
- * budget. It is off now (see `packages/common/src/client.ts`), and the
68
- * demotion that shipped alongside turning it off was treating the symptom.
69
- *
70
- * THE SPARE BEHIND IT IS STILL LOAD-BEARING. `vk_demo` is shared — published on
71
- * chainlist.org — so the budget is not ours alone and the headroom moves with
72
- * other people's use. About one burst request in sixteen still meets a 429, and
73
- * a 429 is an HTTP error, so `fallback` moves to the next entry at once. The
74
- * cost is one wasted round trip on a small fraction of burst requests, not a
75
- * failed read. Never leave a proxied chain with valve.city alone.
76
- *
77
- * @param chainId - the numeric chain id to proxy
78
- * @returns the fully qualified JSON-RPC endpoint
79
- */
80
5
  const valveCity = (chainId) => `https://one.valve.city/rpc/vk_demo/evm/${chainId}`;
81
- /**
82
- * all of the chains that are enabled in this dapp
83
- * and their corresponding useful metadata
84
- *
85
- * Every entry below sets `name` explicitly to `chainDisplayName(...)` rather
86
- * than trusting the spread-in viem chain object or typing a string here. Two
87
- * hand-typed copies of the same name is exactly how chain 943 once read as
88
- * "PulseChain Testnet V4" in the resolver and "Pulsechain V4" here — one
89
- * string, two spellings, and only one of them got fixed. Routing every name
90
- * through `chainDisplayName` leaves nothing to drift a second time.
91
- *
92
- * Each `logoURI` is a getter, not a string fixed at import time, so a later
93
- * `setImageRoot` call (from `image-links.ts`) changes every chain logo. Spread
94
- * an entry (`{ ...chainsMetadata[chain] }`) and the copy holds the URL as it
95
- * was at that moment.
96
- */
97
6
  export const chainsMetadata = {
98
7
  [Chains.PLS]: {
99
8
  ...pulsechain,
@@ -129,12 +38,6 @@ export const chainsMetadata = {
129
38
  alt: 'two pyramids joined on one side',
130
39
  rpcUrls: {
131
40
  default: {
132
- // TWO PUBLIC ENDPOINTS, and {@link demoRpcUrls} puts valve.city in
133
- // front of them. Both are needed behind it. On 2026-08-25 g4mm4
134
- // answered nothing at all for hours, and the list was g4mm4 then
135
- // valve.city — so every read fell through a dead host onto a key that
136
- // rejects four requests in five. publicnode measured 40 of 40 on
137
- // 2026-08-27 and costs nothing to carry.
138
41
  http: [
139
42
  'https://rpc-ethereum.g4mm4.io',
140
43
  'https://ethereum-rpc.publicnode.com',
@@ -144,9 +47,6 @@ export const chainsMetadata = {
144
47
  },
145
48
  [Chains.BNB]: {
146
49
  ...bsc,
147
- // viem's own default is "BNB Smart Chain" — deferring to the resolver
148
- // keeps this the product's chosen "Binance Smart Chain" without a second
149
- // hand-typed copy of that decision living here.
150
50
  name: chainDisplayName(bsc.id),
151
51
  chainId: Chains.BNB,
152
52
  get logoURI() {
@@ -155,11 +55,6 @@ export const chainsMetadata = {
155
55
  alt: 'a gold cube with slits in the middle of each side',
156
56
  rpcUrls: {
157
57
  default: {
158
- // valve.city does not proxy chain 56 — it answers "Unsupported
159
- // chain" — so this is the one chain with no entry of ours, which
160
- // makes a second PUBLIC endpoint the only fallback available. A
161
- // one-entry list is what took Sepolia down outright (see below).
162
- // Both measured 40 of 40 on 2026-08-27.
163
58
  http: ['https://bsc-rpc.publicnode.com', 'https://bsc-dataseed.binance.org'],
164
59
  },
165
60
  },
@@ -172,31 +67,8 @@ export const chainsMetadata = {
172
67
  return imageLinks.network(sepolia.id);
173
68
  },
174
69
  alt: 'two pyramids joined on one side',
175
- // FOUR endpoints, not one, and the reason is specific: a public endpoint
176
- // answers a single curl perfectly well and returns 403 under a browser's
177
- // load — five times on one page render. A rate limit, not a dead host.
178
- //
179
- // The transport wraps this list in viem's `fallback()`, which moves on for
180
- // an HTTP error, and 403 is one. With a single entry there was nowhere to
181
- // move to, so the whole testnet side simply failed. All three were checked
182
- // for a correct chain id AND for an allow-origin header, because answering
183
- // curl is not the same as being reachable from a page.
184
70
  rpcUrls: {
185
71
  default: {
186
- // Ordered deliberately, by the operational rule that the most reliable
187
- // endpoint goes FIRST.
188
- //
189
- // valve.city is not here. It sits in front of these three only in
190
- // {@link demoRpcUrls}. Being ours does not buy it a budget: the SHARED
191
- // DEMO KEY answered 429 for 32 of 40 burst requests against Sepolia on
192
- // 2026-08-27, which is why nothing may depend on it alone.
193
- //
194
- // These three keep the order an earlier browser measurement earned
195
- // them. publicnode stays last of the public three because it is the one
196
- // observed returning 403 under a browser's load — five times on one
197
- // page render — which a `curl` burst does not reproduce and therefore
198
- // cannot overturn. It answers fine when the others are busy, so it is
199
- // demoted rather than dropped.
200
72
  http: [
201
73
  'https://sepolia.gateway.tenderly.co',
202
74
  'https://1rpc.io/sepolia',
@@ -215,10 +87,6 @@ export const chainsMetadata = {
215
87
  alt: 'a pink blue and purple hexagon with an ekg line running horizontally',
216
88
  rpcUrls: {
217
89
  default: {
218
- // Two, for the reason Ethereum has two: g4mm4 is a single host that
219
- // has gone away before, and valve.city ({@link demoRpcUrls}) alone in
220
- // front of it is not a fallback. The official testnet node measured 40
221
- // of 40 on 2026-08-27.
222
90
  http: [
223
91
  'https://rpc-testnet-pulsechain.g4mm4.io',
224
92
  'https://rpc.v4.testnet.pulsechain.com',
@@ -236,22 +104,6 @@ export const chainsMetadata = {
236
104
  },
237
105
  },
238
106
  };
239
- /**
240
- * The RPC endpoints the Gibs interface uses, FOR DEMOS ONLY.
241
- *
242
- * Each proxied chain's list starts with valve.city's shared `vk_demo` key and
243
- * falls through to that chain's public endpoints in {@link chainsMetadata}.
244
- * Binance Smart Chain has no valve.city entry, so its list is the public one.
245
- *
246
- * WHY IT IS A SEPARATE, NAMED LIST. The key is public, so shipping it discloses
247
- * nothing. But its rate budget is shared by everybody who uses it, and the proxy
248
- * belongs to the Gibs Finance operator. A wallet that inherits it without
249
- * choosing it puts its users' reads on somebody else's budget and uptime. So no
250
- * reader in this package uses it, and `chainsMetadata` does not carry it. A
251
- * caller who wants it asks for it by this name.
252
- *
253
- * Production callers: pass your own viem clients to every reader.
254
- */
255
107
  export const demoRpcUrls = Object.freeze({
256
108
  [Chains.PLS]: [valveCity(pulsechain.id), ...chainsMetadata[Chains.PLS].rpcUrls.default.http],
257
109
  [Chains.ETH]: [valveCity(mainnet.id), ...chainsMetadata[Chains.ETH].rpcUrls.default.http],
@@ -259,61 +111,11 @@ export const demoRpcUrls = Object.freeze({
259
111
  [Chains.SEP]: [valveCity(sepolia.id), ...chainsMetadata[Chains.SEP].rpcUrls.default.http],
260
112
  [Chains.V4PLS]: [valveCity(pulsechainV4.id), ...chainsMetadata[Chains.V4PLS].rpcUrls.default.http],
261
113
  });
262
- /**
263
- * The demo endpoints for one chain, FOR DEMOS ONLY. See {@link demoRpcUrls}.
264
- *
265
- * @param chainId - a decimal chain id
266
- * @returns a copy of the chain's demo endpoints, or an empty list for a chain the bridge does not cross
267
- */
268
114
  export const demoRpcUrlsFor = (chainId) => [
269
115
  ...(demoRpcUrls[toChain(chainId)] ?? []),
270
116
  ];
271
- /**
272
- * Every chain this bridge itself carries funds across, in the order the
273
- * metadata declares them.
274
- *
275
- * Read from {@link chainsMetadata} rather than typed out, for the reason the
276
- * whole table above gives: a second hand-written list is how one chain ends up
277
- * present in one place and missing from another. A control that offers the
278
- * reader a network to add or remove reads this, so a chain added to the
279
- * metadata appears in that control without anybody remembering to add it.
280
- *
281
- * This is NOT every chain a route can traverse. An aggregator reaches dozens
282
- * more, and `chain-names.ts` can name them. These five are the ones the
283
- * transfers archive holds records for.
284
- */
285
117
  export const bridgeNetworkChainIds = Object.values(chainsMetadata).map((metadata) => Number(metadata.id));
286
- /**
287
- * The chain identifiers this product treats as TEST networks.
288
- *
289
- * THE FLAG IS VIEM'S AND IT IS CHECKED FOR `true`, NOT FOR TRUTHINESS. Each
290
- * entry above spreads a viem chain definition, and viem sets `testnet: true` on
291
- * Sepolia and on PulseChain Testnet V4, `testnet: false` on PulseChain, and
292
- * omits the key entirely on Ethereum and on Binance Smart Chain. So the value
293
- * has three states, and only one of them is a claim. Testing for `=== true`
294
- * means a chain whose definition says nothing is treated as a real network —
295
- * which is the safe direction, because the cost of failing to hide a test
296
- * network is an extra row and the cost of hiding a real one is a reader who
297
- * cannot find their money.
298
- *
299
- * WHY NOT DERIVE IT FROM THE BRIDGE KEYS. `validBridgeKeys(isProd)` in
300
- * `config.ts` splits the same five chains into a mainnet set and a testnet set,
301
- * and subtracting one from the other would give the same two identifiers today.
302
- * It would also give the wrong answer the moment a real chain gains a pathway
303
- * that is still behind the testnet switch — the key list records what is
304
- * ENABLED, and this records what a chain IS. Two different questions.
305
- *
306
- * `buildFullChainIdSet` in the interface already gates the pickers on the same
307
- * flag, and `tokenLists.ts` gates the synthesized native assets on it. This is
308
- * that decision written down once so a third reader does not restate it.
309
- */
310
118
  export const testNetworkChainIds = new Set(Object.values(chainsMetadata)
311
119
  .filter((metadata) => metadata.testnet === true)
312
120
  .map((metadata) => Number(metadata.id)));
313
- /**
314
- * Whether one chain is a test network.
315
- *
316
- * @param chainId - a decimal chain id
317
- * @returns true only when the chain's own definition claims it is a test network
318
- */
319
121
  export const isTestNetwork = (chainId) => testNetworkChainIds.has(chainId);
package/dist/cjs/abis.js CHANGED
@@ -14,6 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- // All ABIs have moved to the standalone @gibs/abis package.
18
- // This module re-exports everything for backwards compatibility.
19
17
  __exportStar(require("@gibs/abis"), exports);
@@ -2,27 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkEntryAmount = exports.bridgeEntryLimits = exports.entryLimitsAbi = void 0;
4
4
  const viem_1 = require("viem");
5
- /**
6
- * Exported so a batched reader (`routing/carriers/omnibridge.ts`'s `prepare`)
7
- * can multicall the same two functions across many tokens in one call rather
8
- * than duplicating this ABI.
9
- */
10
5
  exports.entryLimitsAbi = (0, viem_1.parseAbi)([
11
6
  'function minPerTx(address token) external view returns(uint256)',
12
7
  'function maxAvailablePerTx(address token) external view returns(uint256)',
13
8
  ]);
14
- /**
15
- * Reads the bounds the entry mediator will enforce on this exact call.
16
- *
17
- * IT TAKES THE CALL, NOT A MEDIATOR AND A TOKEN. The two travel together on the
18
- * destination call precisely so a caller cannot pair one route's mediator with
19
- * another route's token and get a plausible number back — the reads would
20
- * succeed and the answer would be about a transfer nobody is making.
21
- *
22
- * @param destinationCall - the entry call, or null when none could be built
23
- * @param entryChainClient - a client on the chain the funds leave
24
- * @returns the two bounds, or null when there is no call to measure
25
- */
26
9
  const bridgeEntryLimits = async ({ destinationCall, entryChainClient, }) => {
27
10
  if (!destinationCall) {
28
11
  return null;
@@ -45,28 +28,7 @@ const bridgeEntryLimits = async ({ destinationCall, entryChainClient, }) => {
45
28
  return { minimumPerTransaction, availablePerTransaction };
46
29
  };
47
30
  exports.bridgeEntryLimits = bridgeEntryLimits;
48
- /**
49
- * Decides whether an amount can enter the bridge.
50
- *
51
- * WHY THIS IS WORTH CHECKING BEFORE A ROUTE IS OFFERED: on a consolidated
52
- * route the entry call is made by an aggregator's executor, not by the user.
53
- * When the mediator rejects the amount the executor's call reverts, the
54
- * aggregator has already delivered the funds, and they stop at the fallback
55
- * address on the entry chain. The user is left holding an entry-chain token
56
- * and a second transfer to make. Refusing the quote costs them nothing.
57
- *
58
- * The bounds are inclusive: the mediator accepts an amount equal to either.
59
- *
60
- * @param amount - the transfer, in the token's base units
61
- * @param limits - the bounds from {@link bridgeEntryLimits}, or null when they
62
- * could not be read
63
- * @returns a verdict naming the bound that was missed
64
- */
65
31
  const checkEntryAmount = ({ amount, limits, }) => {
66
- // An unread limit is not a failed one. A network hiccup must not block a
67
- // route that the mediator would accept — the transaction still gets the
68
- // mediator's own answer, and this guard exists to save the user a wasted
69
- // crossing, not to be the only thing standing between them and a revert.
70
32
  if (!limits) {
71
33
  return { fits: true };
72
34
  }
@@ -40,34 +40,8 @@ const viem_1 = require("viem");
40
40
  const abis = __importStar(require("./abis.js"));
41
41
  const chains_js_1 = require("./chains.js");
42
42
  const config_js_1 = require("./config.js");
43
- /** Cache key for the links memoize: one entry per (chain, bridge, token) triple. */
44
43
  const linksCacheKey = ({ chainId, target, address, }) => `${chainId}-${target}-${address}`.toLowerCase();
45
- /**
46
- * Whether a {@link links} answer says the token has no mapping on this bridge
47
- * yet. That answer is temporary: the first transfer of the token creates the
48
- * mapping, so it must not be cached.
49
- * @param pair - the bridged and native addresses the mediator returned
50
- * @returns true when both are the zero address
51
- */
52
44
  const isUnmappedAnswer = ([bridged, native]) => bridged === viem_1.zeroAddress && native === viem_1.zeroAddress;
53
- /**
54
- * Returns the bridged token address and native token address that a mediator
55
- * holds for one token.
56
- *
57
- * A non-zero answer is cached for the life of the process: a mediator never
58
- * changes a mapping once the first transfer creates it. A failed read, and a
59
- * `[zero, zero]` answer (the token is not bridged yet), are not cached, so the
60
- * next call reads the chain again. Call {@link clearChainInfoCaches} to drop
61
- * every cached answer.
62
- *
63
- * @param inputs.chainId - the chain id being targeted
64
- * @param inputs.target - the mediator to ask
65
- * @param inputs.address - the token address
66
- * @param inputs.client - a client for that chain
67
- * @returns the bridged token address and native token address
68
- */
69
- // The body reaches for `links.cache` to evict an answer, so the cache surface
70
- // is spelled out to the extent this file uses it.
71
45
  exports.links = (0, cache_1.memoizeByKey)(async (inputs) => {
72
46
  const { chainId, target, address, client } = inputs;
73
47
  const evict = () => exports.links.cache.delete(linksCacheKey(inputs));
@@ -81,35 +55,18 @@ exports.links = (0, cache_1.memoizeByKey)(async (inputs) => {
81
55
  { functionName: 'nativeTokenAddress', args: [address] },
82
56
  ],
83
57
  }).catch((error) => {
84
- // a transient read failure must not poison the cache for the session
85
58
  evict();
86
59
  throw error;
87
60
  });
88
61
  if (isUnmappedAnswer(pair)) {
89
- // the token may be bridged a minute from now; ask again next time
90
62
  evict();
91
63
  }
92
64
  return pair;
93
65
  }, linksCacheKey);
94
- /**
95
- * Drops every answer this module has cached, so the next read goes to the chain.
96
- *
97
- * Use it after a token's first transfer, in a long-running process that wants
98
- * a fresh view, or between tests.
99
- */
100
66
  const clearChainInfoCaches = () => {
101
67
  exports.links.cache.clear();
102
68
  };
103
69
  exports.clearChainInfoCaches = clearChainInfoCaches;
104
- /**
105
- * Returns the token bridge info for the given bridge key, asset in, is prod, from chain client, and to chain client
106
- * @param bridgeKey - the bridge key
107
- * @param assetIn - the asset in
108
- * @param isProd - whether to use the production pathway
109
- * @param fromChainClient - the from chain client
110
- * @param toChainClient - the to chain client
111
- * @returns the token bridge info
112
- */
113
70
  const tokenBridgeInfo = async ({ bridgeKey, assetIn, isProd, fromChainClient, toChainClient, }) => {
114
71
  const bridgePathway = (0, config_js_1.pathway)(bridgeKey, isProd, assetIn?.address);
115
72
  if (!assetIn || !bridgePathway) {
@@ -177,7 +134,6 @@ const tokenBridgeInfo = async ({ bridgeKey, assetIn, isProd, fromChainClient, to
177
134
  },
178
135
  };
179
136
  }
180
- // the token has not been bridged yet
181
137
  return {
182
138
  originationChainId: toChain,
183
139
  assetInAddress: assetInAddress,
@@ -198,23 +154,11 @@ const tokenBridgeInfo = async ({ bridgeKey, assetIn, isProd, fromChainClient, to
198
154
  };
199
155
  };
200
156
  exports.tokenBridgeInfo = tokenBridgeInfo;
201
- /**
202
- * Check the prices that each router offers for the given paths
203
- * @param assetInAddress the address of the asset going into the bridge
204
- * @param oneTokenInt the number of tokens to push into the bridge (before fees)
205
- * @param chain the chain of the asset going into the bridge
206
- * @param bridgeKey the bridge key
207
- * @param blockNumber the block number to use for the price
208
- * @param paths the paths to check
209
- * @returns the prices as bigint for each path, hex whenever the price is not available
210
- */
211
157
  const readAmountOut = ({ amountIn, chain, paths, client, uniV2Router, }) => {
212
158
  return (0, multicall_1.multicallRead)({
213
159
  chain: chains_js_1.chainsMetadata[chain],
214
160
  client,
215
161
  abi: abis.univ2Router,
216
- // pulsex router
217
- // a chain with no router reads nothing, as lodash's flatMap over undefined did
218
162
  calls: (uniV2Router ? [uniV2Router] : (config_js_1.uniV2Routers[chain] ?? [])).flatMap((target) => paths.map((path) => ({
219
163
  functionName: 'getAmountsOut',
220
164
  allowFailure: true,
@@ -223,22 +167,9 @@ const readAmountOut = ({ amountIn, chain, paths, client, uniV2Router, }) => {
223
167
  }))),
224
168
  });
225
169
  };
226
- /**
227
- * Fetch the price corrective for the given bridge key, asset out, measurement token, from chain client, to chain client, asset link, amount in, and is prod
228
- * @param bridgeKeyPartner - the bridge key partner
229
- * @param assetOut - the asset out
230
- * @param measurementToken - the measurement token
231
- * @param fromChainClient - the from chain client
232
- * @param toChainClient - the to chain client
233
- * @param assetLink - the asset link
234
- * @param amountIn - the amount in
235
- * @param isProd - whether to use the production pathway
236
- * @returns the price corrective
237
- */
238
170
  const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementToken, fromChainClient, toChainClient, assetLink, amountIn, isProd, }) => {
239
171
  return {
240
172
  getPaymentToken: async () => {
241
- // fetch the token bridge info for the token that is about to be spent by the delivery service
242
173
  return await (0, exports.tokenBridgeInfo)({
243
174
  bridgeKey: bridgeKeyPartner,
244
175
  assetIn: {
@@ -246,8 +177,6 @@ const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementToken, fr
246
177
  address: measurementToken,
247
178
  },
248
179
  isProd,
249
- // clients are reversed here because we are actually fetching the
250
- // tokens going the opposite direction to the provided bridge key
251
180
  fromChainClient: toChainClient,
252
181
  toChainClient: fromChainClient,
253
182
  });
@@ -260,9 +189,7 @@ const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementToken, fr
260
189
  uniV2Router,
261
190
  client,
262
191
  paths: [
263
- // check the direct route
264
192
  [assetLink.assetInAddress, paymentTokenResult.assetOutAddress],
265
- // might have heavier liquidity going through the native asset on the home side
266
193
  [assetLink.assetInAddress, config_js_1.nativeAssetOut[chain], paymentTokenResult.assetOutAddress],
267
194
  ],
268
195
  }),
@@ -272,22 +199,17 @@ const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementToken, fr
272
199
  uniV2Router,
273
200
  client,
274
201
  paths: [[assetOut.address, measurementToken]],
275
- // only the direct route is available.
276
- // might be able to create a whitelist for this at some point
277
202
  }),
278
203
  ]);
279
204
  },
280
205
  reduceResults: ({ results, oneToken, }) => {
281
206
  const outputFromRouter = (result) => {
282
207
  if (typeof result === 'string') {
283
- // the router failed to return a result
284
208
  return 0n;
285
209
  }
286
210
  if (!result.length) {
287
- // the router returned an empty result
288
211
  return 0n;
289
212
  }
290
- // the last element is the amount of the output token
291
213
  const last = result[result.length - 1];
292
214
  return (last * oneToken) / amountIn;
293
215
  };
@@ -296,7 +218,6 @@ const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementToken, fr
296
218
  .filter((amount) => amount !== undefined)
297
219
  .reduce((max, current) => (max < current ? current : max), 0n);
298
220
  };
299
- // could do with a refactor to unify the results
300
221
  const [outputs, inputs] = results;
301
222
  const outputAmounts = outputs.map(outputFromRouter);
302
223
  const inputAmounts = inputs.map(outputFromRouter);
@@ -312,29 +233,6 @@ const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementToken, fr
312
233
  };
313
234
  };
314
235
  exports.fetchPriceCorrective = fetchPriceCorrective;
315
- /**
316
- * Read the smallest amount the bridge will accept for this asset on this pathway.
317
- *
318
- * THE ENTRY MEDIATOR DECIDES, so this always reads `pathway.from` on the chain
319
- * the funds leave. `feeManager` says which side prices the transfer; it has
320
- * never said which side validates the amount, and using it for both is what
321
- * produced the defect this replaces.
322
- *
323
- * Both mediators keep a `minPerTx` under the same name, and for a token that
324
- * originates on the entry chain the two sides usually hold the same number. That
325
- * agreement is a coincidence of configuration - each side is separately
326
- * governed, and both happen to apply one blanket default. It breaks outright for
327
- * a token that originates on the far side, because the two mediators key their
328
- * limits by different addresses. Wrapped Pulse entering from Ethereum is the
329
- * live case: the entry mediator enforces 50,000, and the destination mediator
330
- * answers 0 for that same address because it files that token under its
331
- * PulseChain address instead. Reading the destination got both the chain and the
332
- * token key wrong, and reported no floor where a real one stood.
333
- * @param assetIn - the asset the sender holds, on the chain it leaves from
334
- * @param pathway - the pathway, with any per-asset overrides already applied
335
- * @param fromPublicClient - a client for the chain the funds leave
336
- * @returns the smallest amount the entry mediator will accept
337
- */
338
236
  const minBridgeAmountIn = async ({ assetIn, pathway, fromPublicClient, }) => fromPublicClient.readContract({
339
237
  abi: abis.inputBridge,
340
238
  functionName: 'minPerTx',
@@ -342,7 +240,6 @@ const minBridgeAmountIn = async ({ assetIn, pathway, fromPublicClient, }) => fro
342
240
  address: pathway.from,
343
241
  });
344
242
  exports.minBridgeAmountIn = minBridgeAmountIn;
345
- /** get the symbol of the native asset, unwrap it if it needs to be */
346
243
  const nativeSymbol = (asset, unwrap = false) => {
347
244
  return asset
348
245
  ? unwrap && asset.address === config_js_1.nativeAssetOut[(0, config_js_1.toChain)(asset.chainId)]
@@ -351,12 +248,6 @@ const nativeSymbol = (asset, unwrap = false) => {
351
248
  : '';
352
249
  };
353
250
  exports.nativeSymbol = nativeSymbol;
354
- /**
355
- * Returns the Multicall3 contract for the client's chain.
356
- * @param client - a client whose `chain` is one of {@link chainsMetadata}'s chains
357
- * @returns the Multicall3 contract instance
358
- * @throws when the client carries no chain, or the chain has no Multicall3 address
359
- */
360
251
  const chainMulticall = (client) => {
361
252
  const chainId = client.chain?.id;
362
253
  if (chainId === undefined) {
@@ -369,13 +260,6 @@ const chainMulticall = (client) => {
369
260
  return (0, viem_1.getContract)({ abi: viem_1.multicall3Abi, client, address });
370
261
  };
371
262
  exports.chainMulticall = chainMulticall;
372
- /**
373
- * Load the bridge fees for the given pathway, from chain client, and to chain client
374
- * @param pathway - the pathway
375
- * @param fromChainClient - the from chain client
376
- * @param toChainClient - the to chain client
377
- * @returns the bridge fees
378
- */
379
263
  const loadBridgeFees = async ({ pathway, fromChainClient, toChainClient, }) => {
380
264
  const multicall = pathway.feeManager === 'from' ? (0, exports.chainMulticall)(fromChainClient) : (0, exports.chainMulticall)(toChainClient);
381
265
  const [feeManagerResponse] = await multicall.read.aggregate3([