@gibs/bridge-sdk 1.18.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/abis.js +0 -2
- package/dist/bridge-limits.js +0 -38
- package/dist/chain-info.js +0 -116
- package/dist/chain-names.js +0 -151
- package/dist/chains.js +0 -198
- package/dist/cjs/abis.js +0 -2
- package/dist/cjs/bridge-limits.js +0 -38
- package/dist/cjs/chain-info.js +0 -116
- package/dist/cjs/chain-names.js +0 -151
- package/dist/cjs/chains.js +0 -198
- package/dist/cjs/claims.js +0 -60
- package/dist/cjs/config.js +1 -208
- package/dist/cjs/consolidated-quote.js +2 -464
- package/dist/cjs/destination-calldata.js +0 -71
- package/dist/cjs/ecosystems.js +0 -183
- package/dist/cjs/execution.js +0 -92
- package/dist/cjs/fee-type.js +0 -1
- package/dist/cjs/hyperliquid-execution.js +0 -98
- package/dist/cjs/image-links.js +0 -108
- package/dist/cjs/lifi-execution-guard.js +65 -172
- package/dist/cjs/near-intents-conformance.js +0 -110
- package/dist/cjs/near-intents-route.d.ts +13 -0
- package/dist/cjs/near-intents-route.js +7 -140
- package/dist/cjs/near-intents.js +0 -562
- package/dist/cjs/origin-deposit.js +0 -56
- package/dist/cjs/pre-quote.js +0 -80
- package/dist/cjs/prices.js +0 -113
- package/dist/cjs/providers.js +0 -83
- package/dist/cjs/quote-fees.js +0 -80
- package/dist/cjs/referral.js +0 -75
- package/dist/cjs/relay-currencies.js +0 -31
- package/dist/cjs/relay-depository.js +52 -77
- package/dist/cjs/relay-quote.js +0 -394
- package/dist/cjs/route-steps.js +0 -100
- package/dist/cjs/routing/amounts.js +0 -83
- package/dist/cjs/routing/candidate-route.d.ts +46 -1
- package/dist/cjs/routing/candidate-route.js +12 -40
- package/dist/cjs/routing/candidate.js +0 -46
- package/dist/cjs/routing/carrier-provider-key.js +0 -27
- package/dist/cjs/routing/carriers/omnibridge.js +0 -120
- package/dist/cjs/routing/carriers/pulsex-paths.js +0 -57
- package/dist/cjs/routing/carriers/pulsex-split.js +0 -92
- package/dist/cjs/routing/carriers/pulsex.js +0 -279
- package/dist/cjs/routing/carriers/wrap.js +0 -57
- package/dist/cjs/routing/composed-route-quality.js +0 -95
- package/dist/cjs/routing/entry-chain-anchor.js +0 -27
- package/dist/cjs/routing/format.js +0 -50
- package/dist/cjs/routing/index.d.ts +1 -1
- package/dist/cjs/routing/index.js +3 -30
- package/dist/cjs/routing/producers.js +0 -854
- package/dist/cjs/routing/providers.js +0 -27
- package/dist/cjs/routing/search/compose.js +0 -56
- package/dist/cjs/routing/search/graph.js +0 -364
- package/dist/cjs/routing/search/plan-route-data.js +5 -510
- package/dist/cjs/routing/search/score.js +0 -344
- package/dist/cjs/routing/swap-transactions.js +0 -74
- package/dist/cjs/routing/usd-value.js +0 -12
- package/dist/cjs/settings.js +1 -456
- package/dist/cjs/swap-venues.js +0 -17
- package/dist/cjs/ton-connect.js +0 -82
- package/dist/cjs/ton-execution.js +0 -6
- package/dist/cjs/ton.js +0 -42
- package/dist/cjs/tron-execution.js +0 -145
- package/dist/cjs/types.d.ts +8 -0
- package/dist/claims.js +0 -60
- package/dist/config.js +1 -211
- package/dist/consolidated-quote.js +2 -464
- package/dist/destination-calldata.js +0 -71
- package/dist/ecosystems.js +0 -183
- package/dist/execution.js +0 -92
- package/dist/fee-type.js +0 -2
- package/dist/hyperliquid-execution.js +0 -98
- package/dist/image-links.js +0 -108
- package/dist/lifi-execution-guard.js +65 -172
- package/dist/near-intents-conformance.js +0 -110
- package/dist/near-intents-route.d.ts +13 -0
- package/dist/near-intents-route.js +5 -139
- package/dist/near-intents.js +0 -562
- package/dist/origin-deposit.js +0 -56
- package/dist/pre-quote.js +0 -80
- package/dist/prices.js +0 -113
- package/dist/providers.js +0 -83
- package/dist/quote-fees.js +0 -80
- package/dist/referral.js +0 -75
- package/dist/relay-currencies.js +0 -31
- package/dist/relay-depository.js +52 -77
- package/dist/relay-quote.js +0 -394
- package/dist/route-steps.js +0 -100
- package/dist/routing/amounts.js +0 -83
- package/dist/routing/candidate-route.d.ts +46 -1
- package/dist/routing/candidate-route.js +10 -39
- package/dist/routing/candidate.js +0 -46
- package/dist/routing/carrier-provider-key.js +0 -27
- package/dist/routing/carriers/omnibridge.js +0 -120
- package/dist/routing/carriers/pulsex-paths.js +0 -57
- package/dist/routing/carriers/pulsex-split.js +0 -92
- package/dist/routing/carriers/pulsex.js +0 -279
- package/dist/routing/carriers/wrap.js +0 -57
- package/dist/routing/composed-route-quality.js +0 -95
- package/dist/routing/entry-chain-anchor.js +0 -27
- package/dist/routing/format.js +0 -50
- package/dist/routing/index.d.ts +1 -1
- package/dist/routing/index.js +1 -29
- package/dist/routing/producers.js +0 -854
- package/dist/routing/providers.js +0 -27
- package/dist/routing/search/compose.js +0 -56
- package/dist/routing/search/graph.js +0 -364
- package/dist/routing/search/plan-route-data.js +6 -511
- package/dist/routing/search/score.js +0 -344
- package/dist/routing/swap-transactions.js +0 -74
- package/dist/routing/usd-value.js +0 -12
- package/dist/settings.js +1 -456
- package/dist/swap-venues.js +0 -17
- package/dist/ton-connect.js +0 -82
- package/dist/ton-execution.js +0 -6
- package/dist/ton.js +0 -42
- package/dist/tron-execution.js +0 -145
- package/dist/types.d.ts +8 -0
- package/package.json +3 -3
package/dist/cjs/chain-names.js
CHANGED
|
@@ -1,121 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.knownChainName = exports.chainDisplayName = exports.registerChainNames = exports.relayChainNames = exports.isDepositAddressChain = exports.depositAddressChainIds = exports.relayChainIds = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Chain identifiers and their human-readable display names, in one place.
|
|
6
|
-
*
|
|
7
|
-
* This module exists to break an import cycle. `relay-quote.ts` imports the
|
|
8
|
-
* step normalizers from `route-steps.ts`, and `route-steps.ts` needs to name
|
|
9
|
-
* Relay's non-Ethereum chains when it labels a leg. Holding the shared lookup
|
|
10
|
-
* here lets both import it without either importing the other.
|
|
11
|
-
*
|
|
12
|
-
* Names are spelled out in full — these strings are shown to someone choosing
|
|
13
|
-
* where their funds leave from, so "The Open Network", never "TON".
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
|
-
* Relay's numeric chain identifiers for the non-Ethereum-Virtual-Machine origin
|
|
17
|
-
* chains this bridge supports. These are Relay's OWN identifiers, distinct from
|
|
18
|
-
* any native chain id, and are required verbatim as the request's
|
|
19
|
-
* `originChainId`.
|
|
20
|
-
*
|
|
21
|
-
* Source: https://api.relay.link/chains, where each entry's `vmType` names the
|
|
22
|
-
* ecosystem and each is reported `depositEnabled`.
|
|
23
|
-
*/
|
|
24
4
|
exports.relayChainIds = {
|
|
25
|
-
/** Relay's chain id for Solana mainnet (virtual-machine type `svm`). */
|
|
26
5
|
solana: 792703809,
|
|
27
|
-
/**
|
|
28
|
-
* Relay's chain id for Eclipse (virtual-machine type `svm`) — a SECOND chain
|
|
29
|
-
* in the Solana ecosystem, sharing Solana's address encoding, deposit shape
|
|
30
|
-
* and native-asset sentinel while being a different network with a different
|
|
31
|
-
* native asset (Ether, not Sol).
|
|
32
|
-
*
|
|
33
|
-
* Quotable, but see the guard in the interface's Solana signer: sharing an
|
|
34
|
-
* ecosystem means sharing a wallet adapter, and that adapter is bound to ONE
|
|
35
|
-
* Solana network at a time. A deposit for this chain must never be signed
|
|
36
|
-
* against a connection pointed at Solana.
|
|
37
|
-
*/
|
|
38
6
|
eclipse: 9286185,
|
|
39
|
-
/** Relay's chain id for Bitcoin mainnet (virtual-machine type `bvm`). */
|
|
40
7
|
bitcoin: 8253038,
|
|
41
|
-
/** Relay's chain id for Tron mainnet (virtual-machine type `tvm`). */
|
|
42
8
|
tron: 728126428,
|
|
43
|
-
/** Relay's chain id for The Open Network (virtual-machine type `tonvm`). */
|
|
44
9
|
ton: 224235520,
|
|
45
|
-
/**
|
|
46
|
-
* Relay's chain id for Hyperliquid (virtual-machine type `hypevm`).
|
|
47
|
-
*
|
|
48
|
-
* BEWARE: 1337 is also the default chain id of a local Ganache development
|
|
49
|
-
* node, so this is the one Relay identifier that can collide with a real
|
|
50
|
-
* Ethereum Virtual Machine chain a developer might be running. Treating a
|
|
51
|
-
* local test chain as Hyperliquid would route it down the HyperCore deposit
|
|
52
|
-
* path, so never feed a local development chain id through
|
|
53
|
-
* `ecosystemByChainId`.
|
|
54
|
-
*/
|
|
55
10
|
hyperliquid: 1337,
|
|
56
11
|
};
|
|
57
|
-
/**
|
|
58
|
-
* Chain identifiers for origin chains a reader PAYS BY HAND.
|
|
59
|
-
*
|
|
60
|
-
* WHAT MAKES THESE DIFFERENT FROM EVERY OTHER CHAIN HERE. Every identifier
|
|
61
|
-
* above names a chain this interface can connect a wallet to and sign on.
|
|
62
|
-
* These name chains it cannot. There is no connector, no signer and no
|
|
63
|
-
* transaction: the provider issues an address, the reader sends an ordinary
|
|
64
|
-
* transfer to it from any wallet or any exchange, and the provider's own
|
|
65
|
-
* watcher reports the arrival. The chain identifier exists so the route layer
|
|
66
|
-
* can NAME the chain, price it and draw it — nothing more.
|
|
67
|
-
*
|
|
68
|
-
* THE NUMBERS ARE DERIVED, NOT INVENTED, and the derivation is written down
|
|
69
|
-
* because a chain identifier typed from memory is a hypothesis every later
|
|
70
|
-
* reader will trust. Each is the chain's registered SLIP-0044 coin type with
|
|
71
|
-
* the hardened bit set, exactly as a BIP-44 derivation path writes it:
|
|
72
|
-
* `0x80000000 + coinType`. That puts them above every chain identifier in
|
|
73
|
-
* public use, so one can never collide with a real Ethereum chain and be
|
|
74
|
-
* mistaken for one — which is the failure that matters, because an Ethereum
|
|
75
|
-
* chain has a wallet and would be handed a payload to sign.
|
|
76
|
-
*
|
|
77
|
-
* They are LOCAL identifiers and never travel on a wire. NEAR Intents names
|
|
78
|
-
* Zcash `zec`; `chainIdByNearIntentsChain` is where the two are reconciled.
|
|
79
|
-
*/
|
|
80
12
|
exports.depositAddressChainIds = {
|
|
81
|
-
/** Zcash mainnet. SLIP-0044 coin type 133, hardened: 0x80000000 + 133. */
|
|
82
13
|
zcash: 2_147_483_781,
|
|
83
14
|
};
|
|
84
|
-
/**
|
|
85
|
-
* Display names for the chains a reader pays by hand, one entry per member of
|
|
86
|
-
* {@link DepositAddressChain}. Typed on the union rather than on `number` so a
|
|
87
|
-
* chain added to {@link depositAddressChainIds} without a name here is a
|
|
88
|
-
* compile error, not a blank badge.
|
|
89
|
-
*/
|
|
90
15
|
const depositAddressChainNamesByChain = {
|
|
91
16
|
zcash: 'Zcash',
|
|
92
17
|
};
|
|
93
|
-
/** {@link depositAddressChainNamesByChain}, keyed by chain id for lookup. */
|
|
94
18
|
const depositAddressChainNames = new Map(Object.keys(exports.depositAddressChainIds).map((chain) => [
|
|
95
19
|
exports.depositAddressChainIds[chain],
|
|
96
20
|
depositAddressChainNamesByChain[chain],
|
|
97
21
|
]));
|
|
98
|
-
/**
|
|
99
|
-
* Whether a chain identifier names a chain this interface CANNOT SIGN ON.
|
|
100
|
-
*
|
|
101
|
-
* The one predicate every surface asks before offering a wallet. A chain that
|
|
102
|
-
* answers true has no connector, so anything that would connect, switch
|
|
103
|
-
* networks, estimate gas or compose a transaction for it is wrong — the reader
|
|
104
|
-
* is shown an address to pay instead.
|
|
105
|
-
*
|
|
106
|
-
* @param chainId - a chain identifier
|
|
107
|
-
* @returns whether the reader pays this chain by hand
|
|
108
|
-
*/
|
|
109
22
|
const isDepositAddressChain = (chainId) => depositAddressChainNames.has(chainId);
|
|
110
23
|
exports.isDepositAddressChain = isDepositAddressChain;
|
|
111
|
-
/**
|
|
112
|
-
* Display names for Relay's non-Ethereum origin chains.
|
|
113
|
-
*
|
|
114
|
-
* An ecosystem label is NOT a chain name, and using one as a name is actively
|
|
115
|
-
* wrong: `svm` holds both Solana and Eclipse, so labelling by ecosystem renders
|
|
116
|
-
* Eclipse as "Solana" — a different network, shown to someone choosing where
|
|
117
|
-
* their funds leave from. Keyed by chain id for exactly that reason.
|
|
118
|
-
*/
|
|
119
24
|
exports.relayChainNames = new Map([
|
|
120
25
|
[exports.relayChainIds.solana, 'Solana'],
|
|
121
26
|
[exports.relayChainIds.eclipse, 'Eclipse'],
|
|
@@ -124,11 +29,6 @@ exports.relayChainNames = new Map([
|
|
|
124
29
|
[exports.relayChainIds.ton, 'The Open Network'],
|
|
125
30
|
[exports.relayChainIds.hyperliquid, 'Hyperliquid'],
|
|
126
31
|
]);
|
|
127
|
-
/**
|
|
128
|
-
* Display names for the Ethereum-Virtual-Machine chains a route can traverse.
|
|
129
|
-
* Only the chains this bridge actually routes through need an entry; anything
|
|
130
|
-
* else falls back to its numeric identifier rather than being dropped.
|
|
131
|
-
*/
|
|
132
32
|
const virtualMachineChainNames = new Map([
|
|
133
33
|
[1, 'Ethereum'],
|
|
134
34
|
[56, 'Binance Smart Chain'],
|
|
@@ -137,28 +37,7 @@ const virtualMachineChainNames = new Map([
|
|
|
137
37
|
[42161, 'Arbitrum One'],
|
|
138
38
|
[11155111, 'Sepolia'],
|
|
139
39
|
]);
|
|
140
|
-
/**
|
|
141
|
-
* Names registered at startup from the wider chain registry.
|
|
142
|
-
*
|
|
143
|
-
* This package cannot import that registry — it sits below the client that
|
|
144
|
-
* holds it — but it must still be the ONE place a chain name is decided. The
|
|
145
|
-
* alternative was what this replaced: three resolvers, each with different
|
|
146
|
-
* coverage, so the same chain read as "Base" beside one element, "chain 8453"
|
|
147
|
-
* beside another, and vanished entirely from a third. A reader hovering two
|
|
148
|
-
* parts of the same row saw two different answers.
|
|
149
|
-
*/
|
|
150
40
|
const registeredChainNames = new Map();
|
|
151
|
-
/**
|
|
152
|
-
* Registers display names for chains this module does not know about.
|
|
153
|
-
*
|
|
154
|
-
* Call once during startup, before anything renders. Entries are merged, and a
|
|
155
|
-
* name declared in `virtualMachineChainNames` above WINS over a registered one:
|
|
156
|
-
* the local table is deliberate ("Binance Smart Chain", not the registry's
|
|
157
|
-
* "BNB Smart Chain"), and a registry that happens to disagree must not quietly
|
|
158
|
-
* rename a chain the product has already named.
|
|
159
|
-
*
|
|
160
|
-
* @param entries - chain id and display name pairs
|
|
161
|
-
*/
|
|
162
41
|
const registerChainNames = (entries) => {
|
|
163
42
|
for (const [chainId, name] of entries) {
|
|
164
43
|
if (!name)
|
|
@@ -167,38 +46,8 @@ const registerChainNames = (entries) => {
|
|
|
167
46
|
}
|
|
168
47
|
};
|
|
169
48
|
exports.registerChainNames = registerChainNames;
|
|
170
|
-
/**
|
|
171
|
-
* Returns a human-readable chain name for the given chain id, covering both
|
|
172
|
-
* Ethereum-Virtual-Machine chains and Relay's non-Ethereum pseudo identifiers.
|
|
173
|
-
*
|
|
174
|
-
* Falls back to the numeric id stringified when the chain is not known — better
|
|
175
|
-
* to show "chain 999" than to silently drop the leg that traverses it.
|
|
176
|
-
*
|
|
177
|
-
* @param chainId - a decimal chain id, Relay's identifier included
|
|
178
|
-
* @returns the display name, or `chain <id>` when unknown
|
|
179
|
-
*/
|
|
180
49
|
const chainDisplayName = (chainId) => (0, exports.knownChainName)(chainId) ?? `chain ${chainId}`;
|
|
181
50
|
exports.chainDisplayName = chainDisplayName;
|
|
182
|
-
/**
|
|
183
|
-
* The name this module KNOWS for a chain, or null when it knows none.
|
|
184
|
-
*
|
|
185
|
-
* Same lookup as {@link chainDisplayName} without the placeholder, so a caller
|
|
186
|
-
* with a better fallback of its own can reach one. {@link chainDisplayName} is
|
|
187
|
-
* defined in terms of this, which is the point: the two can never disagree
|
|
188
|
-
* about which chains are known.
|
|
189
|
-
*
|
|
190
|
-
* WHY A CALLER WOULD WANT THIS. The network chips in the token picker have a
|
|
191
|
-
* second name to fall back on — the aggregator's own chain list, which reaches
|
|
192
|
-
* chains this registry has never been told about and says "Unknown network"
|
|
193
|
-
* rather than printing a bare number. Choosing between the two used to be done
|
|
194
|
-
* by comparing `chainDisplayName`'s answer against the literal string
|
|
195
|
-
* `chain <id>`, which is a caller reaching into another function's fallback
|
|
196
|
-
* format: rename the placeholder here and that comparison quietly stops
|
|
197
|
-
* matching, leaving every unknown chain labelled with its number.
|
|
198
|
-
*
|
|
199
|
-
* @param chainId - a decimal chain id, Relay's identifiers included
|
|
200
|
-
* @returns the display name, or null when the chain is not known here
|
|
201
|
-
*/
|
|
202
51
|
const knownChainName = (chainId) => virtualMachineChainNames.get(chainId) ??
|
|
203
52
|
exports.relayChainNames.get(chainId) ??
|
|
204
53
|
depositAddressChainNames.get(chainId) ??
|
package/dist/cjs/chains.js
CHANGED
|
@@ -34,102 +34,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.isTestNetwork = exports.testNetworkChainIds = exports.bridgeNetworkChainIds = exports.demoRpcUrlsFor = exports.demoRpcUrls = exports.chainsMetadata = void 0;
|
|
37
|
-
// Relative, not through this package's own name. A self-reference resolves
|
|
38
|
-
// through the `exports` map, which now points at the compiled `dist` — so the
|
|
39
|
-
// same module would be loaded twice, once as source and once as build output,
|
|
40
|
-
// and `Chains.PLS` from one would not be the same object as from the other.
|
|
41
37
|
const chain_names_js_1 = require("./chain-names.js");
|
|
42
38
|
const config_js_1 = require("./config.js");
|
|
43
39
|
const imageLinks = __importStar(require("./image-links.js"));
|
|
44
|
-
// Chain definitions come from viem, not from a wallet-connection library. These
|
|
45
|
-
// five objects are identical in `@reown/appkit/networks`, which is where they used
|
|
46
|
-
// to be imported from — but that made a package with no user interface depend on a
|
|
47
|
-
// wallet modal, and it was never declared in `dependencies`, so the root entry
|
|
48
|
-
// point of this package could not be loaded by anyone outside this repository.
|
|
49
40
|
const chains_1 = require("viem/chains");
|
|
50
|
-
/**
|
|
51
|
-
* Builds an endpoint on valve.city, which proxies four of this dapp's chains.
|
|
52
|
-
*
|
|
53
|
-
* DEMO ONLY. These endpoints live in {@link demoRpcUrls}, never in
|
|
54
|
-
* {@link chainsMetadata}. A third party that hands `chainsMetadata` to viem with
|
|
55
|
-
* a bare `http()` gets the public endpoints below, not this shared key. The Gibs
|
|
56
|
-
* interface asks for the demo list by name (`@gibs/bridge-client`'s
|
|
57
|
-
* `clientFromChain`). Any other caller should pass its own clients.
|
|
58
|
-
*
|
|
59
|
-
* The key in this URL is `vk_demo`, and it is MEANT to be here. It is the
|
|
60
|
-
* proxy's published demo key — it is already listed on chainlist.org, so it is
|
|
61
|
-
* public knowledge and shipping it in a browser bundle discloses nothing. The
|
|
62
|
-
* proxy reflects any `Origin` back, which is what makes it usable at all from
|
|
63
|
-
* an IPFS build: the same bundle is served from gib.show, from ipfs.io, from
|
|
64
|
-
* dweb.link, and from a local node, so an origin-locked key would break every
|
|
65
|
-
* gateway but one.
|
|
66
|
-
*
|
|
67
|
-
* NEVER replace this with the unlimited key from 1Password. That one is a
|
|
68
|
-
* bearer credential, this file compiles into the public bundle, and the two
|
|
69
|
-
* facts together would hand an unmetered proxy to every visitor.
|
|
70
|
-
*
|
|
71
|
-
* Only chains 1, 369, 943 and 11155111 are proxied; the service lists them at
|
|
72
|
-
* its root. Binance Smart Chain is not, which is why it keeps a public endpoint
|
|
73
|
-
* alone. Every chain below keeps its previous endpoints after this one, so a
|
|
74
|
-
* valve.city outage falls through to where it used to go rather than breaking.
|
|
75
|
-
*
|
|
76
|
-
* IT LEADS EVERY LIST IT APPEARS IN, and the measurement that says it may is
|
|
77
|
-
* not a burst — it is the shape this interface actually produces.
|
|
78
|
-
*
|
|
79
|
-
* MEASURED 2026-08-29, against the real cadence rather than a synthetic flood:
|
|
80
|
-
*
|
|
81
|
-
* steady, 1 request per 4 seconds for 3 minutes 45 of 45 answered 200
|
|
82
|
-
* bursts, 8 concurrent, four rounds 30 of 32 answered 200
|
|
83
|
-
* 20 requests at concurrency 1, 2, 4, 6 and 8 20 of 20 every time
|
|
84
|
-
* 20 requests at concurrency 12 19 of 20
|
|
85
|
-
*
|
|
86
|
-
* Four seconds is not arbitrary: `watchBlocks` runs on viem's default poll, one
|
|
87
|
-
* per watched chain, and `clientFromChain` coalesces up to 32 JSON-RPC calls
|
|
88
|
-
* made within 10ms into ONE HTTP POST. So the interface's request rate is about
|
|
89
|
-
* a quarter of a request per second per chain, and the key handles four times
|
|
90
|
-
* that without a single refusal.
|
|
91
|
-
*
|
|
92
|
-
* AN EARLIER READING SAID THE OPPOSITE AND WAS MEASURING SOMETHING ELSE. On
|
|
93
|
-
* 2026-08-27 this key answered 429 for four requests in five — from 40 requests
|
|
94
|
-
* at 12 concurrent, fired four times back to back across four chains, roughly
|
|
95
|
-
* 160 requests with no pause. That exhausts a windowed budget. No browser does
|
|
96
|
-
* it. The reading before THAT one was 40 CONSECUTIVE requests, which cannot see
|
|
97
|
-
* a rate limit at all because it paces itself. Both were honest measurements of
|
|
98
|
-
* the wrong thing.
|
|
99
|
-
*
|
|
100
|
-
* THE PROBE STORM WAS THE REAL CULPRIT. `fallback` used to run `rank: true`,
|
|
101
|
-
* which pings every url on every chain every few seconds forever — on an idle
|
|
102
|
-
* page, every outbound request was one of those. That is what spent the key's
|
|
103
|
-
* budget. It is off now (see `packages/common/src/client.ts`), and the
|
|
104
|
-
* demotion that shipped alongside turning it off was treating the symptom.
|
|
105
|
-
*
|
|
106
|
-
* THE SPARE BEHIND IT IS STILL LOAD-BEARING. `vk_demo` is shared — published on
|
|
107
|
-
* chainlist.org — so the budget is not ours alone and the headroom moves with
|
|
108
|
-
* other people's use. About one burst request in sixteen still meets a 429, and
|
|
109
|
-
* a 429 is an HTTP error, so `fallback` moves to the next entry at once. The
|
|
110
|
-
* cost is one wasted round trip on a small fraction of burst requests, not a
|
|
111
|
-
* failed read. Never leave a proxied chain with valve.city alone.
|
|
112
|
-
*
|
|
113
|
-
* @param chainId - the numeric chain id to proxy
|
|
114
|
-
* @returns the fully qualified JSON-RPC endpoint
|
|
115
|
-
*/
|
|
116
41
|
const valveCity = (chainId) => `https://one.valve.city/rpc/vk_demo/evm/${chainId}`;
|
|
117
|
-
/**
|
|
118
|
-
* all of the chains that are enabled in this dapp
|
|
119
|
-
* and their corresponding useful metadata
|
|
120
|
-
*
|
|
121
|
-
* Every entry below sets `name` explicitly to `chainDisplayName(...)` rather
|
|
122
|
-
* than trusting the spread-in viem chain object or typing a string here. Two
|
|
123
|
-
* hand-typed copies of the same name is exactly how chain 943 once read as
|
|
124
|
-
* "PulseChain Testnet V4" in the resolver and "Pulsechain V4" here — one
|
|
125
|
-
* string, two spellings, and only one of them got fixed. Routing every name
|
|
126
|
-
* through `chainDisplayName` leaves nothing to drift a second time.
|
|
127
|
-
*
|
|
128
|
-
* Each `logoURI` is a getter, not a string fixed at import time, so a later
|
|
129
|
-
* `setImageRoot` call (from `image-links.ts`) changes every chain logo. Spread
|
|
130
|
-
* an entry (`{ ...chainsMetadata[chain] }`) and the copy holds the URL as it
|
|
131
|
-
* was at that moment.
|
|
132
|
-
*/
|
|
133
42
|
exports.chainsMetadata = {
|
|
134
43
|
[config_js_1.Chains.PLS]: {
|
|
135
44
|
...chains_1.pulsechain,
|
|
@@ -165,12 +74,6 @@ exports.chainsMetadata = {
|
|
|
165
74
|
alt: 'two pyramids joined on one side',
|
|
166
75
|
rpcUrls: {
|
|
167
76
|
default: {
|
|
168
|
-
// TWO PUBLIC ENDPOINTS, and {@link demoRpcUrls} puts valve.city in
|
|
169
|
-
// front of them. Both are needed behind it. On 2026-08-25 g4mm4
|
|
170
|
-
// answered nothing at all for hours, and the list was g4mm4 then
|
|
171
|
-
// valve.city — so every read fell through a dead host onto a key that
|
|
172
|
-
// rejects four requests in five. publicnode measured 40 of 40 on
|
|
173
|
-
// 2026-08-27 and costs nothing to carry.
|
|
174
77
|
http: [
|
|
175
78
|
'https://rpc-ethereum.g4mm4.io',
|
|
176
79
|
'https://ethereum-rpc.publicnode.com',
|
|
@@ -180,9 +83,6 @@ exports.chainsMetadata = {
|
|
|
180
83
|
},
|
|
181
84
|
[config_js_1.Chains.BNB]: {
|
|
182
85
|
...chains_1.bsc,
|
|
183
|
-
// viem's own default is "BNB Smart Chain" — deferring to the resolver
|
|
184
|
-
// keeps this the product's chosen "Binance Smart Chain" without a second
|
|
185
|
-
// hand-typed copy of that decision living here.
|
|
186
86
|
name: (0, chain_names_js_1.chainDisplayName)(chains_1.bsc.id),
|
|
187
87
|
chainId: config_js_1.Chains.BNB,
|
|
188
88
|
get logoURI() {
|
|
@@ -191,11 +91,6 @@ exports.chainsMetadata = {
|
|
|
191
91
|
alt: 'a gold cube with slits in the middle of each side',
|
|
192
92
|
rpcUrls: {
|
|
193
93
|
default: {
|
|
194
|
-
// valve.city does not proxy chain 56 — it answers "Unsupported
|
|
195
|
-
// chain" — so this is the one chain with no entry of ours, which
|
|
196
|
-
// makes a second PUBLIC endpoint the only fallback available. A
|
|
197
|
-
// one-entry list is what took Sepolia down outright (see below).
|
|
198
|
-
// Both measured 40 of 40 on 2026-08-27.
|
|
199
94
|
http: ['https://bsc-rpc.publicnode.com', 'https://bsc-dataseed.binance.org'],
|
|
200
95
|
},
|
|
201
96
|
},
|
|
@@ -208,31 +103,8 @@ exports.chainsMetadata = {
|
|
|
208
103
|
return imageLinks.network(chains_1.sepolia.id);
|
|
209
104
|
},
|
|
210
105
|
alt: 'two pyramids joined on one side',
|
|
211
|
-
// FOUR endpoints, not one, and the reason is specific: a public endpoint
|
|
212
|
-
// answers a single curl perfectly well and returns 403 under a browser's
|
|
213
|
-
// load — five times on one page render. A rate limit, not a dead host.
|
|
214
|
-
//
|
|
215
|
-
// The transport wraps this list in viem's `fallback()`, which moves on for
|
|
216
|
-
// an HTTP error, and 403 is one. With a single entry there was nowhere to
|
|
217
|
-
// move to, so the whole testnet side simply failed. All three were checked
|
|
218
|
-
// for a correct chain id AND for an allow-origin header, because answering
|
|
219
|
-
// curl is not the same as being reachable from a page.
|
|
220
106
|
rpcUrls: {
|
|
221
107
|
default: {
|
|
222
|
-
// Ordered deliberately, by the operational rule that the most reliable
|
|
223
|
-
// endpoint goes FIRST.
|
|
224
|
-
//
|
|
225
|
-
// valve.city is not here. It sits in front of these three only in
|
|
226
|
-
// {@link demoRpcUrls}. Being ours does not buy it a budget: the SHARED
|
|
227
|
-
// DEMO KEY answered 429 for 32 of 40 burst requests against Sepolia on
|
|
228
|
-
// 2026-08-27, which is why nothing may depend on it alone.
|
|
229
|
-
//
|
|
230
|
-
// These three keep the order an earlier browser measurement earned
|
|
231
|
-
// them. publicnode stays last of the public three because it is the one
|
|
232
|
-
// observed returning 403 under a browser's load — five times on one
|
|
233
|
-
// page render — which a `curl` burst does not reproduce and therefore
|
|
234
|
-
// cannot overturn. It answers fine when the others are busy, so it is
|
|
235
|
-
// demoted rather than dropped.
|
|
236
108
|
http: [
|
|
237
109
|
'https://sepolia.gateway.tenderly.co',
|
|
238
110
|
'https://1rpc.io/sepolia',
|
|
@@ -251,10 +123,6 @@ exports.chainsMetadata = {
|
|
|
251
123
|
alt: 'a pink blue and purple hexagon with an ekg line running horizontally',
|
|
252
124
|
rpcUrls: {
|
|
253
125
|
default: {
|
|
254
|
-
// Two, for the reason Ethereum has two: g4mm4 is a single host that
|
|
255
|
-
// has gone away before, and valve.city ({@link demoRpcUrls}) alone in
|
|
256
|
-
// front of it is not a fallback. The official testnet node measured 40
|
|
257
|
-
// of 40 on 2026-08-27.
|
|
258
126
|
http: [
|
|
259
127
|
'https://rpc-testnet-pulsechain.g4mm4.io',
|
|
260
128
|
'https://rpc.v4.testnet.pulsechain.com',
|
|
@@ -272,22 +140,6 @@ exports.chainsMetadata = {
|
|
|
272
140
|
},
|
|
273
141
|
},
|
|
274
142
|
};
|
|
275
|
-
/**
|
|
276
|
-
* The RPC endpoints the Gibs interface uses, FOR DEMOS ONLY.
|
|
277
|
-
*
|
|
278
|
-
* Each proxied chain's list starts with valve.city's shared `vk_demo` key and
|
|
279
|
-
* falls through to that chain's public endpoints in {@link chainsMetadata}.
|
|
280
|
-
* Binance Smart Chain has no valve.city entry, so its list is the public one.
|
|
281
|
-
*
|
|
282
|
-
* WHY IT IS A SEPARATE, NAMED LIST. The key is public, so shipping it discloses
|
|
283
|
-
* nothing. But its rate budget is shared by everybody who uses it, and the proxy
|
|
284
|
-
* belongs to the Gibs Finance operator. A wallet that inherits it without
|
|
285
|
-
* choosing it puts its users' reads on somebody else's budget and uptime. So no
|
|
286
|
-
* reader in this package uses it, and `chainsMetadata` does not carry it. A
|
|
287
|
-
* caller who wants it asks for it by this name.
|
|
288
|
-
*
|
|
289
|
-
* Production callers: pass your own viem clients to every reader.
|
|
290
|
-
*/
|
|
291
143
|
exports.demoRpcUrls = Object.freeze({
|
|
292
144
|
[config_js_1.Chains.PLS]: [valveCity(chains_1.pulsechain.id), ...exports.chainsMetadata[config_js_1.Chains.PLS].rpcUrls.default.http],
|
|
293
145
|
[config_js_1.Chains.ETH]: [valveCity(chains_1.mainnet.id), ...exports.chainsMetadata[config_js_1.Chains.ETH].rpcUrls.default.http],
|
|
@@ -295,63 +147,13 @@ exports.demoRpcUrls = Object.freeze({
|
|
|
295
147
|
[config_js_1.Chains.SEP]: [valveCity(chains_1.sepolia.id), ...exports.chainsMetadata[config_js_1.Chains.SEP].rpcUrls.default.http],
|
|
296
148
|
[config_js_1.Chains.V4PLS]: [valveCity(chains_1.pulsechainV4.id), ...exports.chainsMetadata[config_js_1.Chains.V4PLS].rpcUrls.default.http],
|
|
297
149
|
});
|
|
298
|
-
/**
|
|
299
|
-
* The demo endpoints for one chain, FOR DEMOS ONLY. See {@link demoRpcUrls}.
|
|
300
|
-
*
|
|
301
|
-
* @param chainId - a decimal chain id
|
|
302
|
-
* @returns a copy of the chain's demo endpoints, or an empty list for a chain the bridge does not cross
|
|
303
|
-
*/
|
|
304
150
|
const demoRpcUrlsFor = (chainId) => [
|
|
305
151
|
...(exports.demoRpcUrls[(0, config_js_1.toChain)(chainId)] ?? []),
|
|
306
152
|
];
|
|
307
153
|
exports.demoRpcUrlsFor = demoRpcUrlsFor;
|
|
308
|
-
/**
|
|
309
|
-
* Every chain this bridge itself carries funds across, in the order the
|
|
310
|
-
* metadata declares them.
|
|
311
|
-
*
|
|
312
|
-
* Read from {@link chainsMetadata} rather than typed out, for the reason the
|
|
313
|
-
* whole table above gives: a second hand-written list is how one chain ends up
|
|
314
|
-
* present in one place and missing from another. A control that offers the
|
|
315
|
-
* reader a network to add or remove reads this, so a chain added to the
|
|
316
|
-
* metadata appears in that control without anybody remembering to add it.
|
|
317
|
-
*
|
|
318
|
-
* This is NOT every chain a route can traverse. An aggregator reaches dozens
|
|
319
|
-
* more, and `chain-names.ts` can name them. These five are the ones the
|
|
320
|
-
* transfers archive holds records for.
|
|
321
|
-
*/
|
|
322
154
|
exports.bridgeNetworkChainIds = Object.values(exports.chainsMetadata).map((metadata) => Number(metadata.id));
|
|
323
|
-
/**
|
|
324
|
-
* The chain identifiers this product treats as TEST networks.
|
|
325
|
-
*
|
|
326
|
-
* THE FLAG IS VIEM'S AND IT IS CHECKED FOR `true`, NOT FOR TRUTHINESS. Each
|
|
327
|
-
* entry above spreads a viem chain definition, and viem sets `testnet: true` on
|
|
328
|
-
* Sepolia and on PulseChain Testnet V4, `testnet: false` on PulseChain, and
|
|
329
|
-
* omits the key entirely on Ethereum and on Binance Smart Chain. So the value
|
|
330
|
-
* has three states, and only one of them is a claim. Testing for `=== true`
|
|
331
|
-
* means a chain whose definition says nothing is treated as a real network —
|
|
332
|
-
* which is the safe direction, because the cost of failing to hide a test
|
|
333
|
-
* network is an extra row and the cost of hiding a real one is a reader who
|
|
334
|
-
* cannot find their money.
|
|
335
|
-
*
|
|
336
|
-
* WHY NOT DERIVE IT FROM THE BRIDGE KEYS. `validBridgeKeys(isProd)` in
|
|
337
|
-
* `config.ts` splits the same five chains into a mainnet set and a testnet set,
|
|
338
|
-
* and subtracting one from the other would give the same two identifiers today.
|
|
339
|
-
* It would also give the wrong answer the moment a real chain gains a pathway
|
|
340
|
-
* that is still behind the testnet switch — the key list records what is
|
|
341
|
-
* ENABLED, and this records what a chain IS. Two different questions.
|
|
342
|
-
*
|
|
343
|
-
* `buildFullChainIdSet` in the interface already gates the pickers on the same
|
|
344
|
-
* flag, and `tokenLists.ts` gates the synthesized native assets on it. This is
|
|
345
|
-
* that decision written down once so a third reader does not restate it.
|
|
346
|
-
*/
|
|
347
155
|
exports.testNetworkChainIds = new Set(Object.values(exports.chainsMetadata)
|
|
348
156
|
.filter((metadata) => metadata.testnet === true)
|
|
349
157
|
.map((metadata) => Number(metadata.id)));
|
|
350
|
-
/**
|
|
351
|
-
* Whether one chain is a test network.
|
|
352
|
-
*
|
|
353
|
-
* @param chainId - a decimal chain id
|
|
354
|
-
* @returns true only when the chain's own definition claims it is a test network
|
|
355
|
-
*/
|
|
356
158
|
const isTestNetwork = (chainId) => exports.testNetworkChainIds.has(chainId);
|
|
357
159
|
exports.isTestNetwork = isTestNetwork;
|
package/dist/cjs/claims.js
CHANGED
|
@@ -37,12 +37,6 @@ exports.buildClaimTransaction = exports.claimCall = exports.encodeReleaseToRoute
|
|
|
37
37
|
const viem_1 = require("viem");
|
|
38
38
|
const abis = __importStar(require("./abis.js"));
|
|
39
39
|
const strip0x = (input) => input.replace(/^0x/, '');
|
|
40
|
-
/**
|
|
41
|
-
* Splits one 65-byte validator signature into its `v`, `r` and `s` parts.
|
|
42
|
-
*
|
|
43
|
-
* @param rawSignature - the signature as the indexer stores it, with or without a `0x` prefix
|
|
44
|
-
* @returns the three parts, hex without prefixes
|
|
45
|
-
*/
|
|
46
40
|
const signatureToVRS = (rawSignature) => {
|
|
47
41
|
const signature = strip0x(rawSignature);
|
|
48
42
|
const word = 32;
|
|
@@ -54,13 +48,6 @@ const signatureToVRS = (rawSignature) => {
|
|
|
54
48
|
return { v, r, s };
|
|
55
49
|
};
|
|
56
50
|
exports.signatureToVRS = signatureToVRS;
|
|
57
|
-
/**
|
|
58
|
-
* Packs signatures in the layout the bridge's `executeSignatures` reads: one
|
|
59
|
-
* count byte, then every `v`, then every `r`, then every `s`.
|
|
60
|
-
*
|
|
61
|
-
* @param signatures - the split signatures, in the order the validators signed
|
|
62
|
-
* @returns the packed signatures as one hex string
|
|
63
|
-
*/
|
|
64
51
|
const packSignatures = (signatures) => {
|
|
65
52
|
const length = strip0x((0, viem_1.numberToHex)(signatures.length));
|
|
66
53
|
const countByte = length.length === 1 ? `0${length}` : length;
|
|
@@ -70,45 +57,18 @@ const packSignatures = (signatures) => {
|
|
|
70
57
|
return `0x${countByte}${v}${r}${s}`;
|
|
71
58
|
};
|
|
72
59
|
exports.packSignatures = packSignatures;
|
|
73
|
-
/**
|
|
74
|
-
* The calldata for a release that pays no delivery tip: a direct call to the
|
|
75
|
-
* destination bridge.
|
|
76
|
-
*
|
|
77
|
-
* @param options.encodedData - the bridge message, `UserRequest.encodedData`
|
|
78
|
-
* @param options.encodedSignatures - the output of {@link packSignatures}
|
|
79
|
-
* @returns the calldata for `safeExecuteSignaturesWithAutoGasLimit`
|
|
80
|
-
*/
|
|
81
60
|
const encodeReleaseWithoutTipData = ({ encodedData, encodedSignatures, }) => (0, viem_1.encodeFunctionData)({
|
|
82
61
|
abi: abis.relayTokensDirect,
|
|
83
62
|
functionName: 'safeExecuteSignaturesWithAutoGasLimit',
|
|
84
63
|
args: [encodedData, encodedSignatures],
|
|
85
64
|
});
|
|
86
65
|
exports.encodeReleaseWithoutTipData = encodeReleaseWithoutTipData;
|
|
87
|
-
/**
|
|
88
|
-
* The calldata for a release sent through the pathway's destination output
|
|
89
|
-
* router, the path a fee-director (delivery) request uses.
|
|
90
|
-
*
|
|
91
|
-
* @param options.validator - the pathway's validator contract
|
|
92
|
-
* @param options.encodedData - the bridge message, `UserRequest.encodedData`
|
|
93
|
-
* @param options.encodedSignatures - the output of {@link packSignatures}
|
|
94
|
-
* @returns the calldata for the router's `safeExecuteSignaturesWithAutoGasLimit`
|
|
95
|
-
*/
|
|
96
66
|
const encodeReleaseToRouterData = ({ validator, encodedData, encodedSignatures, }) => (0, viem_1.encodeFunctionData)({
|
|
97
67
|
abi: abis.outputRouter,
|
|
98
68
|
functionName: 'safeExecuteSignaturesWithAutoGasLimit',
|
|
99
69
|
args: [validator, encodedData, encodedSignatures],
|
|
100
70
|
});
|
|
101
71
|
exports.encodeReleaseToRouterData = encodeReleaseToRouterData;
|
|
102
|
-
/**
|
|
103
|
-
* The one place a claim's target and calldata come from. The interface's
|
|
104
|
-
* release hook and {@link buildClaimTransaction} both call it.
|
|
105
|
-
*
|
|
106
|
-
* @param options.encodedData - the bridge message
|
|
107
|
-
* @param options.signatures - the raw validator signatures, in signing order
|
|
108
|
-
* @param options.destinationAmbAddress - the destination bridge, used by the `direct` route
|
|
109
|
-
* @param options.via - which contract receives the claim
|
|
110
|
-
* @returns the target contract and the calldata
|
|
111
|
-
*/
|
|
112
72
|
const claimCall = ({ encodedData, signatures, destinationAmbAddress, via, }) => {
|
|
113
73
|
const encodedSignatures = (0, exports.packSignatures)(signatures.map(exports.signatureToVRS));
|
|
114
74
|
if (via.kind === 'router') {
|
|
@@ -122,24 +82,6 @@ const claimCall = ({ encodedData, signatures, destinationAmbAddress, via, }) =>
|
|
|
122
82
|
exports.claimCall = claimCall;
|
|
123
83
|
const isSignatureList = (value) => Array.isArray(value) && value.every((entry) => typeof entry === 'string' && (0, viem_1.isHex)(entry));
|
|
124
84
|
const refused = (refusal) => ({ kind: 'refused', refusal });
|
|
125
|
-
/**
|
|
126
|
-
* Builds the manual-claim transaction for one bridge request, or refuses with
|
|
127
|
-
* a typed reason.
|
|
128
|
-
*
|
|
129
|
-
* The checks run in this order: request type, delivery, signing, then the
|
|
130
|
-
* stored signature count. A delivered request is refused before the signing
|
|
131
|
-
* check, because delivery also sets `finishedSigning`.
|
|
132
|
-
*
|
|
133
|
-
* ASSUMPTION: the signatures are only complete when every validator sent
|
|
134
|
-
* `submitSignature` directly to the home bridge. The indexer drops a
|
|
135
|
-
* signature sent any other way; see this module's head note. This builder
|
|
136
|
-
* catches the drop by comparing the stored list with the required-signature
|
|
137
|
-
* threshold, or with `confirmedSignatures` when the record carries no threshold.
|
|
138
|
-
*
|
|
139
|
-
* @param options.request - the indexer's `UserRequest` record
|
|
140
|
-
* @param options.via - the claim target; see {@link ClaimRoute}
|
|
141
|
-
* @returns a `claim` plan whose transaction runs on the destination chain, or a refusal
|
|
142
|
-
*/
|
|
143
85
|
const buildClaimTransaction = ({ request, via, }) => {
|
|
144
86
|
if (request.type !== 'signature')
|
|
145
87
|
return refused({ reason: 'wrong-type', type: request.type });
|
|
@@ -172,8 +114,6 @@ const buildClaimTransaction = ({ request, via, }) => {
|
|
|
172
114
|
to,
|
|
173
115
|
data,
|
|
174
116
|
value: 0n,
|
|
175
|
-
// The calldata itself asks the bridge to pick its own gas limit
|
|
176
|
-
// (`safeExecuteSignaturesWithAutoGasLimit`); the wallet estimates the rest.
|
|
177
117
|
gasLimit: null,
|
|
178
118
|
waitForReceipt: false,
|
|
179
119
|
},
|