@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
@@ -0,0 +1,410 @@
1
+ import { multicallRead } from '@gibs/common/multicall';
2
+ import * as _ from 'lodash-es';
3
+ import { encodeFunctionData, getContract, multicall3Abi, zeroAddress, } from 'viem';
4
+ import * as abis from './abis.js';
5
+ import { chainsMetadata } from './chains.js';
6
+ import { nativeAssetOut, pathway, toChain, uniV2Routers, } from './config.js';
7
+ /** Cache key for the links memoize: one entry per (chain, bridge, token) triple. */
8
+ const linksCacheKey = ({ chainId, target, address, }) => `${chainId}-${target}-${address}`.toLowerCase();
9
+ /**
10
+ * Whether a {@link links} answer says the token has no mapping on this bridge
11
+ * yet. That answer is temporary: the first transfer of the token creates the
12
+ * mapping, so it must not be cached.
13
+ * @param pair - the bridged and native addresses the mediator returned
14
+ * @returns true when both are the zero address
15
+ */
16
+ const isUnmappedAnswer = ([bridged, native]) => bridged === zeroAddress && native === zeroAddress;
17
+ /**
18
+ * Returns the bridged token address and native token address that a mediator
19
+ * holds for one token.
20
+ *
21
+ * A non-zero answer is cached for the life of the process: a mediator never
22
+ * changes a mapping once the first transfer creates it. A failed read, and a
23
+ * `[zero, zero]` answer (the token is not bridged yet), are not cached, so the
24
+ * next call reads the chain again. Call {@link clearChainInfoCaches} to drop
25
+ * every cached answer.
26
+ *
27
+ * @param inputs.chainId - the chain id being targeted
28
+ * @param inputs.target - the mediator to ask
29
+ * @param inputs.address - the token address
30
+ * @param inputs.client - a client for that chain
31
+ * @returns the bridged token address and native token address
32
+ */
33
+ // The annotation is required, not stylistic: `@types/lodash-es` re-exports its
34
+ // `MemoizedFunction` type from a nested `@types/lodash` that a generated
35
+ // declaration file cannot name (TS2742). The body reaches for `links.cache` to
36
+ // evict an answer, so the cache surface is spelled out to the extent this file
37
+ // uses it.
38
+ export const links = _.memoize(async (inputs) => {
39
+ const { chainId, target, address, client } = inputs;
40
+ const evict = () => links.cache.delete(linksCacheKey(inputs));
41
+ const pair = await multicallRead({
42
+ client,
43
+ chain: chainsMetadata[toChain(chainId)],
44
+ abi: abis.inputBridge,
45
+ target,
46
+ calls: [
47
+ { functionName: 'bridgedTokenAddress', args: [address] },
48
+ { functionName: 'nativeTokenAddress', args: [address] },
49
+ ],
50
+ }).catch((error) => {
51
+ // a transient read failure must not poison the cache for the session
52
+ evict();
53
+ throw error;
54
+ });
55
+ if (isUnmappedAnswer(pair)) {
56
+ // the token may be bridged a minute from now; ask again next time
57
+ evict();
58
+ }
59
+ return pair;
60
+ }, linksCacheKey);
61
+ /**
62
+ * Drops every answer this module has cached, so the next read goes to the chain.
63
+ *
64
+ * Use it after a token's first transfer, in a long-running process that wants
65
+ * a fresh view, or between tests.
66
+ */
67
+ export const clearChainInfoCaches = () => {
68
+ // lodash types mark `clear` optional; the default MapCache always has it
69
+ links.cache.clear?.();
70
+ };
71
+ /**
72
+ * Returns the token bridge info for the given bridge key, asset in, is prod, from chain client, and to chain client
73
+ * @param bridgeKey - the bridge key
74
+ * @param assetIn - the asset in
75
+ * @param isProd - whether to use the production pathway
76
+ * @param fromChainClient - the from chain client
77
+ * @param toChainClient - the to chain client
78
+ * @returns the token bridge info
79
+ */
80
+ export const tokenBridgeInfo = async ({ bridgeKey, assetIn, isProd, fromChainClient, toChainClient, }) => {
81
+ const bridgePathway = pathway(bridgeKey, isProd, assetIn?.address);
82
+ if (!assetIn || !bridgePathway) {
83
+ return null;
84
+ }
85
+ const [, fromChain, toChain] = bridgeKey;
86
+ const assetInAddress = assetIn.address === zeroAddress ? nativeAssetOut[fromChain] : assetIn.address;
87
+ const [toMappings, fromMappings] = await Promise.all([
88
+ links({
89
+ chainId: Number(toChain),
90
+ target: bridgePathway.to,
91
+ address: assetInAddress,
92
+ client: toChainClient,
93
+ }),
94
+ links({
95
+ chainId: Number(fromChain),
96
+ target: bridgePathway.from,
97
+ address: assetInAddress,
98
+ client: fromChainClient,
99
+ }),
100
+ ]);
101
+ const [toBridged, toNative] = toMappings;
102
+ if (toBridged !== zeroAddress) {
103
+ return {
104
+ originationChainId: fromChain,
105
+ assetInAddress: assetInAddress,
106
+ assetOutAddress: toBridged,
107
+ toHome: {
108
+ home: toBridged,
109
+ foreign: assetInAddress,
110
+ },
111
+ };
112
+ }
113
+ if (toNative !== zeroAddress) {
114
+ return {
115
+ originationChainId: toChain,
116
+ assetInAddress: assetInAddress,
117
+ assetOutAddress: toNative,
118
+ toForeign: {
119
+ home: toNative,
120
+ foreign: assetInAddress,
121
+ },
122
+ };
123
+ }
124
+ const [fromBridged, fromNative] = fromMappings;
125
+ if (fromNative !== zeroAddress) {
126
+ return {
127
+ originationChainId: toChain,
128
+ assetInAddress: assetInAddress,
129
+ assetOutAddress: fromNative,
130
+ toHome: {
131
+ home: assetInAddress,
132
+ foreign: fromNative,
133
+ },
134
+ };
135
+ }
136
+ if (fromBridged !== zeroAddress) {
137
+ return {
138
+ originationChainId: fromChain,
139
+ assetInAddress: assetInAddress,
140
+ assetOutAddress: fromBridged,
141
+ toForeign: {
142
+ foreign: fromBridged,
143
+ home: assetInAddress,
144
+ },
145
+ };
146
+ }
147
+ // the token has not been bridged yet
148
+ return {
149
+ originationChainId: toChain,
150
+ assetInAddress: assetInAddress,
151
+ assetOutAddress: null,
152
+ ...(bridgePathway.toHome
153
+ ? {
154
+ toHome: {
155
+ foreign: assetInAddress,
156
+ home: null,
157
+ },
158
+ }
159
+ : {
160
+ toForeign: {
161
+ foreign: null,
162
+ home: assetInAddress,
163
+ },
164
+ }),
165
+ };
166
+ };
167
+ /**
168
+ * Check the prices that each router offers for the given paths
169
+ * @param assetInAddress the address of the asset going into the bridge
170
+ * @param oneTokenInt the number of tokens to push into the bridge (before fees)
171
+ * @param chain the chain of the asset going into the bridge
172
+ * @param bridgeKey the bridge key
173
+ * @param blockNumber the block number to use for the price
174
+ * @param paths the paths to check
175
+ * @returns the prices as bigint for each path, hex whenever the price is not available
176
+ */
177
+ const readAmountOut = ({ amountIn, chain, paths, client, uniV2Router, }) => {
178
+ return multicallRead({
179
+ chain: chainsMetadata[chain],
180
+ client,
181
+ abi: abis.univ2Router,
182
+ // pulsex router
183
+ calls: _.flatMap(uniV2Router ? [uniV2Router] : uniV2Routers[chain], (target) => paths.map((path) => ({
184
+ functionName: 'getAmountsOut',
185
+ allowFailure: true,
186
+ args: [amountIn, path],
187
+ target,
188
+ }))),
189
+ });
190
+ };
191
+ /**
192
+ * Fetch the price corrective for the given bridge key, asset out, measurement token, from chain client, to chain client, asset link, amount in, and is prod
193
+ * @param bridgeKeyPartner - the bridge key partner
194
+ * @param assetOut - the asset out
195
+ * @param measurementToken - the measurement token
196
+ * @param fromChainClient - the from chain client
197
+ * @param toChainClient - the to chain client
198
+ * @param assetLink - the asset link
199
+ * @param amountIn - the amount in
200
+ * @param isProd - whether to use the production pathway
201
+ * @returns the price corrective
202
+ */
203
+ export const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementToken, fromChainClient, toChainClient, assetLink, amountIn, isProd, }) => {
204
+ return {
205
+ getPaymentToken: async () => {
206
+ // fetch the token bridge info for the token that is about to be spent by the delivery service
207
+ return await tokenBridgeInfo({
208
+ bridgeKey: bridgeKeyPartner,
209
+ assetIn: {
210
+ ...assetOut,
211
+ address: measurementToken,
212
+ },
213
+ isProd,
214
+ // clients are reversed here because we are actually fetching the
215
+ // tokens going the opposite direction to the provided bridge key
216
+ fromChainClient: toChainClient,
217
+ toChainClient: fromChainClient,
218
+ });
219
+ },
220
+ getSwapResults: async ({ paymentTokenResult, chain, uniV2Router, client, }) => {
221
+ return await Promise.all([
222
+ readAmountOut({
223
+ amountIn,
224
+ chain,
225
+ uniV2Router,
226
+ client,
227
+ paths: [
228
+ // check the direct route
229
+ [assetLink.assetInAddress, paymentTokenResult.assetOutAddress],
230
+ // might have heavier liquidity going through the native asset on the home side
231
+ [assetLink.assetInAddress, nativeAssetOut[chain], paymentTokenResult.assetOutAddress],
232
+ ],
233
+ }),
234
+ readAmountOut({
235
+ amountIn,
236
+ chain,
237
+ uniV2Router,
238
+ client,
239
+ paths: [[assetOut.address, measurementToken]],
240
+ // only the direct route is available.
241
+ // might be able to create a whitelist for this at some point
242
+ }),
243
+ ]);
244
+ },
245
+ reduceResults: ({ results, oneToken, }) => {
246
+ const outputFromRouter = (result) => {
247
+ if (_.isString(result)) {
248
+ // the router failed to return a result
249
+ return 0n;
250
+ }
251
+ if (!result.length) {
252
+ // the router returned an empty result
253
+ return 0n;
254
+ }
255
+ // the last element is the amount of the output token
256
+ const last = result[result.length - 1];
257
+ return (last * oneToken) / amountIn;
258
+ };
259
+ const max = (amountsOut) => {
260
+ return _.compact(amountsOut).reduce((max, current) => (max < current ? current : max), 0n);
261
+ };
262
+ // could do with a refactor to unify the results
263
+ const [outputs, inputs] = results;
264
+ const outputAmounts = outputs.map(outputFromRouter);
265
+ const inputAmounts = inputs.map(outputFromRouter);
266
+ const outputToken = max(outputAmounts);
267
+ const inputToken = max(inputAmounts);
268
+ const result = outputToken && outputToken > 0n
269
+ ? inputToken && inputToken > outputToken && inputToken / outputToken === 1n
270
+ ? inputToken
271
+ : outputToken
272
+ : inputToken;
273
+ return result;
274
+ },
275
+ };
276
+ };
277
+ /**
278
+ * Read the smallest amount the bridge will accept for this asset on this pathway.
279
+ *
280
+ * THE ENTRY MEDIATOR DECIDES, so this always reads `pathway.from` on the chain
281
+ * the funds leave. `feeManager` says which side prices the transfer; it has
282
+ * never said which side validates the amount, and using it for both is what
283
+ * produced the defect this replaces.
284
+ *
285
+ * Both mediators keep a `minPerTx` under the same name, and for a token that
286
+ * originates on the entry chain the two sides usually hold the same number. That
287
+ * agreement is a coincidence of configuration - each side is separately
288
+ * governed, and both happen to apply one blanket default. It breaks outright for
289
+ * a token that originates on the far side, because the two mediators key their
290
+ * limits by different addresses. Wrapped Pulse entering from Ethereum is the
291
+ * live case: the entry mediator enforces 50,000, and the destination mediator
292
+ * answers 0 for that same address because it files that token under its
293
+ * PulseChain address instead. Reading the destination got both the chain and the
294
+ * token key wrong, and reported no floor where a real one stood.
295
+ * @param assetIn - the asset the sender holds, on the chain it leaves from
296
+ * @param pathway - the pathway, with any per-asset overrides already applied
297
+ * @param fromPublicClient - a client for the chain the funds leave
298
+ * @returns the smallest amount the entry mediator will accept
299
+ */
300
+ export const minBridgeAmountIn = async ({ assetIn, pathway, fromPublicClient, }) => fromPublicClient.readContract({
301
+ abi: abis.inputBridge,
302
+ functionName: 'minPerTx',
303
+ args: [assetIn.address],
304
+ address: pathway.from,
305
+ });
306
+ /** get the symbol of the native asset, unwrap it if it needs to be */
307
+ export const nativeSymbol = (asset, unwrap = false) => {
308
+ return asset
309
+ ? unwrap && asset.address === nativeAssetOut[toChain(asset.chainId)]
310
+ ? asset.symbol.slice(1)
311
+ : asset.symbol
312
+ : '';
313
+ };
314
+ /**
315
+ * Returns the Multicall3 contract for the client's chain.
316
+ * @param client - a client whose `chain` is one of {@link chainsMetadata}'s chains
317
+ * @returns the Multicall3 contract instance
318
+ * @throws when the client carries no chain, or the chain has no Multicall3 address
319
+ */
320
+ export const chainMulticall = (client) => {
321
+ const chainId = client.chain?.id;
322
+ if (chainId === undefined) {
323
+ throw new Error('chainMulticall: the client has no chain configured');
324
+ }
325
+ const address = chainsMetadata[toChain(chainId)]?.contracts?.multicall3?.address;
326
+ if (!address) {
327
+ throw new Error(`chainMulticall: no Multicall3 address known for chain ${chainId}`);
328
+ }
329
+ return getContract({ abi: multicall3Abi, client, address });
330
+ };
331
+ /**
332
+ * Load the bridge fees for the given pathway, from chain client, and to chain client
333
+ * @param pathway - the pathway
334
+ * @param fromChainClient - the from chain client
335
+ * @param toChainClient - the to chain client
336
+ * @returns the bridge fees
337
+ */
338
+ export const loadBridgeFees = async ({ pathway, fromChainClient, toChainClient, }) => {
339
+ const multicall = pathway.feeManager === 'from' ? chainMulticall(fromChainClient) : chainMulticall(toChainClient);
340
+ const [feeManagerResponse] = await multicall.read.aggregate3([
341
+ [
342
+ {
343
+ allowFailure: false,
344
+ target: pathway[pathway.feeManager],
345
+ callData: encodeFunctionData({
346
+ abi: abis.inputBridge,
347
+ functionName: 'feeManager',
348
+ }),
349
+ },
350
+ ],
351
+ ]);
352
+ const { success, returnData } = feeManagerResponse;
353
+ if (!success) {
354
+ throw new Error('unable to load feeManager');
355
+ }
356
+ if (returnData === '0x') {
357
+ throw new Error('unable to read feeManager');
358
+ }
359
+ const feeManager = (returnData.startsWith('0x000000000000000000000000')
360
+ ? `0x${returnData.slice(26)}`
361
+ : `0x${returnData.slice(-40)}`);
362
+ const [keyH2F, keyF2H] = await multicall.read.aggregate3([
363
+ [
364
+ {
365
+ allowFailure: false,
366
+ target: feeManager,
367
+ callData: encodeFunctionData({
368
+ abi: abis.feeManager,
369
+ functionName: 'HOME_TO_FOREIGN_FEE',
370
+ }),
371
+ },
372
+ {
373
+ allowFailure: false,
374
+ target: feeManager,
375
+ callData: encodeFunctionData({
376
+ abi: abis.feeManager,
377
+ functionName: 'FOREIGN_TO_HOME_FEE',
378
+ }),
379
+ },
380
+ ],
381
+ ]);
382
+ const [feeH2F, feeF2H] = await multicall.read.aggregate3([
383
+ [
384
+ {
385
+ allowFailure: false,
386
+ target: feeManager,
387
+ callData: encodeFunctionData({
388
+ abi: abis.feeManager,
389
+ functionName: 'getFee',
390
+ args: [keyH2F.returnData, zeroAddress],
391
+ }),
392
+ },
393
+ {
394
+ allowFailure: false,
395
+ target: feeManager,
396
+ callData: encodeFunctionData({
397
+ abi: abis.feeManager,
398
+ functionName: 'getFee',
399
+ args: [keyF2H.returnData, zeroAddress],
400
+ }),
401
+ },
402
+ ],
403
+ ]);
404
+ const setting = {
405
+ feeManager,
406
+ feeH2F: BigInt(feeH2F.returnData),
407
+ feeF2H: BigInt(feeF2H.returnData),
408
+ };
409
+ return setting;
410
+ };
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Chain identifiers and their human-readable display names, in one place.
3
+ *
4
+ * This module exists to break an import cycle. `relay-quote.ts` imports the
5
+ * step normalizers from `route-steps.ts`, and `route-steps.ts` needs to name
6
+ * Relay's non-Ethereum chains when it labels a leg. Holding the shared lookup
7
+ * here lets both import it without either importing the other.
8
+ *
9
+ * Names are spelled out in full — these strings are shown to someone choosing
10
+ * where their funds leave from, so "The Open Network", never "TON".
11
+ */
12
+ /**
13
+ * Relay's numeric chain identifiers for the non-Ethereum-Virtual-Machine origin
14
+ * chains this bridge supports. These are Relay's OWN identifiers, distinct from
15
+ * any native chain id, and are required verbatim as the request's
16
+ * `originChainId`.
17
+ *
18
+ * Source: https://api.relay.link/chains, where each entry's `vmType` names the
19
+ * ecosystem and each is reported `depositEnabled`.
20
+ */
21
+ export declare const relayChainIds: {
22
+ /** Relay's chain id for Solana mainnet (virtual-machine type `svm`). */
23
+ readonly solana: 792703809;
24
+ /**
25
+ * Relay's chain id for Eclipse (virtual-machine type `svm`) — a SECOND chain
26
+ * in the Solana ecosystem, sharing Solana's address encoding, deposit shape
27
+ * and native-asset sentinel while being a different network with a different
28
+ * native asset (Ether, not Sol).
29
+ *
30
+ * Quotable, but see the guard in the interface's Solana signer: sharing an
31
+ * ecosystem means sharing a wallet adapter, and that adapter is bound to ONE
32
+ * Solana network at a time. A deposit for this chain must never be signed
33
+ * against a connection pointed at Solana.
34
+ */
35
+ readonly eclipse: 9286185;
36
+ /** Relay's chain id for Bitcoin mainnet (virtual-machine type `bvm`). */
37
+ readonly bitcoin: 8253038;
38
+ /** Relay's chain id for Tron mainnet (virtual-machine type `tvm`). */
39
+ readonly tron: 728126428;
40
+ /** Relay's chain id for The Open Network (virtual-machine type `tonvm`). */
41
+ readonly ton: 224235520;
42
+ /**
43
+ * Relay's chain id for Hyperliquid (virtual-machine type `hypevm`).
44
+ *
45
+ * BEWARE: 1337 is also the default chain id of a local Ganache development
46
+ * node, so this is the one Relay identifier that can collide with a real
47
+ * Ethereum Virtual Machine chain a developer might be running. Treating a
48
+ * local test chain as Hyperliquid would route it down the HyperCore deposit
49
+ * path, so never feed a local development chain id through
50
+ * `ecosystemByChainId`.
51
+ */
52
+ readonly hyperliquid: 1337;
53
+ };
54
+ /**
55
+ * Chain identifiers for origin chains a reader PAYS BY HAND.
56
+ *
57
+ * WHAT MAKES THESE DIFFERENT FROM EVERY OTHER CHAIN HERE. Every identifier
58
+ * above names a chain this interface can connect a wallet to and sign on.
59
+ * These name chains it cannot. There is no connector, no signer and no
60
+ * transaction: the provider issues an address, the reader sends an ordinary
61
+ * transfer to it from any wallet or any exchange, and the provider's own
62
+ * watcher reports the arrival. The chain identifier exists so the route layer
63
+ * can NAME the chain, price it and draw it — nothing more.
64
+ *
65
+ * THE NUMBERS ARE DERIVED, NOT INVENTED, and the derivation is written down
66
+ * because a chain identifier typed from memory is a hypothesis every later
67
+ * reader will trust. Each is the chain's registered SLIP-0044 coin type with
68
+ * the hardened bit set, exactly as a BIP-44 derivation path writes it:
69
+ * `0x80000000 + coinType`. That puts them above every chain identifier in
70
+ * public use, so one can never collide with a real Ethereum chain and be
71
+ * mistaken for one — which is the failure that matters, because an Ethereum
72
+ * chain has a wallet and would be handed a payload to sign.
73
+ *
74
+ * They are LOCAL identifiers and never travel on a wire. NEAR Intents names
75
+ * Zcash `zec`; `chainIdByNearIntentsChain` is where the two are reconciled.
76
+ */
77
+ export declare const depositAddressChainIds: {
78
+ /** Zcash mainnet. SLIP-0044 coin type 133, hardened: 0x80000000 + 133. */
79
+ readonly zcash: 2147483781;
80
+ };
81
+ /**
82
+ * One member per pay-by-hand origin chain — the union every table keyed by a
83
+ * pay-by-hand chain must be typed against.
84
+ *
85
+ * WHY THIS UNION, NOT `number`. `DepositAddressDeposit`'s own doc says the same
86
+ * shape will serve Zcash, Dogecoin, Litecoin and the XRP Ledger alike, so a
87
+ * second member is coming. A table typed `Record<number, X>` or
88
+ * `Map<number, X>` accepts a member of {@link depositAddressChainIds} being
89
+ * missing silently; a table typed `Record<DepositAddressChain, X>` cannot
90
+ * compile until every member has an entry. The dangerous table this protects
91
+ * is the ecosystem lookup in `relay-quote.ts`: a miss there makes a pay-by-hand
92
+ * chain read as an Ethereum chain, which has a wallet, a signer and a
93
+ * transaction.
94
+ */
95
+ export type DepositAddressChain = keyof typeof depositAddressChainIds;
96
+ /**
97
+ * Whether a chain identifier names a chain this interface CANNOT SIGN ON.
98
+ *
99
+ * The one predicate every surface asks before offering a wallet. A chain that
100
+ * answers true has no connector, so anything that would connect, switch
101
+ * networks, estimate gas or compose a transaction for it is wrong — the reader
102
+ * is shown an address to pay instead.
103
+ *
104
+ * @param chainId - a chain identifier
105
+ * @returns whether the reader pays this chain by hand
106
+ */
107
+ export declare const isDepositAddressChain: (chainId: number) => boolean;
108
+ /**
109
+ * Display names for Relay's non-Ethereum origin chains.
110
+ *
111
+ * An ecosystem label is NOT a chain name, and using one as a name is actively
112
+ * wrong: `svm` holds both Solana and Eclipse, so labelling by ecosystem renders
113
+ * Eclipse as "Solana" — a different network, shown to someone choosing where
114
+ * their funds leave from. Keyed by chain id for exactly that reason.
115
+ */
116
+ export declare const relayChainNames: Map<number, string>;
117
+ /**
118
+ * Registers display names for chains this module does not know about.
119
+ *
120
+ * Call once during startup, before anything renders. Entries are merged, and a
121
+ * name declared in `virtualMachineChainNames` above WINS over a registered one:
122
+ * the local table is deliberate ("Binance Smart Chain", not the registry's
123
+ * "BNB Smart Chain"), and a registry that happens to disagree must not quietly
124
+ * rename a chain the product has already named.
125
+ *
126
+ * @param entries - chain id and display name pairs
127
+ */
128
+ export declare const registerChainNames: (entries: Iterable<readonly [number, string]>) => void;
129
+ /**
130
+ * Returns a human-readable chain name for the given chain id, covering both
131
+ * Ethereum-Virtual-Machine chains and Relay's non-Ethereum pseudo identifiers.
132
+ *
133
+ * Falls back to the numeric id stringified when the chain is not known — better
134
+ * to show "chain 999" than to silently drop the leg that traverses it.
135
+ *
136
+ * @param chainId - a decimal chain id, Relay's identifier included
137
+ * @returns the display name, or `chain <id>` when unknown
138
+ */
139
+ export declare const chainDisplayName: (chainId: number) => string;
140
+ /**
141
+ * The name this module KNOWS for a chain, or null when it knows none.
142
+ *
143
+ * Same lookup as {@link chainDisplayName} without the placeholder, so a caller
144
+ * with a better fallback of its own can reach one. {@link chainDisplayName} is
145
+ * defined in terms of this, which is the point: the two can never disagree
146
+ * about which chains are known.
147
+ *
148
+ * WHY A CALLER WOULD WANT THIS. The network chips in the token picker have a
149
+ * second name to fall back on — the aggregator's own chain list, which reaches
150
+ * chains this registry has never been told about and says "Unknown network"
151
+ * rather than printing a bare number. Choosing between the two used to be done
152
+ * by comparing `chainDisplayName`'s answer against the literal string
153
+ * `chain <id>`, which is a caller reaching into another function's fallback
154
+ * format: rename the placeholder here and that comparison quietly stops
155
+ * matching, leaving every unknown chain labelled with its number.
156
+ *
157
+ * @param chainId - a decimal chain id, Relay's identifiers included
158
+ * @returns the display name, or null when the chain is not known here
159
+ */
160
+ export declare const knownChainName: (chainId: number) => string | null;