@gibs/bridge-sdk 1.10.1 → 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.
- package/LICENSE +15 -0
- package/README.md +234 -432
- package/dist/abis.d.ts +1 -0
- package/dist/abis.js +3 -0
- package/dist/bridge-limits.d.ts +103 -0
- package/dist/bridge-limits.js +84 -0
- package/dist/{src/chain-info.d.ts → chain-info.d.ts} +66 -27
- package/dist/{src/chain-info.js → chain-info.js} +106 -46
- package/dist/chain-names.d.ts +160 -0
- package/dist/chain-names.js +200 -0
- package/dist/chains.d.ts +65 -0
- package/dist/chains.js +284 -0
- package/dist/config.d.ts +216 -0
- package/dist/{src/config.js → config.js} +151 -44
- package/dist/consolidated-quote.d.ts +554 -0
- package/dist/consolidated-quote.js +773 -0
- package/dist/destination-calldata.d.ts +118 -0
- package/dist/destination-calldata.js +152 -0
- package/dist/ecosystems.d.ts +217 -0
- package/dist/ecosystems.js +288 -0
- package/dist/hyperliquid-execution.d.ts +152 -0
- package/dist/hyperliquid-execution.js +168 -0
- package/dist/image-links.d.ts +117 -0
- package/dist/image-links.js +142 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +20 -0
- package/dist/lifi-execution-guard.d.ts +199 -0
- package/dist/lifi-execution-guard.js +400 -0
- package/dist/near-intents-conformance.d.ts +85 -0
- package/dist/near-intents-conformance.js +329 -0
- package/dist/near-intents-route.d.ts +47 -0
- package/dist/near-intents-route.js +265 -0
- package/dist/near-intents.d.ts +524 -0
- package/dist/near-intents.js +1055 -0
- package/dist/origin-deposit.d.ts +326 -0
- package/dist/origin-deposit.js +68 -0
- package/dist/pre-quote.d.ts +198 -0
- package/dist/pre-quote.js +175 -0
- package/dist/prices.d.ts +107 -0
- package/dist/prices.js +162 -0
- package/dist/providers.d.ts +221 -0
- package/dist/providers.js +157 -0
- package/dist/quote-fees.d.ts +102 -0
- package/dist/quote-fees.js +195 -0
- package/dist/referral.d.ts +77 -0
- package/dist/referral.js +72 -0
- package/dist/relay-currencies.d.ts +47 -0
- package/dist/relay-currencies.js +89 -0
- package/dist/relay-quote.d.ts +301 -0
- package/dist/relay-quote.js +983 -0
- package/dist/route-steps.d.ts +138 -0
- package/dist/route-steps.js +305 -0
- package/dist/routing/amounts.d.ts +80 -0
- package/dist/routing/amounts.js +120 -0
- package/dist/routing/candidate-route.d.ts +43 -0
- package/dist/routing/candidate-route.js +45 -0
- package/dist/routing/candidate.d.ts +237 -0
- package/dist/routing/candidate.js +96 -0
- package/dist/routing/carriers/ask-answer.d.ts +58 -0
- package/dist/routing/carriers/omnibridge.d.ts +137 -0
- package/dist/routing/carriers/omnibridge.js +419 -0
- package/dist/routing/carriers/pulsex.d.ts +111 -0
- package/dist/routing/carriers/pulsex.js +404 -0
- package/dist/routing/carriers/wrap.d.ts +25 -0
- package/dist/routing/carriers/wrap.js +115 -0
- package/dist/routing/composed-route-quality.d.ts +103 -0
- package/dist/routing/composed-route-quality.js +108 -0
- package/dist/routing/entry-chain-anchor.d.ts +88 -0
- package/dist/routing/entry-chain-anchor.js +55 -0
- package/dist/routing/format.d.ts +31 -0
- package/dist/routing/format.js +58 -0
- package/dist/routing/index.d.ts +34 -0
- package/dist/routing/index.js +42 -0
- package/dist/routing/producers.d.ts +770 -0
- package/dist/routing/producers.js +1564 -0
- package/dist/routing/providers.d.ts +26 -0
- package/dist/routing/providers.js +38 -0
- package/dist/routing/route-data.d.ts +355 -0
- package/dist/routing/route-data.js +1 -0
- package/dist/routing/search/compose.d.ts +168 -0
- package/dist/routing/search/compose.js +98 -0
- package/dist/routing/search/graph.d.ts +639 -0
- package/dist/routing/search/graph.js +445 -0
- package/dist/routing/search/plan-route-data.d.ts +244 -0
- package/dist/routing/search/plan-route-data.js +767 -0
- package/dist/routing/search/score.d.ts +324 -0
- package/dist/routing/search/score.js +400 -0
- package/dist/routing/usd-value.d.ts +17 -0
- package/dist/routing/usd-value.js +25 -0
- package/dist/settings.d.ts +692 -0
- package/dist/{src/settings.js → settings.js} +338 -71
- package/dist/ton-execution.d.ts +117 -0
- package/dist/ton-execution.js +247 -0
- package/dist/tron-execution.d.ts +146 -0
- package/dist/tron-execution.js +239 -0
- package/dist/{src/types.d.ts → types.d.ts} +8 -1
- package/dist/types.js +1 -0
- package/package.json +210 -23
- package/dist/src/abis.d.ts +0 -384
- package/dist/src/abis.js +0 -68
- package/dist/src/chains.d.ts +0 -6
- package/dist/src/chains.js +0 -86
- package/dist/src/config.d.ts +0 -136
- package/dist/src/image-links.d.ts +0 -41
- package/dist/src/image-links.js +0 -45
- package/dist/src/index.d.ts +0 -8
- package/dist/src/index.js +0 -8
- package/dist/src/settings.d.ts +0 -357
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/abis.ts +0 -70
- package/src/chain-info.ts +0 -464
- package/src/chains.ts +0 -88
- package/src/config.ts +0 -480
- package/src/fee-type.ts +0 -14
- package/src/image-links.ts +0 -61
- package/src/index.ts +0 -8
- package/src/settings.ts +0 -898
- package/src/types.ts +0 -48
- package/tsconfig.json +0 -16
- /package/dist/{src/fee-type.d.ts → fee-type.d.ts} +0 -0
- /package/dist/{src/fee-type.js → fee-type.js} +0 -0
- /package/dist/{src/types.js → routing/carriers/ask-answer.js} +0 -0
package/dist/chains.js
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
// Relative, not through this package's own name. A self-reference resolves
|
|
2
|
+
// through the `exports` map, which now points at the compiled `dist` — so the
|
|
3
|
+
// same module would be loaded twice, once as source and once as build output,
|
|
4
|
+
// and `Chains.PLS` from one would not be the same object as from the other.
|
|
5
|
+
import { chainDisplayName } from './chain-names.js';
|
|
6
|
+
import { Chains } from './config.js';
|
|
7
|
+
import * as imageLinks from './image-links.js';
|
|
8
|
+
// Chain definitions come from viem, not from a wallet-connection library. These
|
|
9
|
+
// five objects are identical in `@reown/appkit/networks`, which is where they used
|
|
10
|
+
// to be imported from — but that made a package with no user interface depend on a
|
|
11
|
+
// wallet modal, and it was never declared in `dependencies`, so the root entry
|
|
12
|
+
// point of this package could not be loaded by anyone outside this repository.
|
|
13
|
+
import { bsc, mainnet, pulsechain, pulsechainV4, sepolia } from 'viem/chains';
|
|
14
|
+
/**
|
|
15
|
+
* Builds an endpoint on valve.city, which proxies four of this dapp's chains.
|
|
16
|
+
*
|
|
17
|
+
* The key in this URL is `vk_demo`, and it is MEANT to be here. It is the
|
|
18
|
+
* proxy's published demo key — it is already listed on chainlist.org, so it is
|
|
19
|
+
* public knowledge and shipping it in a browser bundle discloses nothing. The
|
|
20
|
+
* proxy reflects any `Origin` back, which is what makes it usable at all from
|
|
21
|
+
* an IPFS build: the same bundle is served from gib.show, from ipfs.io, from
|
|
22
|
+
* dweb.link, and from a local node, so an origin-locked key would break every
|
|
23
|
+
* gateway but one.
|
|
24
|
+
*
|
|
25
|
+
* NEVER replace this with the unlimited key from 1Password. That one is a
|
|
26
|
+
* bearer credential, this file compiles into the public bundle, and the two
|
|
27
|
+
* facts together would hand an unmetered proxy to every visitor.
|
|
28
|
+
*
|
|
29
|
+
* Only chains 1, 369, 943 and 11155111 are proxied; the service lists them at
|
|
30
|
+
* its root. Binance Smart Chain is not, which is why it keeps a public endpoint
|
|
31
|
+
* alone. Every chain below keeps its previous endpoints after this one, so a
|
|
32
|
+
* valve.city outage falls through to where it used to go rather than breaking.
|
|
33
|
+
*
|
|
34
|
+
* IT LEADS EVERY LIST IT APPEARS IN, and the measurement that says it may is
|
|
35
|
+
* not a burst — it is the shape this interface actually produces.
|
|
36
|
+
*
|
|
37
|
+
* MEASURED 2026-08-29, against the real cadence rather than a synthetic flood:
|
|
38
|
+
*
|
|
39
|
+
* steady, 1 request per 4 seconds for 3 minutes 45 of 45 answered 200
|
|
40
|
+
* bursts, 8 concurrent, four rounds 30 of 32 answered 200
|
|
41
|
+
* 20 requests at concurrency 1, 2, 4, 6 and 8 20 of 20 every time
|
|
42
|
+
* 20 requests at concurrency 12 19 of 20
|
|
43
|
+
*
|
|
44
|
+
* Four seconds is not arbitrary: `watchBlocks` runs on viem's default poll, one
|
|
45
|
+
* per watched chain, and `clientFromChain` coalesces up to 32 JSON-RPC calls
|
|
46
|
+
* made within 10ms into ONE HTTP POST. So the interface's request rate is about
|
|
47
|
+
* a quarter of a request per second per chain, and the key handles four times
|
|
48
|
+
* that without a single refusal.
|
|
49
|
+
*
|
|
50
|
+
* AN EARLIER READING SAID THE OPPOSITE AND WAS MEASURING SOMETHING ELSE. On
|
|
51
|
+
* 2026-08-27 this key answered 429 for four requests in five — from 40 requests
|
|
52
|
+
* at 12 concurrent, fired four times back to back across four chains, roughly
|
|
53
|
+
* 160 requests with no pause. That exhausts a windowed budget. No browser does
|
|
54
|
+
* it. The reading before THAT one was 40 CONSECUTIVE requests, which cannot see
|
|
55
|
+
* a rate limit at all because it paces itself. Both were honest measurements of
|
|
56
|
+
* the wrong thing.
|
|
57
|
+
*
|
|
58
|
+
* THE PROBE STORM WAS THE REAL CULPRIT. `fallback` used to run `rank: true`,
|
|
59
|
+
* which pings every url on every chain every few seconds forever — on an idle
|
|
60
|
+
* page, every outbound request was one of those. That is what spent the key's
|
|
61
|
+
* budget. It is off now (see `packages/common/src/client.ts`), and the
|
|
62
|
+
* demotion that shipped alongside turning it off was treating the symptom.
|
|
63
|
+
*
|
|
64
|
+
* THE SPARE BEHIND IT IS STILL LOAD-BEARING. `vk_demo` is shared — published on
|
|
65
|
+
* chainlist.org — so the budget is not ours alone and the headroom moves with
|
|
66
|
+
* other people's use. About one burst request in sixteen still meets a 429, and
|
|
67
|
+
* a 429 is an HTTP error, so `fallback` moves to the next entry at once. The
|
|
68
|
+
* cost is one wasted round trip on a small fraction of burst requests, not a
|
|
69
|
+
* failed read. Never leave a proxied chain with valve.city alone.
|
|
70
|
+
*
|
|
71
|
+
* @param chainId - the numeric chain id to proxy
|
|
72
|
+
* @returns the fully qualified JSON-RPC endpoint
|
|
73
|
+
*/
|
|
74
|
+
const valveCity = (chainId) => `https://one.valve.city/rpc/vk_demo/evm/${chainId}`;
|
|
75
|
+
/**
|
|
76
|
+
* all of the chains that are enabled in this dapp
|
|
77
|
+
* and their corresponding useful metadata
|
|
78
|
+
*
|
|
79
|
+
* Every entry below sets `name` explicitly to `chainDisplayName(...)` rather
|
|
80
|
+
* than trusting the spread-in viem chain object or typing a string here. Two
|
|
81
|
+
* hand-typed copies of the same name is exactly how chain 943 once read as
|
|
82
|
+
* "PulseChain Testnet V4" in the resolver and "Pulsechain V4" here — one
|
|
83
|
+
* string, two spellings, and only one of them got fixed. Routing every name
|
|
84
|
+
* through `chainDisplayName` leaves nothing to drift a second time.
|
|
85
|
+
*
|
|
86
|
+
* Each `logoURI` is a getter, not a string fixed at import time, so a later
|
|
87
|
+
* `setImageRoot` call (from `image-links.ts`) changes every chain logo. Spread
|
|
88
|
+
* an entry (`{ ...chainsMetadata[chain] }`) and the copy holds the URL as it
|
|
89
|
+
* was at that moment.
|
|
90
|
+
*/
|
|
91
|
+
export const chainsMetadata = {
|
|
92
|
+
[Chains.PLS]: {
|
|
93
|
+
...pulsechain,
|
|
94
|
+
name: chainDisplayName(pulsechain.id),
|
|
95
|
+
chainId: Chains.PLS,
|
|
96
|
+
get logoURI() {
|
|
97
|
+
return imageLinks.network(pulsechain.id);
|
|
98
|
+
},
|
|
99
|
+
alt: 'a pink blue and purple hexagon with an ekg line running horizontally',
|
|
100
|
+
rpcUrls: {
|
|
101
|
+
default: {
|
|
102
|
+
http: [valveCity(pulsechain.id), 'https://rpc.pulsechain.com'],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
contracts: {
|
|
106
|
+
...pulsechain.contracts,
|
|
107
|
+
ensRegistry: {
|
|
108
|
+
address: '0xbd5133993FCDED5945c5539D9f032261F0d13170',
|
|
109
|
+
},
|
|
110
|
+
ensUniversalResolver: {
|
|
111
|
+
address: '0x2FDBb906b4FE68e31D928C1ED0b6a3bD1f204374',
|
|
112
|
+
blockCreated: 19_400_610,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
[Chains.ETH]: {
|
|
117
|
+
...mainnet,
|
|
118
|
+
name: chainDisplayName(mainnet.id),
|
|
119
|
+
chainId: Chains.ETH,
|
|
120
|
+
get logoURI() {
|
|
121
|
+
return imageLinks.network(mainnet.id);
|
|
122
|
+
},
|
|
123
|
+
alt: 'two pyramids joined on one side',
|
|
124
|
+
rpcUrls: {
|
|
125
|
+
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.
|
|
131
|
+
http: [
|
|
132
|
+
valveCity(mainnet.id),
|
|
133
|
+
'https://rpc-ethereum.g4mm4.io',
|
|
134
|
+
'https://ethereum-rpc.publicnode.com',
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
[Chains.BNB]: {
|
|
140
|
+
...bsc,
|
|
141
|
+
// viem's own default is "BNB Smart Chain" — deferring to the resolver
|
|
142
|
+
// keeps this the product's chosen "Binance Smart Chain" without a second
|
|
143
|
+
// hand-typed copy of that decision living here.
|
|
144
|
+
name: chainDisplayName(bsc.id),
|
|
145
|
+
chainId: Chains.BNB,
|
|
146
|
+
get logoURI() {
|
|
147
|
+
return imageLinks.network(bsc.id);
|
|
148
|
+
},
|
|
149
|
+
alt: 'a gold cube with slits in the middle of each side',
|
|
150
|
+
rpcUrls: {
|
|
151
|
+
default: {
|
|
152
|
+
// valve.city does not proxy chain 56 — it answers "Unsupported
|
|
153
|
+
// chain" — so this is the one chain with no entry of ours, which
|
|
154
|
+
// makes a second PUBLIC endpoint the only fallback available. A
|
|
155
|
+
// one-entry list is what took Sepolia down outright (see below).
|
|
156
|
+
// Both measured 40 of 40 on 2026-08-27.
|
|
157
|
+
http: ['https://bsc-rpc.publicnode.com', 'https://bsc-dataseed.binance.org'],
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
[Chains.SEP]: {
|
|
162
|
+
...sepolia,
|
|
163
|
+
name: chainDisplayName(sepolia.id),
|
|
164
|
+
chainId: Chains.SEP,
|
|
165
|
+
get logoURI() {
|
|
166
|
+
return imageLinks.network(sepolia.id);
|
|
167
|
+
},
|
|
168
|
+
alt: 'two pyramids joined on one side',
|
|
169
|
+
// FOUR endpoints, not one, and the reason is specific: a public endpoint
|
|
170
|
+
// answers a single curl perfectly well and returns 403 under a browser's
|
|
171
|
+
// load — five times on one page render. A rate limit, not a dead host.
|
|
172
|
+
//
|
|
173
|
+
// The transport wraps this list in viem's `fallback()`, which moves on for
|
|
174
|
+
// an HTTP error, and 403 is one. With a single entry there was nowhere to
|
|
175
|
+
// move to, so the whole testnet side simply failed. All three were checked
|
|
176
|
+
// for a correct chain id AND for an allow-origin header, because answering
|
|
177
|
+
// curl is not the same as being reachable from a page.
|
|
178
|
+
rpcUrls: {
|
|
179
|
+
default: {
|
|
180
|
+
// Ordered deliberately, by the operational rule that the most reliable
|
|
181
|
+
// endpoint goes FIRST.
|
|
182
|
+
//
|
|
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.
|
|
188
|
+
//
|
|
189
|
+
// The other three keep the order an earlier browser measurement earned
|
|
190
|
+
// them. publicnode stays last of the public three because it is the one
|
|
191
|
+
// observed returning 403 under a browser's load — five times on one
|
|
192
|
+
// page render — which a `curl` burst does not reproduce and therefore
|
|
193
|
+
// cannot overturn. It answers fine when the others are busy, so it is
|
|
194
|
+
// demoted rather than dropped.
|
|
195
|
+
http: [
|
|
196
|
+
valveCity(sepolia.id),
|
|
197
|
+
'https://sepolia.gateway.tenderly.co',
|
|
198
|
+
'https://1rpc.io/sepolia',
|
|
199
|
+
'https://ethereum-sepolia-rpc.publicnode.com',
|
|
200
|
+
],
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
[Chains.V4PLS]: {
|
|
205
|
+
...pulsechainV4,
|
|
206
|
+
name: chainDisplayName(pulsechainV4.id),
|
|
207
|
+
chainId: Chains.V4PLS,
|
|
208
|
+
get logoURI() {
|
|
209
|
+
return imageLinks.network(pulsechainV4.id);
|
|
210
|
+
},
|
|
211
|
+
alt: 'a pink blue and purple hexagon with an ekg line running horizontally',
|
|
212
|
+
rpcUrls: {
|
|
213
|
+
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
|
+
http: [
|
|
219
|
+
valveCity(pulsechainV4.id),
|
|
220
|
+
'https://rpc-testnet-pulsechain.g4mm4.io',
|
|
221
|
+
'https://rpc.v4.testnet.pulsechain.com',
|
|
222
|
+
],
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
contracts: {
|
|
226
|
+
...pulsechainV4.contracts,
|
|
227
|
+
ensRegistry: {
|
|
228
|
+
address: '0xaDB38309aF7F85034FDC35bd6E6B45d1216CfB56',
|
|
229
|
+
},
|
|
230
|
+
ensUniversalResolver: {
|
|
231
|
+
address: '0xDDFde3fA938dE0cdff82645579d03Ed750DE2e69',
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* Every chain this bridge itself carries funds across, in the order the
|
|
238
|
+
* metadata declares them.
|
|
239
|
+
*
|
|
240
|
+
* Read from {@link chainsMetadata} rather than typed out, for the reason the
|
|
241
|
+
* whole table above gives: a second hand-written list is how one chain ends up
|
|
242
|
+
* present in one place and missing from another. A control that offers the
|
|
243
|
+
* reader a network to add or remove reads this, so a chain added to the
|
|
244
|
+
* metadata appears in that control without anybody remembering to add it.
|
|
245
|
+
*
|
|
246
|
+
* This is NOT every chain a route can traverse. An aggregator reaches dozens
|
|
247
|
+
* more, and `chain-names.ts` can name them. These five are the ones the
|
|
248
|
+
* transfers archive holds records for.
|
|
249
|
+
*/
|
|
250
|
+
export const bridgeNetworkChainIds = Object.values(chainsMetadata).map((metadata) => Number(metadata.id));
|
|
251
|
+
/**
|
|
252
|
+
* The chain identifiers this product treats as TEST networks.
|
|
253
|
+
*
|
|
254
|
+
* THE FLAG IS VIEM'S AND IT IS CHECKED FOR `true`, NOT FOR TRUTHINESS. Each
|
|
255
|
+
* entry above spreads a viem chain definition, and viem sets `testnet: true` on
|
|
256
|
+
* Sepolia and on PulseChain Testnet V4, `testnet: false` on PulseChain, and
|
|
257
|
+
* omits the key entirely on Ethereum and on Binance Smart Chain. So the value
|
|
258
|
+
* has three states, and only one of them is a claim. Testing for `=== true`
|
|
259
|
+
* means a chain whose definition says nothing is treated as a real network —
|
|
260
|
+
* which is the safe direction, because the cost of failing to hide a test
|
|
261
|
+
* network is an extra row and the cost of hiding a real one is a reader who
|
|
262
|
+
* cannot find their money.
|
|
263
|
+
*
|
|
264
|
+
* WHY NOT DERIVE IT FROM THE BRIDGE KEYS. `validBridgeKeys(isProd)` in
|
|
265
|
+
* `config.ts` splits the same five chains into a mainnet set and a testnet set,
|
|
266
|
+
* and subtracting one from the other would give the same two identifiers today.
|
|
267
|
+
* It would also give the wrong answer the moment a real chain gains a pathway
|
|
268
|
+
* that is still behind the testnet switch — the key list records what is
|
|
269
|
+
* ENABLED, and this records what a chain IS. Two different questions.
|
|
270
|
+
*
|
|
271
|
+
* `buildFullChainIdSet` in the interface already gates the pickers on the same
|
|
272
|
+
* flag, and `tokenLists.ts` gates the synthesized native assets on it. This is
|
|
273
|
+
* that decision written down once so a third reader does not restate it.
|
|
274
|
+
*/
|
|
275
|
+
export const testNetworkChainIds = new Set(Object.values(chainsMetadata)
|
|
276
|
+
.filter((metadata) => metadata.testnet === true)
|
|
277
|
+
.map((metadata) => Number(metadata.id)));
|
|
278
|
+
/**
|
|
279
|
+
* Whether one chain is a test network.
|
|
280
|
+
*
|
|
281
|
+
* @param chainId - a decimal chain id
|
|
282
|
+
* @returns true only when the chain's own definition claims it is a test network
|
|
283
|
+
*/
|
|
284
|
+
export const isTestNetwork = (chainId) => testNetworkChainIds.has(chainId);
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { type Hex } from 'viem';
|
|
2
|
+
import type { BridgeKey, Token, TokenOut } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Add here your chain id as hex, be sure to add your chain in the chainsMetadata object too
|
|
5
|
+
*/
|
|
6
|
+
export declare enum Chains {
|
|
7
|
+
PLS = "0x171",
|
|
8
|
+
ETH = "0x1",
|
|
9
|
+
BNB = "0x38",
|
|
10
|
+
SEP = "0xaa36a7",
|
|
11
|
+
V4PLS = "0x3af"
|
|
12
|
+
}
|
|
13
|
+
/** The key of a chain - human readable for query params */
|
|
14
|
+
export type ChainKey = keyof typeof Chains;
|
|
15
|
+
/** A map of chain ids to chain keys */
|
|
16
|
+
export declare const chainIdToKey: Map<Chains, "PLS" | "ETH" | "BNB" | "SEP" | "V4PLS">;
|
|
17
|
+
/**
|
|
18
|
+
* Converts a chain id to a chain key
|
|
19
|
+
* @param chainId - the chain id
|
|
20
|
+
* @returns the chain key
|
|
21
|
+
*/
|
|
22
|
+
export declare const toChain: (chainId: number | string) => Chains;
|
|
23
|
+
/**
|
|
24
|
+
* Converts a chain id to a chain key
|
|
25
|
+
* @param chainId - the chain id
|
|
26
|
+
* @returns the chain key
|
|
27
|
+
*/
|
|
28
|
+
export declare const toChainKey: (chainId: number | string) => "PLS" | "ETH" | "BNB" | "SEP" | "V4PLS" | undefined;
|
|
29
|
+
export declare const Providers: {
|
|
30
|
+
readonly PULSECHAIN: "pulsechain";
|
|
31
|
+
readonly TOKENSEX: "tokensex";
|
|
32
|
+
};
|
|
33
|
+
export type Provider = (typeof Providers)[keyof typeof Providers];
|
|
34
|
+
/** A map of chains to native asset out addresses */
|
|
35
|
+
export declare const nativeAssetOut: Record<Chains, Hex>;
|
|
36
|
+
/** A map of chains to deprecated native asset out addresses */
|
|
37
|
+
export declare const deprecatedNativeAssetOut: Partial<Record<Chains, Set<Hex>>>;
|
|
38
|
+
/** A map of chains to uni v2 router addresses */
|
|
39
|
+
export declare const uniV2Routers: Record<Chains, Hex[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Each {@link uniV2Routers} entry's OWN factory address, same index, same
|
|
42
|
+
* chain — `router.factory()` read live from `one.valve.city` on 2026-09-24.
|
|
43
|
+
* Only PulseChain mainnet is filled: PulseX carries funds nowhere else
|
|
44
|
+
* (`routing/carriers/pulsex.ts`'s own `pulseXCarries`), so no other chain's
|
|
45
|
+
* factory has ever been needed or verified.
|
|
46
|
+
*
|
|
47
|
+
* MEASURED, NOT ASSUMED (owner Rule 13). Reading each factory's `getPair`
|
|
48
|
+
* and the resulting pool's `getReserves`, then recomputing `getAmountsOut`
|
|
49
|
+
* from the standard constant-product formula, showed the SAME fee ratio for
|
|
50
|
+
* both — `9971/10000` (0.29%) — to the base unit, on both a one-hop and a
|
|
51
|
+
* two-hop path. "V1 and V2 differ" was the assumption going in; measurement
|
|
52
|
+
* said otherwise, so `routing/carriers/pulsex.ts`'s `exact` uses one shared
|
|
53
|
+
* fee constant rather than two.
|
|
54
|
+
*
|
|
55
|
+
* `0x1715a3E4A142d8b698131108995174F37aEBA10D` (the V1 factory, index 0) is
|
|
56
|
+
* NOT a copy-paste of the omnibridge's Ethereum mediator address from
|
|
57
|
+
* `pathways` above — it is the same string on a DIFFERENT chain (PulseChain,
|
|
58
|
+
* not Ethereum), confirmed by reading it fresh from `one.valve.city/…/evm/369`.
|
|
59
|
+
* Two unrelated contracts landing on the same address on two different
|
|
60
|
+
* chains is possible (a shared deployer at a matching nonce, or a CREATE2
|
|
61
|
+
* salt collision) and worth this note so a future reader does not assume a
|
|
62
|
+
* transcription error and "fix" it back to something wrong.
|
|
63
|
+
*/
|
|
64
|
+
export declare const uniV2Factories: Record<Chains, Hex[]>;
|
|
65
|
+
/** A map of chains to native token symbols */
|
|
66
|
+
export declare const nativeTokenSymbol: Record<Chains, string>;
|
|
67
|
+
/** A map of chains to native token names */
|
|
68
|
+
export declare const nativeTokenName: Record<Chains, string>;
|
|
69
|
+
/** The pathway of a bridge */
|
|
70
|
+
export type Pathway = {
|
|
71
|
+
from: Hex;
|
|
72
|
+
to: Hex;
|
|
73
|
+
destinationRouter: Hex | null;
|
|
74
|
+
nativeRouter: Hex;
|
|
75
|
+
validator: Hex;
|
|
76
|
+
usesExtraParam: boolean;
|
|
77
|
+
feeManager: 'from' | 'to';
|
|
78
|
+
toHome: boolean;
|
|
79
|
+
requiresDelivery: boolean;
|
|
80
|
+
bridgedNativeAssetOut: Hex;
|
|
81
|
+
settingOverrides?: Record<Hex, Partial<Pathway>>;
|
|
82
|
+
};
|
|
83
|
+
/** A map of providers to pathways */
|
|
84
|
+
export type DeepPathwayConfig = Record<Provider, Partial<Record<Chains, Partial<Record<Chains, Pathway>>>>>;
|
|
85
|
+
export declare const pathways: DeepPathwayConfig;
|
|
86
|
+
export declare const testnetPathways: DeepPathwayConfig;
|
|
87
|
+
/** Returns the valid bridge keys for the given is prod */
|
|
88
|
+
export declare const validBridgeKeys: (isProd: boolean) => BridgeKey[];
|
|
89
|
+
/**
|
|
90
|
+
* Whether a chain belongs to the testnet pathway map rather than the mainnet one.
|
|
91
|
+
* @param chain - the chain to classify
|
|
92
|
+
* @returns true for Sepolia and PulseChain testnet V4
|
|
93
|
+
*/
|
|
94
|
+
export declare const isTestnetChain: (chain: Chains) => boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Infers the bridge key from the current key, provider, from chain, and to chain.
|
|
97
|
+
*
|
|
98
|
+
* A chain the provider does not serve falls back to the provider's first chain,
|
|
99
|
+
* so a provider switch lands on a real pathway. That fallback never crosses
|
|
100
|
+
* between the testnet and mainnet maps: when testnets are off and a requested
|
|
101
|
+
* chain is a testnet chain, this returns null rather than a mainnet key for a
|
|
102
|
+
* testnet pair.
|
|
103
|
+
*
|
|
104
|
+
* @param options.currentKey - the current bridge key
|
|
105
|
+
* @param options.provider - the provider
|
|
106
|
+
* @param options.fromChain - the from chain (defaults to the current key's)
|
|
107
|
+
* @param options.toChain - the to chain (defaults to the current key's)
|
|
108
|
+
* @param options.isProd - true leaves testnet pathways out (default false: both maps)
|
|
109
|
+
* @returns the inferred bridge key, or null when no pathway can honour the request
|
|
110
|
+
*/
|
|
111
|
+
export declare const inferBridgeKey: ({ currentKey, provider, fromChain, toChain, isProd, }: {
|
|
112
|
+
currentKey: BridgeKey;
|
|
113
|
+
provider: Provider;
|
|
114
|
+
fromChain?: Chains;
|
|
115
|
+
toChain?: Chains;
|
|
116
|
+
isProd?: boolean;
|
|
117
|
+
}) => BridgeKey | null;
|
|
118
|
+
/**
|
|
119
|
+
* Returns the pathway for the given bridge key, is prod, and asset in address
|
|
120
|
+
* @param bridgeKey - the bridge key
|
|
121
|
+
* @param isProd - whether to use the production pathway
|
|
122
|
+
* @param assetInAddress - the asset in address
|
|
123
|
+
* @returns the pathway
|
|
124
|
+
*/
|
|
125
|
+
/**
|
|
126
|
+
* The pathway group for one provider on one chain, honouring the testnet map.
|
|
127
|
+
*
|
|
128
|
+
* Exists because {@link pathway} already knew that testnet pathways live in a
|
|
129
|
+
* SECOND map and are only in play off production, while other callers reached
|
|
130
|
+
* straight into `pathways` and therefore could not see a testnet route at all.
|
|
131
|
+
* That is the sort of knowledge that has to live in one place: duplicated, one
|
|
132
|
+
* copy silently lags the other, and the symptom is a thrown "no pathway found"
|
|
133
|
+
* on a route the rest of the application considers perfectly valid.
|
|
134
|
+
*
|
|
135
|
+
* @param provider - the bridge provider
|
|
136
|
+
* @param chain - the chain being bridged FROM
|
|
137
|
+
* @param isProd - whether this is a production build; testnets are off when true
|
|
138
|
+
* @returns the group keyed by destination chain, or undefined when unknown
|
|
139
|
+
*/
|
|
140
|
+
export declare const pathwayGroup: (provider: Provider, chain: Chains, isProd: boolean) => Partial<Record<Chains, Pathway>> | undefined;
|
|
141
|
+
export declare const pathway: (bridgeKey: BridgeKey | null, isProd: boolean, assetInAddress?: string | Hex | null | undefined) => Pathway | undefined;
|
|
142
|
+
/**
|
|
143
|
+
* Returns the default asset in for the given bridge key and is prod
|
|
144
|
+
* @param bridgeKey - the bridge key
|
|
145
|
+
* @param isProd - whether to use the production pathway
|
|
146
|
+
* @returns the default asset in
|
|
147
|
+
*/
|
|
148
|
+
export declare const defaultAssetIn: ($bridgeKey: BridgeKey | null, isProd: boolean) => `0x${string}` | null | undefined;
|
|
149
|
+
/** Which pathway maps a lookup reads. */
|
|
150
|
+
export type PathwayLookupOptions = {
|
|
151
|
+
/**
|
|
152
|
+
* true reads the mainnet map alone; false (the default) also reads the
|
|
153
|
+
* testnet map, which is what every caller did before this option existed.
|
|
154
|
+
*/
|
|
155
|
+
isProd?: boolean;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Returns whether the given asset is the native asset for the given bridge key.
|
|
159
|
+
*
|
|
160
|
+
* Never throws. A token whose address is not known yet (a {@link TokenOut} for a
|
|
161
|
+
* not-yet-bridged token), an address that is not a valid address, and a bridge
|
|
162
|
+
* key with no pathway each answer false.
|
|
163
|
+
*
|
|
164
|
+
* @param asset - the asset
|
|
165
|
+
* @param bridgeKey - the bridge key
|
|
166
|
+
* @param options - which pathway maps to read; see {@link PathwayLookupOptions}
|
|
167
|
+
* @returns whether the given asset is the native asset for the given bridge key
|
|
168
|
+
*/
|
|
169
|
+
export declare const isNative: (asset: Token | TokenOut | null, bridgeKey: BridgeKey | null, options?: PathwayLookupOptions) => boolean;
|
|
170
|
+
/**
|
|
171
|
+
* Returns whether the given asset is unwrappable for the given bridge key.
|
|
172
|
+
*
|
|
173
|
+
* Never throws: a missing or malformed address and a bridge key with no
|
|
174
|
+
* pathway each answer false.
|
|
175
|
+
*
|
|
176
|
+
* @param bridgeKey - the bridge key
|
|
177
|
+
* @param assetIn - the asset in
|
|
178
|
+
* @param options - which pathway maps to read; see {@link PathwayLookupOptions}
|
|
179
|
+
* @returns whether the given asset is unwrappable for the given bridge key
|
|
180
|
+
*/
|
|
181
|
+
export declare const isUnwrappable: (bridgeKey: BridgeKey | null, assetIn: {
|
|
182
|
+
address: string | null;
|
|
183
|
+
} | null, options?: PathwayLookupOptions) => boolean;
|
|
184
|
+
/**
|
|
185
|
+
* Returns whether the given asset can be unwrapped for the given bridge key
|
|
186
|
+
* @param bridgeKey - the bridge key
|
|
187
|
+
* @param assetIn - the asset in
|
|
188
|
+
* @param options - which pathway maps to read; see {@link PathwayLookupOptions}
|
|
189
|
+
* @returns boolean
|
|
190
|
+
*/
|
|
191
|
+
export declare const canChangeUnwrap: (bridgeKey: BridgeKey, assetIn: Token | null, options?: PathwayLookupOptions) => boolean;
|
|
192
|
+
export declare const chains: {
|
|
193
|
+
readonly ethereum: 1;
|
|
194
|
+
readonly bsc: 56;
|
|
195
|
+
readonly pulsechain: 369;
|
|
196
|
+
readonly pulsechainV4: 943;
|
|
197
|
+
readonly sepolia: 11155111;
|
|
198
|
+
};
|
|
199
|
+
export declare const chainIds: (1 | 56 | 369 | 943 | 11155111)[];
|
|
200
|
+
/** Start blocks aligned with when bridge validators began operating — canonical reference for all ponder indexers in this monorepo. */
|
|
201
|
+
export declare const startBlocks: Record<keyof typeof chains, number>;
|
|
202
|
+
export type ChainId = (typeof chainIds)[number];
|
|
203
|
+
export type Side = 'home' | 'foreign';
|
|
204
|
+
export type MinimalKey = `${ChainId}-${Hex}`;
|
|
205
|
+
export type PathwayInfo = {
|
|
206
|
+
pair: string;
|
|
207
|
+
key: string;
|
|
208
|
+
home: Hex;
|
|
209
|
+
foreign: Hex;
|
|
210
|
+
};
|
|
211
|
+
export type ProviderHomeChainEntry = Partial<Record<ChainId, PathwayInfo[]>>;
|
|
212
|
+
export type ProviderEntries = Partial<Record<ChainId, ProviderHomeChainEntry>>;
|
|
213
|
+
export type BridgeConfig = Record<Provider, ProviderEntries>;
|
|
214
|
+
export declare const bridgeConfigs: BridgeConfig;
|
|
215
|
+
export declare const HOME_TO_FOREIGN_FEE: `0x${string}`;
|
|
216
|
+
export declare const FOREIGN_TO_HOME_FEE: `0x${string}`;
|