Skip to content

Commit 1facd02

Browse files
authored
Merge pull request #6312 from BitGo/coin-4567
feat: add vechain token standard support
2 parents 19c049d + f81cf23 commit 1facd02

File tree

7 files changed

+195
-0
lines changed

7 files changed

+195
-0
lines changed

modules/sdk-coin-vet/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from './lib';
22
export * from './vet';
33
export * from './tvet';
44
export * from './register';
5+
export * from './vetToken';
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { BitGoBase } from '@bitgo/sdk-core';
22
import { Vet } from './vet';
33
import { Tvet } from './tvet';
4+
import { VetToken } from './vetToken';
45

56
export const register = (sdk: BitGoBase): void => {
67
sdk.register('vet', Vet.createInstance);
78
sdk.register('tvet', Tvet.createInstance);
9+
VetToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
10+
sdk.register(name, coinConstructor);
11+
});
812
};
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { Vet } from './vet';
2+
import { BitGoBase, CoinConstructor, NamedCoinConstructor } from '@bitgo/sdk-core';
3+
import { VetTokenConfig, coins, tokens } from '@bitgo/statics';
4+
5+
export class VetToken extends Vet {
6+
public readonly tokenConfig: VetTokenConfig;
7+
8+
constructor(bitgo: BitGoBase, tokenConfig: VetTokenConfig) {
9+
const staticsCoin = tokenConfig.network === 'Mainnet' ? coins.get('vet') : coins.get('tvet');
10+
super(bitgo, staticsCoin);
11+
this.tokenConfig = tokenConfig;
12+
}
13+
14+
static createTokenConstructor(config: VetTokenConfig): CoinConstructor {
15+
return (bitgo: BitGoBase) => new VetToken(bitgo, config);
16+
}
17+
18+
static createTokenConstructors(): NamedCoinConstructor[] {
19+
const tokensCtors: NamedCoinConstructor[] = [];
20+
for (const token of [...tokens.bitcoin.vet.tokens, ...tokens.testnet.vet.tokens]) {
21+
const tokenConstructor = VetToken.createTokenConstructor(token);
22+
tokensCtors.push({ name: token.type, coinConstructor: tokenConstructor });
23+
}
24+
return tokensCtors;
25+
}
26+
27+
get name(): string {
28+
return this.tokenConfig.name;
29+
}
30+
31+
get coin(): string {
32+
return this.tokenConfig.coin;
33+
}
34+
35+
get network(): string {
36+
return this.tokenConfig.network;
37+
}
38+
39+
get contractAddress(): string {
40+
return this.tokenConfig.contractAddress;
41+
}
42+
43+
get decimalPlaces(): number {
44+
return this.tokenConfig.decimalPlaces;
45+
}
46+
47+
getChain(): string {
48+
return this.tokenConfig.type;
49+
}
50+
51+
getBaseChain(): string {
52+
return this.coin;
53+
}
54+
55+
getFullName(): string {
56+
return 'Vet Token';
57+
}
58+
59+
getBaseFactor(): number {
60+
return Math.pow(10, this.tokenConfig.decimalPlaces);
61+
}
62+
}

modules/statics/src/account.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ export interface Nep141TokenConstructorOptions extends AccountConstructorOptions
146146
storageDepositAmount: string;
147147
}
148148

149+
export interface VetTokenConstructorOptions extends AccountConstructorOptions {
150+
contractAddress: string;
151+
}
152+
149153
export interface ContractAddress extends String {
150154
__contractaddress_phantom__: never;
151155
}
@@ -603,6 +607,16 @@ export class Nep141Token extends AccountCoinToken {
603607
}
604608
}
605609

610+
export class VetToken extends AccountCoinToken {
611+
public contractAddress: string;
612+
constructor(options: VetTokenConstructorOptions) {
613+
super({
614+
...options,
615+
});
616+
this.contractAddress = options.contractAddress;
617+
}
618+
}
619+
606620
/**
607621
* Factory function for account coin instances.
608622
*
@@ -3015,3 +3029,79 @@ export function tnep141Token(
30153029
network
30163030
);
30173031
}
3032+
3033+
/**
3034+
* Factory function for vet token instances.
3035+
*
3036+
* @param id uuid v4
3037+
* @param name unique identifier of the token
3038+
* @param fullName Complete human-readable name of the token
3039+
* @param decimalPlaces Number of decimal places this token supports (divisibility exponent)
3040+
* @param contractAddress Contract address of this token
3041+
* @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin.
3042+
* @param features Features of this coin. Defaults to the DEFAULT_FEATURES defined in `AccountCoin`
3043+
* @param prefix Optional token prefix. Defaults to empty string
3044+
* @param suffix Optional token suffix. Defaults to token name.
3045+
* @param network Optional token network. Defaults to Near main network.
3046+
* @param primaryKeyCurve The elliptic curve for this chain/token
3047+
*/
3048+
export function vetToken(
3049+
id: string,
3050+
name: string,
3051+
fullName: string,
3052+
decimalPlaces: number,
3053+
contractAddress: string,
3054+
asset: UnderlyingAsset,
3055+
features: CoinFeature[] = AccountCoin.DEFAULT_FEATURES,
3056+
prefix = '',
3057+
suffix: string = name.toUpperCase(),
3058+
network: AccountNetwork = Networks.main.vet,
3059+
primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1
3060+
) {
3061+
return Object.freeze(
3062+
new VetToken({
3063+
id,
3064+
name,
3065+
fullName,
3066+
network,
3067+
contractAddress,
3068+
prefix,
3069+
suffix,
3070+
features,
3071+
decimalPlaces,
3072+
asset,
3073+
isToken: true,
3074+
primaryKeyCurve,
3075+
baseUnit: BaseUnit.VET,
3076+
})
3077+
);
3078+
}
3079+
3080+
/**
3081+
* Factory function for testnet vet token instances.
3082+
*
3083+
* @param id uuid v4
3084+
* @param name unique identifier of the token
3085+
* @param fullName Complete human-readable name of the token
3086+
* @param decimalPlaces Number of decimal places this token supports (divisibility exponent)
3087+
* @param contractAddress Contract address of this token
3088+
* @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin.
3089+
* @param features Features of this coin. Defaults to the DEFAULT_FEATURES defined in `AccountCoin`
3090+
* @param prefix Optional token prefix. Defaults to empty string
3091+
* @param suffix Optional token suffix. Defaults to token name.
3092+
* @param network Optional token network. Defaults to the testnet Near network.
3093+
*/
3094+
export function tvetToken(
3095+
id: string,
3096+
name: string,
3097+
fullName: string,
3098+
decimalPlaces: number,
3099+
contractAddress: string,
3100+
asset: UnderlyingAsset,
3101+
features: CoinFeature[] = AccountCoin.DEFAULT_FEATURES,
3102+
prefix = '',
3103+
suffix: string = name.toUpperCase(),
3104+
network: AccountNetwork = Networks.test.vet
3105+
) {
3106+
return vetToken(id, name, fullName, decimalPlaces, contractAddress, asset, features, prefix, suffix, network);
3107+
}

modules/statics/src/base.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2809,6 +2809,7 @@ export enum BaseUnit {
28092809
FETCHAI = 'afet',
28102810
INITIA = 'uinit',
28112811
ASI = 'afet',
2812+
VET = 'wei',
28122813
}
28132814

28142815
export interface BaseCoinConstructorOptions {

modules/statics/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export {
2626
AptNFTCollection,
2727
Sip10Token,
2828
Nep141Token,
29+
VetToken,
2930
} from './account';
3031
export { CoinMap } from './map';
3132
export { networkFeatureMapForTokens } from './networkFeatureMapForTokens';

modules/statics/src/tokenConfig.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
StellarCoin,
2323
SuiCoin,
2424
TronErc20Coin,
25+
VetToken,
2526
XrpCoin,
2627
ZkethERC20Token,
2728
} from './account';
@@ -112,6 +113,10 @@ export type Nep141TokenConfig = BaseNetworkConfig & {
112113
storageDepositAmount: string;
113114
};
114115

116+
export type VetTokenConfig = BaseNetworkConfig & {
117+
contractAddress: string;
118+
};
119+
115120
export type TokenConfig =
116121
| Erc20TokenConfig
117122
| StellarTokenConfig
@@ -207,6 +212,9 @@ export interface Tokens {
207212
near: {
208213
tokens: Nep141TokenConfig[];
209214
};
215+
vet: {
216+
tokens: VetTokenConfig[];
217+
};
210218
};
211219
testnet: {
212220
eth: {
@@ -282,6 +290,9 @@ export interface Tokens {
282290
near: {
283291
tokens: Nep141TokenConfig[];
284292
};
293+
vet: {
294+
tokens: VetTokenConfig[];
295+
};
285296
};
286297
}
287298

@@ -822,6 +833,25 @@ const getFormattedNep141Tokens = (customCoinMap = coins) =>
822833
return acc;
823834
}, []);
824835

836+
function getVetTokenConfig(coin: VetToken): VetTokenConfig {
837+
return {
838+
type: coin.name,
839+
coin: coin.network.type === NetworkType.MAINNET ? 'vet' : 'tvet',
840+
network: coin.network.type === NetworkType.MAINNET ? 'Mainnet' : 'Testnet',
841+
name: coin.fullName,
842+
contractAddress: coin.contractAddress,
843+
decimalPlaces: coin.decimalPlaces,
844+
};
845+
}
846+
847+
const getFormattedVetTokens = (customCoinMap = coins) =>
848+
customCoinMap.reduce((acc: VetTokenConfig[], coin) => {
849+
if (coin instanceof VetToken) {
850+
acc.push(getVetTokenConfig(coin));
851+
}
852+
return acc;
853+
}, []);
854+
825855
export const getFormattedTokens = (coinMap = coins): Tokens => {
826856
const formattedAptNFTCollections = getFormattedAptNFTCollections(coinMap);
827857
return {
@@ -903,6 +933,9 @@ export const getFormattedTokens = (coinMap = coins): Tokens => {
903933
near: {
904934
tokens: getFormattedNep141Tokens(coinMap).filter((token) => token.network === 'Mainnet'),
905935
},
936+
vet: {
937+
tokens: getFormattedVetTokens(coinMap).filter((token) => token.network === 'Mainnet'),
938+
},
906939
},
907940
testnet: {
908941
eth: {
@@ -982,6 +1015,9 @@ export const getFormattedTokens = (coinMap = coins): Tokens => {
9821015
near: {
9831016
tokens: getFormattedNep141Tokens(coinMap).filter((token) => token.network === 'Testnet'),
9841017
},
1018+
vet: {
1019+
tokens: getFormattedVetTokens(coinMap).filter((token) => token.network === 'Testnet'),
1020+
},
9851021
},
9861022
};
9871023
};

0 commit comments

Comments
 (0)