@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/README.md CHANGED
@@ -11,24 +11,108 @@ response parsers. It does not sign or send anything. You bring a
11
11
  Every TypeScript sample in this file is compiled by the package's test suite
12
12
  (`src/compile-checks.test.ts`), so a sample that stops matching the code fails the build.
13
13
 
14
+ ## Integration guide
15
+
16
+ To add Gibs routes to a wallet or app from start to end, read the integration
17
+ guide. It shows how to search for routes, plan the transactions, send them with
18
+ your own signer, track the transfer and claim it. It has two complete examples.
19
+
20
+ - Online: <https://next.gibs.finance/docs/>
21
+ - In this package: `docs/integration-guide.md`, with the example files in
22
+ `docs/examples/`. After you install, they are in
23
+ `node_modules/@gibs/bridge-sdk/docs/`.
24
+ - For AI tools: <https://next.gibs.finance/llms-full.txt> holds the guide, the
25
+ examples and every package guide in one file.
26
+
14
27
  ## Install
15
28
 
16
29
  ```sh
17
30
  npm install @gibs/bridge-sdk viem
18
31
  ```
19
32
 
20
- - **ESM only.** The package is `"type": "module"` and ships no CommonJS build.
21
- Use `import`, not `require`.
22
- - **Node.js 20 or later** (`engines.node` is `>=20`).
23
- - **viem is a peer dependency** (`>=2.37.0`).
24
- - **Browsers and `@gibs/bridge-sdk/ton-execution`.** That entry point uses
25
- `@ton/core`, which expects a global `Buffer`. Node has one. In a browser,
26
- install the `buffer` package and set `globalThis.Buffer` before you import it.
27
- No other entry point needs `Buffer`.
33
+ - **Node.js 20 or later** (`engines.node` is `>=20`), or React Native with Hermes.
34
+ - **viem is a peer dependency** (`>=2.35.0 <3`).
28
35
 
29
36
  Import from the narrowest entry point you need (`@gibs/bridge-sdk/config`,
30
37
  `@gibs/bridge-sdk/chain-info`, and so on). The root `@gibs/bridge-sdk` exports
31
- everything.
38
+ everything except TON.
39
+
40
+ ## Ways to use the package
41
+
42
+ The package ships two builds of the same code, and picks one for you through
43
+ the `exports` map. You need no extra configuration for any of these.
44
+
45
+ | Option | What you write | What loads |
46
+ |---|---|---|
47
+ | ECMAScript modules | `import { pathway } from '@gibs/bridge-sdk/config'` | `dist/config.js` |
48
+ | CommonJS | `const { pathway } = require('@gibs/bridge-sdk/config')` | `dist/cjs/config.js` |
49
+ | React Native (Metro) | either of the above | `import` gets `dist/`, `require` gets `dist/cjs/` |
50
+ | React Native (jest) | either of the above | `dist/cjs/` |
51
+
52
+ **ECMAScript modules.** Node, Vite, webpack, esbuild, Rollup and Bun use the
53
+ `import` condition.
54
+
55
+ ```ts
56
+ import { Chains, pathway, Providers } from '@gibs/bridge-sdk/config'
57
+ import { amountAfterBridgeFee, bridgeCost } from '@gibs/bridge-sdk/settings'
58
+
59
+ const route = pathway([Providers.PULSECHAIN, Chains.PLS, Chains.ETH], true)
60
+ const cost = bridgeCost({ amountToBridge: 10n ** 18n, bridgeFee: 3n * 10n ** 15n })
61
+ const amountOut = amountAfterBridgeFee({ amountToBridge: 10n ** 18n, bridgeCost: cost })
62
+ console.log(route?.from, amountOut)
63
+ ```
64
+
65
+ **CommonJS.** `require` loads `dist/cjs/`, with its own declaration files.
66
+
67
+ ```js
68
+ const { Chains, pathway, Providers } = require('@gibs/bridge-sdk/config')
69
+ ```
70
+
71
+ **React Native.** The package works with the default Metro configuration of
72
+ React Native 0.77 or later. You need no change to `metro.config.js`, no
73
+ `resolveRequest` hook, no `transformIgnorePatterns` in jest, and no polyfill.
74
+ It runs on React Native's own `URL` and `URLSearchParams`, which React Native
75
+ 0.77 implements only in part: no code in the package reads them.
76
+ In React Native 0.79 or later, Metro reads the `exports` map.
77
+ The `react-native` condition follows Metro's own choice: an `import` statement
78
+ gets the ECMAScript module build, and a `require` call gets CommonJS. That
79
+ keeps the SDK on the same build of viem as your own code, so Metro bundles
80
+ viem once. The React Native jest preset loads `node_modules` untransformed, so
81
+ it gets CommonJS. Hermes runs both builds.
82
+
83
+ In React Native 0.77 and 0.78, or with `unstable_enablePackageExports: false`,
84
+ Metro ignores `exports`. Every subpath still resolves: the package ships one
85
+ folder per subpath, such as `config/package.json`, whose `main` and
86
+ `react-native` fields point at the CommonJS build. Metro then loads CommonJS for
87
+ every import, and viem's own CommonJS build with it, so viem is still bundled
88
+ once.
89
+
90
+ **Import only what you use.** Metro does not drop unused exports, so the entry
91
+ point you pick decides what your bundle carries. Measured with React Native
92
+ 0.87.1 and viem 2.56.3, in a production ios bundle that already holds viem:
93
+
94
+ | You import | Added to the bundle |
95
+ |---|---|
96
+ | `@gibs/bridge-sdk/config` and `/settings` (offline quoting) | about 24 kB (7 kB gzipped) |
97
+ | `@gibs/bridge-sdk/chain-info` (live fee reads), with the above | about 1.16 MB, of which `viem/chains` is 1.12 MB |
98
+ | `@gibs/bridge-sdk` (the root, everything but TON) | about 1.29 MB |
99
+
100
+ If your app already imports `viem/chains`, `chain-info` adds about 41 kB and the
101
+ root adds about 164 kB. In React Native 0.77 with viem 2.35.0, where Metro
102
+ loads the CommonJS build, `config` and `settings` add about 28 kB.
103
+
104
+ **TON.** TON lives behind its own entry points, so an app that bridges only
105
+ between Ethereum-style chains never loads a TON library.
106
+
107
+ - `@gibs/bridge-sdk/ton-connect` builds TON Connect requests and re-encodes
108
+ addresses. It needs no TON library, no `Buffer` and no polyfill.
109
+ - `@gibs/bridge-sdk/ton` holds the same helpers plus `tonExternalMessageHash`,
110
+ which needs `@ton/core`. `@ton/core` expects a global `Buffer`: in a browser
111
+ or in React Native, install the `buffer` package and set `globalThis.Buffer`
112
+ before you import it. In React Native, `@ton/core`'s `@ton/crypto` dependency
113
+ also resolves to a build that requires `expo-crypto`, so Metro fails to
114
+ bundle this entry point unless the app installs `expo-crypto`.
115
+ - `@gibs/bridge-sdk/ton-execution` is the old name of `@gibs/bridge-sdk/ton`.
32
116
 
33
117
  ## Chains and bridge keys
34
118
 
@@ -179,19 +263,21 @@ chain again. Call `clearChainInfoCaches()` to drop every cached answer.
179
263
  ## Aggregator quotes and your identity
180
264
 
181
265
  The request builders turn one `ConsolidatedQuoteRequest` into a provider's
182
- request. The package ships **no API key**. It sends a Gibs Finance label only
183
- where that costs you nothing.
266
+ request. The package ships **no API key**, and it attributes nothing to Gibs
267
+ Finance unless you pass Gibs Finance's values yourself.
184
268
 
185
269
  | Field | Default | Why |
186
270
  |---|---|---|
187
271
  | Relay `x-api-key` | none | Pass your own to `relayRequestHeaders`. A key carries a rate-limit budget. |
188
272
  | Relay `referrer` | **not sent** | Relay requires an API key from any request that names a referrer, so a default would break keyless callers. |
189
- | LI.FI `integrator` | `gibs.finance` | A free label. It changes neither the quote nor your rate limit. |
273
+ | LI.FI `integrator` | **not sent** | LI.FI records your traffic under this label and pays any fee to the account behind it. Name your own. |
190
274
  | LI.FI `fee` | not sent | A fee needs your own `lifiIntegrator`, because LI.FI pays the fee to the integrator label. The builders throw otherwise. |
191
- | NEAR Intents `User-Agent` | `gibs-bridge/1.0 (+https://gibs.finance)` | No key and no budget, and browsers drop it. |
275
+ | NEAR Intents `referral` | **not sent** | Pass `referral` in the quote context to tag your traffic. |
276
+ | NEAR Intents `User-Agent` | `gibs-bridge/1.0 (+https://gibs.finance)` | Browsers drop it, so it reaches the service only from Node or React Native. Pass `{ userAgent: 'your-app/1.0' }`, or `{ userAgent: null }` to send none. |
192
277
 
193
- Each attribution field takes three states: leave it out for the default, pass
194
- `null` to omit it, or pass your own string.
278
+ Each attribution field takes two states: leave it out (or pass `null`) to send
279
+ nothing, or pass your own string. The NEAR Intents `User-Agent` is the one
280
+ exception: leave it out and it names Gibs Finance.
195
281
 
196
282
  ```ts
197
283
  import {
@@ -227,6 +313,58 @@ const nearHeaders = nearIntentsRequestHeaders(undefined, { userAgent: 'your-app/
227
313
  Relay quotes work without a key on its anonymous tier. Relay's `/requests/v3`
228
314
  status lookup does not: it answers 400 without `x-api-key`.
229
315
 
316
+ ## Which fees apply, and how you control each one
317
+
318
+ The package adds no fee and no attribution on its own. A request carries one
319
+ only when your code passes it. The test `src/no-default-fees.test.ts` builds a
320
+ request with every builder and fails if any of them adds a fee, a payout
321
+ address or a Gibs Finance label that the caller did not pass.
322
+
323
+ | Fee | When it applies | Who receives it | How you see it | How you control it |
324
+ |---|---|---|---|---|
325
+ | Bridge fee | Every direct omnibridge crossing. It is an on-chain setting, per direction. | The bridge's fee manager | `loadBridgeFees`, then `bridgeCost` | You cannot turn it off. Read it, and show it before the user signs. |
326
+ | Delivery fee | Only when you request delivery: `shouldDeliver: true` and a `feeDirectorStructEncoded` in `transactionInputs`. | Whoever executes the claim on the destination chain | `deliveryFee` | Choose the fee type and amount, or pass `shouldDeliver: false` and let the user claim. |
327
+ | LI.FI referral fee | Only when you pass `lifiFee` and your own `lifiIntegrator` | The account behind your integrator label | The `fee` field of the built request | Leave `lifiFee` out to charge nothing. |
328
+ | Relay application fee | Only when you pass `relayAppFee: { recipient, basisPoints }` | `recipient`, on the destination chain | The `appFees` field of the built request | Leave `relayAppFee` out to charge nothing. |
329
+ | Provider fees (gas, solver, protocol) | Every aggregator route. The provider charges them. | LI.FI, Relay or NEAR Intents | `lifiQuoteFees`, `relayQuoteFees`, and the NEAR Intents quote parser | Not in your control. Show them. |
330
+ | NEAR Intents key-less surcharge | Every NEAR Intents quote sent without a partner key: 25 basis points (`nearIntentsUnauthenticatedFeeBasisPoints`) | NEAR Intents | The NEAR Intents quote parser reports it as a charge | Get a partner key and pass it to `nearIntentsRequestHeaders`. |
331
+
332
+ The `@gibs/bridge-sdk/referral` module holds **Gibs Finance's own values**:
333
+ `referralIntegrator`, `relayReferralRecipient` (Gibs Finance's payout wallet)
334
+ and `defaultReferralFeeBasisPoints` (10, a tenth of a percent).
335
+ `lifiReferralFeePercent`, `lifiIntegrator` and `relayReferrer` repeat them for
336
+ each provider. No builder reads any of them. The Gibs interface passes them
337
+ explicitly. Do not pass them from your own wallet: they pay Gibs Finance.
338
+
339
+ ## RPC endpoints: the defaults are for demos only
340
+
341
+ Every reader in this package takes your clients. `loadBridgeFees`,
342
+ `tokenBridgeInfo`, `fetchPriceCorrective`, `minBridgeAmountIn`, the limit
343
+ reads and the route carriers all take a viem `PublicClient` (or a
344
+ `clientForChain` function) from you. None of them builds a client of its own.
345
+
346
+ `chainsMetadata` carries only public endpoints. The Gibs interface also uses a
347
+ shared valve.city proxy key, `vk_demo`. That key is published (it is listed on
348
+ chainlist.org), so it is not a secret. But its rate budget is shared by
349
+ everybody who uses it, and the Gibs Finance operator runs the proxy. It lives
350
+ in `demoRpcUrls` and `demoRpcUrlsFor`, which exist **for demos only**. Use your
351
+ own RPC provider in production.
352
+
353
+ ```ts
354
+ import { demoRpcUrlsFor } from '@gibs/bridge-sdk/chains'
355
+ import { createPublicClient, fallback, http } from 'viem'
356
+ import { mainnet } from 'viem/chains'
357
+
358
+ // Production: your own endpoint.
359
+ const ethereumClient = createPublicClient({ chain: mainnet, transport: http('https://your-rpc.example') })
360
+
361
+ // A demo, by explicit choice: the shared demo key first, public endpoints behind it.
362
+ const demoClient = createPublicClient({
363
+ chain: mainnet,
364
+ transport: fallback(demoRpcUrlsFor(mainnet.id).map((url) => http(url))),
365
+ })
366
+ ```
367
+
230
368
  ## Images
231
369
 
232
370
  Chain logos and token images come from [gib.show](https://gib.show). Point them
@@ -243,6 +381,141 @@ chainsMetadata[Chains.PLS].logoURI // 'https://images.example.org/image/369'
243
381
  image({ chainId: 1, address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' })
244
382
  ```
245
383
 
384
+ ## Execution plans
385
+
386
+ `planCandidateExecution` turns a chosen route candidate into the ordered list of
387
+ transactions a wallet sends. Each `PlannedTx` names its chain, its kind
388
+ (`approve`, `bridge`, `swap`, `wrap`, `unwrap` or `claim`), its target, calldata,
389
+ value and gas limit. Every transaction except the last has
390
+ `waitForReceipt: true`, because the next one spends what it produced. When the
391
+ next transaction is on another chain, a receipt is not enough: wait for the
392
+ funds to arrive before you send it.
393
+
394
+ ```ts
395
+ import {
396
+ type AllowanceReader,
397
+ type ResolveNodeToken,
398
+ type RouteCandidate,
399
+ type TokenBridgeInfo,
400
+ planCandidateExecution,
401
+ } from '@gibs/bridge-sdk';
402
+ import type { Hex } from 'viem';
403
+
404
+ declare const candidate: RouteCandidate;
405
+ declare const account: Hex;
406
+ declare const recipient: Hex;
407
+ declare const amountIn: bigint;
408
+ declare const readAllowance: AllowanceReader;
409
+ declare const resolveToken: ResolveNodeToken;
410
+ declare const assetLink: TokenBridgeInfo;
411
+
412
+ const plan = await planCandidateExecution({
413
+ candidate, // a RouteCandidate, with or without an engine plan
414
+ account, // the wallet that signs
415
+ readAllowance, // (chainId, token, owner, spender) => Promise<bigint>
416
+ resolveToken, // the resolver the candidate was built with
417
+ sections: [{
418
+ amountIn,
419
+ recipient,
420
+ omnibridge: { isProd: true, assetLink, unwrap: false, delivery: { shouldDeliver: false } },
421
+ }],
422
+ });
423
+ if (plan.kind === 'refused') throw new Error(plan.refusal.reason);
424
+ ```
425
+
426
+ - **Delivery is your choice, stated up front.** `delivery` is
427
+ `{ shouldDeliver: false }` or `{ shouldDeliver: true, fee }`, where `fee` holds
428
+ the quoted terms, including `maximumFee`, the most the router may take. There
429
+ is no default. The plan reports each delivery it buys in `deliveries`.
430
+ - **Approvals are exact.** The plan approves only the amount a transaction
431
+ spends, and skips an approval the allowance on chain already covers. A short,
432
+ non-zero allowance is reset to zero first, because some tokens refuse to change
433
+ one non-zero allowance into another.
434
+ - **Spenders come from fixed tables.** The plan approves only the omnibridge
435
+ mediator and the swap routers in the swap venues (PulseX by default, see
436
+ "Overriding swap routers"), LI.FI's
437
+ Diamond (`lifiDiamondAddressByChainId`, plus the LI.FI execution guard), and
438
+ Relay's depository (`relayDepositoryByChainId`). A quote that names any other
439
+ spender or deposit target is refused. NEAR Intents may name no spender at all.
440
+ - **Only a live quote is signed.** An aggregator section needs the live quote
441
+ asked for your wallet, in `sections[i].aggregator`. The candidate's own quote
442
+ priced the route on screen and is never signed.
443
+
444
+ ## Overriding swap routers
445
+
446
+ The package swaps on PulseX V1 and V2 on PulseChain by default. You can swap on
447
+ other routers, on any chain. Describe each router as a `SwapVenue` and pass the
448
+ venues to the route search and to execution. Today the only `kind` is
449
+ `'uniswap-v2'`: a router with `getAmountsOut` and the three
450
+ `swapExact...` functions, a factory with `getPair`, and pairs with
451
+ `getReserves`.
452
+
453
+ ```ts
454
+ import {
455
+ type SwapVenues,
456
+ defaultSwapVenues,
457
+ planCandidateExecution,
458
+ resolveSwapVenues,
459
+ } from '@gibs/bridge-sdk';
460
+
461
+ const swapVenues: SwapVenues = {
462
+ // Swap on Ethereum, on Uniswap V2.
463
+ 1: [{
464
+ kind: 'uniswap-v2',
465
+ chainId: 1,
466
+ router: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
467
+ factory: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f',
468
+ feeBasisPoints: 30, // 29 for PulseX, 30 for Uniswap V2 forks
469
+ label: 'Uniswap V2',
470
+ }],
471
+ // An empty list switches swaps off on PulseChain.
472
+ 369: [],
473
+ };
474
+
475
+ // What the engine will use: your chains replace the defaults, other chains keep them.
476
+ const venues = resolveSwapVenues(swapVenues);
477
+ console.log(Object.keys(defaultSwapVenues)); // ['369']
478
+ ```
479
+
480
+ - **A chain you name replaces that chain's default list.** A chain you leave out
481
+ keeps its defaults. An empty list disables swaps on that chain.
482
+ - **A venue on any chain builds swap steps there.** The rule that aggregators
483
+ never receive PulseChain is separate and does not change.
484
+ - **Each swap step records the venue it was priced on.** Signing uses that
485
+ venue's router, also as the approval spender. Pass the same `swapVenues` to
486
+ `planExecution`, `planCandidateExecution` and `readPulseXSectionQuote` that
487
+ you gave the search. A router that is not in the venues throws an error. The
488
+ package never falls back to PulseX.
489
+ - **The LI.FI execution guard does not change.** It checks the LI.FI Diamond
490
+ address and has no override.
491
+ - `uniV2Routers` and `uniV2Factories` stay exported. They are frozen and derive
492
+ from `defaultSwapVenues`.
493
+
494
+ ## Manual claims
495
+
496
+ A crossing from PulseChain to Ethereum or BNB Smart Chain ends with a release on
497
+ the destination chain. When nobody delivers it, the reader claims it.
498
+ `buildClaimTransaction` takes the bridge indexer's `UserRequest` record and
499
+ returns a `claim` transaction, or a typed refusal: `wrong-type`,
500
+ `already-delivered`, `not-signed-yet`, `signatures-incomplete` or
501
+ `malformed-request`. `packSignatures`, `signatureToVRS`,
502
+ `encodeReleaseWithoutTipData`, `encodeReleaseToRouterData` and `claimCall` are
503
+ the parts it is built from.
504
+
505
+ **An assumption about the indexer.** The indexer stores a validator's signature
506
+ only when the validator sends `submitSignature` straight to the home bridge
507
+ (`handleSignedFor` in `packages/indexer/src/index.ts` decodes the transaction's
508
+ own input). A validator that signs through a multisig wallet, a proxy or a
509
+ batching contract still emits `SignedForUserRequest`, so the indexer counts the
510
+ signature in `confirmedSignatures`, but it does not store it in `signatures`.
511
+ `CollectedSignatures` still sets `finishedSigning` to true. The record then says
512
+ "signed" while it holds too few signatures, and a claim built from it reverts on
513
+ the destination bridge. `buildClaimTransaction` catches this. When it stores
514
+ fewer signatures than the threshold (`requiredSignatures.value`, or every counted
515
+ signature when the record carries no threshold), it refuses with
516
+ `signatures-incomplete`. Waiting does not fix that refusal. The indexer has to
517
+ store the missing signature.
518
+
246
519
  ## Nulls, falses and throws
247
520
 
248
521
  The package follows one rule: **a question it cannot answer returns `null`,
@@ -272,18 +545,22 @@ The package writes nothing to the console.
272
545
  | Entry point | What it holds |
273
546
  |---|---|
274
547
  | `@gibs/bridge-sdk/config` | Chains, providers, pathways, native-asset tables |
275
- | `@gibs/bridge-sdk/chains` | viem chain objects with logos and RPC URLs |
548
+ | `@gibs/bridge-sdk/chains` | viem chain objects with logos and public RPC URLs; `demoRpcUrls` for demos only |
276
549
  | `@gibs/bridge-sdk/chain-info` | On-chain reads: token mappings, fees, minimum amounts |
277
550
  | `@gibs/bridge-sdk/settings` | Fee and amount arithmetic, transaction inputs |
278
551
  | `@gibs/bridge-sdk/consolidated-quote` | LI.FI request builders and parsers |
279
552
  | `@gibs/bridge-sdk/relay-quote` | Relay request builders and parsers |
280
553
  | `@gibs/bridge-sdk/near-intents` | NEAR Intents requests and parsers |
281
554
  | `@gibs/bridge-sdk/pre-quote` | Forward-solving price checks before a binding quote |
282
- | `@gibs/bridge-sdk/referral` | Gibs Finance's own referral settings |
555
+ | `@gibs/bridge-sdk/referral` | Gibs Finance's own referral values. No builder applies them. |
283
556
  | `@gibs/bridge-sdk/image-links` | Image URLs |
284
557
  | `@gibs/bridge-sdk/abis` | Contract ABIs |
285
- | `@gibs/bridge-sdk/ton-execution` | TON Connect requests (needs `Buffer`) |
558
+ | `@gibs/bridge-sdk/ton-connect` | TON Connect requests, with no TON library |
559
+ | `@gibs/bridge-sdk/ton` | TON Connect requests and the message hash (needs `@ton/core` and `Buffer`) |
560
+ | `@gibs/bridge-sdk/ton-execution` | Old name of `@gibs/bridge-sdk/ton` |
286
561
  | `@gibs/bridge-sdk/routing` | Route search across carriers |
562
+ | `@gibs/bridge-sdk/execution` | Execution plans: the transactions a chosen route signs, in order |
563
+ | `@gibs/bridge-sdk/claims` | Manual claim transactions for a release nobody delivered |
287
564
 
288
565
  The API can still change in a minor version. Read the release notes before you
289
566
  upgrade.
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../dist/cjs/abis.js",
3
+ "module": "../dist/abis.js",
4
+ "types": "../dist/abis.d.ts",
5
+ "react-native": "../dist/cjs/abis.js"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../dist/cjs/bridge-limits.js",
3
+ "module": "../dist/bridge-limits.js",
4
+ "types": "../dist/bridge-limits.d.ts",
5
+ "react-native": "../dist/cjs/bridge-limits.js"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../dist/cjs/chain-info.js",
3
+ "module": "../dist/chain-info.js",
4
+ "types": "../dist/chain-info.d.ts",
5
+ "react-native": "../dist/cjs/chain-info.js"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../dist/cjs/chain-names.js",
3
+ "module": "../dist/chain-names.js",
4
+ "types": "../dist/chain-names.d.ts",
5
+ "react-native": "../dist/cjs/chain-names.js"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../dist/cjs/chains.js",
3
+ "module": "../dist/chains.js",
4
+ "types": "../dist/chains.d.ts",
5
+ "react-native": "../dist/cjs/chains.js"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../dist/cjs/claims.js",
3
+ "module": "../dist/claims.js",
4
+ "types": "../dist/claims.d.ts",
5
+ "react-native": "../dist/cjs/claims.js"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../dist/cjs/config.js",
3
+ "module": "../dist/config.js",
4
+ "types": "../dist/config.d.ts",
5
+ "react-native": "../dist/cjs/config.js"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../dist/cjs/consolidated-quote.js",
3
+ "module": "../dist/consolidated-quote.js",
4
+ "types": "../dist/consolidated-quote.d.ts",
5
+ "react-native": "../dist/cjs/consolidated-quote.js"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../dist/cjs/destination-calldata.js",
3
+ "module": "../dist/destination-calldata.js",
4
+ "types": "../dist/destination-calldata.d.ts",
5
+ "react-native": "../dist/cjs/destination-calldata.js"
6
+ }
@@ -40,7 +40,7 @@ type LinksInputs = {
40
40
  export declare const links: ((inputs: LinksInputs) => Promise<[Hex, Hex]>) & {
41
41
  cache: {
42
42
  delete: (key: string) => boolean;
43
- clear?: () => void;
43
+ clear: () => void;
44
44
  };
45
45
  };
46
46
  /**
@@ -1,5 +1,5 @@
1
+ import { memoizeByKey } from '@gibs/common/cache';
1
2
  import { multicallRead } from '@gibs/common/multicall';
2
- import * as _ from 'lodash-es';
3
3
  import { encodeFunctionData, getContract, multicall3Abi, zeroAddress, } from 'viem';
4
4
  import * as abis from './abis.js';
5
5
  import { chainsMetadata } from './chains.js';
@@ -30,12 +30,9 @@ const isUnmappedAnswer = ([bridged, native]) => bridged === zeroAddress && nativ
30
30
  * @param inputs.client - a client for that chain
31
31
  * @returns the bridged token address and native token address
32
32
  */
33
- // The annotation is required, not stylistic: `@types/lodash-es` re-exports its
34
- // `MemoizedFunction` type from a nested `@types/lodash` that a generated
35
- // declaration file cannot name (TS2742). The body reaches for `links.cache` to
36
- // evict an answer, so the cache surface is spelled out to the extent this file
37
- // uses it.
38
- export const links = _.memoize(async (inputs) => {
33
+ // The body reaches for `links.cache` to evict an answer, so the cache surface
34
+ // is spelled out to the extent this file uses it.
35
+ export const links = memoizeByKey(async (inputs) => {
39
36
  const { chainId, target, address, client } = inputs;
40
37
  const evict = () => links.cache.delete(linksCacheKey(inputs));
41
38
  const pair = await multicallRead({
@@ -65,8 +62,7 @@ export const links = _.memoize(async (inputs) => {
65
62
  * a fresh view, or between tests.
66
63
  */
67
64
  export const clearChainInfoCaches = () => {
68
- // lodash types mark `clear` optional; the default MapCache always has it
69
- links.cache.clear?.();
65
+ links.cache.clear();
70
66
  };
71
67
  /**
72
68
  * Returns the token bridge info for the given bridge key, asset in, is prod, from chain client, and to chain client
@@ -180,7 +176,8 @@ const readAmountOut = ({ amountIn, chain, paths, client, uniV2Router, }) => {
180
176
  client,
181
177
  abi: abis.univ2Router,
182
178
  // pulsex router
183
- calls: _.flatMap(uniV2Router ? [uniV2Router] : uniV2Routers[chain], (target) => paths.map((path) => ({
179
+ // a chain with no router reads nothing, as lodash's flatMap over undefined did
180
+ calls: (uniV2Router ? [uniV2Router] : (uniV2Routers[chain] ?? [])).flatMap((target) => paths.map((path) => ({
184
181
  functionName: 'getAmountsOut',
185
182
  allowFailure: true,
186
183
  args: [amountIn, path],
@@ -244,7 +241,7 @@ export const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementTo
244
241
  },
245
242
  reduceResults: ({ results, oneToken, }) => {
246
243
  const outputFromRouter = (result) => {
247
- if (_.isString(result)) {
244
+ if (typeof result === 'string') {
248
245
  // the router failed to return a result
249
246
  return 0n;
250
247
  }
@@ -257,7 +254,9 @@ export const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementTo
257
254
  return (last * oneToken) / amountIn;
258
255
  };
259
256
  const max = (amountsOut) => {
260
- return _.compact(amountsOut).reduce((max, current) => (max < current ? current : max), 0n);
257
+ return amountsOut
258
+ .filter((amount) => amount !== undefined)
259
+ .reduce((max, current) => (max < current ? current : max), 0n);
261
260
  };
262
261
  // could do with a refactor to unify the results
263
262
  const [outputs, inputs] = results;
package/dist/chains.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Chains } from './config.js';
1
2
  import type { ChainsMetadata } from './types.js';
2
3
  /**
3
4
  * all of the chains that are enabled in this dapp
@@ -16,6 +17,30 @@ import type { ChainsMetadata } from './types.js';
16
17
  * was at that moment.
17
18
  */
18
19
  export declare const chainsMetadata: ChainsMetadata;
20
+ /**
21
+ * The RPC endpoints the Gibs interface uses, FOR DEMOS ONLY.
22
+ *
23
+ * Each proxied chain's list starts with valve.city's shared `vk_demo` key and
24
+ * falls through to that chain's public endpoints in {@link chainsMetadata}.
25
+ * Binance Smart Chain has no valve.city entry, so its list is the public one.
26
+ *
27
+ * WHY IT IS A SEPARATE, NAMED LIST. The key is public, so shipping it discloses
28
+ * nothing. But its rate budget is shared by everybody who uses it, and the proxy
29
+ * belongs to the Gibs Finance operator. A wallet that inherits it without
30
+ * choosing it puts its users' reads on somebody else's budget and uptime. So no
31
+ * reader in this package uses it, and `chainsMetadata` does not carry it. A
32
+ * caller who wants it asks for it by this name.
33
+ *
34
+ * Production callers: pass your own viem clients to every reader.
35
+ */
36
+ export declare const demoRpcUrls: Readonly<Record<Chains, readonly string[]>>;
37
+ /**
38
+ * The demo endpoints for one chain, FOR DEMOS ONLY. See {@link demoRpcUrls}.
39
+ *
40
+ * @param chainId - a decimal chain id
41
+ * @returns a copy of the chain's demo endpoints, or an empty list for a chain the bridge does not cross
42
+ */
43
+ export declare const demoRpcUrlsFor: (chainId: number) => string[];
19
44
  /**
20
45
  * Every chain this bridge itself carries funds across, in the order the
21
46
  * metadata declares them.