Skip to content

Commit dadfc4d

Browse files
committed
feat(sdk-coin-canton): added canton token skeleton
Ticket: COIN-7293
1 parent aa2abeb commit dadfc4d

File tree

7 files changed

+239
-0
lines changed

7 files changed

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

modules/sdk-coin-canton/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 './canton';
33
export * from './tcanton';
44
export * from './register';
5+
export * from './cantonToken';
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 { Canton } from './canton';
33
import { Tcanton } from './tcanton';
4+
import { CantonToken } from './cantonToken';
45

56
export const register = (sdk: BitGoBase): void => {
67
sdk.register('canton', Canton.createInstance);
78
sdk.register('tcanton', Tcanton.createInstance);
9+
CantonToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
10+
sdk.register(name, coinConstructor);
11+
});
812
};

modules/statics/src/account.ts

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { AccountNetwork, BaseNetwork, EthereumNetwork, Networks, TronNetwork } f
55
import {
66
ACCOUNT_COIN_DEFAULT_FEATURES,
77
ACCOUNT_COIN_DEFAULT_FEATURES_EXCLUDE_SINGAPORE,
8+
CANTON_FEATURES,
89
CELO_TOKEN_FEATURES,
910
COSMOS_SIDECHAIN_FEATURES,
1011
} from './coinFeatures';
@@ -181,6 +182,13 @@ export interface AdaTokenConstructorOptions extends AccountConstructorOptions {
181182
assetName: string;
182183
contractAddress: string;
183184
}
185+
186+
export interface CantonTokenConstructorOptions extends AccountConstructorOptions {
187+
baseUrl: string;
188+
admin: string;
189+
assetName: string;
190+
}
191+
184192
export interface ContractAddress extends String {
185193
__contractaddress_phantom__: never;
186194
}
@@ -774,6 +782,25 @@ export class AdaToken extends AccountCoinToken {
774782
}
775783
}
776784

785+
/**
786+
* The canton network supports tokens
787+
* Canton tokens work similar to Canton coin,
788+
* but they will have their own token standard base url and instrument admin
789+
*/
790+
export class CantonToken extends AccountCoinToken {
791+
public baseUrl: string;
792+
public admin: string;
793+
public assetName: string;
794+
constructor(options: CantonTokenConstructorOptions) {
795+
super({
796+
...options,
797+
});
798+
this.baseUrl = options.baseUrl;
799+
this.admin = options.admin;
800+
this.assetName = options.assetName;
801+
}
802+
}
803+
777804
/**
778805
* Factory function for account coin instances.
779806
*
@@ -4171,3 +4198,105 @@ export function tjettonToken(
41714198
primaryKeyCurve
41724199
);
41734200
}
4201+
4202+
/**
4203+
* Factory function for prod canton token instances.
4204+
*
4205+
* @param id uuid v4
4206+
* @param name Name of the token
4207+
* @param fullName Complete human-readable name of the token
4208+
* @param decimalPlaces Number of decimal places this token supports (divisibility exponent)
4209+
* @param baseUrl token standard base url, ref: https://docs.digitalasset.com/utilities/devnet/overview/registry-user-guide/token-standard.html#token-standard-endpoints
4210+
* @param assetName the token instrument name
4211+
* @param admin the instrument admin for this token
4212+
* @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin.
4213+
* @param features Features of this coin. Defaults to CANTON_FEATURES
4214+
* @param prefix Optional token prefix. Defaults to empty string
4215+
* @param suffix Optional token suffix. Defaults to token name.
4216+
* @param network Optional token network. Defaults to the mainnet canton network.
4217+
* @param primaryKeyCurve The elliptic curve for this chain/token
4218+
*/
4219+
export function cantonToken(
4220+
id: string,
4221+
name: string,
4222+
fullName: string,
4223+
decimalPlaces: number,
4224+
baseUrl: string,
4225+
assetName: string,
4226+
admin: string,
4227+
asset: UnderlyingAsset,
4228+
features: CoinFeature[] = CANTON_FEATURES,
4229+
prefix = '',
4230+
suffix: string = name.toUpperCase(),
4231+
network: AccountNetwork = Networks.main.canton,
4232+
primaryKeyCurve: KeyCurve = KeyCurve.Ed25519
4233+
) {
4234+
return Object.freeze(
4235+
new CantonToken({
4236+
id,
4237+
name,
4238+
fullName,
4239+
decimalPlaces,
4240+
network,
4241+
baseUrl,
4242+
assetName,
4243+
admin,
4244+
asset,
4245+
features,
4246+
prefix,
4247+
suffix,
4248+
isToken: true,
4249+
primaryKeyCurve,
4250+
baseUnit: BaseUnit.CANTON,
4251+
})
4252+
);
4253+
}
4254+
4255+
/**
4256+
* Factory function for testnet canton token instances.
4257+
*
4258+
* @param id uuid v4
4259+
* @param name unique identifier of the token
4260+
* @param fullName Complete human-readable name of the token
4261+
* @param decimalPlaces Number of decimal places this token supports (divisibility exponent)
4262+
* @param baseUrl token standard base url
4263+
* @param assetName the token instrument name
4264+
* @param admin the instrument admin for this token
4265+
* @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin.
4266+
* @param features Features of this coin. Defaults to the CANTON_FEATURES
4267+
* @param prefix Optional token prefix. Defaults to empty string
4268+
* @param suffix Optional token suffix. Defaults to token name.
4269+
* @param network Optional token network. Defaults to the testnet Canton network.
4270+
* @param primaryKeyCurve The elliptic curve for this chain/token
4271+
*/
4272+
export function tcantonToken(
4273+
id: string,
4274+
name: string,
4275+
fullName: string,
4276+
decimalPlaces: number,
4277+
baseUrl: string,
4278+
assetName: string,
4279+
admin: string,
4280+
asset: UnderlyingAsset,
4281+
features: CoinFeature[] = CANTON_FEATURES,
4282+
prefix = '',
4283+
suffix: string = name.toUpperCase(),
4284+
network: AccountNetwork = Networks.test.canton,
4285+
primaryKeyCurve: KeyCurve = KeyCurve.Ed25519
4286+
) {
4287+
return cantonToken(
4288+
id,
4289+
name,
4290+
fullName,
4291+
decimalPlaces,
4292+
baseUrl,
4293+
assetName,
4294+
admin,
4295+
asset,
4296+
features,
4297+
prefix,
4298+
suffix,
4299+
network,
4300+
primaryKeyCurve
4301+
);
4302+
}

modules/statics/src/coinFeatures.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,4 +753,5 @@ export const CANTON_FEATURES = [
753753
CoinFeature.REQUIRES_WALLET_INITIALIZATION_TRANSACTION,
754754
CoinFeature.REQUIRES_DEPOSIT_ACCEPTANCE_TRANSACTION,
755755
CoinFeature.ALPHANUMERIC_MEMO_ID,
756+
CoinFeature.SUPPORTS_TOKENS,
756757
];

modules/statics/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export {
3333
CosmosChainToken,
3434
AdaToken,
3535
JettonToken,
36+
CantonToken,
3637
} from './account';
3738
export { CoinMap } from './map';
3839
export { networkFeatureMapForTokens } from './networkFeatureMapForTokens';

modules/statics/src/tokenConfig.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
AdaToken,
3838
JettonToken,
3939
AccountCoin,
40+
CantonToken,
4041
} from './account';
4142
import { CoinFamily, CoinKind, BaseCoin, CoinFeature } from './base';
4243
import { coins } from './coins';
@@ -135,6 +136,12 @@ export type Nep141TokenConfig = BaseNetworkConfig & {
135136
storageDepositAmount: string;
136137
};
137138

139+
export type CantonTokenConfig = BaseNetworkConfig & {
140+
baseUrl: string;
141+
assetName: string;
142+
admin: string;
143+
};
144+
138145
export type VetTokenConfig = BaseNetworkConfig & {
139146
contractAddress: string;
140147
};
@@ -176,6 +183,7 @@ export type TokenConfig =
176183
| AptNFTCollectionConfig
177184
| Sip10TokenConfig
178185
| Nep141TokenConfig
186+
| CantonTokenConfig
179187
| CosmosTokenConfig
180188
| VetTokenConfig
181189
| VetNFTCollectionConfig
@@ -235,6 +243,7 @@ export interface TokenNetwork {
235243
cosmos: { tokens: CosmosTokenConfig[] };
236244
ton: { tokens: JettonTokenConfig[] };
237245
tempo: { tokens: Tip20TokenConfig[] };
246+
canton: { tokens: CantonTokenConfig[] };
238247
}
239248

240249
export interface Tokens {
@@ -1024,6 +1033,26 @@ const getFormattedNep141Tokens = (customCoinMap = coins) =>
10241033
return acc;
10251034
}, []);
10261035

1036+
function getCantonTokenConfig(coin: CantonToken): CantonTokenConfig {
1037+
return {
1038+
type: coin.name,
1039+
coin: coin.network.type === NetworkType.MAINNET ? 'canton' : 'tcanton',
1040+
network: coin.network.type === NetworkType.MAINNET ? 'Mainnet' : 'Testnet',
1041+
name: coin.fullName,
1042+
decimalPlaces: coin.decimalPlaces,
1043+
baseUrl: coin.baseUrl,
1044+
admin: coin.admin,
1045+
assetName: coin.assetName,
1046+
};
1047+
}
1048+
const getFormattedCantonTokens = (customCoinMap = coins) =>
1049+
customCoinMap.reduce((acc: CantonTokenConfig[], coin) => {
1050+
if (coin instanceof CantonToken) {
1051+
acc.push(getCantonTokenConfig(coin));
1052+
}
1053+
return acc;
1054+
}, []);
1055+
10271056
function getVetTokenConfig(coin: VetToken): VetTokenConfig {
10281057
return {
10291058
type: coin.name,
@@ -1313,6 +1342,9 @@ export const getFormattedTokensByNetwork = (network: 'Mainnet' | 'Testnet', coin
13131342
tempo: {
13141343
tokens: getFormattedTip20Tokens(coinMap).filter((token) => token.network === network),
13151344
},
1345+
canton: {
1346+
tokens: getFormattedCantonTokens(coinMap).filter((token) => token.network === network),
1347+
},
13161348
};
13171349
};
13181350

@@ -1473,6 +1505,8 @@ export function getFormattedTokenConfigForCoin(coin: Readonly<BaseCoin>): TokenC
14731505
return getEthLikeTokenConfig(coin);
14741506
} else if (coin instanceof EthLikeERC721Token) {
14751507
return getEthLikeERC721TokenConfig(coin);
1508+
} else if (coin instanceof CantonToken) {
1509+
return getCantonTokenConfig(coin);
14761510
}
14771511
// TODO: Add Tip20Token instance check when class is added to statics
14781512
// else if (coin instanceof Tip20Token) {

0 commit comments

Comments
 (0)