@gibs/bridge-sdk 1.13.1 → 1.18.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 (228) hide show
  1. package/README.md +295 -18
  2. package/abis/package.json +6 -0
  3. package/bridge-limits/package.json +6 -0
  4. package/chain-info/package.json +6 -0
  5. package/chain-names/package.json +6 -0
  6. package/chains/package.json +6 -0
  7. package/claims/package.json +6 -0
  8. package/config/package.json +6 -0
  9. package/consolidated-quote/package.json +6 -0
  10. package/destination-calldata/package.json +6 -0
  11. package/dist/chain-info.d.ts +1 -1
  12. package/dist/chain-info.js +11 -12
  13. package/dist/chains.d.ts +25 -0
  14. package/dist/chains.js +55 -20
  15. package/dist/cjs/abis.d.ts +1 -0
  16. package/dist/cjs/abis.js +19 -0
  17. package/dist/cjs/bridge-limits.d.ts +103 -0
  18. package/dist/cjs/bridge-limits.js +89 -0
  19. package/dist/cjs/chain-info.d.ts +169 -0
  20. package/dist/cjs/chain-info.js +452 -0
  21. package/dist/cjs/chain-names.d.ts +160 -0
  22. package/dist/cjs/chain-names.js +207 -0
  23. package/dist/cjs/chains.d.ts +90 -0
  24. package/dist/cjs/chains.js +357 -0
  25. package/dist/cjs/claims.d.ts +198 -0
  26. package/dist/cjs/claims.js +182 -0
  27. package/dist/cjs/config.d.ts +255 -0
  28. package/dist/cjs/config.js +569 -0
  29. package/dist/cjs/consolidated-quote.d.ts +648 -0
  30. package/dist/cjs/consolidated-quote.js +1048 -0
  31. package/dist/cjs/destination-calldata.d.ts +118 -0
  32. package/dist/cjs/destination-calldata.js +156 -0
  33. package/dist/cjs/ecosystems.d.ts +217 -0
  34. package/dist/cjs/ecosystems.js +298 -0
  35. package/dist/cjs/execution.d.ts +359 -0
  36. package/dist/cjs/execution.js +495 -0
  37. package/dist/cjs/fee-type.d.ts +10 -0
  38. package/dist/cjs/fee-type.js +10 -0
  39. package/dist/cjs/hyperliquid-execution.d.ts +152 -0
  40. package/dist/cjs/hyperliquid-execution.js +175 -0
  41. package/dist/cjs/image-links.d.ts +117 -0
  42. package/dist/cjs/image-links.js +153 -0
  43. package/dist/cjs/index.d.ts +24 -0
  44. package/dist/cjs/index.js +40 -0
  45. package/dist/cjs/lifi-execution-guard.d.ts +210 -0
  46. package/dist/cjs/lifi-execution-guard.js +409 -0
  47. package/dist/cjs/near-intents-conformance.d.ts +85 -0
  48. package/dist/cjs/near-intents-conformance.js +337 -0
  49. package/dist/cjs/near-intents-route.d.ts +47 -0
  50. package/dist/cjs/near-intents-route.js +303 -0
  51. package/dist/cjs/near-intents.d.ts +524 -0
  52. package/dist/cjs/near-intents.js +1071 -0
  53. package/dist/cjs/origin-deposit.d.ts +326 -0
  54. package/dist/cjs/origin-deposit.js +82 -0
  55. package/dist/cjs/package.json +3 -0
  56. package/dist/cjs/pre-quote.d.ts +198 -0
  57. package/dist/cjs/pre-quote.js +180 -0
  58. package/dist/cjs/prices.d.ts +117 -0
  59. package/dist/cjs/prices.js +224 -0
  60. package/dist/cjs/providers.d.ts +238 -0
  61. package/dist/cjs/providers.js +171 -0
  62. package/dist/cjs/quote-fees.d.ts +102 -0
  63. package/dist/cjs/quote-fees.js +201 -0
  64. package/dist/cjs/referral.d.ts +85 -0
  65. package/dist/cjs/referral.js +85 -0
  66. package/dist/cjs/relay-currencies.d.ts +47 -0
  67. package/dist/cjs/relay-currencies.js +95 -0
  68. package/dist/cjs/relay-depository.d.ts +2 -0
  69. package/dist/cjs/relay-depository.js +85 -0
  70. package/dist/cjs/relay-quote.d.ts +301 -0
  71. package/dist/cjs/relay-quote.js +996 -0
  72. package/dist/cjs/route-steps.d.ts +138 -0
  73. package/dist/cjs/route-steps.js +310 -0
  74. package/dist/cjs/routing/amounts.d.ts +80 -0
  75. package/dist/cjs/routing/amounts.js +126 -0
  76. package/dist/cjs/routing/candidate-route.d.ts +43 -0
  77. package/dist/cjs/routing/candidate-route.js +50 -0
  78. package/dist/cjs/routing/candidate.d.ts +237 -0
  79. package/dist/cjs/routing/candidate.js +100 -0
  80. package/dist/cjs/routing/carrier-provider-key.d.ts +31 -0
  81. package/dist/cjs/routing/carrier-provider-key.js +42 -0
  82. package/dist/cjs/routing/carriers/ask-answer.d.ts +77 -0
  83. package/dist/cjs/routing/carriers/ask-answer.js +2 -0
  84. package/dist/cjs/routing/carriers/omnibridge.d.ts +137 -0
  85. package/dist/cjs/routing/carriers/omnibridge.js +459 -0
  86. package/dist/cjs/routing/carriers/pulsex-paths.d.ts +80 -0
  87. package/dist/cjs/routing/carriers/pulsex-paths.js +97 -0
  88. package/dist/cjs/routing/carriers/pulsex-split.d.ts +175 -0
  89. package/dist/cjs/routing/carriers/pulsex-split.js +193 -0
  90. package/dist/cjs/routing/carriers/pulsex.d.ts +184 -0
  91. package/dist/cjs/routing/carriers/pulsex.js +615 -0
  92. package/dist/cjs/routing/carriers/wrap.d.ts +25 -0
  93. package/dist/cjs/routing/carriers/wrap.js +119 -0
  94. package/dist/cjs/routing/composed-route-quality.d.ts +125 -0
  95. package/dist/cjs/routing/composed-route-quality.js +144 -0
  96. package/dist/cjs/routing/entry-chain-anchor.d.ts +88 -0
  97. package/dist/cjs/routing/entry-chain-anchor.js +59 -0
  98. package/dist/cjs/routing/format.d.ts +31 -0
  99. package/dist/cjs/routing/format.js +64 -0
  100. package/dist/cjs/routing/index.d.ts +42 -0
  101. package/dist/cjs/routing/index.js +142 -0
  102. package/dist/cjs/routing/producers.d.ts +770 -0
  103. package/dist/cjs/routing/producers.js +1617 -0
  104. package/dist/cjs/routing/providers.d.ts +31 -0
  105. package/dist/cjs/routing/providers.js +48 -0
  106. package/dist/cjs/routing/route-data.d.ts +397 -0
  107. package/dist/cjs/routing/route-data.js +2 -0
  108. package/dist/cjs/routing/search/compose.d.ts +168 -0
  109. package/dist/cjs/routing/search/compose.js +104 -0
  110. package/dist/cjs/routing/search/graph.d.ts +668 -0
  111. package/dist/cjs/routing/search/graph.js +461 -0
  112. package/dist/cjs/routing/search/plan-route-data.d.ts +285 -0
  113. package/dist/cjs/routing/search/plan-route-data.js +871 -0
  114. package/dist/cjs/routing/search/score.d.ts +356 -0
  115. package/dist/cjs/routing/search/score.js +445 -0
  116. package/dist/cjs/routing/swap-transactions.d.ts +95 -0
  117. package/dist/cjs/routing/swap-transactions.js +133 -0
  118. package/dist/cjs/routing/usd-value.d.ts +17 -0
  119. package/dist/cjs/routing/usd-value.js +29 -0
  120. package/dist/cjs/settings.d.ts +785 -0
  121. package/dist/cjs/settings.js +1074 -0
  122. package/dist/cjs/swap-venues.d.ts +43 -0
  123. package/dist/cjs/swap-venues.js +29 -0
  124. package/dist/cjs/ton-connect.d.ts +98 -0
  125. package/dist/cjs/ton-connect.js +206 -0
  126. package/dist/cjs/ton-execution.d.ts +7 -0
  127. package/dist/cjs/ton-execution.js +23 -0
  128. package/dist/cjs/ton.d.ts +37 -0
  129. package/dist/cjs/ton.js +83 -0
  130. package/dist/cjs/tron-execution.d.ts +146 -0
  131. package/dist/cjs/tron-execution.js +248 -0
  132. package/dist/cjs/types.d.ts +51 -0
  133. package/dist/cjs/types.js +2 -0
  134. package/dist/claims.d.ts +198 -0
  135. package/dist/claims.js +140 -0
  136. package/dist/config.d.ts +42 -3
  137. package/dist/config.js +87 -21
  138. package/dist/consolidated-quote.d.ts +109 -15
  139. package/dist/consolidated-quote.js +310 -52
  140. package/dist/execution.d.ts +359 -0
  141. package/dist/execution.js +455 -0
  142. package/dist/hyperliquid-execution.js +2 -3
  143. package/dist/index.d.ts +4 -0
  144. package/dist/index.js +4 -0
  145. package/dist/lifi-execution-guard.d.ts +13 -2
  146. package/dist/lifi-execution-guard.js +4 -0
  147. package/dist/near-intents.js +2 -3
  148. package/dist/pre-quote.d.ts +6 -6
  149. package/dist/pre-quote.js +10 -14
  150. package/dist/prices.d.ts +10 -0
  151. package/dist/prices.js +52 -1
  152. package/dist/providers.d.ts +17 -0
  153. package/dist/providers.js +6 -0
  154. package/dist/referral.d.ts +12 -4
  155. package/dist/referral.js +12 -4
  156. package/dist/relay-depository.d.ts +2 -0
  157. package/dist/relay-depository.js +82 -0
  158. package/dist/relay-quote.js +2 -3
  159. package/dist/routing/candidate.d.ts +3 -3
  160. package/dist/routing/candidate.js +3 -3
  161. package/dist/routing/carrier-provider-key.d.ts +31 -0
  162. package/dist/routing/carrier-provider-key.js +37 -0
  163. package/dist/routing/carriers/ask-answer.d.ts +17 -0
  164. package/dist/routing/carriers/omnibridge.js +23 -21
  165. package/dist/routing/carriers/pulsex-paths.d.ts +80 -0
  166. package/dist/routing/carriers/pulsex-paths.js +92 -0
  167. package/dist/routing/carriers/pulsex-split.d.ts +175 -0
  168. package/dist/routing/carriers/pulsex-split.js +185 -0
  169. package/dist/routing/carriers/pulsex.d.ts +81 -46
  170. package/dist/routing/carriers/pulsex.js +267 -148
  171. package/dist/routing/composed-route-quality.d.ts +28 -6
  172. package/dist/routing/composed-route-quality.js +36 -5
  173. package/dist/routing/entry-chain-anchor.d.ts +1 -1
  174. package/dist/routing/entry-chain-anchor.js +1 -1
  175. package/dist/routing/index.d.ts +11 -3
  176. package/dist/routing/index.js +8 -2
  177. package/dist/routing/producers.js +1 -1
  178. package/dist/routing/providers.d.ts +5 -0
  179. package/dist/routing/providers.js +5 -0
  180. package/dist/routing/route-data.d.ts +47 -5
  181. package/dist/routing/search/graph.d.ts +15 -0
  182. package/dist/routing/search/plan-route-data.d.ts +42 -1
  183. package/dist/routing/search/plan-route-data.js +68 -9
  184. package/dist/routing/search/score.d.ts +3 -0
  185. package/dist/routing/search/score.js +11 -3
  186. package/dist/routing/swap-transactions.d.ts +95 -0
  187. package/dist/routing/swap-transactions.js +127 -0
  188. package/dist/settings.d.ts +94 -1
  189. package/dist/settings.js +95 -3
  190. package/dist/swap-venues.d.ts +43 -0
  191. package/dist/swap-venues.js +24 -0
  192. package/dist/ton-connect.d.ts +98 -0
  193. package/dist/ton-connect.js +200 -0
  194. package/dist/ton-execution.d.ts +4 -114
  195. package/dist/ton-execution.js +4 -244
  196. package/dist/ton.d.ts +37 -0
  197. package/dist/ton.js +65 -0
  198. package/docs/examples/example-a-ether-to-pulse.ts +300 -0
  199. package/docs/examples/example-b-token-pulsechain-to-ethereum.ts +270 -0
  200. package/docs/examples/shared.ts +261 -0
  201. package/docs/examples/tsconfig.json +18 -0
  202. package/docs/integration-guide.md +617 -0
  203. package/ecosystems/package.json +6 -0
  204. package/execution/package.json +6 -0
  205. package/fee-type/package.json +6 -0
  206. package/hyperliquid-execution/package.json +6 -0
  207. package/image-links/package.json +6 -0
  208. package/lifi-execution-guard/package.json +6 -0
  209. package/llms.txt +75 -10
  210. package/near-intents/package.json +6 -0
  211. package/near-intents-route/package.json +6 -0
  212. package/origin-deposit/package.json +6 -0
  213. package/package.json +817 -10
  214. package/pre-quote/package.json +6 -0
  215. package/prices/package.json +6 -0
  216. package/providers/package.json +6 -0
  217. package/quote-fees/package.json +6 -0
  218. package/referral/package.json +6 -0
  219. package/relay-currencies/package.json +6 -0
  220. package/relay-quote/package.json +6 -0
  221. package/route-steps/package.json +6 -0
  222. package/routing/package.json +6 -0
  223. package/settings/package.json +6 -0
  224. package/ton/package.json +6 -0
  225. package/ton-connect/package.json +6 -0
  226. package/ton-execution/package.json +6 -0
  227. package/tron-execution/package.json +6 -0
  228. package/types/package.json +6 -0
package/dist/chains.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // same module would be loaded twice, once as source and once as build output,
4
4
  // and `Chains.PLS` from one would not be the same object as from the other.
5
5
  import { chainDisplayName } from './chain-names.js';
6
- import { Chains } from './config.js';
6
+ import { Chains, toChain } from './config.js';
7
7
  import * as imageLinks from './image-links.js';
8
8
  // Chain definitions come from viem, not from a wallet-connection library. These
9
9
  // five objects are identical in `@reown/appkit/networks`, which is where they used
@@ -14,6 +14,12 @@ import { bsc, mainnet, pulsechain, pulsechainV4, sepolia } from 'viem/chains';
14
14
  /**
15
15
  * Builds an endpoint on valve.city, which proxies four of this dapp's chains.
16
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
+ *
17
23
  * The key in this URL is `vk_demo`, and it is MEANT to be here. It is the
18
24
  * proxy's published demo key — it is already listed on chainlist.org, so it is
19
25
  * public knowledge and shipping it in a browser bundle discloses nothing. The
@@ -99,7 +105,7 @@ export const chainsMetadata = {
99
105
  alt: 'a pink blue and purple hexagon with an ekg line running horizontally',
100
106
  rpcUrls: {
101
107
  default: {
102
- http: [valveCity(pulsechain.id), 'https://rpc.pulsechain.com'],
108
+ http: ['https://rpc.pulsechain.com'],
103
109
  },
104
110
  },
105
111
  contracts: {
@@ -123,13 +129,13 @@ export const chainsMetadata = {
123
129
  alt: 'two pyramids joined on one side',
124
130
  rpcUrls: {
125
131
  default: {
126
- // THREE, because the middle one is the only real fallback. On
127
- // 2026-08-25 g4mm4 answered nothing at all for hours, and this list
128
- // was g4mm4 then valve.city — so every read fell through a dead host
129
- // onto a key that rejects four requests in five. publicnode measured
130
- // 40 of 40 on 2026-08-27 and costs nothing to carry.
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.
131
138
  http: [
132
- valveCity(mainnet.id),
133
139
  'https://rpc-ethereum.g4mm4.io',
134
140
  'https://ethereum-rpc.publicnode.com',
135
141
  ],
@@ -180,20 +186,18 @@ export const chainsMetadata = {
180
186
  // Ordered deliberately, by the operational rule that the most reliable
181
187
  // endpoint goes FIRST.
182
188
  //
183
- // valve.city led this list on the belief that it "is ours and is not
184
- // rate limited against us". The first half is true and the second is
185
- // not: the SHARED DEMO KEY is what ships here, and it answered 429 for
186
- // 32 of 40 burst requests against Sepolia on 2026-08-27. Being ours
187
- // does not buy a budget, so it goes last with the rest.
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.
188
193
  //
189
- // The other three keep the order an earlier browser measurement earned
194
+ // These three keep the order an earlier browser measurement earned
190
195
  // them. publicnode stays last of the public three because it is the one
191
196
  // observed returning 403 under a browser's load — five times on one
192
197
  // page render — which a `curl` burst does not reproduce and therefore
193
198
  // cannot overturn. It answers fine when the others are busy, so it is
194
199
  // demoted rather than dropped.
195
200
  http: [
196
- valveCity(sepolia.id),
197
201
  'https://sepolia.gateway.tenderly.co',
198
202
  'https://1rpc.io/sepolia',
199
203
  'https://ethereum-sepolia-rpc.publicnode.com',
@@ -211,12 +215,11 @@ export const chainsMetadata = {
211
215
  alt: 'a pink blue and purple hexagon with an ekg line running horizontally',
212
216
  rpcUrls: {
213
217
  default: {
214
- // Three for the reason Ethereum is three: g4mm4 is a single host
215
- // that has gone away before, and valve.city alone behind it is not a
216
- // fallback. The official testnet node measured 40 of 40 on
217
- // 2026-08-27.
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.
218
222
  http: [
219
- valveCity(pulsechainV4.id),
220
223
  'https://rpc-testnet-pulsechain.g4mm4.io',
221
224
  'https://rpc.v4.testnet.pulsechain.com',
222
225
  ],
@@ -233,6 +236,38 @@ export const chainsMetadata = {
233
236
  },
234
237
  },
235
238
  };
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
+ export const demoRpcUrls = Object.freeze({
256
+ [Chains.PLS]: [valveCity(pulsechain.id), ...chainsMetadata[Chains.PLS].rpcUrls.default.http],
257
+ [Chains.ETH]: [valveCity(mainnet.id), ...chainsMetadata[Chains.ETH].rpcUrls.default.http],
258
+ [Chains.BNB]: [...chainsMetadata[Chains.BNB].rpcUrls.default.http],
259
+ [Chains.SEP]: [valveCity(sepolia.id), ...chainsMetadata[Chains.SEP].rpcUrls.default.http],
260
+ [Chains.V4PLS]: [valveCity(pulsechainV4.id), ...chainsMetadata[Chains.V4PLS].rpcUrls.default.http],
261
+ });
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
+ export const demoRpcUrlsFor = (chainId) => [
269
+ ...(demoRpcUrls[toChain(chainId)] ?? []),
270
+ ];
236
271
  /**
237
272
  * Every chain this bridge itself carries funds across, in the order the
238
273
  * metadata declares them.
@@ -0,0 +1 @@
1
+ export * from '@gibs/abis';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
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
+ __exportStar(require("@gibs/abis"), exports);
@@ -0,0 +1,103 @@
1
+ import type { PublicClient } from 'viem';
2
+ import type { DestinationCall } from './destination-calldata.js';
3
+ /**
4
+ * The two bounds the entry mediator puts on a single transfer, read from the
5
+ * contract the transaction actually calls.
6
+ *
7
+ * BOTH ARE READ FROM THE ENTRY SIDE, NOT THE FAR SIDE. The mediator validates
8
+ * the amount before it emits anything, so the bound that decides whether a
9
+ * transfer happens at all belongs to the chain the funds leave. The far side
10
+ * keeps its own limits under the same names, and nothing makes the two agree —
11
+ * they are separately governed contracts. Measured 2026-08-31: raising
12
+ * `minPerTx` on the Ethereum mediator alone, with PulseChain untouched, makes
13
+ * the entry call revert. `bridge-limits.fork.test.ts` keeps that honest.
14
+ */
15
+ export type EntryLimits = {
16
+ /** Smallest transfer the mediator will accept, in the token's base units. */
17
+ minimumPerTransaction: bigint;
18
+ /**
19
+ * Largest transfer the mediator will accept RIGHT NOW, in base units.
20
+ *
21
+ * This is not a constant ceiling. The mediator returns the lower of its
22
+ * per-transfer cap and what is left of today's allowance, so it falls as the
23
+ * day is used up and resets on its own schedule. Do not cache it.
24
+ */
25
+ availablePerTransaction: bigint;
26
+ };
27
+ /** Why an amount cannot enter the bridge, or that it can. */
28
+ export type EntryAmountVerdict = {
29
+ fits: true;
30
+ } | {
31
+ fits: false;
32
+ reason: 'below-minimum';
33
+ minimumPerTransaction: bigint;
34
+ } | {
35
+ fits: false;
36
+ reason: 'above-available';
37
+ availablePerTransaction: bigint;
38
+ };
39
+ /**
40
+ * Exported so a batched reader (`routing/carriers/omnibridge.ts`'s `prepare`)
41
+ * can multicall the same two functions across many tokens in one call rather
42
+ * than duplicating this ABI.
43
+ */
44
+ export declare const entryLimitsAbi: readonly [{
45
+ readonly name: "minPerTx";
46
+ readonly type: "function";
47
+ readonly stateMutability: "view";
48
+ readonly inputs: readonly [{
49
+ readonly type: "address";
50
+ readonly name: "token";
51
+ }];
52
+ readonly outputs: readonly [{
53
+ readonly type: "uint256";
54
+ }];
55
+ }, {
56
+ readonly name: "maxAvailablePerTx";
57
+ readonly type: "function";
58
+ readonly stateMutability: "view";
59
+ readonly inputs: readonly [{
60
+ readonly type: "address";
61
+ readonly name: "token";
62
+ }];
63
+ readonly outputs: readonly [{
64
+ readonly type: "uint256";
65
+ }];
66
+ }];
67
+ /**
68
+ * Reads the bounds the entry mediator will enforce on this exact call.
69
+ *
70
+ * IT TAKES THE CALL, NOT A MEDIATOR AND A TOKEN. The two travel together on the
71
+ * destination call precisely so a caller cannot pair one route's mediator with
72
+ * another route's token and get a plausible number back — the reads would
73
+ * succeed and the answer would be about a transfer nobody is making.
74
+ *
75
+ * @param destinationCall - the entry call, or null when none could be built
76
+ * @param entryChainClient - a client on the chain the funds leave
77
+ * @returns the two bounds, or null when there is no call to measure
78
+ */
79
+ export declare const bridgeEntryLimits: ({ destinationCall, entryChainClient, }: {
80
+ destinationCall: Pick<DestinationCall, "entryMediator" | "entryTokenAddress"> | null;
81
+ entryChainClient: PublicClient;
82
+ }) => Promise<EntryLimits | null>;
83
+ /**
84
+ * Decides whether an amount can enter the bridge.
85
+ *
86
+ * WHY THIS IS WORTH CHECKING BEFORE A ROUTE IS OFFERED: on a consolidated
87
+ * route the entry call is made by an aggregator's executor, not by the user.
88
+ * When the mediator rejects the amount the executor's call reverts, the
89
+ * aggregator has already delivered the funds, and they stop at the fallback
90
+ * address on the entry chain. The user is left holding an entry-chain token
91
+ * and a second transfer to make. Refusing the quote costs them nothing.
92
+ *
93
+ * The bounds are inclusive: the mediator accepts an amount equal to either.
94
+ *
95
+ * @param amount - the transfer, in the token's base units
96
+ * @param limits - the bounds from {@link bridgeEntryLimits}, or null when they
97
+ * could not be read
98
+ * @returns a verdict naming the bound that was missed
99
+ */
100
+ export declare const checkEntryAmount: ({ amount, limits, }: {
101
+ amount: bigint;
102
+ limits: EntryLimits | null;
103
+ }) => EntryAmountVerdict;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkEntryAmount = exports.bridgeEntryLimits = exports.entryLimitsAbi = void 0;
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
+ exports.entryLimitsAbi = (0, viem_1.parseAbi)([
11
+ 'function minPerTx(address token) external view returns(uint256)',
12
+ 'function maxAvailablePerTx(address token) external view returns(uint256)',
13
+ ]);
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
+ const bridgeEntryLimits = async ({ destinationCall, entryChainClient, }) => {
27
+ if (!destinationCall) {
28
+ return null;
29
+ }
30
+ const { entryMediator, entryTokenAddress } = destinationCall;
31
+ const [minimumPerTransaction, availablePerTransaction] = await Promise.all([
32
+ entryChainClient.readContract({
33
+ abi: exports.entryLimitsAbi,
34
+ functionName: 'minPerTx',
35
+ args: [entryTokenAddress],
36
+ address: entryMediator,
37
+ }),
38
+ entryChainClient.readContract({
39
+ abi: exports.entryLimitsAbi,
40
+ functionName: 'maxAvailablePerTx',
41
+ args: [entryTokenAddress],
42
+ address: entryMediator,
43
+ }),
44
+ ]);
45
+ return { minimumPerTransaction, availablePerTransaction };
46
+ };
47
+ 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
+ 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
+ if (!limits) {
71
+ return { fits: true };
72
+ }
73
+ if (amount < limits.minimumPerTransaction) {
74
+ return {
75
+ fits: false,
76
+ reason: 'below-minimum',
77
+ minimumPerTransaction: limits.minimumPerTransaction,
78
+ };
79
+ }
80
+ if (amount > limits.availablePerTransaction) {
81
+ return {
82
+ fits: false,
83
+ reason: 'above-available',
84
+ availablePerTransaction: limits.availablePerTransaction,
85
+ };
86
+ }
87
+ return { fits: true };
88
+ };
89
+ exports.checkEntryAmount = checkEntryAmount;
@@ -0,0 +1,169 @@
1
+ import { type Address, type GetContractReturnType, type Hex, multicall3Abi, type PublicClient } from 'viem';
2
+ import { type Chains, type Pathway } from './config.js';
3
+ import type { BridgeKey, Token } from './types.js';
4
+ export type TokenBridgeInfo = {
5
+ originationChainId: Chains;
6
+ assetInAddress: Hex;
7
+ assetOutAddress: Hex | null;
8
+ toForeign?: {
9
+ home: Hex;
10
+ foreign: Hex | null;
11
+ };
12
+ toHome?: {
13
+ home: Hex | null;
14
+ foreign: Hex;
15
+ };
16
+ };
17
+ /** The inputs of one {@link links} read. */
18
+ type LinksInputs = {
19
+ chainId: number;
20
+ target: Hex;
21
+ address: Hex;
22
+ client: PublicClient;
23
+ };
24
+ /**
25
+ * Returns the bridged token address and native token address that a mediator
26
+ * holds for one token.
27
+ *
28
+ * A non-zero answer is cached for the life of the process: a mediator never
29
+ * changes a mapping once the first transfer creates it. A failed read, and a
30
+ * `[zero, zero]` answer (the token is not bridged yet), are not cached, so the
31
+ * next call reads the chain again. Call {@link clearChainInfoCaches} to drop
32
+ * every cached answer.
33
+ *
34
+ * @param inputs.chainId - the chain id being targeted
35
+ * @param inputs.target - the mediator to ask
36
+ * @param inputs.address - the token address
37
+ * @param inputs.client - a client for that chain
38
+ * @returns the bridged token address and native token address
39
+ */
40
+ export declare const links: ((inputs: LinksInputs) => Promise<[Hex, Hex]>) & {
41
+ cache: {
42
+ delete: (key: string) => boolean;
43
+ clear: () => void;
44
+ };
45
+ };
46
+ /**
47
+ * Drops every answer this module has cached, so the next read goes to the chain.
48
+ *
49
+ * Use it after a token's first transfer, in a long-running process that wants
50
+ * a fresh view, or between tests.
51
+ */
52
+ export declare const clearChainInfoCaches: () => void;
53
+ /**
54
+ * Returns the token bridge info for the given bridge key, asset in, is prod, from chain client, and to chain client
55
+ * @param bridgeKey - the bridge key
56
+ * @param assetIn - the asset in
57
+ * @param isProd - whether to use the production pathway
58
+ * @param fromChainClient - the from chain client
59
+ * @param toChainClient - the to chain client
60
+ * @returns the token bridge info
61
+ */
62
+ export declare const tokenBridgeInfo: ({ bridgeKey, assetIn, isProd, fromChainClient, toChainClient, }: {
63
+ bridgeKey: BridgeKey;
64
+ assetIn: Token | null;
65
+ isProd: boolean;
66
+ fromChainClient: PublicClient;
67
+ toChainClient: PublicClient;
68
+ }) => Promise<null | TokenBridgeInfo>;
69
+ /** The result of reading the amount out from a router */
70
+ export type FetchResult = bigint[] | Hex;
71
+ /**
72
+ * 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
73
+ * @param bridgeKeyPartner - the bridge key partner
74
+ * @param assetOut - the asset out
75
+ * @param measurementToken - the measurement token
76
+ * @param fromChainClient - the from chain client
77
+ * @param toChainClient - the to chain client
78
+ * @param assetLink - the asset link
79
+ * @param amountIn - the amount in
80
+ * @param isProd - whether to use the production pathway
81
+ * @returns the price corrective
82
+ */
83
+ export declare const fetchPriceCorrective: ({ bridgeKeyPartner, assetOut, measurementToken, fromChainClient, toChainClient, assetLink, amountIn, isProd, }: {
84
+ bridgeKey: BridgeKey;
85
+ bridgeKeyPartner: BridgeKey;
86
+ measurementToken: Hex;
87
+ assetOut: Token;
88
+ fromChainClient: PublicClient;
89
+ toChainClient: PublicClient;
90
+ assetLink: TokenBridgeInfo;
91
+ amountIn: bigint;
92
+ isProd: boolean;
93
+ }) => {
94
+ getPaymentToken: () => Promise<TokenBridgeInfo | null>;
95
+ getSwapResults: ({ paymentTokenResult, chain, uniV2Router, client, }: {
96
+ paymentTokenResult: TokenBridgeInfo;
97
+ chain: Chains;
98
+ client: PublicClient;
99
+ uniV2Router?: Hex;
100
+ }) => Promise<[FetchResult[], FetchResult[]]>;
101
+ reduceResults: ({ results, oneToken, }: {
102
+ results: [FetchResult[], ...[FetchResult[]]];
103
+ oneToken: bigint;
104
+ }) => bigint;
105
+ };
106
+ /**
107
+ * Read the smallest amount the bridge will accept for this asset on this pathway.
108
+ *
109
+ * THE ENTRY MEDIATOR DECIDES, so this always reads `pathway.from` on the chain
110
+ * the funds leave. `feeManager` says which side prices the transfer; it has
111
+ * never said which side validates the amount, and using it for both is what
112
+ * produced the defect this replaces.
113
+ *
114
+ * Both mediators keep a `minPerTx` under the same name, and for a token that
115
+ * originates on the entry chain the two sides usually hold the same number. That
116
+ * agreement is a coincidence of configuration - each side is separately
117
+ * governed, and both happen to apply one blanket default. It breaks outright for
118
+ * a token that originates on the far side, because the two mediators key their
119
+ * limits by different addresses. Wrapped Pulse entering from Ethereum is the
120
+ * live case: the entry mediator enforces 50,000, and the destination mediator
121
+ * answers 0 for that same address because it files that token under its
122
+ * PulseChain address instead. Reading the destination got both the chain and the
123
+ * token key wrong, and reported no floor where a real one stood.
124
+ * @param assetIn - the asset the sender holds, on the chain it leaves from
125
+ * @param pathway - the pathway, with any per-asset overrides already applied
126
+ * @param fromPublicClient - a client for the chain the funds leave
127
+ * @returns the smallest amount the entry mediator will accept
128
+ */
129
+ export declare const minBridgeAmountIn: ({ assetIn, pathway, fromPublicClient, }: {
130
+ assetIn: Token;
131
+ pathway: Pathway;
132
+ fromPublicClient: PublicClient;
133
+ }) => Promise<bigint>;
134
+ /** get the symbol of the native asset, unwrap it if it needs to be */
135
+ export declare const nativeSymbol: (asset: {
136
+ address: string;
137
+ symbol: string;
138
+ chainId: number;
139
+ } | null, unwrap?: boolean) => string;
140
+ /** The input for loading the bridge fees */
141
+ export type InputLoadFeeFor = {
142
+ pathway: Pathway;
143
+ fromChainClient: PublicClient;
144
+ toChainClient: PublicClient;
145
+ };
146
+ /** The fee configuration for a given pathway */
147
+ export type PathwayExtendableConfig = {
148
+ feeManager: Hex;
149
+ feeH2F: bigint;
150
+ feeF2H: bigint;
151
+ };
152
+ /** A typed Multicall3 contract instance for one chain. */
153
+ export type ChainMulticall = GetContractReturnType<typeof multicall3Abi, PublicClient, Address>;
154
+ /**
155
+ * Returns the Multicall3 contract for the client's chain.
156
+ * @param client - a client whose `chain` is one of {@link chainsMetadata}'s chains
157
+ * @returns the Multicall3 contract instance
158
+ * @throws when the client carries no chain, or the chain has no Multicall3 address
159
+ */
160
+ export declare const chainMulticall: (client: PublicClient) => ChainMulticall;
161
+ /**
162
+ * Load the bridge fees for the given pathway, from chain client, and to chain client
163
+ * @param pathway - the pathway
164
+ * @param fromChainClient - the from chain client
165
+ * @param toChainClient - the to chain client
166
+ * @returns the bridge fees
167
+ */
168
+ export declare const loadBridgeFees: ({ pathway, fromChainClient, toChainClient, }: InputLoadFeeFor) => Promise<PathwayExtendableConfig>;
169
+ export {};