@gibs/bridge-sdk 1.10.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.
- package/package.json +12 -5
- package/src/abis.ts +3 -70
- package/src/chain-info.test.ts +968 -0
- package/src/chain-info.ts +161 -127
- package/src/chains.test.ts +123 -0
- package/src/chains.ts +5 -5
- package/src/config.test.ts +679 -0
- package/src/config.ts +138 -118
- package/src/fee-type.test.ts +45 -0
- package/src/fee-type.ts +2 -2
- package/src/image-links.test.ts +160 -0
- package/src/image-links.ts +20 -16
- package/src/index.ts +8 -8
- package/src/settings.test.ts +2754 -0
- package/src/settings.ts +325 -348
- package/src/types.ts +25 -25
- package/tsconfig.json +2 -1
- package/vitest.config.ts +13 -0
- package/dist/src/abis.d.ts +0 -384
- package/dist/src/abis.js +0 -68
- package/dist/src/chain-info.d.ts +0 -130
- package/dist/src/chain-info.js +0 -350
- package/dist/src/chains.d.ts +0 -6
- package/dist/src/chains.js +0 -86
- package/dist/src/config.d.ts +0 -136
- package/dist/src/config.js +0 -386
- package/dist/src/fee-type.d.ts +0 -10
- package/dist/src/fee-type.js +0 -9
- package/dist/src/image-links.d.ts +0 -41
- package/dist/src/image-links.js +0 -45
- package/dist/src/index.d.ts +0 -8
- package/dist/src/index.js +0 -8
- package/dist/src/settings.d.ts +0 -357
- package/dist/src/settings.js +0 -642
- package/dist/src/types.d.ts +0 -44
- package/dist/src/types.js +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
package/src/config.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import type { BridgeKey, Token, TokenOut } from
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import { getAddress, type Hex, keccak256, stringToHex, zeroAddress } from 'viem';
|
|
3
|
+
import type { BridgeKey, Token, TokenOut } from './types.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Add here your chain id as hex, be sure to add your chain in the chainsMetadata object too
|
|
@@ -16,26 +16,26 @@ export enum Chains {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/** The key of a chain - human readable for query params */
|
|
19
|
-
export type ChainKey = keyof typeof Chains
|
|
19
|
+
export type ChainKey = keyof typeof Chains;
|
|
20
20
|
|
|
21
21
|
/** A map of chain ids to chain keys */
|
|
22
22
|
export const chainIdToKey = new Map<Chains, ChainKey>(
|
|
23
23
|
Object.entries(Chains).map(([key, chain]) => [chain, key] as [Chains, ChainKey]),
|
|
24
|
-
)
|
|
24
|
+
);
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Converts a chain id to a chain key
|
|
28
28
|
* @param chainId - the chain id
|
|
29
29
|
* @returns the chain key
|
|
30
30
|
*/
|
|
31
|
-
export const toChain = (chainId: number | string) => `0x${Number(chainId).toString(16)}` as Chains
|
|
31
|
+
export const toChain = (chainId: number | string) => `0x${Number(chainId).toString(16)}` as Chains;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Converts a chain id to a chain key
|
|
35
35
|
* @param chainId - the chain id
|
|
36
36
|
* @returns the chain key
|
|
37
37
|
*/
|
|
38
|
-
export const toChainKey = (chainId: number | string) => chainIdToKey.get(toChain(chainId))
|
|
38
|
+
export const toChainKey = (chainId: number | string) => chainIdToKey.get(toChain(chainId));
|
|
39
39
|
|
|
40
40
|
// /** The provider of an omnibridge */
|
|
41
41
|
// export enum Provider {
|
|
@@ -43,13 +43,12 @@ export const toChainKey = (chainId: number | string) => chainIdToKey.get(toChain
|
|
|
43
43
|
// TOKENSEX = 'tokensex',
|
|
44
44
|
// }
|
|
45
45
|
|
|
46
|
-
|
|
47
46
|
export const Providers = {
|
|
48
47
|
PULSECHAIN: 'pulsechain',
|
|
49
48
|
TOKENSEX: 'tokensex',
|
|
50
|
-
} as const
|
|
49
|
+
} as const;
|
|
51
50
|
|
|
52
|
-
export type Provider = typeof Providers[keyof typeof Providers]
|
|
51
|
+
export type Provider = (typeof Providers)[keyof typeof Providers];
|
|
53
52
|
|
|
54
53
|
/** A map of chains to native asset out addresses */
|
|
55
54
|
export const nativeAssetOut = {
|
|
@@ -58,12 +57,12 @@ export const nativeAssetOut = {
|
|
|
58
57
|
[Chains.PLS]: '0xA1077a294dDE1B09bB078844df40758a5D0f9a27',
|
|
59
58
|
[Chains.SEP]: '0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9',
|
|
60
59
|
[Chains.V4PLS]: '0x70499adEBB11Efd915E3b69E700c331778628707',
|
|
61
|
-
} as Record<Chains, Hex
|
|
60
|
+
} as Record<Chains, Hex>;
|
|
62
61
|
|
|
63
62
|
/** A map of chains to deprecated native asset out addresses */
|
|
64
63
|
export const deprecatedNativeAssetOut = {
|
|
65
64
|
[Chains.PLS]: new Set(['0x97Ac4a2439A47c07ad535bb1188c989dae755341']),
|
|
66
|
-
} as Partial<Record<Chains, Set<Hex
|
|
65
|
+
} as Partial<Record<Chains, Set<Hex>>>;
|
|
67
66
|
|
|
68
67
|
/** A map of chains to uni v2 router addresses */
|
|
69
68
|
export const uniV2Routers = {
|
|
@@ -78,7 +77,7 @@ export const uniV2Routers = {
|
|
|
78
77
|
'0xDaE9dd3d1A52CfCe9d5F2fAC7fDe164D500E50f7',
|
|
79
78
|
'0x636f6407B90661b73b1C0F7e24F4C79f624d0738',
|
|
80
79
|
],
|
|
81
|
-
} as Record<Chains, Hex[]
|
|
80
|
+
} as Record<Chains, Hex[]>;
|
|
82
81
|
|
|
83
82
|
/** A map of chains to native token symbols */
|
|
84
83
|
export const nativeTokenSymbol = {
|
|
@@ -87,7 +86,7 @@ export const nativeTokenSymbol = {
|
|
|
87
86
|
[Chains.ETH]: 'ETH',
|
|
88
87
|
[Chains.SEP]: 'sepETH',
|
|
89
88
|
[Chains.BNB]: 'BNB',
|
|
90
|
-
} as Record<Chains, string
|
|
89
|
+
} as Record<Chains, string>;
|
|
91
90
|
|
|
92
91
|
/** A map of chains to native token names */
|
|
93
92
|
export const nativeTokenName = {
|
|
@@ -96,29 +95,29 @@ export const nativeTokenName = {
|
|
|
96
95
|
[Chains.ETH]: 'Ether',
|
|
97
96
|
[Chains.SEP]: 'Sepolia Ether',
|
|
98
97
|
[Chains.BNB]: 'BNB',
|
|
99
|
-
} as Record<Chains, string
|
|
98
|
+
} as Record<Chains, string>;
|
|
100
99
|
|
|
101
100
|
/** The pathway of a bridge */
|
|
102
101
|
export type Pathway = {
|
|
103
|
-
from: Hex
|
|
104
|
-
to: Hex
|
|
105
|
-
destinationRouter: Hex | null
|
|
106
|
-
nativeRouter: Hex
|
|
107
|
-
validator: Hex
|
|
102
|
+
from: Hex;
|
|
103
|
+
to: Hex;
|
|
104
|
+
destinationRouter: Hex | null;
|
|
105
|
+
nativeRouter: Hex;
|
|
106
|
+
validator: Hex;
|
|
108
107
|
// defaultAssetIn: Token
|
|
109
|
-
usesExtraParam: boolean
|
|
110
|
-
feeManager: 'from' | 'to'
|
|
111
|
-
toHome: boolean
|
|
112
|
-
requiresDelivery: boolean
|
|
113
|
-
bridgedNativeAssetOut: Hex
|
|
114
|
-
settingOverrides?: Record<Hex, Partial<Pathway
|
|
115
|
-
}
|
|
108
|
+
usesExtraParam: boolean;
|
|
109
|
+
feeManager: 'from' | 'to';
|
|
110
|
+
toHome: boolean;
|
|
111
|
+
requiresDelivery: boolean;
|
|
112
|
+
bridgedNativeAssetOut: Hex;
|
|
113
|
+
settingOverrides?: Record<Hex, Partial<Pathway>>;
|
|
114
|
+
};
|
|
116
115
|
|
|
117
116
|
/** A map of providers to pathways */
|
|
118
117
|
export type DeepPathwayConfig = Record<
|
|
119
118
|
Provider,
|
|
120
119
|
Partial<Record<Chains, Partial<Record<Chains, Pathway>>>>
|
|
121
|
-
|
|
120
|
+
>;
|
|
122
121
|
|
|
123
122
|
/** The settings for the pulsechain pls eth pathway */
|
|
124
123
|
const pulsechainPLSETHSettings = {
|
|
@@ -126,7 +125,7 @@ const pulsechainPLSETHSettings = {
|
|
|
126
125
|
to: '0xe20E337DB2a00b1C37139c873B92a0AAd3F468bF',
|
|
127
126
|
destinationRouter: '0x1F0144Ce3BDaf11944Fe0beF6444599a0500695B',
|
|
128
127
|
nativeRouter: '0xE66877Cfe4CEc10ffBbBB3092B7001321AB5809D',
|
|
129
|
-
}
|
|
128
|
+
};
|
|
130
129
|
|
|
131
130
|
export const pathways = {
|
|
132
131
|
[Providers.PULSECHAIN]: {
|
|
@@ -205,7 +204,7 @@ export const pathways = {
|
|
|
205
204
|
},
|
|
206
205
|
},
|
|
207
206
|
},
|
|
208
|
-
} as DeepPathwayConfig
|
|
207
|
+
} as DeepPathwayConfig;
|
|
209
208
|
|
|
210
209
|
export const testnetPathways = {
|
|
211
210
|
[Providers.TOKENSEX]: {
|
|
@@ -261,7 +260,7 @@ export const testnetPathways = {
|
|
|
261
260
|
},
|
|
262
261
|
},
|
|
263
262
|
},
|
|
264
|
-
} as DeepPathwayConfig
|
|
263
|
+
} as DeepPathwayConfig;
|
|
265
264
|
|
|
266
265
|
/** The mainnet bridge keys */
|
|
267
266
|
const mainnetBridgeKeys = [
|
|
@@ -269,19 +268,19 @@ const mainnetBridgeKeys = [
|
|
|
269
268
|
[Providers.PULSECHAIN, Chains.ETH, Chains.PLS],
|
|
270
269
|
[Providers.TOKENSEX, Chains.PLS, Chains.BNB],
|
|
271
270
|
[Providers.TOKENSEX, Chains.BNB, Chains.PLS],
|
|
272
|
-
] as BridgeKey[]
|
|
271
|
+
] as BridgeKey[];
|
|
273
272
|
|
|
274
273
|
/** The testnet bridge keys */
|
|
275
274
|
const testnetBridgeKeys = [
|
|
276
275
|
[Providers.PULSECHAIN, Chains.SEP, Chains.V4PLS],
|
|
277
276
|
[Providers.PULSECHAIN, Chains.V4PLS, Chains.SEP],
|
|
278
|
-
] as BridgeKey[]
|
|
277
|
+
] as BridgeKey[];
|
|
279
278
|
|
|
280
279
|
/** Returns the valid bridge keys for the given is prod */
|
|
281
280
|
export const validBridgeKeys = (isProd: boolean) => [
|
|
282
281
|
...mainnetBridgeKeys,
|
|
283
282
|
...(isProd ? [] : testnetBridgeKeys),
|
|
284
|
-
]
|
|
283
|
+
];
|
|
285
284
|
|
|
286
285
|
/**
|
|
287
286
|
* Infers the bridge key from the current key, provider, from chain, and to chain
|
|
@@ -297,24 +296,24 @@ export const inferBridgeKey = ({
|
|
|
297
296
|
fromChain,
|
|
298
297
|
toChain,
|
|
299
298
|
}: {
|
|
300
|
-
currentKey: BridgeKey
|
|
301
|
-
provider: Provider
|
|
302
|
-
fromChain?: Chains
|
|
303
|
-
toChain?: Chains
|
|
299
|
+
currentKey: BridgeKey;
|
|
300
|
+
provider: Provider;
|
|
301
|
+
fromChain?: Chains;
|
|
302
|
+
toChain?: Chains;
|
|
304
303
|
}) => {
|
|
305
|
-
const [, fromChainKey, toChainKey] = currentKey
|
|
306
|
-
const from = fromChain ?? fromChainKey
|
|
307
|
-
const to = toChain ?? toChainKey
|
|
308
|
-
const currentFromChainIsValid = !!_.get(pathways, [provider, from])
|
|
304
|
+
const [, fromChainKey, toChainKey] = currentKey;
|
|
305
|
+
const from = fromChain ?? fromChainKey;
|
|
306
|
+
const to = toChain ?? toChainKey;
|
|
307
|
+
const currentFromChainIsValid = !!_.get(pathways, [provider, from]);
|
|
309
308
|
const nextFromChain = currentFromChainIsValid
|
|
310
309
|
? from
|
|
311
|
-
: (Object.keys(pathways[provider])[0] as Chains)
|
|
312
|
-
const currentToChainIsValid = !!_.get(pathways, [provider, nextFromChain, to])
|
|
310
|
+
: (Object.keys(pathways[provider])[0] as Chains);
|
|
311
|
+
const currentToChainIsValid = !!_.get(pathways, [provider, nextFromChain, to]);
|
|
313
312
|
const nextToChain = currentToChainIsValid
|
|
314
313
|
? to
|
|
315
|
-
: (Object.keys(pathways[provider]![nextFromChain]!)[0] as Chains)
|
|
316
|
-
return [provider, nextFromChain, nextToChain] as BridgeKey
|
|
317
|
-
}
|
|
314
|
+
: (Object.keys(pathways[provider]![nextFromChain]!)[0] as Chains);
|
|
315
|
+
return [provider, nextFromChain, nextToChain] as BridgeKey;
|
|
316
|
+
};
|
|
318
317
|
|
|
319
318
|
/**
|
|
320
319
|
* Returns the pathway for the given bridge key, is prod, and asset in address
|
|
@@ -323,20 +322,25 @@ export const inferBridgeKey = ({
|
|
|
323
322
|
* @param assetInAddress - the asset in address
|
|
324
323
|
* @returns the pathway
|
|
325
324
|
*/
|
|
326
|
-
export const pathway = (
|
|
327
|
-
|
|
328
|
-
|
|
325
|
+
export const pathway = (
|
|
326
|
+
bridgeKey: BridgeKey | null,
|
|
327
|
+
isProd: boolean,
|
|
328
|
+
assetInAddress?: string | Hex | null | undefined,
|
|
329
|
+
) => {
|
|
330
|
+
if (!bridgeKey) return;
|
|
331
|
+
let pathway =
|
|
332
|
+
_.get(pathways, bridgeKey) || (!isProd ? _.get(testnetPathways, bridgeKey) : undefined);
|
|
329
333
|
if (assetInAddress) {
|
|
330
|
-
const addr = getAddress(assetInAddress)
|
|
334
|
+
const addr = getAddress(assetInAddress);
|
|
331
335
|
if (pathway?.settingOverrides?.[addr]) {
|
|
332
336
|
pathway = {
|
|
333
337
|
...pathway,
|
|
334
338
|
...pathway.settingOverrides[addr],
|
|
335
|
-
}
|
|
339
|
+
};
|
|
336
340
|
}
|
|
337
341
|
}
|
|
338
|
-
return pathway
|
|
339
|
-
}
|
|
342
|
+
return pathway;
|
|
343
|
+
};
|
|
340
344
|
|
|
341
345
|
/**
|
|
342
346
|
* Returns the default asset in for the given bridge key and is prod
|
|
@@ -345,11 +349,11 @@ export const pathway = (bridgeKey: BridgeKey | null, isProd: boolean, assetInAdd
|
|
|
345
349
|
* @returns the default asset in
|
|
346
350
|
*/
|
|
347
351
|
export const defaultAssetIn = ($bridgeKey: BridgeKey | null, isProd: boolean) => {
|
|
348
|
-
if (!$bridgeKey) return null
|
|
349
|
-
const conf = pathway($bridgeKey, isProd)
|
|
350
|
-
const defaultAssetIn = _.get(conf, ['bridgedNativeAssetOut']) as Hex | undefined
|
|
351
|
-
return defaultAssetIn
|
|
352
|
-
}
|
|
352
|
+
if (!$bridgeKey) return null;
|
|
353
|
+
const conf = pathway($bridgeKey, isProd);
|
|
354
|
+
const defaultAssetIn = _.get(conf, ['bridgedNativeAssetOut']) as Hex | undefined;
|
|
355
|
+
return defaultAssetIn;
|
|
356
|
+
};
|
|
353
357
|
|
|
354
358
|
/**
|
|
355
359
|
* Returns whether the given asset is the native asset for the given bridge key
|
|
@@ -359,16 +363,16 @@ export const defaultAssetIn = ($bridgeKey: BridgeKey | null, isProd: boolean) =>
|
|
|
359
363
|
*/
|
|
360
364
|
export const isNative = (asset: Token | TokenOut | null, bridgeKey: BridgeKey | null) => {
|
|
361
365
|
if (!bridgeKey || !asset) {
|
|
362
|
-
return false
|
|
366
|
+
return false;
|
|
363
367
|
}
|
|
364
|
-
const path = pathway(bridgeKey, false)
|
|
368
|
+
const path = pathway(bridgeKey, false);
|
|
365
369
|
return (
|
|
366
370
|
getAddress(asset.address!) === getAddress(path!.bridgedNativeAssetOut!) ||
|
|
367
|
-
(asset.address === zeroAddress ||
|
|
371
|
+
((asset.address === zeroAddress ||
|
|
368
372
|
nativeAssetOut[toChain(asset.chainId)]?.toLowerCase() === asset.address?.toLowerCase()) &&
|
|
369
|
-
|
|
370
|
-
)
|
|
371
|
-
}
|
|
373
|
+
!asset.name.includes(' from Pulsechain'))
|
|
374
|
+
);
|
|
375
|
+
};
|
|
372
376
|
|
|
373
377
|
/**
|
|
374
378
|
* Returns whether the given asset is unwrappable for the given bridge key
|
|
@@ -381,13 +385,13 @@ export const isUnwrappable = (
|
|
|
381
385
|
assetIn: Pick<Token, 'address'> | null,
|
|
382
386
|
) => {
|
|
383
387
|
if (!bridgeKey || !assetIn) {
|
|
384
|
-
return false
|
|
388
|
+
return false;
|
|
385
389
|
}
|
|
386
|
-
const addr = getAddress(assetIn.address)
|
|
387
|
-
const path = pathway(bridgeKey, false)
|
|
388
|
-
if (!path) return false
|
|
389
|
-
return path.bridgedNativeAssetOut === getAddress(addr)
|
|
390
|
-
}
|
|
390
|
+
const addr = getAddress(assetIn.address);
|
|
391
|
+
const path = pathway(bridgeKey, false);
|
|
392
|
+
if (!path) return false;
|
|
393
|
+
return path.bridgedNativeAssetOut === getAddress(addr);
|
|
394
|
+
};
|
|
391
395
|
|
|
392
396
|
/**
|
|
393
397
|
* Returns whether the given asset can be unwrapped for the given bridge key
|
|
@@ -396,8 +400,8 @@ export const isUnwrappable = (
|
|
|
396
400
|
* @returns boolean
|
|
397
401
|
*/
|
|
398
402
|
export const canChangeUnwrap = (bridgeKey: BridgeKey, assetIn: Token | null) => {
|
|
399
|
-
return !!assetIn && isUnwrappable(bridgeKey, assetIn)
|
|
400
|
-
}
|
|
403
|
+
return !!assetIn && isUnwrappable(bridgeKey, assetIn);
|
|
404
|
+
};
|
|
401
405
|
|
|
402
406
|
export const chains = {
|
|
403
407
|
ethereum: 1,
|
|
@@ -405,15 +409,24 @@ export const chains = {
|
|
|
405
409
|
pulsechain: 369,
|
|
406
410
|
pulsechainV4: 943,
|
|
407
411
|
sepolia: 11155111,
|
|
408
|
-
} as const
|
|
412
|
+
} as const;
|
|
413
|
+
|
|
414
|
+
export const chainIds = Object.values(chains);
|
|
409
415
|
|
|
410
|
-
|
|
416
|
+
/** Start blocks aligned with when bridge validators began operating — canonical reference for all ponder indexers in this monorepo. */
|
|
417
|
+
export const startBlocks: Record<keyof typeof chains, number> = {
|
|
418
|
+
ethereum: 17_264_119,
|
|
419
|
+
bsc: 28_987_313,
|
|
420
|
+
pulsechain: 17_268_300,
|
|
421
|
+
pulsechainV4: 16_564_233,
|
|
422
|
+
sepolia: 3_331_901,
|
|
423
|
+
};
|
|
411
424
|
|
|
412
|
-
export type ChainId = (typeof chainIds)[number]
|
|
425
|
+
export type ChainId = (typeof chainIds)[number];
|
|
413
426
|
|
|
414
|
-
export type Side = 'home' | 'foreign'
|
|
427
|
+
export type Side = 'home' | 'foreign';
|
|
415
428
|
|
|
416
|
-
export type MinimalKey = `${ChainId}-${Hex}
|
|
429
|
+
export type MinimalKey = `${ChainId}-${Hex}`;
|
|
417
430
|
|
|
418
431
|
// export const Providers = {
|
|
419
432
|
// PULSECHAIN: 'pulsechain',
|
|
@@ -421,60 +434,67 @@ export type MinimalKey = `${ChainId}-${Hex}`
|
|
|
421
434
|
// } as const
|
|
422
435
|
|
|
423
436
|
export type PathwayInfo = {
|
|
424
|
-
pair: string
|
|
425
|
-
key: string
|
|
426
|
-
home: Hex
|
|
427
|
-
foreign: Hex
|
|
428
|
-
}
|
|
437
|
+
pair: string;
|
|
438
|
+
key: string;
|
|
439
|
+
home: Hex;
|
|
440
|
+
foreign: Hex;
|
|
441
|
+
};
|
|
429
442
|
|
|
430
|
-
export type ProviderHomeChainEntry = Partial<Record<ChainId, PathwayInfo[]
|
|
443
|
+
export type ProviderHomeChainEntry = Partial<Record<ChainId, PathwayInfo[]>>;
|
|
431
444
|
|
|
432
|
-
export type ProviderEntries = Partial<Record<ChainId, ProviderHomeChainEntry
|
|
445
|
+
export type ProviderEntries = Partial<Record<ChainId, ProviderHomeChainEntry>>;
|
|
433
446
|
|
|
434
|
-
export type BridgeConfig = Record<Provider, ProviderEntries
|
|
447
|
+
export type BridgeConfig = Record<Provider, ProviderEntries>;
|
|
435
448
|
|
|
436
449
|
// provider -> home -> foreign
|
|
437
450
|
export const bridgeConfigs = {
|
|
438
451
|
[Providers.PULSECHAIN]: {
|
|
439
452
|
[chains.pulsechain]: {
|
|
440
|
-
[chains.ethereum]: [
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
453
|
+
[chains.ethereum]: [
|
|
454
|
+
{
|
|
455
|
+
pair: 'mainnet',
|
|
456
|
+
key: 'erc20',
|
|
457
|
+
home: '0x4fD0aaa7506f3d9cB8274bdB946Ec42A1b8751Ef',
|
|
458
|
+
foreign: '0x1715a3e4a142d8b698131108995174f37aeba10d',
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
pair: 'mainnet',
|
|
462
|
+
key: 'native',
|
|
463
|
+
home: '0x0e18d0d556b652794EF12Bf68B2dC857EF5f3996',
|
|
464
|
+
foreign: '0xe20E337DB2a00b1C37139c873B92a0AAd3F468bF',
|
|
465
|
+
},
|
|
466
|
+
],
|
|
451
467
|
},
|
|
452
468
|
[chains.pulsechainV4]: {
|
|
453
|
-
[chains.sepolia]: [
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
469
|
+
[chains.sepolia]: [
|
|
470
|
+
{
|
|
471
|
+
pair: 'v4',
|
|
472
|
+
key: 'erc20',
|
|
473
|
+
home: '0x6B08a50865aDeCe6e3869D9AfbB316d0a0436B6c',
|
|
474
|
+
foreign: '0x546e37DAA15cdb82fd1a717E5dEEa4AF08D4349A',
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
pair: 'v4',
|
|
478
|
+
key: 'native',
|
|
479
|
+
home: '0x81c10846F40fA2B173FC47958D0a892529983F50',
|
|
480
|
+
foreign: '0x5e238ef968467cf443ef5ecb683b76c5a04a0421',
|
|
481
|
+
},
|
|
482
|
+
],
|
|
464
483
|
},
|
|
465
484
|
},
|
|
466
485
|
[Providers.TOKENSEX]: {
|
|
467
486
|
[chains.pulsechain]: {
|
|
468
|
-
[chains.bsc]: [
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
487
|
+
[chains.bsc]: [
|
|
488
|
+
{
|
|
489
|
+
pair: 'bsctokensex',
|
|
490
|
+
key: 'erc20',
|
|
491
|
+
home: '0xf1DFc63e10fF01b8c3d307529b47AefaD2154C0e',
|
|
492
|
+
foreign: '0xb4005881e81a6ecd2c1f75d58e8e41f28d59c6b1',
|
|
493
|
+
},
|
|
494
|
+
],
|
|
474
495
|
},
|
|
475
496
|
},
|
|
476
|
-
} as BridgeConfig
|
|
477
|
-
|
|
497
|
+
} as BridgeConfig;
|
|
478
498
|
|
|
479
|
-
export const HOME_TO_FOREIGN_FEE = keccak256(stringToHex(
|
|
480
|
-
export const FOREIGN_TO_HOME_FEE = keccak256(stringToHex(
|
|
499
|
+
export const HOME_TO_FOREIGN_FEE = keccak256(stringToHex('homeToForeignFee'));
|
|
500
|
+
export const FOREIGN_TO_HOME_FEE = keccak256(stringToHex('foreignToHomeFee'));
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { FeeType, feeTypeValToKeyMap } from './fee-type';
|
|
3
|
+
|
|
4
|
+
describe('fee-type', () => {
|
|
5
|
+
describe('FeeType enum', () => {
|
|
6
|
+
it('should have PERCENT fee type', () => {
|
|
7
|
+
expect(FeeType.PERCENT).toBe('%');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('should have GAS_TIP fee type', () => {
|
|
11
|
+
expect(FeeType.GAS_TIP).toBe('gas+%');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should have FIXED fee type', () => {
|
|
15
|
+
expect(FeeType.FIXED).toBe('fixed');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should have exactly 3 fee types', () => {
|
|
19
|
+
const keys = Object.keys(FeeType);
|
|
20
|
+
expect(keys).toHaveLength(3);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('feeTypeValToKeyMap', () => {
|
|
25
|
+
it('should map PERCENT value to key', () => {
|
|
26
|
+
expect(feeTypeValToKeyMap.get(FeeType.PERCENT)).toBe('PERCENT');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should map GAS_TIP value to key', () => {
|
|
30
|
+
expect(feeTypeValToKeyMap.get(FeeType.GAS_TIP)).toBe('GAS_TIP');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should map FIXED value to key', () => {
|
|
34
|
+
expect(feeTypeValToKeyMap.get(FeeType.FIXED)).toBe('FIXED');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should map all fee type values to keys', () => {
|
|
38
|
+
expect(feeTypeValToKeyMap.size).toBe(3);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should return undefined for invalid fee type', () => {
|
|
42
|
+
expect(feeTypeValToKeyMap.get('invalid' as FeeType)).toBeUndefined();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
});
|
package/src/fee-type.ts
CHANGED
|
@@ -6,9 +6,9 @@ export enum FeeType {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
/** The keys of the fee type */
|
|
9
|
-
export type FeeTypeKeys = keyof typeof FeeType
|
|
9
|
+
export type FeeTypeKeys = keyof typeof FeeType;
|
|
10
10
|
|
|
11
11
|
/** A map of fee type values to keys */
|
|
12
12
|
export const feeTypeValToKeyMap = new Map<FeeType, FeeTypeKeys>(
|
|
13
13
|
(Object.keys(FeeType) as FeeTypeKeys[]).map((key) => [FeeType[key], key]),
|
|
14
|
-
)
|
|
14
|
+
);
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
+
import { getImageRoot, image, images, list, network, setImageRoot } from './image-links';
|
|
3
|
+
|
|
4
|
+
describe('image-links', () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
// Reset to default before each test
|
|
7
|
+
setImageRoot('https://gib.show');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe('setImageRoot and getImageRoot', () => {
|
|
11
|
+
it('should have default image root', () => {
|
|
12
|
+
expect(getImageRoot()).toBe('https://gib.show');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should update image root', () => {
|
|
16
|
+
setImageRoot('https://custom.domain');
|
|
17
|
+
expect(getImageRoot()).toBe('https://custom.domain');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should affect all subsequent URL generations', () => {
|
|
21
|
+
setImageRoot('https://test.com');
|
|
22
|
+
expect(list('/tokens')).toBe('https://test.com/list/tokens');
|
|
23
|
+
expect(network(1)).toBe('https://test.com/image/1');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('list', () => {
|
|
28
|
+
it('should generate list URL with path', () => {
|
|
29
|
+
expect(list('/pulsex')).toBe('https://gib.show/list/pulsex');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should handle paths without leading slash', () => {
|
|
33
|
+
expect(list('tokens')).toBe('https://gib.show/listtokens');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should handle paths with query params', () => {
|
|
37
|
+
expect(list('/pulsechain-bridge/foreign?extensions=bridgeInfo')).toBe(
|
|
38
|
+
'https://gib.show/list/pulsechain-bridge/foreign?extensions=bridgeInfo',
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should handle empty path', () => {
|
|
43
|
+
expect(list('')).toBe('https://gib.show/list');
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('network', () => {
|
|
48
|
+
it('should generate network image URL for Ethereum', () => {
|
|
49
|
+
expect(network(1)).toBe('https://gib.show/image/1');
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should generate network image URL for PulseChain', () => {
|
|
53
|
+
expect(network(369)).toBe('https://gib.show/image/369');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should generate network image URL for BSC', () => {
|
|
57
|
+
expect(network(56)).toBe('https://gib.show/image/56');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should convert string numbers to number', () => {
|
|
61
|
+
expect(network('369' as any)).toBe('https://gib.show/image/369');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should handle zero chainId', () => {
|
|
65
|
+
expect(network(0)).toBe('https://gib.show/image/0');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should handle falsy chainId', () => {
|
|
69
|
+
expect(network(null as any)).toBe('https://gib.show/image/0');
|
|
70
|
+
expect(network(undefined as any)).toBe('https://gib.show/image/NaN');
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('image', () => {
|
|
75
|
+
it('should use logoURI if provided', () => {
|
|
76
|
+
const token = {
|
|
77
|
+
chainId: 1,
|
|
78
|
+
address: '0xdac17f958d2ee523a2206206994597c13d831ec7',
|
|
79
|
+
logoURI: 'https://custom.com/usdt.png',
|
|
80
|
+
};
|
|
81
|
+
expect(image(token)).toBe('https://custom.com/usdt.png');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should generate URL from chainId and address if no logoURI', () => {
|
|
85
|
+
const token = {
|
|
86
|
+
chainId: 1,
|
|
87
|
+
address: '0xdac17f958d2ee523a2206206994597c13d831ec7',
|
|
88
|
+
};
|
|
89
|
+
expect(image(token)).toBe(
|
|
90
|
+
'https://gib.show/image/1/0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should checksum the address', () => {
|
|
95
|
+
const token = {
|
|
96
|
+
chainId: 1,
|
|
97
|
+
address: '0xdac17f958d2ee523a2206206994597c13d831ec7', // lowercase
|
|
98
|
+
};
|
|
99
|
+
const result = image(token);
|
|
100
|
+
// Address should be checksummed in the URL
|
|
101
|
+
expect(result).toContain('0xdAC17F958D2ee523a2206206994597C13D831ec7');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should handle null logoURI', () => {
|
|
105
|
+
const token = {
|
|
106
|
+
chainId: 369,
|
|
107
|
+
address: '0xa1077a294dde1b09bb078844df40758a5d0f9a27',
|
|
108
|
+
logoURI: null,
|
|
109
|
+
};
|
|
110
|
+
expect(image(token)).toBe(
|
|
111
|
+
'https://gib.show/image/369/0xA1077a294dDE1B09bB078844df40758a5D0f9a27',
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should handle different chain IDs', () => {
|
|
116
|
+
const bscToken = {
|
|
117
|
+
chainId: 56,
|
|
118
|
+
address: '0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82',
|
|
119
|
+
};
|
|
120
|
+
expect(image(bscToken)).toBe(
|
|
121
|
+
'https://gib.show/image/56/0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82',
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('images', () => {
|
|
127
|
+
it('should generate multi-source image URL', () => {
|
|
128
|
+
const sources = ['source1', 'source2', 'source3'];
|
|
129
|
+
expect(images(sources)).toBe('https://gib.show/image/?i=source1&i=source2&i=source3');
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should handle single source', () => {
|
|
133
|
+
expect(images(['single'])).toBe('https://gib.show/image/?i=single');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should handle empty array', () => {
|
|
137
|
+
expect(images([])).toBe('https://gib.show/image/?');
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should handle URL-encoded sources', () => {
|
|
141
|
+
const sources = ['https://example.com/image1.png', 'https://example.com/image2.png'];
|
|
142
|
+
expect(images(sources)).toBe(
|
|
143
|
+
'https://gib.show/image/?i=https://example.com/image1.png&i=https://example.com/image2.png',
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
describe('integration', () => {
|
|
149
|
+
it('should work with custom root across all functions', () => {
|
|
150
|
+
setImageRoot('https://cdn.example.com');
|
|
151
|
+
|
|
152
|
+
expect(list('/tokens')).toBe('https://cdn.example.com/list/tokens');
|
|
153
|
+
expect(network(1)).toBe('https://cdn.example.com/image/1');
|
|
154
|
+
expect(image({ chainId: 1, address: '0xdac17f958d2ee523a2206206994597c13d831ec7' })).toBe(
|
|
155
|
+
'https://cdn.example.com/image/1/0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
|
156
|
+
);
|
|
157
|
+
expect(images(['a', 'b'])).toBe('https://cdn.example.com/image/?i=a&i=b');
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
});
|