Skip to content

Commit a8b60f1

Browse files
authored
feat(statics): add method to create coin map from trimmed ams response
2 parents e37f2ee + 7475788 commit a8b60f1

File tree

4 files changed

+140
-6
lines changed

4 files changed

+140
-6
lines changed

modules/statics/src/coins.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,15 @@ import {
4747
import { ada } from './ada';
4848
import { avaxp } from './avaxp';
4949
import { BaseCoin, BaseUnit, CoinFeature, KeyCurve, UnderlyingAsset } from './base';
50-
import { AmsTokenConfig } from './tokenConfig';
50+
import { AmsTokenConfig, TrimmedAmsTokenConfig } from './tokenConfig';
5151
import { erc20Coins } from './coins/erc20Coins';
5252
import { avaxTokens } from './coins/avaxTokens';
5353
import { bscTokens } from './coins/bscTokens';
5454
import { polygonTokens } from './coins/polygonTokens';
5555
import { solTokens } from './coins/solTokens';
5656
import { CoinMap } from './map';
5757
import { Networks } from './networks';
58+
import { networkFeatureMapForTokens } from './networkFeatureMapForTokens';
5859
import { utxoCoins } from './utxo';
5960
import { lightningCoins } from './lightning';
6061
import { ofcErc20Coins, tOfcErc20Coins } from './coins/ofcErc20Coins';
@@ -3289,6 +3290,25 @@ function getAptTokenInitializer(token: AmsTokenConfig) {
32893290
};
32903291
}
32913292

3293+
export function isCoinPresentInCoinMap({
3294+
name,
3295+
id,
3296+
contractAddress,
3297+
alias,
3298+
}: {
3299+
name: string;
3300+
id?: string;
3301+
contractAddress?: string;
3302+
alias?: string;
3303+
}): boolean {
3304+
return Boolean(
3305+
coins.has(name) ||
3306+
(id && coins.has(id)) ||
3307+
(contractAddress && coins.has(contractAddress)) ||
3308+
(alias && coins.has(alias))
3309+
);
3310+
}
3311+
32923312
export function createTokenMapUsingConfigDetails(tokenConfigMap: Record<string, AmsTokenConfig[]>): CoinMap {
32933313
const BaseCoins: Map<string, Readonly<BaseCoin>> = new Map();
32943314
const initializerMap: Record<string, unknown> = {
@@ -3341,9 +3361,12 @@ export function createTokenMapUsingConfigDetails(tokenConfigMap: Record<string,
33413361
for (const tokenConfigs of Object.values(tokenConfigMap)) {
33423362
const tokenConfig = tokenConfigs[0];
33433363
const family = tokenConfig.family;
3344-
const name = tokenConfig.name;
33453364

3346-
if (!coins.has(name) && tokenConfig.isToken && !nftAndOtherTokens.has(tokenConfig.name)) {
3365+
if (
3366+
!isCoinPresentInCoinMap({ ...tokenConfig }) &&
3367+
tokenConfig.isToken &&
3368+
!nftAndOtherTokens.has(tokenConfig.name)
3369+
) {
33473370
const token = createToken(family, tokenConfig, initializerMap);
33483371
if (token) {
33493372
BaseCoins.set(token.name, token);
@@ -3353,3 +3376,34 @@ export function createTokenMapUsingConfigDetails(tokenConfigMap: Record<string,
33533376

33543377
return CoinMap.fromCoins(Array.from(BaseCoins.values()));
33553378
}
3379+
3380+
export function createTokenMapUsingTrimmedConfigDetails(
3381+
reducedTokenConfigMap: Record<string, TrimmedAmsTokenConfig[]>
3382+
): CoinMap {
3383+
const amsTokenConfigMap: Record<string, AmsTokenConfig[]> = {};
3384+
const networkNameMap = new Map(
3385+
Object.values(Networks).flatMap((networkType) =>
3386+
Object.values(networkType).map((network) => [network.name, network])
3387+
)
3388+
);
3389+
3390+
for (const tokenConfigs of Object.values(reducedTokenConfigMap)) {
3391+
const tokenConfig = tokenConfigs[0];
3392+
const network = networkNameMap.get(tokenConfig.network.name);
3393+
if (
3394+
!isCoinPresentInCoinMap({ ...tokenConfig }) &&
3395+
network &&
3396+
tokenConfig.isToken &&
3397+
networkFeatureMapForTokens[network.family]
3398+
) {
3399+
const features = new Set([
3400+
...(networkFeatureMapForTokens[network.family] || []),
3401+
...(tokenConfig.additionalFeatures || []),
3402+
]);
3403+
tokenConfig.excludedFeatures?.forEach((feature) => features.delete(feature));
3404+
amsTokenConfigMap[tokenConfig.name] = [{ ...tokenConfig, features: Array.from(features), network }];
3405+
}
3406+
}
3407+
3408+
return createTokenMapUsingConfigDetails(amsTokenConfigMap);
3409+
}

modules/statics/src/tokenConfig.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,15 @@ export interface AmsTokenConfig {
261261
isToken: boolean;
262262
}
263263

264+
export interface TrimmedAmsNetworkConfig {
265+
name: string;
266+
}
267+
export interface TrimmedAmsTokenConfig extends Omit<AmsTokenConfig, 'features' | 'network'> {
268+
network: TrimmedAmsNetworkConfig;
269+
excludedFeatures?: string[];
270+
additionalFeatures?: string[];
271+
}
272+
264273
// Get the list of ERC-20 tokens from statics and format it properly
265274
const getFormattedErc20Tokens = (customCoinMap = coins) =>
266275
customCoinMap.reduce((acc: Erc20TokenConfig[], coin) => {

modules/statics/test/unit/coins.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,17 @@ import {
2020
tokens,
2121
getFormattedTokens,
2222
createTokenMapUsingConfigDetails,
23+
createTokenMapUsingTrimmedConfigDetails,
2324
} from '../../src';
2425
import { utxo } from '../../src/utxo';
2526
import { expectedColdFeatures } from './fixtures/expectedColdFeatures';
26-
import { amsTokenConfig, amsTokenConfigWithCustomToken, incorrectAmsTokenConfig } from './resources/amsTokenConfig';
27+
import {
28+
amsTokenConfig,
29+
amsTokenConfigWithCustomToken,
30+
incorrectAmsTokenConfig,
31+
reducedAmsTokenConfig,
32+
amsTokenWithUnsupportedNetwork,
33+
} from './resources/amsTokenConfig';
2734

2835
interface DuplicateCoinObject {
2936
name: string;
@@ -958,4 +965,18 @@ describe('create token map using config details', () => {
958965
formattedTokens.testnet.eth.should.not.deepEqual(tokens.testnet.eth);
959966
formattedTokens.testnet.eth.tokens.some((token) => token.type === 'hteth:faketoken').should.eql(true);
960967
});
968+
it('should not create an base coin object in coin map for token with unsupported network', () => {
969+
const tokenMap = createTokenMapUsingTrimmedConfigDetails(amsTokenWithUnsupportedNetwork);
970+
tokenMap.has('hteth:faketoken').should.eql(false);
971+
});
972+
it('should create a coin map using reduced token config details', () => {
973+
const coinMap1 = createTokenMapUsingTrimmedConfigDetails(reducedAmsTokenConfig);
974+
const amsToken1 = coinMap1.get('hteth:faketoken');
975+
const coinMap2 = createTokenMapUsingConfigDetails(amsTokenConfigWithCustomToken);
976+
const amsToken2 = coinMap2.get('hteth:faketoken');
977+
const { network: tokenNetwork1, ...tokenRest1 } = amsToken1;
978+
const { network: tokenNetwork2, ...tokenRest2 } = amsToken2;
979+
tokenRest1.should.deepEqual(tokenRest2);
980+
JSON.stringify(tokenNetwork1).should.eql(JSON.stringify(tokenNetwork2));
981+
});
961982
});

modules/statics/test/unit/resources/amsTokenConfig.ts

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -629,9 +629,9 @@ export const amsTokenConfigWithCustomToken = {
629629
'custody-bitgo-mena-fze',
630630
'custody-bitgo-custody-mena-fze',
631631
'custody-bitgo-singapore',
632-
'custody-bitgo-korea',
633632
'custody-bitgo-europe-aps',
634633
'custody-bitgo-frankfurt',
634+
'bulk-transaction',
635635
],
636636
decimalPlaces: 6,
637637
asset: 'hteth:faketoken',
@@ -643,7 +643,7 @@ export const amsTokenConfigWithCustomToken = {
643643
accountExplorerUrl: 'https://holesky.etherscan.io/address/',
644644
blockExplorerUrl: 'https://holesky.etherscan.io/block/',
645645
chainId: 17000,
646-
batcherContractAddress: '0xb1b7e7cc1ecafbfd0771a5eb5454ab5b0356980d',
646+
batcherContractAddress: '0x3e1e5d78e44f15593b3b61ed278f12c27f0ff33e',
647647
forwarderFactoryAddress: '0xffa397285ce46fb78c588a9e993286aac68c37cd',
648648
forwarderImplementationAddress: '0x059ffafdc6ef594230de44f824e2bd0a51ca5ded',
649649
nativeCoinOperationHashPrefix: 'ETHER',
@@ -697,3 +697,53 @@ export const incorrectAmsTokenConfig = {
697697
},
698698
],
699699
};
700+
701+
export const reducedAmsTokenConfig = {
702+
'hteth:faketoken': [
703+
{
704+
id: '49ff49ea-3355-4717-bbb0-5e8f5cae2201',
705+
fullName: 'Holesky Testnet fake token',
706+
name: 'hteth:faketoken',
707+
prefix: '',
708+
suffix: 'HTETH:FAKETOKEN',
709+
baseUnit: 'wei',
710+
kind: 'crypto',
711+
family: 'eth',
712+
isToken: true,
713+
additionalFeatures: ['bulk-transaction'],
714+
excludedFeatures: ['custody-bitgo-korea'],
715+
decimalPlaces: 6,
716+
asset: 'hteth:faketoken',
717+
network: {
718+
name: 'Holesky',
719+
},
720+
primaryKeyCurve: 'secp256k1',
721+
contractAddress: '0x89a959b9184b4f8c8633646d5dfd049d2ebc983a',
722+
},
723+
],
724+
};
725+
726+
export const amsTokenWithUnsupportedNetwork = {
727+
'hteth:faketoken': [
728+
{
729+
id: '49ff49ea-3355-4717-bbb0-5e8f5cae2201',
730+
fullName: 'Holesky Testnet fake token',
731+
name: 'hteth:faketoken',
732+
prefix: '',
733+
suffix: 'HTETH:FAKETOKEN',
734+
baseUnit: 'wei',
735+
kind: 'crypto',
736+
family: 'eth',
737+
isToken: true,
738+
additionalFeatures: ['bulk-transaction'],
739+
excludedFeatures: ['custody-bitgo-korea'],
740+
decimalPlaces: 6,
741+
asset: 'hteth:faketoken',
742+
network: {
743+
name: 'FakeNetwork',
744+
},
745+
primaryKeyCurve: 'secp256k1',
746+
contractAddress: '0x89a959b9184b4f8c8633646d5dfd049d2ebc983a',
747+
},
748+
],
749+
};

0 commit comments

Comments
 (0)