@gibs/bridge-sdk 1.13.0 → 1.17.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 +244 -18
- package/abis/package.json +6 -0
- package/bridge-limits/package.json +6 -0
- package/chain-info/package.json +6 -0
- package/chain-names/package.json +6 -0
- package/chains/package.json +6 -0
- package/claims/package.json +6 -0
- package/config/package.json +6 -0
- package/consolidated-quote/package.json +6 -0
- package/destination-calldata/package.json +6 -0
- package/dist/chain-info.d.ts +1 -1
- package/dist/chain-info.js +11 -12
- package/dist/chains.d.ts +25 -0
- package/dist/chains.js +55 -20
- package/dist/cjs/abis.d.ts +1 -0
- package/dist/cjs/abis.js +19 -0
- package/dist/cjs/bridge-limits.d.ts +103 -0
- package/dist/cjs/bridge-limits.js +89 -0
- package/dist/cjs/chain-info.d.ts +169 -0
- package/dist/cjs/chain-info.js +452 -0
- package/dist/cjs/chain-names.d.ts +160 -0
- package/dist/cjs/chain-names.js +207 -0
- package/dist/cjs/chains.d.ts +90 -0
- package/dist/cjs/chains.js +357 -0
- package/dist/cjs/claims.d.ts +198 -0
- package/dist/cjs/claims.js +182 -0
- package/dist/cjs/config.d.ts +240 -0
- package/dist/cjs/config.js +537 -0
- package/dist/cjs/consolidated-quote.d.ts +648 -0
- package/dist/cjs/consolidated-quote.js +1048 -0
- package/dist/cjs/destination-calldata.d.ts +118 -0
- package/dist/cjs/destination-calldata.js +156 -0
- package/dist/cjs/ecosystems.d.ts +217 -0
- package/dist/cjs/ecosystems.js +298 -0
- package/dist/cjs/execution.d.ts +346 -0
- package/dist/cjs/execution.js +468 -0
- package/dist/cjs/fee-type.d.ts +10 -0
- package/dist/cjs/fee-type.js +10 -0
- package/dist/cjs/hyperliquid-execution.d.ts +152 -0
- package/dist/cjs/hyperliquid-execution.js +175 -0
- package/dist/cjs/image-links.d.ts +117 -0
- package/dist/cjs/image-links.js +153 -0
- package/dist/cjs/index.d.ts +23 -0
- package/dist/cjs/index.js +39 -0
- package/dist/cjs/lifi-execution-guard.d.ts +210 -0
- package/dist/cjs/lifi-execution-guard.js +409 -0
- package/dist/cjs/near-intents-conformance.d.ts +85 -0
- package/dist/cjs/near-intents-conformance.js +337 -0
- package/dist/cjs/near-intents-route.d.ts +47 -0
- package/dist/cjs/near-intents-route.js +303 -0
- package/dist/cjs/near-intents.d.ts +524 -0
- package/dist/cjs/near-intents.js +1071 -0
- package/dist/cjs/origin-deposit.d.ts +326 -0
- package/dist/cjs/origin-deposit.js +82 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/pre-quote.d.ts +198 -0
- package/dist/cjs/pre-quote.js +180 -0
- package/dist/cjs/prices.d.ts +107 -0
- package/dist/cjs/prices.js +172 -0
- package/dist/cjs/providers.d.ts +238 -0
- package/dist/cjs/providers.js +171 -0
- package/dist/cjs/quote-fees.d.ts +102 -0
- package/dist/cjs/quote-fees.js +201 -0
- package/dist/cjs/referral.d.ts +85 -0
- package/dist/cjs/referral.js +85 -0
- package/dist/cjs/relay-currencies.d.ts +47 -0
- package/dist/cjs/relay-currencies.js +95 -0
- package/dist/cjs/relay-depository.d.ts +2 -0
- package/dist/cjs/relay-depository.js +85 -0
- package/dist/cjs/relay-quote.d.ts +301 -0
- package/dist/cjs/relay-quote.js +996 -0
- package/dist/cjs/route-steps.d.ts +138 -0
- package/dist/cjs/route-steps.js +310 -0
- package/dist/cjs/routing/amounts.d.ts +80 -0
- package/dist/cjs/routing/amounts.js +126 -0
- package/dist/cjs/routing/candidate-route.d.ts +43 -0
- package/dist/cjs/routing/candidate-route.js +50 -0
- package/dist/cjs/routing/candidate.d.ts +237 -0
- package/dist/cjs/routing/candidate.js +100 -0
- package/dist/cjs/routing/carriers/ask-answer.d.ts +77 -0
- package/dist/cjs/routing/carriers/ask-answer.js +2 -0
- package/dist/cjs/routing/carriers/omnibridge.d.ts +137 -0
- package/dist/cjs/routing/carriers/omnibridge.js +459 -0
- package/dist/cjs/routing/carriers/pulsex-paths.d.ts +80 -0
- package/dist/cjs/routing/carriers/pulsex-paths.js +97 -0
- package/dist/cjs/routing/carriers/pulsex-split.d.ts +175 -0
- package/dist/cjs/routing/carriers/pulsex-split.js +193 -0
- package/dist/cjs/routing/carriers/pulsex.d.ts +159 -0
- package/dist/cjs/routing/carriers/pulsex.js +565 -0
- package/dist/cjs/routing/carriers/wrap.d.ts +25 -0
- package/dist/cjs/routing/carriers/wrap.js +119 -0
- package/dist/cjs/routing/composed-route-quality.d.ts +125 -0
- package/dist/cjs/routing/composed-route-quality.js +144 -0
- package/dist/cjs/routing/entry-chain-anchor.d.ts +88 -0
- package/dist/cjs/routing/entry-chain-anchor.js +59 -0
- package/dist/cjs/routing/format.d.ts +31 -0
- package/dist/cjs/routing/format.js +64 -0
- package/dist/cjs/routing/index.d.ts +38 -0
- package/dist/cjs/routing/index.js +134 -0
- package/dist/cjs/routing/producers.d.ts +770 -0
- package/dist/cjs/routing/producers.js +1617 -0
- package/dist/cjs/routing/providers.d.ts +31 -0
- package/dist/cjs/routing/providers.js +48 -0
- package/dist/cjs/routing/route-data.d.ts +355 -0
- package/dist/cjs/routing/route-data.js +2 -0
- package/dist/cjs/routing/search/compose.d.ts +168 -0
- package/dist/cjs/routing/search/compose.js +104 -0
- package/dist/cjs/routing/search/graph.d.ts +668 -0
- package/dist/cjs/routing/search/graph.js +461 -0
- package/dist/cjs/routing/search/plan-route-data.d.ts +269 -0
- package/dist/cjs/routing/search/plan-route-data.js +848 -0
- package/dist/cjs/routing/search/score.d.ts +356 -0
- package/dist/cjs/routing/search/score.js +445 -0
- package/dist/cjs/routing/swap-transactions.d.ts +91 -0
- package/dist/cjs/routing/swap-transactions.js +131 -0
- package/dist/cjs/routing/usd-value.d.ts +17 -0
- package/dist/cjs/routing/usd-value.js +29 -0
- package/dist/cjs/settings.d.ts +785 -0
- package/dist/cjs/settings.js +1074 -0
- package/dist/cjs/ton-connect.d.ts +98 -0
- package/dist/cjs/ton-connect.js +206 -0
- package/dist/cjs/ton-execution.d.ts +7 -0
- package/dist/cjs/ton-execution.js +23 -0
- package/dist/cjs/ton.d.ts +37 -0
- package/dist/cjs/ton.js +83 -0
- package/dist/cjs/tron-execution.d.ts +146 -0
- package/dist/cjs/tron-execution.js +248 -0
- package/dist/cjs/types.d.ts +51 -0
- package/dist/cjs/types.js +2 -0
- package/dist/claims.d.ts +198 -0
- package/dist/claims.js +140 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.js +39 -5
- package/dist/consolidated-quote.d.ts +109 -15
- package/dist/consolidated-quote.js +310 -52
- package/dist/execution.d.ts +346 -0
- package/dist/execution.js +428 -0
- package/dist/hyperliquid-execution.js +2 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/lifi-execution-guard.d.ts +13 -2
- package/dist/lifi-execution-guard.js +4 -0
- package/dist/near-intents.js +2 -3
- package/dist/pre-quote.d.ts +6 -6
- package/dist/pre-quote.js +10 -14
- package/dist/providers.d.ts +17 -0
- package/dist/providers.js +6 -0
- package/dist/referral.d.ts +12 -4
- package/dist/referral.js +12 -4
- package/dist/relay-depository.d.ts +2 -0
- package/dist/relay-depository.js +82 -0
- package/dist/relay-quote.js +2 -3
- package/dist/routing/candidate.d.ts +3 -3
- package/dist/routing/candidate.js +3 -3
- package/dist/routing/carriers/ask-answer.d.ts +19 -0
- package/dist/routing/carriers/omnibridge.js +23 -21
- package/dist/routing/carriers/pulsex-paths.d.ts +80 -0
- package/dist/routing/carriers/pulsex-paths.js +92 -0
- package/dist/routing/carriers/pulsex-split.d.ts +175 -0
- package/dist/routing/carriers/pulsex-split.js +185 -0
- package/dist/routing/carriers/pulsex.d.ts +69 -21
- package/dist/routing/carriers/pulsex.js +184 -65
- package/dist/routing/composed-route-quality.d.ts +28 -6
- package/dist/routing/composed-route-quality.js +36 -5
- package/dist/routing/entry-chain-anchor.d.ts +1 -1
- package/dist/routing/entry-chain-anchor.js +1 -1
- package/dist/routing/index.d.ts +7 -3
- package/dist/routing/index.js +7 -3
- package/dist/routing/producers.js +1 -1
- package/dist/routing/providers.d.ts +5 -0
- package/dist/routing/providers.js +5 -0
- package/dist/routing/search/graph.d.ts +29 -0
- package/dist/routing/search/plan-route-data.d.ts +25 -0
- package/dist/routing/search/plan-route-data.js +43 -7
- package/dist/routing/search/score.d.ts +33 -1
- package/dist/routing/search/score.js +41 -6
- package/dist/routing/swap-transactions.d.ts +91 -0
- package/dist/routing/swap-transactions.js +125 -0
- package/dist/settings.d.ts +94 -1
- package/dist/settings.js +95 -3
- package/dist/ton-connect.d.ts +98 -0
- package/dist/ton-connect.js +200 -0
- package/dist/ton-execution.d.ts +4 -114
- package/dist/ton-execution.js +4 -244
- package/dist/ton.d.ts +37 -0
- package/dist/ton.js +65 -0
- package/docs/examples/example-a-ether-to-pulse.ts +300 -0
- package/docs/examples/example-b-token-pulsechain-to-ethereum.ts +270 -0
- package/docs/examples/shared.ts +261 -0
- package/docs/examples/tsconfig.json +18 -0
- package/docs/integration-guide.md +617 -0
- package/ecosystems/package.json +6 -0
- package/execution/package.json +6 -0
- package/fee-type/package.json +6 -0
- package/hyperliquid-execution/package.json +6 -0
- package/image-links/package.json +6 -0
- package/lifi-execution-guard/package.json +6 -0
- package/llms.txt +234 -0
- package/near-intents/package.json +6 -0
- package/near-intents-route/package.json +6 -0
- package/origin-deposit/package.json +6 -0
- package/package.json +818 -10
- package/pre-quote/package.json +6 -0
- package/prices/package.json +6 -0
- package/providers/package.json +6 -0
- package/quote-fees/package.json +6 -0
- package/referral/package.json +6 -0
- package/relay-currencies/package.json +6 -0
- package/relay-quote/package.json +6 -0
- package/route-steps/package.json +6 -0
- package/routing/package.json +6 -0
- package/settings/package.json +6 -0
- package/ton/package.json +6 -0
- package/ton-connect/package.json +6 -0
- package/ton-execution/package.json +6 -0
- package/tron-execution/package.json +6 -0
- package/types/package.json +6 -0
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.loadBridgeFees = exports.chainMulticall = exports.nativeSymbol = exports.minBridgeAmountIn = exports.fetchPriceCorrective = exports.tokenBridgeInfo = exports.clearChainInfoCaches = exports.links = void 0;
|
|
37
|
+
const cache_1 = require("@gibs/common/cache");
|
|
38
|
+
const multicall_1 = require("@gibs/common/multicall");
|
|
39
|
+
const viem_1 = require("viem");
|
|
40
|
+
const abis = __importStar(require("./abis.js"));
|
|
41
|
+
const chains_js_1 = require("./chains.js");
|
|
42
|
+
const config_js_1 = require("./config.js");
|
|
43
|
+
/** Cache key for the links memoize: one entry per (chain, bridge, token) triple. */
|
|
44
|
+
const linksCacheKey = ({ chainId, target, address, }) => `${chainId}-${target}-${address}`.toLowerCase();
|
|
45
|
+
/**
|
|
46
|
+
* Whether a {@link links} answer says the token has no mapping on this bridge
|
|
47
|
+
* yet. That answer is temporary: the first transfer of the token creates the
|
|
48
|
+
* mapping, so it must not be cached.
|
|
49
|
+
* @param pair - the bridged and native addresses the mediator returned
|
|
50
|
+
* @returns true when both are the zero address
|
|
51
|
+
*/
|
|
52
|
+
const isUnmappedAnswer = ([bridged, native]) => bridged === viem_1.zeroAddress && native === viem_1.zeroAddress;
|
|
53
|
+
/**
|
|
54
|
+
* Returns the bridged token address and native token address that a mediator
|
|
55
|
+
* holds for one token.
|
|
56
|
+
*
|
|
57
|
+
* A non-zero answer is cached for the life of the process: a mediator never
|
|
58
|
+
* changes a mapping once the first transfer creates it. A failed read, and a
|
|
59
|
+
* `[zero, zero]` answer (the token is not bridged yet), are not cached, so the
|
|
60
|
+
* next call reads the chain again. Call {@link clearChainInfoCaches} to drop
|
|
61
|
+
* every cached answer.
|
|
62
|
+
*
|
|
63
|
+
* @param inputs.chainId - the chain id being targeted
|
|
64
|
+
* @param inputs.target - the mediator to ask
|
|
65
|
+
* @param inputs.address - the token address
|
|
66
|
+
* @param inputs.client - a client for that chain
|
|
67
|
+
* @returns the bridged token address and native token address
|
|
68
|
+
*/
|
|
69
|
+
// The body reaches for `links.cache` to evict an answer, so the cache surface
|
|
70
|
+
// is spelled out to the extent this file uses it.
|
|
71
|
+
exports.links = (0, cache_1.memoizeByKey)(async (inputs) => {
|
|
72
|
+
const { chainId, target, address, client } = inputs;
|
|
73
|
+
const evict = () => exports.links.cache.delete(linksCacheKey(inputs));
|
|
74
|
+
const pair = await (0, multicall_1.multicallRead)({
|
|
75
|
+
client,
|
|
76
|
+
chain: chains_js_1.chainsMetadata[(0, config_js_1.toChain)(chainId)],
|
|
77
|
+
abi: abis.inputBridge,
|
|
78
|
+
target,
|
|
79
|
+
calls: [
|
|
80
|
+
{ functionName: 'bridgedTokenAddress', args: [address] },
|
|
81
|
+
{ functionName: 'nativeTokenAddress', args: [address] },
|
|
82
|
+
],
|
|
83
|
+
}).catch((error) => {
|
|
84
|
+
// a transient read failure must not poison the cache for the session
|
|
85
|
+
evict();
|
|
86
|
+
throw error;
|
|
87
|
+
});
|
|
88
|
+
if (isUnmappedAnswer(pair)) {
|
|
89
|
+
// the token may be bridged a minute from now; ask again next time
|
|
90
|
+
evict();
|
|
91
|
+
}
|
|
92
|
+
return pair;
|
|
93
|
+
}, linksCacheKey);
|
|
94
|
+
/**
|
|
95
|
+
* Drops every answer this module has cached, so the next read goes to the chain.
|
|
96
|
+
*
|
|
97
|
+
* Use it after a token's first transfer, in a long-running process that wants
|
|
98
|
+
* a fresh view, or between tests.
|
|
99
|
+
*/
|
|
100
|
+
const clearChainInfoCaches = () => {
|
|
101
|
+
exports.links.cache.clear();
|
|
102
|
+
};
|
|
103
|
+
exports.clearChainInfoCaches = clearChainInfoCaches;
|
|
104
|
+
/**
|
|
105
|
+
* Returns the token bridge info for the given bridge key, asset in, is prod, from chain client, and to chain client
|
|
106
|
+
* @param bridgeKey - the bridge key
|
|
107
|
+
* @param assetIn - the asset in
|
|
108
|
+
* @param isProd - whether to use the production pathway
|
|
109
|
+
* @param fromChainClient - the from chain client
|
|
110
|
+
* @param toChainClient - the to chain client
|
|
111
|
+
* @returns the token bridge info
|
|
112
|
+
*/
|
|
113
|
+
const tokenBridgeInfo = async ({ bridgeKey, assetIn, isProd, fromChainClient, toChainClient, }) => {
|
|
114
|
+
const bridgePathway = (0, config_js_1.pathway)(bridgeKey, isProd, assetIn?.address);
|
|
115
|
+
if (!assetIn || !bridgePathway) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const [, fromChain, toChain] = bridgeKey;
|
|
119
|
+
const assetInAddress = assetIn.address === viem_1.zeroAddress ? config_js_1.nativeAssetOut[fromChain] : assetIn.address;
|
|
120
|
+
const [toMappings, fromMappings] = await Promise.all([
|
|
121
|
+
(0, exports.links)({
|
|
122
|
+
chainId: Number(toChain),
|
|
123
|
+
target: bridgePathway.to,
|
|
124
|
+
address: assetInAddress,
|
|
125
|
+
client: toChainClient,
|
|
126
|
+
}),
|
|
127
|
+
(0, exports.links)({
|
|
128
|
+
chainId: Number(fromChain),
|
|
129
|
+
target: bridgePathway.from,
|
|
130
|
+
address: assetInAddress,
|
|
131
|
+
client: fromChainClient,
|
|
132
|
+
}),
|
|
133
|
+
]);
|
|
134
|
+
const [toBridged, toNative] = toMappings;
|
|
135
|
+
if (toBridged !== viem_1.zeroAddress) {
|
|
136
|
+
return {
|
|
137
|
+
originationChainId: fromChain,
|
|
138
|
+
assetInAddress: assetInAddress,
|
|
139
|
+
assetOutAddress: toBridged,
|
|
140
|
+
toHome: {
|
|
141
|
+
home: toBridged,
|
|
142
|
+
foreign: assetInAddress,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if (toNative !== viem_1.zeroAddress) {
|
|
147
|
+
return {
|
|
148
|
+
originationChainId: toChain,
|
|
149
|
+
assetInAddress: assetInAddress,
|
|
150
|
+
assetOutAddress: toNative,
|
|
151
|
+
toForeign: {
|
|
152
|
+
home: toNative,
|
|
153
|
+
foreign: assetInAddress,
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const [fromBridged, fromNative] = fromMappings;
|
|
158
|
+
if (fromNative !== viem_1.zeroAddress) {
|
|
159
|
+
return {
|
|
160
|
+
originationChainId: toChain,
|
|
161
|
+
assetInAddress: assetInAddress,
|
|
162
|
+
assetOutAddress: fromNative,
|
|
163
|
+
toHome: {
|
|
164
|
+
home: assetInAddress,
|
|
165
|
+
foreign: fromNative,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
if (fromBridged !== viem_1.zeroAddress) {
|
|
170
|
+
return {
|
|
171
|
+
originationChainId: fromChain,
|
|
172
|
+
assetInAddress: assetInAddress,
|
|
173
|
+
assetOutAddress: fromBridged,
|
|
174
|
+
toForeign: {
|
|
175
|
+
foreign: fromBridged,
|
|
176
|
+
home: assetInAddress,
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// the token has not been bridged yet
|
|
181
|
+
return {
|
|
182
|
+
originationChainId: toChain,
|
|
183
|
+
assetInAddress: assetInAddress,
|
|
184
|
+
assetOutAddress: null,
|
|
185
|
+
...(bridgePathway.toHome
|
|
186
|
+
? {
|
|
187
|
+
toHome: {
|
|
188
|
+
foreign: assetInAddress,
|
|
189
|
+
home: null,
|
|
190
|
+
},
|
|
191
|
+
}
|
|
192
|
+
: {
|
|
193
|
+
toForeign: {
|
|
194
|
+
foreign: null,
|
|
195
|
+
home: assetInAddress,
|
|
196
|
+
},
|
|
197
|
+
}),
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
exports.tokenBridgeInfo = tokenBridgeInfo;
|
|
201
|
+
/**
|
|
202
|
+
* Check the prices that each router offers for the given paths
|
|
203
|
+
* @param assetInAddress the address of the asset going into the bridge
|
|
204
|
+
* @param oneTokenInt the number of tokens to push into the bridge (before fees)
|
|
205
|
+
* @param chain the chain of the asset going into the bridge
|
|
206
|
+
* @param bridgeKey the bridge key
|
|
207
|
+
* @param blockNumber the block number to use for the price
|
|
208
|
+
* @param paths the paths to check
|
|
209
|
+
* @returns the prices as bigint for each path, hex whenever the price is not available
|
|
210
|
+
*/
|
|
211
|
+
const readAmountOut = ({ amountIn, chain, paths, client, uniV2Router, }) => {
|
|
212
|
+
return (0, multicall_1.multicallRead)({
|
|
213
|
+
chain: chains_js_1.chainsMetadata[chain],
|
|
214
|
+
client,
|
|
215
|
+
abi: abis.univ2Router,
|
|
216
|
+
// pulsex router
|
|
217
|
+
// a chain with no router reads nothing, as lodash's flatMap over undefined did
|
|
218
|
+
calls: (uniV2Router ? [uniV2Router] : (config_js_1.uniV2Routers[chain] ?? [])).flatMap((target) => paths.map((path) => ({
|
|
219
|
+
functionName: 'getAmountsOut',
|
|
220
|
+
allowFailure: true,
|
|
221
|
+
args: [amountIn, path],
|
|
222
|
+
target,
|
|
223
|
+
}))),
|
|
224
|
+
});
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* 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
|
|
228
|
+
* @param bridgeKeyPartner - the bridge key partner
|
|
229
|
+
* @param assetOut - the asset out
|
|
230
|
+
* @param measurementToken - the measurement token
|
|
231
|
+
* @param fromChainClient - the from chain client
|
|
232
|
+
* @param toChainClient - the to chain client
|
|
233
|
+
* @param assetLink - the asset link
|
|
234
|
+
* @param amountIn - the amount in
|
|
235
|
+
* @param isProd - whether to use the production pathway
|
|
236
|
+
* @returns the price corrective
|
|
237
|
+
*/
|
|
238
|
+
const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementToken, fromChainClient, toChainClient, assetLink, amountIn, isProd, }) => {
|
|
239
|
+
return {
|
|
240
|
+
getPaymentToken: async () => {
|
|
241
|
+
// fetch the token bridge info for the token that is about to be spent by the delivery service
|
|
242
|
+
return await (0, exports.tokenBridgeInfo)({
|
|
243
|
+
bridgeKey: bridgeKeyPartner,
|
|
244
|
+
assetIn: {
|
|
245
|
+
...assetOut,
|
|
246
|
+
address: measurementToken,
|
|
247
|
+
},
|
|
248
|
+
isProd,
|
|
249
|
+
// clients are reversed here because we are actually fetching the
|
|
250
|
+
// tokens going the opposite direction to the provided bridge key
|
|
251
|
+
fromChainClient: toChainClient,
|
|
252
|
+
toChainClient: fromChainClient,
|
|
253
|
+
});
|
|
254
|
+
},
|
|
255
|
+
getSwapResults: async ({ paymentTokenResult, chain, uniV2Router, client, }) => {
|
|
256
|
+
return await Promise.all([
|
|
257
|
+
readAmountOut({
|
|
258
|
+
amountIn,
|
|
259
|
+
chain,
|
|
260
|
+
uniV2Router,
|
|
261
|
+
client,
|
|
262
|
+
paths: [
|
|
263
|
+
// check the direct route
|
|
264
|
+
[assetLink.assetInAddress, paymentTokenResult.assetOutAddress],
|
|
265
|
+
// might have heavier liquidity going through the native asset on the home side
|
|
266
|
+
[assetLink.assetInAddress, config_js_1.nativeAssetOut[chain], paymentTokenResult.assetOutAddress],
|
|
267
|
+
],
|
|
268
|
+
}),
|
|
269
|
+
readAmountOut({
|
|
270
|
+
amountIn,
|
|
271
|
+
chain,
|
|
272
|
+
uniV2Router,
|
|
273
|
+
client,
|
|
274
|
+
paths: [[assetOut.address, measurementToken]],
|
|
275
|
+
// only the direct route is available.
|
|
276
|
+
// might be able to create a whitelist for this at some point
|
|
277
|
+
}),
|
|
278
|
+
]);
|
|
279
|
+
},
|
|
280
|
+
reduceResults: ({ results, oneToken, }) => {
|
|
281
|
+
const outputFromRouter = (result) => {
|
|
282
|
+
if (typeof result === 'string') {
|
|
283
|
+
// the router failed to return a result
|
|
284
|
+
return 0n;
|
|
285
|
+
}
|
|
286
|
+
if (!result.length) {
|
|
287
|
+
// the router returned an empty result
|
|
288
|
+
return 0n;
|
|
289
|
+
}
|
|
290
|
+
// the last element is the amount of the output token
|
|
291
|
+
const last = result[result.length - 1];
|
|
292
|
+
return (last * oneToken) / amountIn;
|
|
293
|
+
};
|
|
294
|
+
const max = (amountsOut) => {
|
|
295
|
+
return amountsOut
|
|
296
|
+
.filter((amount) => amount !== undefined)
|
|
297
|
+
.reduce((max, current) => (max < current ? current : max), 0n);
|
|
298
|
+
};
|
|
299
|
+
// could do with a refactor to unify the results
|
|
300
|
+
const [outputs, inputs] = results;
|
|
301
|
+
const outputAmounts = outputs.map(outputFromRouter);
|
|
302
|
+
const inputAmounts = inputs.map(outputFromRouter);
|
|
303
|
+
const outputToken = max(outputAmounts);
|
|
304
|
+
const inputToken = max(inputAmounts);
|
|
305
|
+
const result = outputToken && outputToken > 0n
|
|
306
|
+
? inputToken && inputToken > outputToken && inputToken / outputToken === 1n
|
|
307
|
+
? inputToken
|
|
308
|
+
: outputToken
|
|
309
|
+
: inputToken;
|
|
310
|
+
return result;
|
|
311
|
+
},
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
exports.fetchPriceCorrective = fetchPriceCorrective;
|
|
315
|
+
/**
|
|
316
|
+
* Read the smallest amount the bridge will accept for this asset on this pathway.
|
|
317
|
+
*
|
|
318
|
+
* THE ENTRY MEDIATOR DECIDES, so this always reads `pathway.from` on the chain
|
|
319
|
+
* the funds leave. `feeManager` says which side prices the transfer; it has
|
|
320
|
+
* never said which side validates the amount, and using it for both is what
|
|
321
|
+
* produced the defect this replaces.
|
|
322
|
+
*
|
|
323
|
+
* Both mediators keep a `minPerTx` under the same name, and for a token that
|
|
324
|
+
* originates on the entry chain the two sides usually hold the same number. That
|
|
325
|
+
* agreement is a coincidence of configuration - each side is separately
|
|
326
|
+
* governed, and both happen to apply one blanket default. It breaks outright for
|
|
327
|
+
* a token that originates on the far side, because the two mediators key their
|
|
328
|
+
* limits by different addresses. Wrapped Pulse entering from Ethereum is the
|
|
329
|
+
* live case: the entry mediator enforces 50,000, and the destination mediator
|
|
330
|
+
* answers 0 for that same address because it files that token under its
|
|
331
|
+
* PulseChain address instead. Reading the destination got both the chain and the
|
|
332
|
+
* token key wrong, and reported no floor where a real one stood.
|
|
333
|
+
* @param assetIn - the asset the sender holds, on the chain it leaves from
|
|
334
|
+
* @param pathway - the pathway, with any per-asset overrides already applied
|
|
335
|
+
* @param fromPublicClient - a client for the chain the funds leave
|
|
336
|
+
* @returns the smallest amount the entry mediator will accept
|
|
337
|
+
*/
|
|
338
|
+
const minBridgeAmountIn = async ({ assetIn, pathway, fromPublicClient, }) => fromPublicClient.readContract({
|
|
339
|
+
abi: abis.inputBridge,
|
|
340
|
+
functionName: 'minPerTx',
|
|
341
|
+
args: [assetIn.address],
|
|
342
|
+
address: pathway.from,
|
|
343
|
+
});
|
|
344
|
+
exports.minBridgeAmountIn = minBridgeAmountIn;
|
|
345
|
+
/** get the symbol of the native asset, unwrap it if it needs to be */
|
|
346
|
+
const nativeSymbol = (asset, unwrap = false) => {
|
|
347
|
+
return asset
|
|
348
|
+
? unwrap && asset.address === config_js_1.nativeAssetOut[(0, config_js_1.toChain)(asset.chainId)]
|
|
349
|
+
? asset.symbol.slice(1)
|
|
350
|
+
: asset.symbol
|
|
351
|
+
: '';
|
|
352
|
+
};
|
|
353
|
+
exports.nativeSymbol = nativeSymbol;
|
|
354
|
+
/**
|
|
355
|
+
* Returns the Multicall3 contract for the client's chain.
|
|
356
|
+
* @param client - a client whose `chain` is one of {@link chainsMetadata}'s chains
|
|
357
|
+
* @returns the Multicall3 contract instance
|
|
358
|
+
* @throws when the client carries no chain, or the chain has no Multicall3 address
|
|
359
|
+
*/
|
|
360
|
+
const chainMulticall = (client) => {
|
|
361
|
+
const chainId = client.chain?.id;
|
|
362
|
+
if (chainId === undefined) {
|
|
363
|
+
throw new Error('chainMulticall: the client has no chain configured');
|
|
364
|
+
}
|
|
365
|
+
const address = chains_js_1.chainsMetadata[(0, config_js_1.toChain)(chainId)]?.contracts?.multicall3?.address;
|
|
366
|
+
if (!address) {
|
|
367
|
+
throw new Error(`chainMulticall: no Multicall3 address known for chain ${chainId}`);
|
|
368
|
+
}
|
|
369
|
+
return (0, viem_1.getContract)({ abi: viem_1.multicall3Abi, client, address });
|
|
370
|
+
};
|
|
371
|
+
exports.chainMulticall = chainMulticall;
|
|
372
|
+
/**
|
|
373
|
+
* Load the bridge fees for the given pathway, from chain client, and to chain client
|
|
374
|
+
* @param pathway - the pathway
|
|
375
|
+
* @param fromChainClient - the from chain client
|
|
376
|
+
* @param toChainClient - the to chain client
|
|
377
|
+
* @returns the bridge fees
|
|
378
|
+
*/
|
|
379
|
+
const loadBridgeFees = async ({ pathway, fromChainClient, toChainClient, }) => {
|
|
380
|
+
const multicall = pathway.feeManager === 'from' ? (0, exports.chainMulticall)(fromChainClient) : (0, exports.chainMulticall)(toChainClient);
|
|
381
|
+
const [feeManagerResponse] = await multicall.read.aggregate3([
|
|
382
|
+
[
|
|
383
|
+
{
|
|
384
|
+
allowFailure: false,
|
|
385
|
+
target: pathway[pathway.feeManager],
|
|
386
|
+
callData: (0, viem_1.encodeFunctionData)({
|
|
387
|
+
abi: abis.inputBridge,
|
|
388
|
+
functionName: 'feeManager',
|
|
389
|
+
}),
|
|
390
|
+
},
|
|
391
|
+
],
|
|
392
|
+
]);
|
|
393
|
+
const { success, returnData } = feeManagerResponse;
|
|
394
|
+
if (!success) {
|
|
395
|
+
throw new Error('unable to load feeManager');
|
|
396
|
+
}
|
|
397
|
+
if (returnData === '0x') {
|
|
398
|
+
throw new Error('unable to read feeManager');
|
|
399
|
+
}
|
|
400
|
+
const feeManager = (returnData.startsWith('0x000000000000000000000000')
|
|
401
|
+
? `0x${returnData.slice(26)}`
|
|
402
|
+
: `0x${returnData.slice(-40)}`);
|
|
403
|
+
const [keyH2F, keyF2H] = await multicall.read.aggregate3([
|
|
404
|
+
[
|
|
405
|
+
{
|
|
406
|
+
allowFailure: false,
|
|
407
|
+
target: feeManager,
|
|
408
|
+
callData: (0, viem_1.encodeFunctionData)({
|
|
409
|
+
abi: abis.feeManager,
|
|
410
|
+
functionName: 'HOME_TO_FOREIGN_FEE',
|
|
411
|
+
}),
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
allowFailure: false,
|
|
415
|
+
target: feeManager,
|
|
416
|
+
callData: (0, viem_1.encodeFunctionData)({
|
|
417
|
+
abi: abis.feeManager,
|
|
418
|
+
functionName: 'FOREIGN_TO_HOME_FEE',
|
|
419
|
+
}),
|
|
420
|
+
},
|
|
421
|
+
],
|
|
422
|
+
]);
|
|
423
|
+
const [feeH2F, feeF2H] = await multicall.read.aggregate3([
|
|
424
|
+
[
|
|
425
|
+
{
|
|
426
|
+
allowFailure: false,
|
|
427
|
+
target: feeManager,
|
|
428
|
+
callData: (0, viem_1.encodeFunctionData)({
|
|
429
|
+
abi: abis.feeManager,
|
|
430
|
+
functionName: 'getFee',
|
|
431
|
+
args: [keyH2F.returnData, viem_1.zeroAddress],
|
|
432
|
+
}),
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
allowFailure: false,
|
|
436
|
+
target: feeManager,
|
|
437
|
+
callData: (0, viem_1.encodeFunctionData)({
|
|
438
|
+
abi: abis.feeManager,
|
|
439
|
+
functionName: 'getFee',
|
|
440
|
+
args: [keyF2H.returnData, viem_1.zeroAddress],
|
|
441
|
+
}),
|
|
442
|
+
},
|
|
443
|
+
],
|
|
444
|
+
]);
|
|
445
|
+
const setting = {
|
|
446
|
+
feeManager,
|
|
447
|
+
feeH2F: BigInt(feeH2F.returnData),
|
|
448
|
+
feeF2H: BigInt(feeF2H.returnData),
|
|
449
|
+
};
|
|
450
|
+
return setting;
|
|
451
|
+
};
|
|
452
|
+
exports.loadBridgeFees = loadBridgeFees;
|
|
@@ -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;
|