Skip to content

Commit 91dc8fb

Browse files
committed
feat: add Flare token support and related configurations
Ticket: WIN-7175
1 parent 5ec3ddd commit 91dc8fb

File tree

11 files changed

+262
-2
lines changed

11 files changed

+262
-2
lines changed

modules/bitgo/src/v2/coinFactory.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ import {
8282
EthLikeCoin,
8383
EvmCoin,
8484
Flr,
85+
FlrToken,
8586
HashToken,
8687
TethLikeCoin,
8788
FiatAED,
@@ -531,6 +532,10 @@ export function registerCoinConstructors(coinFactory: CoinFactory, coinMap: Coin
531532
coinFactory.register(name, coinConstructor)
532533
);
533534

535+
FlrToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
536+
coinFactory.register(name, coinConstructor);
537+
});
538+
534539
// Generic ERC20 token registration for coins with SUPPORTS_ERC20 feature
535540
coins
536541
.filter((coin) => coin.features.includes(CoinFeature.SUPPORTS_ERC20) && !coin.isToken)
@@ -963,6 +968,9 @@ export function getTokenConstructor(tokenConfig: TokenConfig): CoinConstructor |
963968
case 'hash':
964969
case 'thash':
965970
return HashToken.createTokenConstructor(tokenConfig as CosmosTokenConfig);
971+
case 'flr':
972+
case 'tflr':
973+
return FlrToken.createTokenConstructor(tokenConfig as EthLikeTokenConfig);
966974
default:
967975
return undefined;
968976
}

modules/bitgo/src/v2/coins/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { Eos, EosToken, Teos } from '@bitgo/sdk-coin-eos';
3131
import { Etc, Tetc } from '@bitgo/sdk-coin-etc';
3232
import { Erc20Token, Erc721Token, Eth, Gteth, Hteth, Teth } from '@bitgo/sdk-coin-eth';
3333
import { EvmCoin, EthLikeErc20Token } from '@bitgo/sdk-coin-evm';
34-
import { Flr, Tflr } from '@bitgo/sdk-coin-flr';
34+
import { Flr, Tflr, FlrToken } from '@bitgo/sdk-coin-flr';
3535
import { Ethw } from '@bitgo/sdk-coin-ethw';
3636
import { EthLikeCoin, TethLikeCoin } from '@bitgo/sdk-coin-ethlike';
3737
import { Hash, Thash, HashToken } from '@bitgo/sdk-coin-hash';
@@ -107,7 +107,7 @@ export { Ethw };
107107
export { EthLikeCoin, TethLikeCoin };
108108
export { Etc, Tetc };
109109
export { EvmCoin, EthLikeErc20Token };
110-
export { Flr, Tflr };
110+
export { Flr, Tflr, FlrToken };
111111
export { Hash, Thash, HashToken };
112112
export { Hbar, Thbar };
113113
export { Icp, Ticp };

modules/bitgo/test/browser/browser.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ describe('Coins', () => {
5656
VetToken: 1,
5757
EthLikeErc20Token: 1,
5858
HashToken: 1,
59+
FlrToken: 1,
5960
};
6061
Object.keys(BitGoJS.Coin)
6162
.filter((coinName) => !excludedKeys[coinName])
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { coins, EthLikeTokenConfig } from '@bitgo/statics';
2+
import { BitGoBase, CoinConstructor, common, MPCAlgorithm, NamedCoinConstructor } from '@bitgo/sdk-core';
3+
import { CoinNames, EthLikeToken, recoveryBlockchainExplorerQuery } from '@bitgo/abstract-eth';
4+
5+
import { TransactionBuilder } from './lib';
6+
7+
export { EthLikeTokenConfig };
8+
9+
export class FlrToken extends EthLikeToken {
10+
public readonly tokenConfig: EthLikeTokenConfig;
11+
static coinNames: CoinNames = {
12+
Mainnet: 'flr',
13+
Testnet: 'tflr',
14+
};
15+
constructor(bitgo: BitGoBase, tokenConfig: EthLikeTokenConfig) {
16+
super(bitgo, tokenConfig, FlrToken.coinNames);
17+
}
18+
static createTokenConstructor(config: EthLikeTokenConfig): CoinConstructor {
19+
return super.createTokenConstructor(config, FlrToken.coinNames);
20+
}
21+
22+
static createTokenConstructors(): NamedCoinConstructor[] {
23+
return super.createTokenConstructors(FlrToken.coinNames);
24+
}
25+
26+
protected getTransactionBuilder(): TransactionBuilder {
27+
return new TransactionBuilder(coins.get(this.getBaseChain()));
28+
}
29+
30+
/** @inheritDoc **/
31+
getMPCAlgorithm(): MPCAlgorithm {
32+
return 'ecdsa';
33+
}
34+
35+
/** @inheritDoc */
36+
supportsTss(): boolean {
37+
return true;
38+
}
39+
40+
/**
41+
* Make a query to Flare explorer for information such as balance, token balance, solidity calls
42+
* @param {Object} query key-value pairs of parameters to append after /api
43+
* @param {string} apiKey optional API key to use instead of the one from the environment
44+
* @returns {Promise<Object>} response from Flare explorer
45+
*/
46+
async recoveryBlockchainExplorerQuery(
47+
query: Record<string, string>,
48+
apiKey?: string
49+
): Promise<Record<string, unknown>> {
50+
const apiToken = apiKey || common.Environments[this.bitgo.getEnv()].flrExplorerApiToken;
51+
const explorerUrl = common.Environments[this.bitgo.getEnv()].flrExplorerBaseUrl;
52+
return await recoveryBlockchainExplorerQuery(query, explorerUrl as string, apiToken);
53+
}
54+
55+
getFullName(): string {
56+
return 'Flare Token';
57+
}
58+
}

modules/sdk-coin-flr/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 './flr';
33
export * from './tflr';
44
export * from './register';
5+
export * from './flrToken';
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 { Flr } from './flr';
33
import { Tflr } from './tflr';
4+
import { FlrToken } from './flrToken';
45

56
export const register = (sdk: BitGoBase): void => {
67
sdk.register('flr', Flr.createInstance);
78
sdk.register('tflr', Tflr.createInstance);
9+
FlrToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
10+
sdk.register(name, coinConstructor);
11+
});
812
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
2+
import { BitGoAPI } from '@bitgo/sdk-api';
3+
4+
import { FlrToken } from '../../src/flrToken';
5+
6+
describe('Flare Token:', function () {
7+
let bitgo: TestBitGoAPI;
8+
let flrTokenCoin;
9+
const tokenName = 'tflr:wflr';
10+
11+
before(function () {
12+
bitgo = TestBitGo.decorate(BitGoAPI, { env: 'test' });
13+
FlrToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
14+
bitgo.safeRegister(name, coinConstructor);
15+
});
16+
bitgo.initializeTestVars();
17+
flrTokenCoin = bitgo.coin(tokenName);
18+
});
19+
20+
it('should return constants', function () {
21+
flrTokenCoin.getChain().should.equal('tflr:wflr');
22+
flrTokenCoin.getBaseChain().should.equal('tflr');
23+
flrTokenCoin.getFullName().should.equal('Flare Token');
24+
flrTokenCoin.getBaseFactor().should.equal(1e18);
25+
flrTokenCoin.type.should.equal(tokenName);
26+
flrTokenCoin.name.should.equal('Wrapped Flare Testnet');
27+
flrTokenCoin.coin.should.equal('tflr');
28+
flrTokenCoin.network.should.equal('Testnet');
29+
flrTokenCoin.decimalPlaces.should.equal(18);
30+
});
31+
});

modules/statics/src/account.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,16 @@ export class WorldERC20Token extends ContractAddressDefinedToken {
506506
}
507507
}
508508

509+
/**
510+
* The Flr Chain network supports tokens
511+
* Flr Chain Tokens are ERC20 tokens
512+
*/
513+
export class FlrERC20Token extends ContractAddressDefinedToken {
514+
constructor(options: Erc20ConstructorOptions) {
515+
super(options);
516+
}
517+
}
518+
509519
/**
510520
* The Xrp network supports tokens
511521
* Xrp tokens are identified by their issuer address
@@ -2686,6 +2696,96 @@ export function tworldErc20(
26862696
);
26872697
}
26882698

2699+
/**
2700+
* Factory function for FlrErc20 token instances.
2701+
*
2702+
* @param id uuid v4
2703+
* @param name unique identifier of the token
2704+
* @param fullName Complete human-readable name of the token
2705+
* @param decimalPlaces Number of decimal places this token supports (divisibility exponent)
2706+
* @param contractAddress Contract address of this token
2707+
* @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin.
2708+
* @param prefix? Optional token prefix. Defaults to empty string
2709+
* @param suffix? Optional token suffix. Defaults to token name.
2710+
* @param network? Optional token network. Defaults to Flr Chain mainnet network.
2711+
* @param features? Features of this coin. Defaults to the DEFAULT_FEATURES defined in `AccountCoin`
2712+
* @param primaryKeyCurve The elliptic curve for this chain/token
2713+
*/
2714+
export function flrErc20(
2715+
id: string,
2716+
name: string,
2717+
fullName: string,
2718+
decimalPlaces: number,
2719+
contractAddress: string,
2720+
asset: UnderlyingAsset,
2721+
features: CoinFeature[] = [...AccountCoin.DEFAULT_FEATURES, CoinFeature.EIP1559],
2722+
prefix = '',
2723+
suffix: string = name.toUpperCase(),
2724+
network: AccountNetwork = Networks.main.flr,
2725+
primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1
2726+
) {
2727+
return Object.freeze(
2728+
new FlrERC20Token({
2729+
id,
2730+
name,
2731+
fullName,
2732+
network,
2733+
contractAddress,
2734+
prefix,
2735+
suffix,
2736+
features,
2737+
decimalPlaces,
2738+
asset,
2739+
isToken: true,
2740+
primaryKeyCurve,
2741+
baseUnit: BaseUnit.ETH,
2742+
})
2743+
);
2744+
}
2745+
2746+
/**
2747+
* Factory function for Flr testnet FlrErc20 token instances.
2748+
*
2749+
* @param id uuid v4
2750+
* @param name unique identifier of the token
2751+
* @param fullName Complete human-readable name of the token
2752+
* @param decimalPlaces Number of decimal places this token supports (divisibility exponent)
2753+
* @param contractAddress Contract address of this token
2754+
* @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin.
2755+
* @param prefix? Optional token prefix. Defaults to empty string
2756+
* @param suffix? Optional token suffix. Defaults to token name.
2757+
* @param network? Optional token network. Defaults to the Flr Chain test network.
2758+
* @param features? Features of this coin. Defaults to the DEFAULT_FEATURES defined in `AccountCoin`
2759+
* @param primaryKeyCurve The elliptic curve for this chain/token
2760+
*/
2761+
export function tflrErc20(
2762+
id: string,
2763+
name: string,
2764+
fullName: string,
2765+
decimalPlaces: number,
2766+
contractAddress: string,
2767+
asset: UnderlyingAsset,
2768+
features: CoinFeature[] = AccountCoin.DEFAULT_FEATURES,
2769+
prefix = '',
2770+
suffix: string = name.toUpperCase(),
2771+
network: AccountNetwork = Networks.test.flr,
2772+
primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1
2773+
) {
2774+
return flrErc20(
2775+
id,
2776+
name,
2777+
fullName,
2778+
decimalPlaces,
2779+
contractAddress,
2780+
asset,
2781+
features,
2782+
prefix,
2783+
suffix,
2784+
network,
2785+
primaryKeyCurve
2786+
);
2787+
}
2788+
26892789
/**
26902790
* Factory function for xrp token instances.
26912791
*

modules/statics/src/allCoinsAndTokens.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
erc20CompatibleAccountCoin,
1414
erc721,
1515
fiat,
16+
flrErc20,
1617
gasTankAccount,
1718
hederaCoin,
1819
hederaToken,
@@ -30,6 +31,7 @@ import {
3031
teosToken,
3132
terc1155,
3233
terc721,
34+
tflrErc20,
3335
topethErc20,
3436
tpolyxToken,
3537
tronToken,
@@ -3952,6 +3954,24 @@ export const allCoinsAndTokens = [
39523954
UnderlyingAsset['tworld:usdc'],
39533955
[...AccountCoin.DEFAULT_FEATURES, CoinFeature.STABLECOIN]
39543956
),
3957+
flrErc20(
3958+
'1a38ab45-a789-4810-8d1d-2970af380753',
3959+
'flr:wflr',
3960+
'Wrapped Flare',
3961+
18,
3962+
'0x1d80c49bbbcd1c0911346656b529df9e5c2f783d',
3963+
UnderlyingAsset['flr:wflr'],
3964+
[...AccountCoin.DEFAULT_FEATURES, CoinFeature.STABLECOIN]
3965+
),
3966+
tflrErc20(
3967+
'ff4dd56d-8fa0-4e92-b764-88c56ea48549',
3968+
'tflr:wflr',
3969+
'Wrapped Flare Testnet',
3970+
18,
3971+
'0xab6fad89389b73dbc887d31206a26fd88d719d1f',
3972+
UnderlyingAsset['tflr:wflr'],
3973+
[...AccountCoin.DEFAULT_FEATURES, CoinFeature.STABLECOIN]
3974+
),
39553975
txrpToken(
39563976
'8ef16158-1015-4a67-b6fe-db669c18ab2b',
39573977
'txrp:tst-rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd',

modules/statics/src/base.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2814,6 +2814,12 @@ export enum UnderlyingAsset {
28142814
'tworld:wld' = 'tworld:wld',
28152815
'tworld:usdc' = 'tworld:usdc',
28162816

2817+
// Flr mainnet tokens
2818+
'flr:wflr' = 'flr:wflr',
2819+
2820+
// Flr testnet tokens
2821+
'tflr:wflr' = 'tflr:wflr',
2822+
28172823
ERC721 = 'erc721',
28182824
ERC1155 = 'erc1155',
28192825
NONSTANDARD = 'nonstandard',

0 commit comments

Comments
 (0)