@gibs/bridge-sdk 1.9.1 → 1.12.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.
@@ -1,350 +0,0 @@
1
- import { encodeFunctionData, getContract, multicall3Abi, zeroAddress } from "viem";
2
- import { nativeAssetOut, pathway, toChain, uniV2Routers } from "./config.js";
3
- import _ from "lodash";
4
- import { chainsMetadata } from "./chains.js";
5
- import * as abis from "./abis.js";
6
- import { multicallRead } from "@gibs/common/multicall";
7
- /**
8
- * Returns the bridged token address and native token address
9
- * @param chainId - the chain id being targeted
10
- * @param target - the target
11
- * @param address - the address
12
- * @param client - the client
13
- * @returns the bridged token address and native token address
14
- */
15
- export const links = _.memoize(async ({ chainId, target, address, client }) => {
16
- return multicallRead({
17
- client,
18
- chain: chainsMetadata[toChain(chainId)],
19
- abi: abis.inputBridge,
20
- target,
21
- calls: [
22
- { functionName: 'bridgedTokenAddress', args: [address] },
23
- { functionName: 'nativeTokenAddress', args: [address] },
24
- ],
25
- });
26
- }, ({ chainId, target, address }) => `${chainId}-${target}-${address}`.toLowerCase());
27
- /**
28
- * Returns the token bridge info for the given bridge key, asset in, is prod, from chain client, and to chain client
29
- * @param bridgeKey - the bridge key
30
- * @param assetIn - the asset in
31
- * @param isProd - whether to use the production pathway
32
- * @param fromChainClient - the from chain client
33
- * @param toChainClient - the to chain client
34
- * @returns the token bridge info
35
- */
36
- export const tokenBridgeInfo = async ({ bridgeKey, assetIn, isProd, fromChainClient, toChainClient, }) => {
37
- const bridgePathway = pathway(bridgeKey, isProd, assetIn?.address);
38
- if (!assetIn || !bridgePathway) {
39
- console.log('missing asset in or bridge pathway');
40
- return null;
41
- }
42
- const [, fromChain, toChain] = bridgeKey;
43
- const assetInAddress = assetIn.address === zeroAddress ? nativeAssetOut[fromChain] : assetIn.address;
44
- const [toMappings, fromMappings] = await Promise.all([
45
- links({
46
- chainId: Number(toChain),
47
- target: bridgePathway.to,
48
- address: assetInAddress,
49
- client: toChainClient,
50
- }),
51
- links({
52
- chainId: Number(fromChain),
53
- target: bridgePathway.from,
54
- address: assetInAddress,
55
- client: fromChainClient,
56
- }),
57
- ]);
58
- const [toBridged, toNative] = toMappings;
59
- if (toBridged !== zeroAddress) {
60
- return {
61
- originationChainId: fromChain,
62
- assetInAddress: assetInAddress,
63
- assetOutAddress: toBridged,
64
- toHome: {
65
- home: toBridged,
66
- foreign: assetInAddress,
67
- },
68
- };
69
- }
70
- if (toNative !== zeroAddress) {
71
- return {
72
- originationChainId: toChain,
73
- assetInAddress: assetInAddress,
74
- assetOutAddress: toNative,
75
- toForeign: {
76
- home: toNative,
77
- foreign: assetInAddress,
78
- },
79
- };
80
- }
81
- const [fromBridged, fromNative] = fromMappings;
82
- if (fromNative !== zeroAddress) {
83
- return {
84
- originationChainId: toChain,
85
- assetInAddress: assetInAddress,
86
- assetOutAddress: fromNative,
87
- toHome: {
88
- home: assetInAddress,
89
- foreign: fromNative,
90
- },
91
- };
92
- }
93
- if (fromBridged !== zeroAddress) {
94
- return {
95
- originationChainId: fromChain,
96
- assetInAddress: assetInAddress,
97
- assetOutAddress: fromBridged,
98
- toForeign: {
99
- foreign: fromBridged,
100
- home: assetInAddress,
101
- },
102
- };
103
- }
104
- // the token has not been bridged yet
105
- return {
106
- originationChainId: toChain,
107
- assetInAddress: assetInAddress,
108
- assetOutAddress: null,
109
- ...(bridgePathway.toHome
110
- ? {
111
- toHome: {
112
- foreign: assetInAddress,
113
- home: null,
114
- },
115
- }
116
- : {
117
- toForeign: {
118
- foreign: null,
119
- home: assetInAddress,
120
- },
121
- }),
122
- };
123
- };
124
- /**
125
- * Check the prices that each router offers for the given paths
126
- * @param assetInAddress the address of the asset going into the bridge
127
- * @param oneTokenInt the number of tokens to push into the bridge (before fees)
128
- * @param chain the chain of the asset going into the bridge
129
- * @param bridgeKey the bridge key
130
- * @param blockNumber the block number to use for the price
131
- * @param paths the paths to check
132
- * @returns the prices as bigint for each path, hex whenever the price is not available
133
- */
134
- const readAmountOut = ({ amountIn, chain, paths, client, uniV2Router, }) => {
135
- return multicallRead({
136
- chain: chainsMetadata[chain],
137
- client,
138
- abi: abis.univ2Router,
139
- // pulsex router
140
- calls: _.flatMap(uniV2Router ? [uniV2Router] : uniV2Routers[chain], (target) => paths.map((path) => ({
141
- functionName: 'getAmountsOut',
142
- allowFailure: true,
143
- args: [amountIn, path],
144
- target,
145
- }))),
146
- });
147
- };
148
- /**
149
- * 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
150
- * @param bridgeKeyPartner - the bridge key partner
151
- * @param assetOut - the asset out
152
- * @param measurementToken - the measurement token
153
- * @param fromChainClient - the from chain client
154
- * @param toChainClient - the to chain client
155
- * @param assetLink - the asset link
156
- * @param amountIn - the amount in
157
- * @param isProd - whether to use the production pathway
158
- * @returns the price corrective
159
- */
160
- export const fetchPriceCorrective = ({ bridgeKeyPartner, assetOut, measurementToken, fromChainClient, toChainClient, assetLink, amountIn, isProd, }) => {
161
- return {
162
- getPaymentToken: async () => {
163
- // fetch the token bridge info for the token that is about to be spent by the delivery service
164
- return await tokenBridgeInfo({
165
- bridgeKey: bridgeKeyPartner,
166
- assetIn: {
167
- ...assetOut,
168
- address: measurementToken,
169
- },
170
- isProd,
171
- // clients are reversed here because we are actually fetching the
172
- // tokens going the opposite direction to the provided bridge key
173
- fromChainClient: toChainClient,
174
- toChainClient: fromChainClient,
175
- });
176
- },
177
- getSwapResults: async ({ paymentTokenResult, chain, uniV2Router, client, }) => {
178
- return await Promise.all([
179
- readAmountOut({
180
- amountIn,
181
- chain,
182
- uniV2Router,
183
- client,
184
- paths: [
185
- // check the direct route
186
- [assetLink.assetInAddress, paymentTokenResult.assetOutAddress],
187
- // might have heavier liquidity going through the native asset on the home side
188
- [assetLink.assetInAddress, nativeAssetOut[chain], paymentTokenResult.assetOutAddress],
189
- ],
190
- }),
191
- readAmountOut({
192
- amountIn,
193
- chain,
194
- uniV2Router,
195
- client,
196
- paths: [[assetOut.address, measurementToken]],
197
- // only the direct route is available.
198
- // might be able to create a whitelist for this at some point
199
- }),
200
- ]);
201
- },
202
- reduceResults: ({ results, oneToken, }) => {
203
- const outputFromRouter = (result) => {
204
- if (_.isString(result)) {
205
- // the router failed to return a result
206
- return 0n;
207
- }
208
- if (!result.length) {
209
- // the router returned an empty result
210
- return 0n;
211
- }
212
- // the last element is the amount of the output token
213
- const last = result[result.length - 1];
214
- return (last * oneToken) / amountIn;
215
- };
216
- const max = (amountsOut) => {
217
- return _.compact(amountsOut).reduce((max, current) => (max < current ? current : max), 0n);
218
- };
219
- // could do with a refactor to unify the results
220
- const [outputs, inputs] = results;
221
- const outputAmounts = outputs.map(outputFromRouter);
222
- const inputAmounts = inputs.map(outputFromRouter);
223
- const outputToken = max(outputAmounts);
224
- const inputToken = max(inputAmounts);
225
- const result = outputToken && outputToken > 0n
226
- ? inputToken && inputToken > outputToken && inputToken / outputToken === 1n
227
- ? inputToken
228
- : outputToken
229
- : inputToken;
230
- return result;
231
- }
232
- };
233
- };
234
- /**
235
- * Fetch the minimum bridge amount in for the given asset in, pathway, from public client, and to public client
236
- * @param assetIn - the asset in
237
- * @param pathway - the pathway
238
- * @param fromPublicClient - the from public client
239
- * @param toPublicClient - the to public client
240
- * @returns the minimum bridge amount in
241
- */
242
- export const minBridgeAmountIn = async ({ assetIn, pathway, fromPublicClient, toPublicClient, }) => {
243
- const publicClient = pathway?.feeManager === 'from' ? fromPublicClient : toPublicClient;
244
- return publicClient.readContract({
245
- abi: abis.inputBridge,
246
- functionName: 'minPerTx',
247
- args: [assetIn.address],
248
- address: pathway[pathway.feeManager],
249
- });
250
- };
251
- /** get the symbol of the native asset, unwrap it if it needs to be */
252
- export const nativeSymbol = (asset, unwrap = false) => {
253
- return asset ? (unwrap && asset.address === nativeAssetOut[toChain(asset.chainId)] ? asset.symbol.slice(1) : asset.symbol) : '';
254
- };
255
- /**
256
- * Returns the chain multicall for the given client
257
- * @param client - the client
258
- * @returns the chain multicall
259
- */
260
- export const chainMulticall = (client) => {
261
- const chainId = client.chain.id;
262
- const metadata = chainsMetadata[toChain(chainId)];
263
- return getContract({
264
- abi: multicall3Abi,
265
- client: client,
266
- address: metadata.contracts.multicall3.address,
267
- });
268
- };
269
- /**
270
- * Load the bridge fees for the given pathway, from chain client, and to chain client
271
- * @param pathway - the pathway
272
- * @param fromChainClient - the from chain client
273
- * @param toChainClient - the to chain client
274
- * @returns the bridge fees
275
- */
276
- export const loadBridgeFees = async ({ pathway, fromChainClient, toChainClient }) => {
277
- const multicall = pathway.feeManager === 'from'
278
- ? chainMulticall(fromChainClient)
279
- : chainMulticall(toChainClient);
280
- const [feeManagerResponse] = await multicall.read.aggregate3([
281
- [
282
- {
283
- allowFailure: false,
284
- target: pathway[pathway.feeManager],
285
- callData: encodeFunctionData({
286
- abi: abis.inputBridge,
287
- functionName: 'feeManager',
288
- }),
289
- },
290
- ],
291
- ]);
292
- const { success, returnData } = feeManagerResponse;
293
- if (!success) {
294
- throw new Error('unable to load feeManager');
295
- }
296
- if (returnData === '0x') {
297
- throw new Error('unable to read feeManager');
298
- }
299
- const feeManager = (returnData.startsWith('0x000000000000000000000000')
300
- ? `0x${returnData.slice(26)}`
301
- : `0x${returnData.slice(-40)}`);
302
- const [keyH2F, keyF2H] = await multicall.read.aggregate3([
303
- [
304
- {
305
- allowFailure: false,
306
- target: feeManager,
307
- callData: encodeFunctionData({
308
- abi: abis.feeManager,
309
- functionName: 'HOME_TO_FOREIGN_FEE',
310
- }),
311
- },
312
- {
313
- allowFailure: false,
314
- target: feeManager,
315
- callData: encodeFunctionData({
316
- abi: abis.feeManager,
317
- functionName: 'FOREIGN_TO_HOME_FEE',
318
- }),
319
- },
320
- ],
321
- ]);
322
- const [feeH2F, feeF2H] = await multicall.read.aggregate3([
323
- [
324
- {
325
- allowFailure: false,
326
- target: feeManager,
327
- callData: encodeFunctionData({
328
- abi: abis.feeManager,
329
- functionName: 'getFee',
330
- args: [keyH2F.returnData, zeroAddress],
331
- }),
332
- },
333
- {
334
- allowFailure: false,
335
- target: feeManager,
336
- callData: encodeFunctionData({
337
- abi: abis.feeManager,
338
- functionName: 'getFee',
339
- args: [keyF2H.returnData, zeroAddress],
340
- }),
341
- },
342
- ],
343
- ]);
344
- const setting = {
345
- feeManager,
346
- feeH2F: BigInt(feeH2F.returnData),
347
- feeF2H: BigInt(feeF2H.returnData),
348
- };
349
- return setting;
350
- };
@@ -1,6 +0,0 @@
1
- import type { ChainsMetadata } from '@gibs/bridge-sdk/types';
2
- /**
3
- * all of the chains that are enabled in this dapp
4
- * and their corresponding useful metadata
5
- */
6
- export declare const chainsMetadata: ChainsMetadata;
@@ -1,86 +0,0 @@
1
- import { mainnet, pulsechain, bsc, sepolia, pulsechainV4 } from '@reown/appkit/networks';
2
- import { Chains } from '@gibs/bridge-sdk/config';
3
- import * as imageLinks from '@gibs/bridge-sdk/image-links';
4
- /**
5
- * all of the chains that are enabled in this dapp
6
- * and their corresponding useful metadata
7
- */
8
- export const chainsMetadata = {
9
- [Chains.PLS]: {
10
- ...pulsechain,
11
- chainId: Chains.PLS,
12
- logoURI: imageLinks.network(pulsechain.id),
13
- alt: 'a pink blue and purple hexagon with an ekg line running horizontally',
14
- rpcUrls: {
15
- default: {
16
- http: ['https://rpc.pulsechain.com'],
17
- },
18
- },
19
- contracts: {
20
- ...pulsechain.contracts,
21
- ensRegistry: {
22
- address: '0xbd5133993FCDED5945c5539D9f032261F0d13170',
23
- },
24
- ensUniversalResolver: {
25
- address: '0x2FDBb906b4FE68e31D928C1ED0b6a3bD1f204374',
26
- blockCreated: 19_400_610,
27
- },
28
- },
29
- },
30
- [Chains.ETH]: {
31
- ...mainnet,
32
- chainId: Chains.ETH,
33
- logoURI: imageLinks.network(mainnet.id),
34
- alt: 'two pyramids joined on one side',
35
- rpcUrls: {
36
- default: {
37
- http: ['https://rpc-ethereum.g4mm4.io'],
38
- },
39
- },
40
- },
41
- [Chains.BNB]: {
42
- ...bsc,
43
- name: 'Binance Smart Chain',
44
- chainId: Chains.BNB,
45
- logoURI: imageLinks.network(bsc.id),
46
- alt: 'a gold cube with slits in the middle of each side',
47
- rpcUrls: {
48
- default: {
49
- http: ['https://bsc-rpc.publicnode.com'],
50
- },
51
- },
52
- },
53
- [Chains.SEP]: {
54
- ...sepolia,
55
- name: 'Sepolia',
56
- chainId: Chains.SEP,
57
- logoURI: imageLinks.network(sepolia.id),
58
- alt: 'two pyramids joined on one side',
59
- rpcUrls: {
60
- default: {
61
- http: ['https://ethereum-sepolia-rpc.publicnode.com'],
62
- },
63
- },
64
- },
65
- [Chains.V4PLS]: {
66
- ...pulsechainV4,
67
- name: 'Pulsechain V4',
68
- chainId: Chains.V4PLS,
69
- logoURI: imageLinks.network(pulsechainV4.id),
70
- alt: 'a pink blue and purple hexagon with an ekg line running horizontally',
71
- rpcUrls: {
72
- default: {
73
- http: ['https://rpc-testnet-pulsechain.g4mm4.io'],
74
- },
75
- },
76
- contracts: {
77
- ...pulsechainV4.contracts,
78
- ensRegistry: {
79
- address: '0xaDB38309aF7F85034FDC35bd6E6B45d1216CfB56',
80
- },
81
- ensUniversalResolver: {
82
- address: '0xDDFde3fA938dE0cdff82645579d03Ed750DE2e69',
83
- },
84
- },
85
- },
86
- };
@@ -1,136 +0,0 @@
1
- import { type Hex } from "viem";
2
- import type { BridgeKey, Token, TokenOut } from "./types.js";
3
- /**
4
- * Add here your chain id as hex, be sure to add your chain in the chainsMetadata object too
5
- */
6
- export declare enum Chains {
7
- PLS = "0x171",
8
- ETH = "0x1",
9
- BNB = "0x38",
10
- SEP = "0xaa36a7",
11
- V4PLS = "0x3af"
12
- }
13
- /** The key of a chain - human readable for query params */
14
- export type ChainKey = keyof typeof Chains;
15
- /** A map of chain ids to chain keys */
16
- export declare const chainIdToKey: Map<Chains, "ETH" | "PLS" | "BNB" | "SEP" | "V4PLS">;
17
- /**
18
- * Converts a chain id to a chain key
19
- * @param chainId - the chain id
20
- * @returns the chain key
21
- */
22
- export declare const toChain: (chainId: number | string) => Chains;
23
- /**
24
- * Converts a chain id to a chain key
25
- * @param chainId - the chain id
26
- * @returns the chain key
27
- */
28
- export declare const toChainKey: (chainId: number | string) => "ETH" | "PLS" | "BNB" | "SEP" | "V4PLS" | undefined;
29
- export declare const Providers: {
30
- readonly PULSECHAIN: "pulsechain";
31
- readonly TOKENSEX: "tokensex";
32
- };
33
- export type Provider = typeof Providers[keyof typeof Providers];
34
- /** A map of chains to native asset out addresses */
35
- export declare const nativeAssetOut: Record<Chains, Hex>;
36
- /** A map of chains to deprecated native asset out addresses */
37
- export declare const deprecatedNativeAssetOut: Partial<Record<Chains, Set<Hex>>>;
38
- /** A map of chains to uni v2 router addresses */
39
- export declare const uniV2Routers: Record<Chains, Hex[]>;
40
- /** A map of chains to native token symbols */
41
- export declare const nativeTokenSymbol: Record<Chains, string>;
42
- /** A map of chains to native token names */
43
- export declare const nativeTokenName: Record<Chains, string>;
44
- /** The pathway of a bridge */
45
- export type Pathway = {
46
- from: Hex;
47
- to: Hex;
48
- destinationRouter: Hex | null;
49
- nativeRouter: Hex;
50
- validator: Hex;
51
- usesExtraParam: boolean;
52
- feeManager: 'from' | 'to';
53
- toHome: boolean;
54
- requiresDelivery: boolean;
55
- bridgedNativeAssetOut: Hex;
56
- settingOverrides?: Record<Hex, Partial<Pathway>>;
57
- };
58
- /** A map of providers to pathways */
59
- export type DeepPathwayConfig = Record<Provider, Partial<Record<Chains, Partial<Record<Chains, Pathway>>>>>;
60
- export declare const pathways: DeepPathwayConfig;
61
- export declare const testnetPathways: DeepPathwayConfig;
62
- /** Returns the valid bridge keys for the given is prod */
63
- export declare const validBridgeKeys: (isProd: boolean) => BridgeKey[];
64
- /**
65
- * Infers the bridge key from the current key, provider, from chain, and to chain
66
- * @param currentKey - the current bridge key
67
- * @param provider - the provider
68
- * @param fromChain - the from chain
69
- * @param toChain - the to chain
70
- * @returns the inferred bridge key
71
- */
72
- export declare const inferBridgeKey: ({ currentKey, provider, fromChain, toChain, }: {
73
- currentKey: BridgeKey;
74
- provider: Provider;
75
- fromChain?: Chains;
76
- toChain?: Chains;
77
- }) => BridgeKey;
78
- /**
79
- * Returns the pathway for the given bridge key, is prod, and asset in address
80
- * @param bridgeKey - the bridge key
81
- * @param isProd - whether to use the production pathway
82
- * @param assetInAddress - the asset in address
83
- * @returns the pathway
84
- */
85
- export declare const pathway: (bridgeKey: BridgeKey | null, isProd: boolean, assetInAddress?: string | Hex | null | undefined) => Pathway | undefined;
86
- /**
87
- * Returns the default asset in for the given bridge key and is prod
88
- * @param bridgeKey - the bridge key
89
- * @param isProd - whether to use the production pathway
90
- * @returns the default asset in
91
- */
92
- export declare const defaultAssetIn: ($bridgeKey: BridgeKey | null, isProd: boolean) => `0x${string}` | null | undefined;
93
- /**
94
- * Returns whether the given asset is the native asset for the given bridge key
95
- * @param asset - the asset
96
- * @param bridgeKey - the bridge key
97
- * @returns whether the given asset is the native asset for the given bridge key
98
- */
99
- export declare const isNative: (asset: Token | TokenOut | null, bridgeKey: BridgeKey | null) => boolean;
100
- /**
101
- * Returns whether the given asset is unwrappable for the given bridge key
102
- * @param bridgeKey - the bridge key
103
- * @param assetIn - the asset in
104
- * @returns whether the given asset is unwrappable for the given bridge key
105
- */
106
- export declare const isUnwrappable: (bridgeKey: BridgeKey | null, assetIn: Pick<Token, "address"> | null) => boolean;
107
- /**
108
- * Returns whether the given asset can be unwrapped for the given bridge key
109
- * @param bridgeKey - the bridge key
110
- * @param assetIn - the asset in
111
- * @returns boolean
112
- */
113
- export declare const canChangeUnwrap: (bridgeKey: BridgeKey, assetIn: Token | null) => boolean;
114
- export declare const chains: {
115
- readonly ethereum: 1;
116
- readonly bsc: 56;
117
- readonly pulsechain: 369;
118
- readonly pulsechainV4: 943;
119
- readonly sepolia: 11155111;
120
- };
121
- export declare const chainIds: (1 | 56 | 369 | 943 | 11155111)[];
122
- export type ChainId = (typeof chainIds)[number];
123
- export type Side = 'home' | 'foreign';
124
- export type MinimalKey = `${ChainId}-${Hex}`;
125
- export type PathwayInfo = {
126
- pair: string;
127
- key: string;
128
- home: Hex;
129
- foreign: Hex;
130
- };
131
- export type ProviderHomeChainEntry = Partial<Record<ChainId, PathwayInfo[]>>;
132
- export type ProviderEntries = Partial<Record<ChainId, ProviderHomeChainEntry>>;
133
- export type BridgeConfig = Record<Provider, ProviderEntries>;
134
- export declare const bridgeConfigs: BridgeConfig;
135
- export declare const HOME_TO_FOREIGN_FEE: `0x${string}`;
136
- export declare const FOREIGN_TO_HOME_FEE: `0x${string}`;