@gibs/bridge-sdk 1.12.0 → 1.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +234 -432
- package/dist/abis.d.ts +1 -0
- package/dist/bridge-limits.d.ts +103 -0
- package/dist/bridge-limits.js +84 -0
- package/dist/chain-info.d.ts +169 -0
- package/dist/chain-info.js +410 -0
- package/dist/chain-names.d.ts +160 -0
- package/dist/chain-names.js +200 -0
- package/dist/chains.d.ts +65 -0
- package/dist/chains.js +284 -0
- package/dist/config.d.ts +216 -0
- package/dist/config.js +493 -0
- package/dist/consolidated-quote.d.ts +554 -0
- package/dist/consolidated-quote.js +773 -0
- package/dist/destination-calldata.d.ts +118 -0
- package/dist/destination-calldata.js +152 -0
- package/dist/ecosystems.d.ts +217 -0
- package/dist/ecosystems.js +288 -0
- package/dist/fee-type.d.ts +10 -0
- package/dist/fee-type.js +9 -0
- package/dist/hyperliquid-execution.d.ts +152 -0
- package/dist/hyperliquid-execution.js +168 -0
- package/dist/image-links.d.ts +117 -0
- package/dist/image-links.js +142 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +20 -0
- package/dist/lifi-execution-guard.d.ts +199 -0
- package/dist/lifi-execution-guard.js +400 -0
- package/dist/near-intents-conformance.d.ts +85 -0
- package/dist/near-intents-conformance.js +329 -0
- package/dist/near-intents-route.d.ts +47 -0
- package/dist/near-intents-route.js +265 -0
- package/dist/near-intents.d.ts +524 -0
- package/dist/near-intents.js +1055 -0
- package/dist/origin-deposit.d.ts +326 -0
- package/dist/origin-deposit.js +68 -0
- package/dist/pre-quote.d.ts +198 -0
- package/dist/pre-quote.js +175 -0
- package/dist/prices.d.ts +107 -0
- package/dist/prices.js +162 -0
- package/dist/providers.d.ts +221 -0
- package/dist/providers.js +157 -0
- package/dist/quote-fees.d.ts +102 -0
- package/dist/quote-fees.js +195 -0
- package/dist/referral.d.ts +77 -0
- package/dist/referral.js +72 -0
- package/dist/relay-currencies.d.ts +47 -0
- package/dist/relay-currencies.js +89 -0
- package/dist/relay-quote.d.ts +301 -0
- package/dist/relay-quote.js +983 -0
- package/dist/route-steps.d.ts +138 -0
- package/dist/route-steps.js +305 -0
- package/dist/routing/amounts.d.ts +80 -0
- package/dist/routing/amounts.js +120 -0
- package/dist/routing/candidate-route.d.ts +43 -0
- package/dist/routing/candidate-route.js +45 -0
- package/dist/routing/candidate.d.ts +237 -0
- package/dist/routing/candidate.js +96 -0
- package/dist/routing/carriers/ask-answer.d.ts +60 -0
- package/dist/routing/carriers/ask-answer.js +1 -0
- package/dist/routing/carriers/omnibridge.d.ts +137 -0
- package/dist/routing/carriers/omnibridge.js +419 -0
- package/dist/routing/carriers/pulsex.d.ts +149 -0
- package/dist/routing/carriers/pulsex.js +453 -0
- package/dist/routing/carriers/wrap.d.ts +25 -0
- package/dist/routing/carriers/wrap.js +115 -0
- package/dist/routing/composed-route-quality.d.ts +103 -0
- package/dist/routing/composed-route-quality.js +108 -0
- package/dist/routing/entry-chain-anchor.d.ts +88 -0
- package/dist/routing/entry-chain-anchor.js +55 -0
- package/dist/routing/format.d.ts +31 -0
- package/dist/routing/format.js +58 -0
- package/dist/routing/index.d.ts +34 -0
- package/dist/routing/index.js +42 -0
- package/dist/routing/producers.d.ts +770 -0
- package/dist/routing/producers.js +1564 -0
- package/dist/routing/providers.d.ts +26 -0
- package/dist/routing/providers.js +38 -0
- package/dist/routing/route-data.d.ts +355 -0
- package/dist/routing/route-data.js +1 -0
- package/dist/routing/search/compose.d.ts +168 -0
- package/dist/routing/search/compose.js +98 -0
- package/dist/routing/search/graph.d.ts +653 -0
- package/dist/routing/search/graph.js +445 -0
- package/dist/routing/search/plan-route-data.d.ts +244 -0
- package/dist/routing/search/plan-route-data.js +767 -0
- package/dist/routing/search/score.d.ts +353 -0
- package/dist/routing/search/score.js +427 -0
- package/dist/routing/usd-value.d.ts +17 -0
- package/dist/routing/usd-value.js +25 -0
- package/dist/settings.d.ts +692 -0
- package/dist/settings.js +909 -0
- package/dist/ton-execution.d.ts +117 -0
- package/dist/ton-execution.js +247 -0
- package/dist/tron-execution.d.ts +146 -0
- package/dist/tron-execution.js +239 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.js +1 -0
- package/llms.txt +169 -0
- package/package.json +204 -23
- package/src/chain-info.test.ts +0 -968
- package/src/chain-info.ts +0 -498
- package/src/chains.test.ts +0 -123
- package/src/chains.ts +0 -88
- package/src/config.test.ts +0 -679
- package/src/config.ts +0 -500
- package/src/fee-type.test.ts +0 -45
- package/src/fee-type.ts +0 -14
- package/src/image-links.test.ts +0 -160
- package/src/image-links.ts +0 -65
- package/src/index.ts +0 -8
- package/src/settings.test.ts +0 -2754
- package/src/settings.ts +0 -875
- package/src/types.ts +0 -48
- package/tsconfig.json +0 -17
- package/vitest.config.ts +0 -13
- /package/{src/abis.ts → dist/abis.js} +0 -0
package/src/chain-info.ts
DELETED
|
@@ -1,498 +0,0 @@
|
|
|
1
|
-
import { multicallRead } from '@gibs/common/multicall';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import {
|
|
4
|
-
encodeFunctionData,
|
|
5
|
-
getContract,
|
|
6
|
-
type Hex,
|
|
7
|
-
multicall3Abi,
|
|
8
|
-
type PublicClient,
|
|
9
|
-
zeroAddress,
|
|
10
|
-
} from 'viem';
|
|
11
|
-
import * as abis from './abis.js';
|
|
12
|
-
import { chainsMetadata } from './chains.js';
|
|
13
|
-
import {
|
|
14
|
-
type Chains,
|
|
15
|
-
nativeAssetOut,
|
|
16
|
-
type Pathway,
|
|
17
|
-
pathway,
|
|
18
|
-
toChain,
|
|
19
|
-
uniV2Routers,
|
|
20
|
-
} from './config.js';
|
|
21
|
-
import type { BridgeKey, Token } from './types.js';
|
|
22
|
-
|
|
23
|
-
export type TokenBridgeInfo = {
|
|
24
|
-
originationChainId: Chains;
|
|
25
|
-
assetInAddress: Hex;
|
|
26
|
-
assetOutAddress: Hex | null;
|
|
27
|
-
toForeign?: {
|
|
28
|
-
home: Hex;
|
|
29
|
-
foreign: Hex | null;
|
|
30
|
-
};
|
|
31
|
-
toHome?: {
|
|
32
|
-
home: Hex | null;
|
|
33
|
-
foreign: Hex;
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Returns the bridged token address and native token address
|
|
39
|
-
* @param chainId - the chain id being targeted
|
|
40
|
-
* @param target - the target
|
|
41
|
-
* @param address - the address
|
|
42
|
-
* @param client - the client
|
|
43
|
-
* @returns the bridged token address and native token address
|
|
44
|
-
*/
|
|
45
|
-
export const links = _.memoize(
|
|
46
|
-
async ({
|
|
47
|
-
chainId,
|
|
48
|
-
target,
|
|
49
|
-
address,
|
|
50
|
-
client,
|
|
51
|
-
}: {
|
|
52
|
-
chainId: number;
|
|
53
|
-
target: Hex;
|
|
54
|
-
address: Hex;
|
|
55
|
-
client: PublicClient;
|
|
56
|
-
}) => {
|
|
57
|
-
return multicallRead<[Hex, Hex]>({
|
|
58
|
-
client,
|
|
59
|
-
chain: chainsMetadata[toChain(chainId)],
|
|
60
|
-
abi: abis.inputBridge,
|
|
61
|
-
target,
|
|
62
|
-
calls: [
|
|
63
|
-
{ functionName: 'bridgedTokenAddress', args: [address] },
|
|
64
|
-
{ functionName: 'nativeTokenAddress', args: [address] },
|
|
65
|
-
],
|
|
66
|
-
});
|
|
67
|
-
},
|
|
68
|
-
({ chainId, target, address }) => `${chainId}-${target}-${address}`.toLowerCase(),
|
|
69
|
-
);
|
|
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 ({
|
|
81
|
-
bridgeKey,
|
|
82
|
-
assetIn,
|
|
83
|
-
isProd,
|
|
84
|
-
fromChainClient,
|
|
85
|
-
toChainClient,
|
|
86
|
-
}: {
|
|
87
|
-
bridgeKey: BridgeKey;
|
|
88
|
-
assetIn: Token | null;
|
|
89
|
-
isProd: boolean;
|
|
90
|
-
fromChainClient: PublicClient;
|
|
91
|
-
toChainClient: PublicClient;
|
|
92
|
-
}): Promise<null | TokenBridgeInfo> => {
|
|
93
|
-
const bridgePathway = pathway(bridgeKey, isProd, assetIn?.address as Hex | null);
|
|
94
|
-
if (!assetIn || !bridgePathway) {
|
|
95
|
-
console.log('missing asset in or bridge pathway');
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
const [, fromChain, toChain] = bridgeKey;
|
|
99
|
-
const assetInAddress =
|
|
100
|
-
assetIn.address === zeroAddress ? nativeAssetOut[fromChain] : assetIn.address;
|
|
101
|
-
const [toMappings, fromMappings] = await Promise.all([
|
|
102
|
-
links({
|
|
103
|
-
chainId: Number(toChain),
|
|
104
|
-
target: bridgePathway.to,
|
|
105
|
-
address: assetInAddress as Hex,
|
|
106
|
-
client: toChainClient,
|
|
107
|
-
}),
|
|
108
|
-
links({
|
|
109
|
-
chainId: Number(fromChain),
|
|
110
|
-
target: bridgePathway.from,
|
|
111
|
-
address: assetInAddress as Hex,
|
|
112
|
-
client: fromChainClient,
|
|
113
|
-
}),
|
|
114
|
-
]);
|
|
115
|
-
const [toBridged, toNative] = toMappings;
|
|
116
|
-
if (toBridged !== zeroAddress) {
|
|
117
|
-
return {
|
|
118
|
-
originationChainId: fromChain,
|
|
119
|
-
assetInAddress: assetInAddress as Hex,
|
|
120
|
-
assetOutAddress: toBridged,
|
|
121
|
-
toHome: {
|
|
122
|
-
home: toBridged,
|
|
123
|
-
foreign: assetInAddress as Hex,
|
|
124
|
-
},
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
if (toNative !== zeroAddress) {
|
|
128
|
-
return {
|
|
129
|
-
originationChainId: toChain,
|
|
130
|
-
assetInAddress: assetInAddress as Hex,
|
|
131
|
-
assetOutAddress: toNative,
|
|
132
|
-
toForeign: {
|
|
133
|
-
home: toNative,
|
|
134
|
-
foreign: assetInAddress as Hex,
|
|
135
|
-
},
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
const [fromBridged, fromNative] = fromMappings;
|
|
139
|
-
if (fromNative !== zeroAddress) {
|
|
140
|
-
return {
|
|
141
|
-
originationChainId: toChain,
|
|
142
|
-
assetInAddress: assetInAddress as Hex,
|
|
143
|
-
assetOutAddress: fromNative,
|
|
144
|
-
toHome: {
|
|
145
|
-
home: assetInAddress as Hex,
|
|
146
|
-
foreign: fromNative,
|
|
147
|
-
},
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
if (fromBridged !== zeroAddress) {
|
|
151
|
-
return {
|
|
152
|
-
originationChainId: fromChain,
|
|
153
|
-
assetInAddress: assetInAddress as Hex,
|
|
154
|
-
assetOutAddress: fromBridged,
|
|
155
|
-
toForeign: {
|
|
156
|
-
foreign: fromBridged,
|
|
157
|
-
home: assetInAddress as Hex,
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
// the token has not been bridged yet
|
|
162
|
-
return {
|
|
163
|
-
originationChainId: toChain,
|
|
164
|
-
assetInAddress: assetInAddress as Hex,
|
|
165
|
-
assetOutAddress: null,
|
|
166
|
-
...(bridgePathway.toHome
|
|
167
|
-
? {
|
|
168
|
-
toHome: {
|
|
169
|
-
foreign: assetInAddress as Hex,
|
|
170
|
-
home: null,
|
|
171
|
-
},
|
|
172
|
-
}
|
|
173
|
-
: {
|
|
174
|
-
toForeign: {
|
|
175
|
-
foreign: null,
|
|
176
|
-
home: assetInAddress as Hex,
|
|
177
|
-
},
|
|
178
|
-
}),
|
|
179
|
-
};
|
|
180
|
-
};
|
|
181
|
-
/** The result of reading the amount out from a router */
|
|
182
|
-
export type FetchResult = bigint[] | Hex;
|
|
183
|
-
/**
|
|
184
|
-
* Check the prices that each router offers for the given paths
|
|
185
|
-
* @param assetInAddress the address of the asset going into the bridge
|
|
186
|
-
* @param oneTokenInt the number of tokens to push into the bridge (before fees)
|
|
187
|
-
* @param chain the chain of the asset going into the bridge
|
|
188
|
-
* @param bridgeKey the bridge key
|
|
189
|
-
* @param blockNumber the block number to use for the price
|
|
190
|
-
* @param paths the paths to check
|
|
191
|
-
* @returns the prices as bigint for each path, hex whenever the price is not available
|
|
192
|
-
*/
|
|
193
|
-
const readAmountOut = ({
|
|
194
|
-
amountIn,
|
|
195
|
-
chain,
|
|
196
|
-
paths,
|
|
197
|
-
client,
|
|
198
|
-
uniV2Router,
|
|
199
|
-
}: {
|
|
200
|
-
amountIn: bigint;
|
|
201
|
-
chain: Chains;
|
|
202
|
-
paths: Hex[][];
|
|
203
|
-
client: PublicClient;
|
|
204
|
-
uniV2Router?: Hex;
|
|
205
|
-
}): Promise<FetchResult[]> => {
|
|
206
|
-
return multicallRead<FetchResult[]>({
|
|
207
|
-
chain: chainsMetadata[chain],
|
|
208
|
-
client,
|
|
209
|
-
abi: abis.univ2Router,
|
|
210
|
-
// pulsex router
|
|
211
|
-
calls: _.flatMap(uniV2Router ? [uniV2Router] : uniV2Routers[chain], (target) =>
|
|
212
|
-
paths.map((path) => ({
|
|
213
|
-
functionName: 'getAmountsOut',
|
|
214
|
-
allowFailure: true,
|
|
215
|
-
args: [amountIn, path],
|
|
216
|
-
target,
|
|
217
|
-
})),
|
|
218
|
-
),
|
|
219
|
-
});
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* 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
|
|
224
|
-
* @param bridgeKeyPartner - the bridge key partner
|
|
225
|
-
* @param assetOut - the asset out
|
|
226
|
-
* @param measurementToken - the measurement token
|
|
227
|
-
* @param fromChainClient - the from chain client
|
|
228
|
-
* @param toChainClient - the to chain client
|
|
229
|
-
* @param assetLink - the asset link
|
|
230
|
-
* @param amountIn - the amount in
|
|
231
|
-
* @param isProd - whether to use the production pathway
|
|
232
|
-
* @returns the price corrective
|
|
233
|
-
*/
|
|
234
|
-
export const fetchPriceCorrective = ({
|
|
235
|
-
bridgeKeyPartner,
|
|
236
|
-
assetOut,
|
|
237
|
-
measurementToken,
|
|
238
|
-
fromChainClient,
|
|
239
|
-
toChainClient,
|
|
240
|
-
assetLink,
|
|
241
|
-
amountIn,
|
|
242
|
-
isProd,
|
|
243
|
-
}: {
|
|
244
|
-
bridgeKey: BridgeKey;
|
|
245
|
-
bridgeKeyPartner: BridgeKey;
|
|
246
|
-
measurementToken: Hex;
|
|
247
|
-
assetOut: Token;
|
|
248
|
-
fromChainClient: PublicClient;
|
|
249
|
-
toChainClient: PublicClient;
|
|
250
|
-
assetLink: TokenBridgeInfo;
|
|
251
|
-
amountIn: bigint;
|
|
252
|
-
isProd: boolean;
|
|
253
|
-
}) => {
|
|
254
|
-
return {
|
|
255
|
-
getPaymentToken: async () => {
|
|
256
|
-
// fetch the token bridge info for the token that is about to be spent by the delivery service
|
|
257
|
-
return await tokenBridgeInfo({
|
|
258
|
-
bridgeKey: bridgeKeyPartner,
|
|
259
|
-
assetIn: {
|
|
260
|
-
...assetOut,
|
|
261
|
-
address: measurementToken,
|
|
262
|
-
},
|
|
263
|
-
isProd,
|
|
264
|
-
// clients are reversed here because we are actually fetching the
|
|
265
|
-
// tokens going the opposite direction to the provided bridge key
|
|
266
|
-
fromChainClient: toChainClient,
|
|
267
|
-
toChainClient: fromChainClient,
|
|
268
|
-
});
|
|
269
|
-
},
|
|
270
|
-
getSwapResults: async ({
|
|
271
|
-
paymentTokenResult,
|
|
272
|
-
chain,
|
|
273
|
-
uniV2Router,
|
|
274
|
-
client,
|
|
275
|
-
}: {
|
|
276
|
-
paymentTokenResult: TokenBridgeInfo;
|
|
277
|
-
chain: Chains;
|
|
278
|
-
client: PublicClient;
|
|
279
|
-
uniV2Router?: Hex;
|
|
280
|
-
}) => {
|
|
281
|
-
return await Promise.all([
|
|
282
|
-
readAmountOut({
|
|
283
|
-
amountIn,
|
|
284
|
-
chain,
|
|
285
|
-
uniV2Router,
|
|
286
|
-
client,
|
|
287
|
-
paths: [
|
|
288
|
-
// check the direct route
|
|
289
|
-
[assetLink.assetInAddress, paymentTokenResult!.assetOutAddress!],
|
|
290
|
-
// might have heavier liquidity going through the native asset on the home side
|
|
291
|
-
[assetLink.assetInAddress, nativeAssetOut[chain], paymentTokenResult!.assetOutAddress!],
|
|
292
|
-
],
|
|
293
|
-
}),
|
|
294
|
-
readAmountOut({
|
|
295
|
-
amountIn,
|
|
296
|
-
chain,
|
|
297
|
-
uniV2Router,
|
|
298
|
-
client,
|
|
299
|
-
paths: [[assetOut.address as Hex, measurementToken]],
|
|
300
|
-
// only the direct route is available.
|
|
301
|
-
// might be able to create a whitelist for this at some point
|
|
302
|
-
}),
|
|
303
|
-
]);
|
|
304
|
-
},
|
|
305
|
-
reduceResults: ({
|
|
306
|
-
results,
|
|
307
|
-
oneToken,
|
|
308
|
-
}: {
|
|
309
|
-
results: [FetchResult[], ...[FetchResult[]]];
|
|
310
|
-
oneToken: bigint;
|
|
311
|
-
}) => {
|
|
312
|
-
const outputFromRouter = (result: FetchResult) => {
|
|
313
|
-
if (_.isString(result)) {
|
|
314
|
-
// the router failed to return a result
|
|
315
|
-
return 0n;
|
|
316
|
-
}
|
|
317
|
-
if (!result.length) {
|
|
318
|
-
// the router returned an empty result
|
|
319
|
-
return 0n;
|
|
320
|
-
}
|
|
321
|
-
// the last element is the amount of the output token
|
|
322
|
-
const last = result[result.length - 1]!;
|
|
323
|
-
return (last * oneToken) / amountIn;
|
|
324
|
-
};
|
|
325
|
-
const max = (amountsOut: (bigint | undefined)[]) => {
|
|
326
|
-
return _.compact(amountsOut).reduce((max, current) => (max < current ? current : max), 0n);
|
|
327
|
-
};
|
|
328
|
-
// could do with a refactor to unify the results
|
|
329
|
-
const [outputs, inputs] = results;
|
|
330
|
-
const outputAmounts = outputs.map(outputFromRouter);
|
|
331
|
-
const inputAmounts = inputs.map(outputFromRouter);
|
|
332
|
-
const outputToken = max(outputAmounts);
|
|
333
|
-
const inputToken = max(inputAmounts);
|
|
334
|
-
const result =
|
|
335
|
-
outputToken && outputToken > 0n
|
|
336
|
-
? inputToken && inputToken > outputToken && inputToken / outputToken === 1n
|
|
337
|
-
? inputToken
|
|
338
|
-
: outputToken
|
|
339
|
-
: inputToken;
|
|
340
|
-
return result;
|
|
341
|
-
},
|
|
342
|
-
};
|
|
343
|
-
};
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Fetch the minimum bridge amount in for the given asset in, pathway, from public client, and to public client
|
|
347
|
-
* @param assetIn - the asset in
|
|
348
|
-
* @param pathway - the pathway
|
|
349
|
-
* @param fromPublicClient - the from public client
|
|
350
|
-
* @param toPublicClient - the to public client
|
|
351
|
-
* @returns the minimum bridge amount in
|
|
352
|
-
*/
|
|
353
|
-
export const minBridgeAmountIn = async ({
|
|
354
|
-
assetIn,
|
|
355
|
-
pathway,
|
|
356
|
-
fromPublicClient,
|
|
357
|
-
toPublicClient,
|
|
358
|
-
}: {
|
|
359
|
-
assetIn: Token;
|
|
360
|
-
pathway: Pathway;
|
|
361
|
-
fromPublicClient: PublicClient;
|
|
362
|
-
toPublicClient: PublicClient;
|
|
363
|
-
}) => {
|
|
364
|
-
const publicClient = pathway?.feeManager === 'from' ? fromPublicClient : toPublicClient;
|
|
365
|
-
return publicClient.readContract({
|
|
366
|
-
abi: abis.inputBridge,
|
|
367
|
-
functionName: 'minPerTx',
|
|
368
|
-
args: [assetIn.address as Hex],
|
|
369
|
-
address: pathway[pathway.feeManager],
|
|
370
|
-
});
|
|
371
|
-
};
|
|
372
|
-
/** get the symbol of the native asset, unwrap it if it needs to be */
|
|
373
|
-
export const nativeSymbol = (
|
|
374
|
-
asset: { address: string; symbol: string; chainId: number } | null,
|
|
375
|
-
unwrap = false,
|
|
376
|
-
) => {
|
|
377
|
-
return asset
|
|
378
|
-
? unwrap && asset.address === nativeAssetOut[toChain(asset.chainId)]
|
|
379
|
-
? asset.symbol.slice(1)
|
|
380
|
-
: asset.symbol
|
|
381
|
-
: '';
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
/** The input for loading the bridge fees */
|
|
385
|
-
export type InputLoadFeeFor = {
|
|
386
|
-
pathway: Pathway;
|
|
387
|
-
fromChainClient: PublicClient;
|
|
388
|
-
toChainClient: PublicClient;
|
|
389
|
-
};
|
|
390
|
-
|
|
391
|
-
/** The fee configuration for a given pathway */
|
|
392
|
-
export type PathwayExtendableConfig = {
|
|
393
|
-
feeManager: Hex;
|
|
394
|
-
feeH2F: bigint;
|
|
395
|
-
feeF2H: bigint;
|
|
396
|
-
};
|
|
397
|
-
/**
|
|
398
|
-
* Returns the chain multicall for the given client
|
|
399
|
-
* @param client - the client
|
|
400
|
-
* @returns the chain multicall
|
|
401
|
-
*/
|
|
402
|
-
export const chainMulticall = (client: PublicClient) => {
|
|
403
|
-
const chainId = client.chain!.id;
|
|
404
|
-
const metadata = chainsMetadata[toChain(chainId)];
|
|
405
|
-
return getContract({
|
|
406
|
-
abi: multicall3Abi,
|
|
407
|
-
client: client as any,
|
|
408
|
-
address: metadata.contracts!.multicall3!.address,
|
|
409
|
-
}) as any;
|
|
410
|
-
};
|
|
411
|
-
/**
|
|
412
|
-
* Load the bridge fees for the given pathway, from chain client, and to chain client
|
|
413
|
-
* @param pathway - the pathway
|
|
414
|
-
* @param fromChainClient - the from chain client
|
|
415
|
-
* @param toChainClient - the to chain client
|
|
416
|
-
* @returns the bridge fees
|
|
417
|
-
*/
|
|
418
|
-
export const loadBridgeFees = async ({
|
|
419
|
-
pathway,
|
|
420
|
-
fromChainClient,
|
|
421
|
-
toChainClient,
|
|
422
|
-
}: InputLoadFeeFor) => {
|
|
423
|
-
const multicall =
|
|
424
|
-
pathway.feeManager === 'from' ? chainMulticall(fromChainClient) : chainMulticall(toChainClient);
|
|
425
|
-
|
|
426
|
-
const [feeManagerResponse] = await multicall.read.aggregate3([
|
|
427
|
-
[
|
|
428
|
-
{
|
|
429
|
-
allowFailure: false,
|
|
430
|
-
target: pathway[pathway.feeManager],
|
|
431
|
-
callData: encodeFunctionData({
|
|
432
|
-
abi: abis.inputBridge,
|
|
433
|
-
functionName: 'feeManager',
|
|
434
|
-
}),
|
|
435
|
-
},
|
|
436
|
-
],
|
|
437
|
-
]);
|
|
438
|
-
const { success, returnData } = feeManagerResponse;
|
|
439
|
-
if (!success) {
|
|
440
|
-
throw new Error('unable to load feeManager');
|
|
441
|
-
}
|
|
442
|
-
if (returnData === '0x') {
|
|
443
|
-
throw new Error('unable to read feeManager');
|
|
444
|
-
}
|
|
445
|
-
const feeManager = (
|
|
446
|
-
returnData.startsWith('0x000000000000000000000000')
|
|
447
|
-
? `0x${returnData.slice(26)}`
|
|
448
|
-
: `0x${returnData.slice(-40)}`
|
|
449
|
-
) as Hex;
|
|
450
|
-
const [keyH2F, keyF2H] = await multicall.read.aggregate3([
|
|
451
|
-
[
|
|
452
|
-
{
|
|
453
|
-
allowFailure: false,
|
|
454
|
-
target: feeManager,
|
|
455
|
-
callData: encodeFunctionData({
|
|
456
|
-
abi: abis.feeManager,
|
|
457
|
-
functionName: 'HOME_TO_FOREIGN_FEE',
|
|
458
|
-
}),
|
|
459
|
-
},
|
|
460
|
-
{
|
|
461
|
-
allowFailure: false,
|
|
462
|
-
target: feeManager,
|
|
463
|
-
callData: encodeFunctionData({
|
|
464
|
-
abi: abis.feeManager,
|
|
465
|
-
functionName: 'FOREIGN_TO_HOME_FEE',
|
|
466
|
-
}),
|
|
467
|
-
},
|
|
468
|
-
],
|
|
469
|
-
]);
|
|
470
|
-
const [feeH2F, feeF2H] = await multicall.read.aggregate3([
|
|
471
|
-
[
|
|
472
|
-
{
|
|
473
|
-
allowFailure: false,
|
|
474
|
-
target: feeManager,
|
|
475
|
-
callData: encodeFunctionData({
|
|
476
|
-
abi: abis.feeManager,
|
|
477
|
-
functionName: 'getFee',
|
|
478
|
-
args: [keyH2F.returnData, zeroAddress],
|
|
479
|
-
}),
|
|
480
|
-
},
|
|
481
|
-
{
|
|
482
|
-
allowFailure: false,
|
|
483
|
-
target: feeManager,
|
|
484
|
-
callData: encodeFunctionData({
|
|
485
|
-
abi: abis.feeManager,
|
|
486
|
-
functionName: 'getFee',
|
|
487
|
-
args: [keyF2H.returnData, zeroAddress],
|
|
488
|
-
}),
|
|
489
|
-
},
|
|
490
|
-
],
|
|
491
|
-
]);
|
|
492
|
-
const setting = {
|
|
493
|
-
feeManager,
|
|
494
|
-
feeH2F: BigInt(feeH2F.returnData),
|
|
495
|
-
feeF2H: BigInt(feeF2H.returnData),
|
|
496
|
-
} as PathwayExtendableConfig;
|
|
497
|
-
return setting;
|
|
498
|
-
};
|
package/src/chains.test.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { chainsMetadata } from './chains';
|
|
3
|
-
import { Chains } from './config';
|
|
4
|
-
|
|
5
|
-
describe('chains', () => {
|
|
6
|
-
describe('chainsMetadata', () => {
|
|
7
|
-
it('should have metadata for all main chains', () => {
|
|
8
|
-
expect(chainsMetadata[Chains.PLS]).toBeDefined();
|
|
9
|
-
expect(chainsMetadata[Chains.ETH]).toBeDefined();
|
|
10
|
-
expect(chainsMetadata[Chains.BNB]).toBeDefined();
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it('should have metadata for testnet chains', () => {
|
|
14
|
-
expect(chainsMetadata[Chains.SEP]).toBeDefined();
|
|
15
|
-
expect(chainsMetadata[Chains.V4PLS]).toBeDefined();
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('should have required fields for each chain', () => {
|
|
19
|
-
Object.entries(chainsMetadata).forEach(([chainKey, metadata]) => {
|
|
20
|
-
expect(metadata).toHaveProperty('chainId');
|
|
21
|
-
expect(metadata).toHaveProperty('name');
|
|
22
|
-
expect(metadata).toHaveProperty('logoURI');
|
|
23
|
-
expect(metadata).toHaveProperty('alt');
|
|
24
|
-
expect(metadata).toHaveProperty('rpcUrls');
|
|
25
|
-
expect(metadata.rpcUrls).toHaveProperty('default');
|
|
26
|
-
expect(metadata.rpcUrls.default).toHaveProperty('http');
|
|
27
|
-
expect(Array.isArray(metadata.rpcUrls.default.http)).toBe(true);
|
|
28
|
-
expect(metadata.rpcUrls.default.http.length).toBeGreaterThan(0);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('should have valid RPC URLs for each chain', () => {
|
|
33
|
-
Object.values(chainsMetadata).forEach((metadata) => {
|
|
34
|
-
metadata.rpcUrls.default.http.forEach((url) => {
|
|
35
|
-
expect(url).toMatch(/^https?:\/\//);
|
|
36
|
-
expect(url).not.toContain(' ');
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('should have valid logoURIs', () => {
|
|
42
|
-
Object.values(chainsMetadata).forEach((metadata) => {
|
|
43
|
-
expect(metadata.logoURI).toMatch(/^https?:\/\//);
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('should have alt text for accessibility', () => {
|
|
48
|
-
Object.values(chainsMetadata).forEach((metadata) => {
|
|
49
|
-
expect(typeof metadata.alt).toBe('string');
|
|
50
|
-
expect(metadata.alt.length).toBeGreaterThan(0);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('should have matching chainId in metadata', () => {
|
|
55
|
-
Object.entries(chainsMetadata).forEach(([chainKey, metadata]) => {
|
|
56
|
-
expect(metadata.chainId).toBe(chainKey);
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should have ENS contracts for Pulsechain chains', () => {
|
|
61
|
-
// Mainnet PLS should have ENS
|
|
62
|
-
expect(chainsMetadata[Chains.PLS].contracts?.ensRegistry).toBeDefined();
|
|
63
|
-
expect(chainsMetadata[Chains.PLS].contracts?.ensUniversalResolver).toBeDefined();
|
|
64
|
-
expect(chainsMetadata[Chains.PLS].contracts?.ensRegistry?.address).toMatch(
|
|
65
|
-
/^0x[a-fA-F0-9]{40}$/,
|
|
66
|
-
);
|
|
67
|
-
expect(chainsMetadata[Chains.PLS].contracts?.ensUniversalResolver?.address).toMatch(
|
|
68
|
-
/^0x[a-fA-F0-9]{40}$/,
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
// Testnet V4PLS should have ENS
|
|
72
|
-
expect(chainsMetadata[Chains.V4PLS].contracts?.ensRegistry).toBeDefined();
|
|
73
|
-
expect(chainsMetadata[Chains.V4PLS].contracts?.ensUniversalResolver).toBeDefined();
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should have multicall3 contracts for all chains', () => {
|
|
77
|
-
Object.values(chainsMetadata).forEach((metadata) => {
|
|
78
|
-
expect(metadata.contracts?.multicall3).toBeDefined();
|
|
79
|
-
expect(metadata.contracts?.multicall3?.address).toMatch(/^0x[a-fA-F0-9]{40}$/);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('should have unique RPC URLs per chain', () => {
|
|
84
|
-
const rpcUrls = Object.values(chainsMetadata).map((m) => m.rpcUrls.default.http[0]);
|
|
85
|
-
const uniqueUrls = new Set(rpcUrls);
|
|
86
|
-
expect(uniqueUrls.size).toBe(rpcUrls.length);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
describe('specific chain validation', () => {
|
|
90
|
-
it('should have correct Pulsechain mainnet config', () => {
|
|
91
|
-
const pls = chainsMetadata[Chains.PLS];
|
|
92
|
-
expect(pls.name).toContain('Pulse');
|
|
93
|
-
expect(pls.chainId).toBe(Chains.PLS);
|
|
94
|
-
expect(pls.rpcUrls.default.http[0]).toContain('pulsechain');
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should have correct Ethereum mainnet config', () => {
|
|
98
|
-
const eth = chainsMetadata[Chains.ETH];
|
|
99
|
-
expect(eth.name).toContain('Ethereum');
|
|
100
|
-
expect(eth.chainId).toBe(Chains.ETH);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('should have correct BSC config', () => {
|
|
104
|
-
const bnb = chainsMetadata[Chains.BNB];
|
|
105
|
-
expect(bnb.name).toContain('Binance');
|
|
106
|
-
expect(bnb.chainId).toBe(Chains.BNB);
|
|
107
|
-
expect(bnb.rpcUrls.default.http[0]).toContain('bsc');
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('should have correct Sepolia testnet config', () => {
|
|
111
|
-
const sep = chainsMetadata[Chains.SEP];
|
|
112
|
-
expect(sep.name).toBe('Sepolia');
|
|
113
|
-
expect(sep.chainId).toBe(Chains.SEP);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it('should have correct Pulsechain V4 testnet config', () => {
|
|
117
|
-
const v4pls = chainsMetadata[Chains.V4PLS];
|
|
118
|
-
expect(v4pls.name).toContain('Pulsechain V4');
|
|
119
|
-
expect(v4pls.chainId).toBe(Chains.V4PLS);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
});
|
package/src/chains.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { Chains } from '@gibs/bridge-sdk/config';
|
|
2
|
-
import * as imageLinks from '@gibs/bridge-sdk/image-links';
|
|
3
|
-
import type { ChainsMetadata } from '@gibs/bridge-sdk/types';
|
|
4
|
-
import { bsc, mainnet, pulsechain, pulsechainV4, sepolia } from '@reown/appkit/networks';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* all of the chains that are enabled in this dapp
|
|
8
|
-
* and their corresponding useful metadata
|
|
9
|
-
*/
|
|
10
|
-
export const chainsMetadata = {
|
|
11
|
-
[Chains.PLS]: {
|
|
12
|
-
...pulsechain,
|
|
13
|
-
chainId: Chains.PLS,
|
|
14
|
-
logoURI: imageLinks.network(pulsechain.id),
|
|
15
|
-
alt: 'a pink blue and purple hexagon with an ekg line running horizontally',
|
|
16
|
-
rpcUrls: {
|
|
17
|
-
default: {
|
|
18
|
-
http: ['https://rpc.pulsechain.com'],
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
contracts: {
|
|
22
|
-
...pulsechain.contracts,
|
|
23
|
-
ensRegistry: {
|
|
24
|
-
address: '0xbd5133993FCDED5945c5539D9f032261F0d13170',
|
|
25
|
-
},
|
|
26
|
-
ensUniversalResolver: {
|
|
27
|
-
address: '0x2FDBb906b4FE68e31D928C1ED0b6a3bD1f204374',
|
|
28
|
-
blockCreated: 19_400_610,
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
[Chains.ETH]: {
|
|
33
|
-
...mainnet,
|
|
34
|
-
chainId: Chains.ETH,
|
|
35
|
-
logoURI: imageLinks.network(mainnet.id),
|
|
36
|
-
alt: 'two pyramids joined on one side',
|
|
37
|
-
rpcUrls: {
|
|
38
|
-
default: {
|
|
39
|
-
http: ['https://rpc-ethereum.g4mm4.io'],
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
[Chains.BNB]: {
|
|
44
|
-
...bsc,
|
|
45
|
-
name: 'Binance Smart Chain',
|
|
46
|
-
chainId: Chains.BNB,
|
|
47
|
-
logoURI: imageLinks.network(bsc.id),
|
|
48
|
-
alt: 'a gold cube with slits in the middle of each side',
|
|
49
|
-
rpcUrls: {
|
|
50
|
-
default: {
|
|
51
|
-
http: ['https://bsc-rpc.publicnode.com'],
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
[Chains.SEP]: {
|
|
56
|
-
...sepolia,
|
|
57
|
-
name: 'Sepolia',
|
|
58
|
-
chainId: Chains.SEP,
|
|
59
|
-
logoURI: imageLinks.network(sepolia.id),
|
|
60
|
-
alt: 'two pyramids joined on one side',
|
|
61
|
-
rpcUrls: {
|
|
62
|
-
default: {
|
|
63
|
-
http: ['https://ethereum-sepolia-rpc.publicnode.com'],
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
[Chains.V4PLS]: {
|
|
68
|
-
...pulsechainV4,
|
|
69
|
-
name: 'Pulsechain V4',
|
|
70
|
-
chainId: Chains.V4PLS,
|
|
71
|
-
logoURI: imageLinks.network(pulsechainV4.id),
|
|
72
|
-
alt: 'a pink blue and purple hexagon with an ekg line running horizontally',
|
|
73
|
-
rpcUrls: {
|
|
74
|
-
default: {
|
|
75
|
-
http: ['https://rpc-testnet-pulsechain.g4mm4.io'],
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
contracts: {
|
|
79
|
-
...pulsechainV4.contracts,
|
|
80
|
-
ensRegistry: {
|
|
81
|
-
address: '0xaDB38309aF7F85034FDC35bd6E6B45d1216CfB56',
|
|
82
|
-
},
|
|
83
|
-
ensUniversalResolver: {
|
|
84
|
-
address: '0xDDFde3fA938dE0cdff82645579d03Ed750DE2e69',
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
} as ChainsMetadata;
|