@gibs/bridge-sdk 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +234 -432
  3. package/dist/abis.d.ts +1 -0
  4. package/dist/bridge-limits.d.ts +103 -0
  5. package/dist/bridge-limits.js +84 -0
  6. package/dist/chain-info.d.ts +169 -0
  7. package/dist/chain-info.js +410 -0
  8. package/dist/chain-names.d.ts +160 -0
  9. package/dist/chain-names.js +200 -0
  10. package/dist/chains.d.ts +65 -0
  11. package/dist/chains.js +284 -0
  12. package/dist/config.d.ts +216 -0
  13. package/dist/config.js +493 -0
  14. package/dist/consolidated-quote.d.ts +554 -0
  15. package/dist/consolidated-quote.js +773 -0
  16. package/dist/destination-calldata.d.ts +118 -0
  17. package/dist/destination-calldata.js +152 -0
  18. package/dist/ecosystems.d.ts +217 -0
  19. package/dist/ecosystems.js +288 -0
  20. package/dist/fee-type.d.ts +10 -0
  21. package/dist/fee-type.js +9 -0
  22. package/dist/hyperliquid-execution.d.ts +152 -0
  23. package/dist/hyperliquid-execution.js +168 -0
  24. package/dist/image-links.d.ts +117 -0
  25. package/dist/image-links.js +142 -0
  26. package/dist/index.d.ts +20 -0
  27. package/dist/index.js +20 -0
  28. package/dist/lifi-execution-guard.d.ts +199 -0
  29. package/dist/lifi-execution-guard.js +400 -0
  30. package/dist/near-intents-conformance.d.ts +85 -0
  31. package/dist/near-intents-conformance.js +329 -0
  32. package/dist/near-intents-route.d.ts +47 -0
  33. package/dist/near-intents-route.js +265 -0
  34. package/dist/near-intents.d.ts +524 -0
  35. package/dist/near-intents.js +1055 -0
  36. package/dist/origin-deposit.d.ts +326 -0
  37. package/dist/origin-deposit.js +68 -0
  38. package/dist/pre-quote.d.ts +198 -0
  39. package/dist/pre-quote.js +175 -0
  40. package/dist/prices.d.ts +107 -0
  41. package/dist/prices.js +162 -0
  42. package/dist/providers.d.ts +221 -0
  43. package/dist/providers.js +157 -0
  44. package/dist/quote-fees.d.ts +102 -0
  45. package/dist/quote-fees.js +195 -0
  46. package/dist/referral.d.ts +77 -0
  47. package/dist/referral.js +72 -0
  48. package/dist/relay-currencies.d.ts +47 -0
  49. package/dist/relay-currencies.js +89 -0
  50. package/dist/relay-quote.d.ts +301 -0
  51. package/dist/relay-quote.js +983 -0
  52. package/dist/route-steps.d.ts +138 -0
  53. package/dist/route-steps.js +305 -0
  54. package/dist/routing/amounts.d.ts +80 -0
  55. package/dist/routing/amounts.js +120 -0
  56. package/dist/routing/candidate-route.d.ts +43 -0
  57. package/dist/routing/candidate-route.js +45 -0
  58. package/dist/routing/candidate.d.ts +237 -0
  59. package/dist/routing/candidate.js +96 -0
  60. package/dist/routing/carriers/ask-answer.d.ts +58 -0
  61. package/dist/routing/carriers/ask-answer.js +1 -0
  62. package/dist/routing/carriers/omnibridge.d.ts +137 -0
  63. package/dist/routing/carriers/omnibridge.js +419 -0
  64. package/dist/routing/carriers/pulsex.d.ts +111 -0
  65. package/dist/routing/carriers/pulsex.js +404 -0
  66. package/dist/routing/carriers/wrap.d.ts +25 -0
  67. package/dist/routing/carriers/wrap.js +115 -0
  68. package/dist/routing/composed-route-quality.d.ts +103 -0
  69. package/dist/routing/composed-route-quality.js +108 -0
  70. package/dist/routing/entry-chain-anchor.d.ts +88 -0
  71. package/dist/routing/entry-chain-anchor.js +55 -0
  72. package/dist/routing/format.d.ts +31 -0
  73. package/dist/routing/format.js +58 -0
  74. package/dist/routing/index.d.ts +34 -0
  75. package/dist/routing/index.js +42 -0
  76. package/dist/routing/producers.d.ts +770 -0
  77. package/dist/routing/producers.js +1564 -0
  78. package/dist/routing/providers.d.ts +26 -0
  79. package/dist/routing/providers.js +38 -0
  80. package/dist/routing/route-data.d.ts +355 -0
  81. package/dist/routing/route-data.js +1 -0
  82. package/dist/routing/search/compose.d.ts +168 -0
  83. package/dist/routing/search/compose.js +98 -0
  84. package/dist/routing/search/graph.d.ts +639 -0
  85. package/dist/routing/search/graph.js +445 -0
  86. package/dist/routing/search/plan-route-data.d.ts +244 -0
  87. package/dist/routing/search/plan-route-data.js +767 -0
  88. package/dist/routing/search/score.d.ts +324 -0
  89. package/dist/routing/search/score.js +400 -0
  90. package/dist/routing/usd-value.d.ts +17 -0
  91. package/dist/routing/usd-value.js +25 -0
  92. package/dist/settings.d.ts +692 -0
  93. package/dist/settings.js +909 -0
  94. package/dist/ton-execution.d.ts +117 -0
  95. package/dist/ton-execution.js +247 -0
  96. package/dist/tron-execution.d.ts +146 -0
  97. package/dist/tron-execution.js +239 -0
  98. package/dist/types.d.ts +51 -0
  99. package/dist/types.js +1 -0
  100. package/package.json +203 -23
  101. package/src/chain-info.test.ts +0 -968
  102. package/src/chain-info.ts +0 -498
  103. package/src/chains.test.ts +0 -123
  104. package/src/chains.ts +0 -88
  105. package/src/config.test.ts +0 -679
  106. package/src/config.ts +0 -500
  107. package/src/fee-type.test.ts +0 -45
  108. package/src/fee-type.ts +0 -14
  109. package/src/image-links.test.ts +0 -160
  110. package/src/image-links.ts +0 -65
  111. package/src/index.ts +0 -8
  112. package/src/settings.test.ts +0 -2754
  113. package/src/settings.ts +0 -875
  114. package/src/types.ts +0 -48
  115. package/tsconfig.json +0 -17
  116. package/vitest.config.ts +0 -13
  117. /package/{src/abis.ts → dist/abis.js} +0 -0
package/README.md CHANGED
@@ -1,487 +1,289 @@
1
- # Bridge SDK
1
+ # @gibs/bridge-sdk
2
2
 
3
- A comprehensive toolkit for facilitating cross-chain bridge operations across multiple blockchain networks. This SDK provides low-level building blocks for implementing bridge functionality in decentralized applications.
3
+ Build and price transfers across the PulseChain omnibridges (PulseChain and
4
+ Ethereum, PulseChain and Binance Smart Chain), and the aggregator routes
5
+ (LI.FI, Relay, NEAR Intents) that reach those bridges from other chains.
4
6
 
5
- ## 🎯 Use Cases
7
+ The package gives you pathway configuration, fee reads, request builders and
8
+ response parsers. It does not sign or send anything. You bring a
9
+ [viem](https://viem.sh) client and a wallet.
6
10
 
7
- ### Primary Use Cases
8
- - **Cross-Chain Bridge Implementation**: Build applications that move tokens between different blockchain networks
9
- - **Multi-Chain DApp Development**: Create applications that operate across PulseChain, Ethereum, Binance Smart Chain, and other supported networks
10
- - **Bridge Provider Integration**: Integrate with multiple bridge providers (PulseChain native bridges, TokenSex, etc.)
11
- - **Token Metadata Management**: Access standardized token information, logos, and network-specific addresses
12
- - **Fee Calculation**: Calculate and manage bridge fees across different providers and networks
11
+ Every TypeScript sample in this file is compiled by the package's test suite
12
+ (`src/compile-checks.test.ts`), so a sample that stops matching the code fails the build.
13
13
 
14
- ### Target Applications
15
- - Cross-chain DEX interfaces
16
- - Bridge aggregator platforms
17
- - Multi-chain portfolio management tools
18
- - DeFi applications requiring cross-chain functionality
19
- - Wallet applications with bridge features
20
-
21
- ## 🔧 Core Functionality
22
-
23
- ### Chain Management
24
- - **Supported Networks**: PulseChain (0x171), Ethereum (0x1), Binance Smart Chain (0x38), and testnets
25
- - **Chain Metadata**: Complete chain configurations including RPC URLs, native tokens, and visual assets
26
- - **Chain Utilities**: Convert between chain IDs and human-readable chain keys
27
-
28
- ### Token & Bridge Configuration
29
- - **Token Types**: Standardized token metadata with cross-chain bridge information
30
- - **Bridge Providers**: Support for multiple bridge providers with different fee structures
31
- - **Asset Mapping**: Native asset addresses and wrapped token configurations across chains
32
-
33
- ### Smart Contract Integration
34
- - **ABIs**: Pre-configured contract ABIs for bridge operations
35
- - **Contract Addresses**: Deployed contract addresses across supported networks
36
- - **Type Safety**: Full TypeScript support with strongly typed contract interactions
37
-
38
- ## 📦 Installation
14
+ ## Install
39
15
 
40
16
  ```sh
41
- npm install @gibs/bridge-sdk
42
- # or
43
- yarn add @gibs/bridge-sdk
17
+ npm install @gibs/bridge-sdk viem
44
18
  ```
45
19
 
46
- ## 📖 API Examples
47
-
48
- ### Types (`@gibs/bridge-sdk/types`)
49
-
50
- ```typescript
51
- import type {
52
- Token,
53
- BridgeKey,
54
- TokenList,
55
- TokenOut,
56
- PerNetworkBridgeLink,
57
- Extensions,
58
- TokenMetadata,
59
- VisualChain
60
- } from '@gibs/bridge-sdk/types'
61
-
62
- // Core token metadata
63
- const tokenMetadata: TokenMetadata = {
64
- name: "Wrapped Ethereum",
65
- symbol: "WETH",
66
- decimals: 18
67
- }
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`.
68
28
 
69
- // Bridge link information
70
- const bridgeLink: PerNetworkBridgeLink = {
71
- tokenAddress: "0x..." // Address on destination chain
72
- }
29
+ Import from the narrowest entry point you need (`@gibs/bridge-sdk/config`,
30
+ `@gibs/bridge-sdk/chain-info`, and so on). The root `@gibs/bridge-sdk` exports
31
+ everything.
73
32
 
74
- // Token extensions for cross-chain info
75
- const extensions: Extensions = {
76
- wrapped: { address: "0x..." },
77
- bridgeInfo: {
78
- 369: { tokenAddress: "0x..." } // PulseChain mapping
79
- }
80
- }
33
+ ## Chains and bridge keys
81
34
 
82
- // Complete token with bridge metadata
83
- const token: Token = {
84
- ...tokenMetadata,
85
- address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
86
- chainId: 1,
87
- logoURI: "https://example.com/weth.png",
88
- extensions
89
- }
35
+ A chain is a hex chain id from the `Chains` enum. A route is a `BridgeKey`:
36
+ `[provider, fromChain, toChain]`.
90
37
 
91
- // Token for output (address can be null)
92
- const tokenOut: TokenOut = {
93
- ...tokenMetadata,
94
- address: null, // Can be null for native tokens
95
- chainId: 369,
96
- logoURI: null
97
- }
38
+ ```ts
39
+ import { Chains, Providers, toChain, toChainKey, validBridgeKeys } from '@gibs/bridge-sdk/config'
40
+ import type { BridgeKey } from '@gibs/bridge-sdk/types'
98
41
 
99
- // Bridge route definition
100
- const bridgeKey: BridgeKey = [
101
- 'pulsechain', // Provider
102
- '0x1', // From chain (Ethereum)
103
- '0x171' // To chain (PulseChain)
104
- ]
105
-
106
- // Visual chain with logo info
107
- const visualChain: VisualChain = {
108
- id: 369,
109
- name: 'PulseChain',
110
- chainId: '0x171' as any,
111
- logoURI: 'https://example.com/pls.png',
112
- alt: 'PulseChain logo'
113
- // ... other Chain properties
114
- }
115
- ```
42
+ const ethereumToPulsechain: BridgeKey = [Providers.PULSECHAIN, Chains.ETH, Chains.PLS]
43
+ const binanceToPulsechain: BridgeKey = [Providers.TOKENSEX, Chains.BNB, Chains.PLS]
116
44
 
117
- ### Config (`@gibs/bridge-sdk/config`)
45
+ toChain(369) // Chains.PLS, which is '0x171'
46
+ toChainKey(369) // 'PLS'
118
47
 
119
- ```typescript
120
- import {
121
- Chains,
122
- Provider,
123
- toChain,
124
- toChainKey,
125
- pathways,
126
- validBridgeKeys,
127
- inferBridgeKey,
128
- pathway,
129
- isNative,
130
- canChangeUnwrap,
131
- defaultAssetIn
132
- } from '@gibs/bridge-sdk/config'
133
-
134
- // Chain enum usage
135
- console.log(Chains.PLS) // "0x171"
136
- console.log(Chains.ETH) // "0x1"
137
-
138
- // Provider enum usage
139
- console.log(Provider.PULSECHAIN) // "pulsechain"
140
-
141
- // Convert numeric chain ID to hex
142
- const chainHex = toChain(369) // "0x171"
143
- const chainHex2 = toChain("369") // "0x171"
144
-
145
- // Convert chain ID to human-readable key
146
- const chainKey = toChainKey(369) // "PLS"
147
-
148
- // Get all valid bridge routes for environment
149
- const bridgeRoutes = validBridgeKeys(true) // Production routes
150
- const testRoutes = validBridgeKeys(false) // Include testnets
151
-
152
- // Find bridge provider for chain pair
153
- const bridgeKey = inferBridgeKey({
154
- fromChain: Chains.ETH,
155
- toChain: Chains.PLS,
156
- isProd: true
157
- }) // Returns: ['pulsechain', '0x1', '0x171']
158
-
159
- // Get pathway configuration for a bridge route
160
- const pathwayConfig = pathway(['pulsechain', '0x1', '0x171'], true)
161
- console.log(pathwayConfig?.from) // Bridge contract on Ethereum
162
- console.log(pathwayConfig?.to) // Bridge contract on PulseChain
163
-
164
- // Check if token is native to chain
165
- const native = isNative(token, bridgeKey) // boolean
166
-
167
- // Check if unwrapping is allowed
168
- const canUnwrap = canChangeUnwrap(bridgeKey, token) // boolean
169
-
170
- // Get default asset for bridge route
171
- const defaultToken = defaultAssetIn(bridgeKey, true) // Default token address
48
+ // Mainnet keys only. Pass false to add the testnet pair (Sepolia and PulseChain testnet V4).
49
+ const mainnetKeys: BridgeKey[] = validBridgeKeys(true)
172
50
  ```
173
51
 
174
- ```typescript
175
- import {
176
- nativeAssetOut,
177
- nativeTokenSymbol,
178
- nativeTokenName,
179
- uniV2Routers
180
- } from '@gibs/bridge-sdk/config'
181
-
182
- // Get native wrapped token address for a chain
183
- const wethAddress = nativeAssetOut[Chains.ETH] // "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
184
- const wplsAddress = nativeAssetOut[Chains.PLS] // "0xA1077a294dDE1B09bB078844df40758a5D0f9a27"
185
-
186
- // Get native token symbols and names
187
- const ethSymbol = nativeTokenSymbol[Chains.ETH] // "ETH"
188
- const plsName = nativeTokenName[Chains.PLS] // "Pulse"
189
-
190
- // Get UniV2 router addresses for chain
191
- const plsRouters = uniV2Routers[Chains.PLS] // Array of router addresses
192
- ```
52
+ `isProd` means "mainnet only" everywhere in this package. With `isProd: false`,
53
+ lookups read the mainnet map first and then the testnet map.
193
54
 
194
- ### Settings (`@gibs/bridge-sdk/settings`)
55
+ `inferBridgeKey` repairs a key after the reader changes provider or chain. It
56
+ returns `null` when no pathway can serve the request. It never answers a
57
+ testnet pair with a mainnet key.
195
58
 
196
- ```typescript
197
- import {
198
- oneEther,
199
- basisPoints,
200
- bridgePathway,
201
- amountToBridge,
202
- bridgeCost,
203
- estimatedAmountOut,
204
- estimatedFee,
205
- oneTokenInt,
206
- assetOutKey,
207
- assetOut
208
- } from '@gibs/bridge-sdk/settings'
209
-
210
- // Common constants
211
- console.log(oneEther) // 1000000000000000000n (1e18)
212
- console.log(basisPoints) // 10000n
213
-
214
- // Calculate actual amount to bridge
215
- const amount = amountToBridge({
216
- amountIn: 1000000000000000000n, // 1 ETH
217
- assetIn: token,
218
- }) // Returns 1000000000000000000n or 0n if invalid
219
-
220
- // Calculate bridge cost
221
- const cost = bridgeCost({
222
- bridgeKey: ['pulsechain', '0x1', '0x171'],
223
- amountIn: oneEther,
224
- // ... other parameters
225
- })
59
+ ```ts
60
+ import { Chains, inferBridgeKey, Providers } from '@gibs/bridge-sdk/config'
226
61
 
227
- // Estimate output amount after fees
228
- const outputAmount = estimatedAmountOut({
229
- amountIn: oneEther,
230
- bridgeKey: ['pulsechain', '0x1', '0x171'],
231
- // ... fee parameters
232
- })
62
+ const repaired = inferBridgeKey({
63
+ currentKey: [Providers.PULSECHAIN, Chains.SEP, Chains.ETH],
64
+ provider: Providers.PULSECHAIN,
65
+ }) // [pulsechain, Sepolia, PulseChain testnet V4]
233
66
 
234
- // Calculate fee amount
235
- const feeAmount = estimatedFee({
236
- amountIn: oneEther,
237
- feeType: 'percent',
238
- // ... other parameters
239
- })
240
-
241
- // Convert amount to "one token" representation
242
- const oneToken = oneTokenInt({
243
- decimals: 18,
244
- amount: oneEther
245
- }) // 1000000000000000000n
246
-
247
- // Generate asset out key for caching
248
- const cacheKey = assetOutKey({
249
- bridgeKey: ['pulsechain', '0x1', '0x171'],
250
- assetIn: token
251
- }) // String key for asset lookup
252
-
253
- // Get output asset configuration
254
- const outputAsset = assetOut({
255
- bridgeKey: ['pulsechain', '0x1', '0x171'],
256
- assetIn: token,
257
- // ... other parameters
258
- })
67
+ const refused = inferBridgeKey({
68
+ currentKey: [Providers.PULSECHAIN, Chains.SEP, Chains.V4PLS],
69
+ provider: Providers.PULSECHAIN,
70
+ isProd: true,
71
+ }) // null: testnets are off
259
72
  ```
260
73
 
261
- ### Chain Info (`@gibs/bridge-sdk/chain-info`)
262
-
263
- ```typescript
264
- import {
265
- loadBridgeFees,
266
- nativeSymbol,
267
- tokenBridgeInfo,
268
- fetchPriceCorrective,
269
- minBridgeAmountIn,
270
- chainMulticall
271
- } from '@gibs/bridge-sdk/chain-info'
272
-
273
- // Load bridge fees for a route
274
- const fees = await loadBridgeFees({
275
- pathway: pathwayConfig,
276
- fromChainClient: ethClient,
277
- toChainClient: plsClient
278
- })
279
-
280
- // Get native symbol for token, with unwrap logic
281
- const symbol = nativeSymbol(token, false) // "WETH" or "ETH" if unwrapped
282
-
283
- // Get token bridge information
284
- const bridgeInfo = await tokenBridgeInfo({
285
- bridgeKey: ['pulsechain', '0x1', '0x171'],
286
- client: ethClient,
287
- target: token.address,
288
- // ... other parameters
289
- })
74
+ ## Pathways and native assets
290
75
 
291
- // Fetch price corrective data
292
- const priceData = fetchPriceCorrective({
293
- bridgeKey: ['pulsechain', '0x1', '0x171'],
294
- // ... other parameters
295
- })
76
+ ```ts
77
+ import { Chains, isNative, isUnwrappable, pathway, Providers } from '@gibs/bridge-sdk/config'
78
+ import type { BridgeKey, Token } from '@gibs/bridge-sdk/types'
296
79
 
297
- // Get minimum bridge amount
298
- const minAmount = await minBridgeAmountIn({
299
- bridgeKey: ['pulsechain', '0x1', '0x171'],
300
- client: ethClient,
301
- // ... other parameters
302
- })
80
+ const bridgeKey: BridgeKey = [Providers.PULSECHAIN, Chains.ETH, Chains.PLS]
81
+ const route = pathway(bridgeKey, true)
82
+ if (route) {
83
+ route.from // the mediator on Ethereum, where the funds enter
84
+ route.feeManager // 'to': the PulseChain mediator owns the fee manager
85
+ }
303
86
 
304
- // Create multicall helper for chain
305
- const multicall = chainMulticall(ethClient)
306
- // Use for batched contract calls
87
+ declare const token: Token
88
+ const native: boolean = isNative(token, bridgeKey, { isProd: true })
89
+ const unwrappable: boolean = isUnwrappable(bridgeKey, token, { isProd: true })
307
90
  ```
308
91
 
309
- ### Image Links (`@gibs/bridge-sdk/image-links`)
310
-
311
- ```typescript
312
- import * as imageLinks from '@gibs/bridge-sdk/image-links'
313
-
314
- // Configure image root URL
315
- imageLinks.setImageRoot('https://cdn.example.com/images/')
316
- const currentRoot = imageLinks.getImageRoot() // Current root URL
317
-
318
- // Get network image URL
319
- const networkImage = imageLinks.network(1) // Ethereum logo URL
320
- const plsImage = imageLinks.network(369) // PulseChain logo URL
321
-
322
- // Get single token image
323
- const tokenImage = imageLinks.image({
324
- chainId: 1,
325
- address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
326
- })
327
-
328
- // Get token images for multiple sources
329
- const tokenImages = imageLinks.images([
330
- "1/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH on Ethereum
331
- "369/0xA1077a294dDE1B09bB078844df40758a5D0f9a27" // WPLS on PulseChain
332
- ])
333
-
334
- // List available images in a directory
335
- const availableImages = imageLinks.list('tokens/') // Array of image paths
92
+ `isNative` and `isUnwrappable` never throw. They answer `false` for a token with
93
+ a `null` address, a malformed address, or a bridge key with no pathway. Leave
94
+ out the options and they read both maps, as before the option existed.
95
+
96
+ ## Fees and units
97
+
98
+ Two unit systems appear, and they are not the same:
99
+
100
+ - **Bridge fees are a rate per `1e18`.** `1e18` is one hundred percent.
101
+ `loadBridgeFees` returns `feeH2F` and `feeF2H` in this unit, and `bridgeCost`
102
+ divides by `oneEther` (`10n ** 18n`).
103
+ - **Aggregator referral fees are basis points.** `10_000n` is one hundred
104
+ percent, so `10n` is a tenth of a percent. LI.FI takes the same fee as a
105
+ decimal fraction (`0.001`).
106
+
107
+ **Direction decides which fee applies.** PulseChain is the home side of both
108
+ omnibridges.
109
+
110
+ - Foreign to home (`feeF2H`): **entering** PulseChain.
111
+ - Home to foreign (`feeH2F`): **leaving** PulseChain.
112
+
113
+ The pathway's `feeManager` field names the side whose mediator owns the fee
114
+ manager (`'from'` or `'to'`). `loadBridgeFees` reads it on that side.
115
+
116
+ When this file was written, entering PulseChain over Ethereum charged nothing
117
+ and leaving charged 0.3%. The Binance Smart Chain bridge charged 2.97% each
118
+ way. These are on-chain settings, so read them; do not hard-code them.
119
+
120
+ ```ts
121
+ import { loadBridgeFees } from '@gibs/bridge-sdk/chain-info'
122
+ import { Chains, pathway, Providers } from '@gibs/bridge-sdk/config'
123
+ import { amountAfterBridgeFee, bridgeCost } from '@gibs/bridge-sdk/settings'
124
+ import type { PublicClient } from 'viem'
125
+
126
+ declare const ethereumClient: PublicClient
127
+ declare const pulsechainClient: PublicClient
128
+
129
+ const route = pathway([Providers.PULSECHAIN, Chains.ETH, Chains.PLS], true)
130
+ if (route) {
131
+ const { feeF2H } = await loadBridgeFees({
132
+ pathway: route,
133
+ fromChainClient: ethereumClient,
134
+ toChainClient: pulsechainClient,
135
+ })
136
+ const amountToBridge = 1_000_000n
137
+ const cost = bridgeCost({ amountToBridge, bridgeFee: feeF2H })
138
+ const received = amountAfterBridgeFee({ amountToBridge, bridgeCost: cost })
139
+ }
336
140
  ```
337
141
 
338
- ### ABIs (`@gibs/bridge-sdk/abis`)
142
+ `loadBridgeFees` reads the fee manager's default rate (`getFee(key, address(0))`).
143
+ A fee manager can also hold a rate for one token. This package does not read
144
+ per-token rates yet.
339
145
 
340
- ```typescript
341
- import * as abis from '@gibs/bridge-sdk/abis'
146
+ ## Tokens that are not bridged yet
342
147
 
343
- // Bridge contract ABIs
344
- const inputBridgeAbi = abis.inputBridge // Input bridge contract
345
- const outputBridgeAbi = abis.outputBridge // Output bridge contract
346
- const outputRouterAbi = abis.outputRouter // Output router contract
148
+ `tokenBridgeInfo` asks both mediators how a token maps across the bridge.
347
149
 
348
- // Token contract ABIs
349
- const erc677Abi = abis.erc677 // ERC677 token contract
350
- const erc677ExtraAbi = abis.erc677ExtraInput // With extra input functions
150
+ ```ts
151
+ import { tokenBridgeInfo } from '@gibs/bridge-sdk/chain-info'
152
+ import { Chains, Providers } from '@gibs/bridge-sdk/config'
153
+ import type { Token } from '@gibs/bridge-sdk/types'
154
+ import type { PublicClient } from 'viem'
351
155
 
352
- // Router and fee ABIs
353
- const nativeRouterAbi = abis.nativeRouter // Native token router
354
- const feeManagerAbi = abis.feeManager // Fee management contract
355
- const univ2RouterAbi = abis.univ2Router // UniswapV2 router
156
+ declare const assetIn: Token
157
+ declare const ethereumClient: PublicClient
158
+ declare const pulsechainClient: PublicClient
356
159
 
357
- // Utility ABIs and types
358
- const feeDeliveryStruct = abis.feeDeliveryStruct // Fee delivery struct ABI
359
- const homeAmbAbi = abis.homeAmb // Home AMB contract
360
- const pairAbi = abis.pair // Pair contract
361
-
362
- // Use with viem contract calls
363
- const contract = getContract({
364
- address: bridgeAddress,
365
- abi: inputBridgeAbi,
366
- client: publicClient
160
+ const info = await tokenBridgeInfo({
161
+ bridgeKey: [Providers.PULSECHAIN, Chains.ETH, Chains.PLS],
162
+ assetIn,
163
+ isProd: true,
164
+ fromChainClient: ethereumClient,
165
+ toChainClient: pulsechainClient,
367
166
  })
368
-
369
- const bridgeFunction = contract.read.someFunction()
167
+ if (info && info.assetOutAddress === null) {
168
+ // Not bridged yet: the first transfer creates the token on the far side.
169
+ }
370
170
  ```
371
171
 
372
- ### Fee Types (`@gibs/bridge-sdk/fee-type`)
172
+ A `null` `assetOutAddress` is a normal answer, not an error. The token gets an
173
+ address on the far side when its first transfer arrives.
373
174
 
374
- ```typescript
375
- import { FeeType, feeTypeValToKeyMap, type FeeTypeKeys } from '@gibs/bridge-sdk/fee-type'
175
+ The package caches a mapping once it exists, because a mediator never changes
176
+ one. It does not cache the "not bridged yet" answer, so the next call reads the
177
+ chain again. Call `clearChainInfoCaches()` to drop every cached answer.
376
178
 
377
- // Fee type enum
378
- console.log(FeeType.PERCENT) // "%"
379
- console.log(FeeType.GAS_TIP) // "gas+%"
380
- console.log(FeeType.FIXED) // "fixed"
179
+ ## Aggregator quotes and your identity
381
180
 
382
- // Fee type keys
383
- const percentKey: FeeTypeKeys = 'PERCENT'
384
- const gasTipKey: FeeTypeKeys = 'GAS_TIP'
181
+ 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.
385
184
 
386
- // Convert fee type value back to key
387
- const feeTypeKey = feeTypeValToKeyMap.get('%') // "PERCENT"
388
- const gasKey = feeTypeValToKeyMap.get('gas+%') // "GAS_TIP"
389
- ```
390
-
391
- ### Chains (`@gibs/bridge-sdk/chains`)
185
+ | Field | Default | Why |
186
+ |---|---|---|
187
+ | Relay `x-api-key` | none | Pass your own to `relayRequestHeaders`. A key carries a rate-limit budget. |
188
+ | 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. |
190
+ | 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. |
392
192
 
393
- ```typescript
394
- import { chainsMetadata } from '@gibs/bridge-sdk/chains'
395
- import { Chains } from '@gibs/bridge-sdk/config'
193
+ Each attribution field takes three states: leave it out for the default, pass
194
+ `null` to omit it, or pass your own string.
396
195
 
397
- // Get complete chain configuration
398
- const pulseChain = chainsMetadata[Chains.PLS]
399
- console.log(pulseChain.name) // "PulseChain"
400
- console.log(pulseChain.chainId) // "0x171"
401
- console.log(pulseChain.logoURI) // Chain logo URL
402
- console.log(pulseChain.rpcUrls.default.http[0]) // Default RPC URL
403
-
404
- // Access native currency info
405
- console.log(pulseChain.nativeCurrency.name) // "Pulse"
406
- console.log(pulseChain.nativeCurrency.symbol) // "PLS"
407
- console.log(pulseChain.nativeCurrency.decimals) // 18
408
-
409
- // Access contract addresses
410
- console.log(pulseChain.contracts?.multicall3?.address) // Multicall3 address
411
- console.log(pulseChain.contracts?.ensRegistry?.address) // ENS registry if available
412
- ```
413
-
414
- ## 📋 API Reference
415
-
416
- ### Exports
417
-
418
- | Export Path | Description |
419
- |-------------|-------------|
420
- | `@gibs/bridge-sdk` | Main entry point with all exports |
421
- | `@gibs/bridge-sdk/types` | TypeScript type definitions |
422
- | `@gibs/bridge-sdk/config` | Chain IDs, providers, and core configuration |
423
- | `@gibs/bridge-sdk/chains` | Chain metadata and network configurations |
424
- | `@gibs/bridge-sdk/abis` | Smart contract ABIs |
425
- | `@gibs/bridge-sdk/image-links` | Network and token image utilities |
426
- | `@gibs/bridge-sdk/fee-type` | Fee calculation types and utilities |
427
- | `@gibs/bridge-sdk/settings` | Bridge settings and configuration |
428
- | `@gibs/bridge-sdk/chain-info` | Chain-specific bridge information |
429
-
430
- ### Key Types
431
-
432
- ```typescript
433
- // Core chain identifier
434
- enum Chains {
435
- PLS = '0x171', // PulseChain
436
- ETH = '0x1', // Ethereum
437
- BNB = '0x38', // Binance Smart Chain
438
- SEP = '0xaa36a7', // Sepolia Testnet
439
- V4PLS = '0x3af' // PulseChain V4 Testnet
196
+ ```ts
197
+ import {
198
+ buildLifiContractCallsRequest,
199
+ type ConsolidatedQuoteRequest,
200
+ } from '@gibs/bridge-sdk/consolidated-quote'
201
+ import { nearIntentsRequestHeaders } from '@gibs/bridge-sdk/near-intents'
202
+ import { buildRelayQuoteRequest, relayQuoteUrl, relayRequestHeaders } from '@gibs/bridge-sdk/relay-quote'
203
+
204
+ declare const baseRequest: ConsolidatedQuoteRequest
205
+ declare const myRelayApiKey: string
206
+
207
+ const request: ConsolidatedQuoteRequest = {
208
+ ...baseRequest,
209
+ lifiIntegrator: 'your-app.example',
210
+ lifiFee: 0.001, // a tenth of a percent, paid to your LI.FI integrator account
211
+ relayReferrer: 'your-app.example',
440
212
  }
441
213
 
442
- // Bridge providers
443
- enum Provider {
444
- PULSECHAIN = 'pulsechain',
445
- TOKENSEX = 'tokensex'
214
+ const lifiBody = buildLifiContractCallsRequest(request)
215
+ const relayBody = buildRelayQuoteRequest(request)
216
+ if (relayBody) {
217
+ await fetch(relayQuoteUrl, {
218
+ method: 'POST',
219
+ body: JSON.stringify(relayBody),
220
+ headers: relayRequestHeaders(myRelayApiKey),
221
+ })
446
222
  }
447
223
 
448
- // Bridge route: [Provider, FromChain, ToChain]
449
- type BridgeKey = [Provider, Chains, Chains]
450
-
451
- // Token with bridge metadata
452
- interface Token {
453
- name: string
454
- symbol: string
455
- decimals: number
456
- address: string
457
- chainId: number
458
- logoURI: string | null
459
- extensions?: {
460
- wrapped?: { address: Hex }
461
- bridgeInfo?: Record<number, PerNetworkBridgeLink>
462
- }
463
- }
224
+ const nearHeaders = nearIntentsRequestHeaders(undefined, { userAgent: 'your-app/1.0' })
464
225
  ```
465
226
 
466
- ## ⚠️ Important Notes
467
-
468
- - **Beta Stage**: This SDK is in active development. APIs may change between versions.
469
- - **Version Sync**: All packages in this monorepo maintain synchronized versions.
470
- - **Low-Level Tools**: These are building blocks that require careful integration.
471
- - **Dependencies**: Built on top of `@gibs/common` utilities and `viem` for Ethereum interactions.
472
-
473
- ## 🔗 Dependencies
227
+ Relay quotes work without a key on its anonymous tier. Relay's `/requests/v3`
228
+ status lookup does not: it answers 400 without `x-api-key`.
474
229
 
475
- - `@gibs/common`: Shared utilities for RPC clients, caching, and ERC20 operations
476
- - `viem`: Type-safe Ethereum library for contract interactions
477
- - `lodash`: Utility functions for data manipulation
230
+ ## Images
478
231
 
479
- ## 📝 Development Status
232
+ Chain logos and token images come from [gib.show](https://gib.show). Point them
233
+ at your own host with `setImageRoot`. Chain logos in `chainsMetadata` read the
234
+ root each time you access them, so a later call still takes effect.
480
235
 
481
- This package is actively maintained and used in production bridge applications. However, as it's in beta:
236
+ ```ts
237
+ import { chainsMetadata } from '@gibs/bridge-sdk/chains'
238
+ import { Chains } from '@gibs/bridge-sdk/config'
239
+ import { image, setImageRoot } from '@gibs/bridge-sdk/image-links'
482
240
 
483
- - APIs may change in minor version updates
484
- - New bridge providers and chains are regularly added
485
- - Breaking changes will be documented in release notes
241
+ setImageRoot('https://images.example.org')
242
+ chainsMetadata[Chains.PLS].logoURI // 'https://images.example.org/image/369'
243
+ image({ chainId: 1, address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' })
244
+ ```
486
245
 
487
- For the most up-to-date information, check the package version and changelog.
246
+ ## Nulls, falses and throws
247
+
248
+ The package follows one rule: **a question it cannot answer returns `null`,
249
+ `undefined` or `false`; a caller mistake or a failed read throws.**
250
+
251
+ Returns without throwing:
252
+
253
+ - `pathway` and `defaultAssetIn` return `undefined` or `null` for a key with no pathway.
254
+ - `inferBridgeKey` returns `null` when no pathway fits.
255
+ - `isNative`, `isUnwrappable` and `canChangeUnwrap` return `false`.
256
+ - `tokenBridgeInfo` returns `null` without an asset or a pathway.
257
+ - Every request builder returns `null` for a request its provider cannot express.
258
+ - Every response parser returns `null` for a response of an unexpected shape.
259
+
260
+ Throws:
261
+
262
+ - `buildLifiQuoteRequest` and `buildLifiContractCallsRequest`, for a positive
263
+ `lifiFee` without your own `lifiIntegrator`.
264
+ - `chainMulticall`, for a client with no chain or a chain without Multicall3.
265
+ - `loadBridgeFees`, `links` and `minBridgeAmountIn`, when the chain read fails.
266
+ - `pathway`, for an `assetInAddress` that is not an address.
267
+
268
+ The package writes nothing to the console.
269
+
270
+ ## Entry points
271
+
272
+ | Entry point | What it holds |
273
+ |---|---|
274
+ | `@gibs/bridge-sdk/config` | Chains, providers, pathways, native-asset tables |
275
+ | `@gibs/bridge-sdk/chains` | viem chain objects with logos and RPC URLs |
276
+ | `@gibs/bridge-sdk/chain-info` | On-chain reads: token mappings, fees, minimum amounts |
277
+ | `@gibs/bridge-sdk/settings` | Fee and amount arithmetic, transaction inputs |
278
+ | `@gibs/bridge-sdk/consolidated-quote` | LI.FI request builders and parsers |
279
+ | `@gibs/bridge-sdk/relay-quote` | Relay request builders and parsers |
280
+ | `@gibs/bridge-sdk/near-intents` | NEAR Intents requests and parsers |
281
+ | `@gibs/bridge-sdk/pre-quote` | Forward-solving price checks before a binding quote |
282
+ | `@gibs/bridge-sdk/referral` | Gibs Finance's own referral settings |
283
+ | `@gibs/bridge-sdk/image-links` | Image URLs |
284
+ | `@gibs/bridge-sdk/abis` | Contract ABIs |
285
+ | `@gibs/bridge-sdk/ton-execution` | TON Connect requests (needs `Buffer`) |
286
+ | `@gibs/bridge-sdk/routing` | Route search across carriers |
287
+
288
+ The API can still change in a minor version. Read the release notes before you
289
+ upgrade.