Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modules/bitgo/test/v2/unit/keychains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ describe('V2 Keychains', function () {
n.asset !== UnderlyingAsset.IP && // Story Chain
n.asset !== UnderlyingAsset.BASEETH &&
n.asset !== UnderlyingAsset.SOMI &&
n.asset !== UnderlyingAsset.FLRP &&
coinFamilyValues.includes(n.name)
);

Expand Down
9 changes: 9 additions & 0 deletions modules/statics/src/allCoinsAndTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import { sip10Tokens } from './coins/sip10Tokens';
import { nep141Tokens } from './coins/nep141Tokens';
import { vetTokens } from './coins/vetTokens';
import { cosmosTokens } from './coins/cosmosTokens';
import { flrp } from './flrp';
import {
ADA_FEATURES_WITH_FRANKFURT,
ALGO_FEATURES,
Expand Down Expand Up @@ -149,6 +150,14 @@ export const allCoinsAndTokens = [
Networks.test.avalancheP,
UnderlyingAsset.AVAXP
),
flrp('84749ce6-a3ca-4270-9970-4e21cca026ca', 'flrp', 'Flare P-Chain', Networks.main.flrP, UnderlyingAsset.FLRP),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we not need to add new coins to coins.ts ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw they are migrated recently here.

flrp(
'e8a58db3-eedd-423c-89ae-817dfb6c6249',
'tflrp',
'Testnet Flare P-Chain',
Networks.test.flrP,
UnderlyingAsset.FLRP
),
ada(
'fd4d125e-f14f-414b-bd17-6cb1393265f0',
'ada',
Expand Down
2 changes: 2 additions & 0 deletions modules/statics/src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export enum CoinFamily {
FETCHAI = 'fetchai',
FIAT = 'fiat',
FLR = 'flr',
FLRP = 'flrp',
HASH = 'hash', // Provenance
HBAR = 'hbar',
ICP = 'icp',
Expand Down Expand Up @@ -518,6 +519,7 @@ export enum UnderlyingAsset {
EURR = 'eurr',
FETCHAI = 'fetchai',
FLR = 'flr',
FLRP = 'flrp',
GTC = 'gtc',
HASH = 'hash', // Provenance
HBAR = 'hbar', // Hedera main coin
Expand Down
94 changes: 94 additions & 0 deletions modules/statics/src/flrp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { BaseCoin, BaseUnit, CoinFeature, CoinKind, KeyCurve, UnderlyingAsset } from './base';
import { FlareP } from './networks';

export interface FLRPConstructorOptions {
id: string;
fullName: string;
name: string;
network: FlareP;
features: CoinFeature[];
asset: UnderlyingAsset;
prefix?: string;
suffix?: string;
primaryKeyCurve: KeyCurve;
}

export class FLRPCoin extends BaseCoin {
public static readonly DEFAULT_FEATURES = [
CoinFeature.UNSPENT_MODEL,
CoinFeature.CUSTODY_BITGO_TRUST,
CoinFeature.CUSTODY_BITGO_INDIA,
CoinFeature.CUSTODY_BITGO_MENA_FZE,
CoinFeature.CUSTODY_BITGO_CUSTODY_MENA_FZE,
CoinFeature.CUSTODY_BITGO_GERMANY,
CoinFeature.CUSTODY_BITGO_FRANKFURT,
CoinFeature.MULTISIG_COLD,
CoinFeature.MULTISIG,
CoinFeature.STAKING,
];

/**
* Additional fields for utxo coins
*/
public readonly network: FlareP;

constructor(options: FLRPConstructorOptions) {
super({
...options,
kind: CoinKind.CRYPTO,
isToken: false,
decimalPlaces: 9,
baseUnit: BaseUnit.ETH,
});

this.network = options.network;
}

protected disallowedFeatures(): Set<CoinFeature> {
return new Set([CoinFeature.ACCOUNT_MODEL]);
}

protected requiredFeatures(): Set<CoinFeature> {
return new Set([CoinFeature.UNSPENT_MODEL]);
}
}

/**
* Factory function for utxo coin instances.
*
* @param id uuid v4
* @param name unique identifier of the coin
* @param fullName Complete human-readable name of the coin
* @param network Network object for this coin
* @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin.
* @param features? Features of this coin. Defaults to the DEFAULT_FEATURES defined in `UtxoCoin`
* @param prefix? Optional coin prefix. Defaults to empty string
* @param suffix? Optional coin suffix. Defaults to coin name.
* @param primaryKeyCurve The elliptic curve for this chain/token
*/
export function flrp(
id: string,
name: string,
fullName: string,
network: FlareP,
asset: UnderlyingAsset,
features: CoinFeature[] = FLRPCoin.DEFAULT_FEATURES,
prefix = '',
suffix: string = name.toUpperCase(),
/** All UTXOs BitGo supports are SECP256K1 **/
primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1
) {
return Object.freeze(
new FLRPCoin({
id,
name,
fullName,
network,
prefix,
suffix,
features,
asset,
primaryKeyCurve,
})
);
}
94 changes: 92 additions & 2 deletions modules/statics/src/networks.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
// FlareNetwork interface for Flare-family chains
export interface FlareNetwork {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should extend BaseNetwork.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name: string;
family: CoinFamily;
explorerUrl: string;
accountExplorerUrl: string;
chainId?: number;
nativeCoinOperationHashPrefix?: string;
batcherContractAddress?: string;
forwarderFactoryAddress?: string;
forwarderImplementationAddress?: string;
blockchainID?: string;
cChainBlockchainID?: string;
avaxAssetID?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

networkID?: number;
hrp?: string;
alias?: string;
vm?: string;
txFee?: string;
maxImportFee?: string;
createSubnetTx?: string;
createChainTx?: string;
creationTxFee?: string;
minConsumption?: string;
maxConsumption?: string;
maxSupply?: string;
minStake?: string;
minStakeDuration?: string;
maxStakeDuration?: string;
minDelegationStake?: string;
minDelegationFee?: string;
}

import { CoinFamily } from './base';

export enum NetworkType {
Expand Down Expand Up @@ -1678,7 +1711,61 @@ class Somi extends Mainnet implements EthereumNetwork {
batcherContractAddress = '0x3e1e5d78e44f15593b3b61ed278f12c27f0ff33e';
}

class Flare extends Mainnet implements EthereumNetwork {
export class FlareP extends Mainnet implements FlareNetwork {
name = 'FlareP';
family = CoinFamily.FLRP;
explorerUrl = 'https://flarescan.com/blockchain/pvm/transactions/';
accountExplorerUrl = 'https://flarescan.com/blockchain/pvm/address/';
blockchainID = '11111111111111111111111111111111LpoYY';
cChainBlockchainID = '2q9e4r6Mu3U68nU1fYjgbR6JvwrRx36CohpAX5UQxse55x1Q5';
avaxAssetID = ''; // This is not applicable to our chain, so just any string that passes validation will suffice
networkID = 14;
hrp = 'flare'; //The Human-Readable Part for Bech32 addresses on the network (e.g., avax for Mainnet). It's the prefix before the 1 in an address.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update the comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alias = 'P';
vm = 'platformvm';
txFee = '1000000'; // defaults
maxImportFee = '10000000'; // defaults
createSubnetTx = '100000000'; // defaults
createChainTx = '100000000'; // defaults
creationTxFee = '10000000'; // defaults
minConsumption = '0.1';
maxConsumption = '0.12';
maxSupply = '103688266974000000000'; // 103B tokens
minStake = '1000000000000000'; // 1M FLR
minStakeDuration = '5256000'; // 2 months
maxStakeDuration = '31536000'; // 1 year
minDelegationStake = '50000000000000'; // 50000 FLR
minDelegationFee = '0';
}

export class FlarePTestnet extends Testnet implements FlareNetwork {
name = 'FlarePTestnet';
family = CoinFamily.FLRP;
explorerUrl = 'https://coston2.testnet.flarescan.com/blockchain/pvm/transactions';
accountExplorerUrl = 'https://coston2.testnet.flarescan.com/blockchain/pvm/address/';
blockchainID = '11111111111111111111111111111111LpoYY';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this same for mainnet and testnet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These settings I got from foundation

cChainBlockchainID = 'vE8M98mEQH6wk56sStD1ML8HApTgSqfJZLk9gQ3Fsd4i6m3Bi';
avaxAssetID = ''; // This is not applicable to our chain, so just any string that passes validation will suffice
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not remove this if it's not applicable. We are not using/extending AVAXNetwork, what's forcing us to keep this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since flarejs is extension of avax I thought of keeping it for now, but have removed it here
https://github.com/BitGo/BitGoJS/pull/6770/files

networkID = 114;
hrp = 'costwo'; //The Human-Readable Part for Bech32 addresses on the network (e.g., avax for Mainnet). It's the prefix before the 1 in an address.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update the comment

alias = 'P';
vm = 'platformvm';
txFee = '1000000'; // defaults
maxImportFee = '10000000'; // defaults
createSubnetTx = '100000000'; // defaults
createChainTx = '100000000'; // defaults
creationTxFee = '10000000'; // defaults
minConsumption = '0.1';
maxConsumption = '0.12';
maxSupply = '79000000000000000000000'; // 79 trillion tokens
minStake = '1000000000000000'; // 1M FLR
minStakeDuration = '5256000'; // 2 months
maxStakeDuration = '31536000'; // 1 year
minDelegationStake = '50000000000000'; // 50000 FLR
minDelegationFee = '0';
}

export class Flare extends Mainnet implements FlareNetwork, EthereumNetwork {
name = 'Flarechain';
family = CoinFamily.FLR;
explorerUrl = 'https://flare-explorer.flare.network/tx/';
Expand All @@ -1689,7 +1776,8 @@ class Flare extends Mainnet implements EthereumNetwork {
forwarderFactoryAddress = '0x37996e762fa8b671869740c79eb33f625b3bf92a';
forwarderImplementationAddress = '0xd5fe1c1f216b775dfd30638fa7164d41321ef79b';
}
class FlareTestnet extends Testnet implements EthereumNetwork {

export class FlareTestnet extends Testnet implements FlareNetwork, EthereumNetwork {
name = 'FlarechainTestnet';
family = CoinFamily.FLR;
explorerUrl = 'https://coston2-explorer.flare.network/tx/';
Expand Down Expand Up @@ -1831,6 +1919,7 @@ export const Networks = {
fiat: Object.freeze(new Fiat()),
fetchai: Object.freeze(new FetchAi()),
flr: Object.freeze(new Flare()),
flrP: Object.freeze(new FlareP()),
hash: Object.freeze(new Hash()),
hedera: Object.freeze(new Hedera()),
icp: Object.freeze(new Icp()),
Expand Down Expand Up @@ -1919,6 +2008,7 @@ export const Networks = {
fiat: Object.freeze(new FiatTestnet()),
fetchai: Object.freeze(new FetchAiTestnet()),
flr: Object.freeze(new FlareTestnet()),
flrP: Object.freeze(new FlarePTestnet()),
mon: Object.freeze(new MonadTestnet()),
pyrmont: Object.freeze(new Pyrmont()),
ethereumClassicTestnet: Object.freeze(new EthereumClassicTestnet()),
Expand Down
4 changes: 4 additions & 0 deletions modules/statics/test/unit/coins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,10 @@ coins.forEach((coin, coinName) => {
it(`should return true for CUSTODY_BITGO_INDIA ${coin.family} coin feature`, () => {
coin.features.includes(CoinFeature.CUSTODY_BITGO_INDIA).should.eql(true);
});
} else if (coin.family === CoinFamily.FLRP) {
it('does not require custody', () => {
coin.features.includes(CoinFeature.CUSTODY).should.eql(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do not plan to support Custody for FlareP chain, we should add this coinFeature to the disallowedFeatures

});
} else if (coin.features.includes(CoinFeature.GENERIC_TOKEN)) {
it(`should return false for all custody ${coin.family} coin feature`, () => {
coin.features.includes(CoinFeature.CUSTODY).should.eql(false);
Expand Down
2 changes: 2 additions & 0 deletions modules/statics/test/unit/fixtures/expectedColdFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const expectedColdFeatures = {
'doge',
'eos',
'etc',
'flrp',
'hbar',
'ltc',
'rbtc',
Expand All @@ -35,6 +36,7 @@ export const expectedColdFeatures = {
'tdoge',
'teos',
'tetc',
'tflrp',
'thbar',
'tltc',
'trbtc',
Expand Down
Loading