Skip to content

Commit

Permalink
feat(sdk-coin-bera): add bera token support
Browse files Browse the repository at this point in the history
Ticket: WIN-3493
  • Loading branch information
adarsh312 committed Sep 30, 2024
1 parent 9fa8553 commit 6dc002d
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 2 deletions.
5 changes: 5 additions & 0 deletions modules/bitgo/src/v2/coinFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
AvaxP,
Bch,
Bera,
BeraToken,
Bld,
Bsc,
BscToken,
Expand Down Expand Up @@ -296,6 +297,10 @@ function registerCoinConstructors(globalCoinFactory: CoinFactory): void {
globalCoinFactory.register(name, coinConstructor);
});

BeraToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
globalCoinFactory.register(name, coinConstructor);
});

SolToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
globalCoinFactory.register(name, coinConstructor);
});
Expand Down
4 changes: 2 additions & 2 deletions modules/bitgo/src/v2/coins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AvaxC, AvaxCToken, TavaxC } from '@bitgo/sdk-coin-avaxc';
import { AvaxP, TavaxP } from '@bitgo/sdk-coin-avaxp';
import { Bch, Tbch } from '@bitgo/sdk-coin-bch';
import { Bcha, Tbcha } from '@bitgo/sdk-coin-bcha';
import { Bera, Tbera } from '@bitgo/sdk-coin-bera';
import { Bera, Tbera, BeraToken } from '@bitgo/sdk-coin-bera';
import { Bld, Tbld } from '@bitgo/sdk-coin-bld';
import { Bsc, BscToken, Tbsc } from '@bitgo/sdk-coin-bsc';
import { Bsv, Tbsv } from '@bitgo/sdk-coin-bsv';
Expand Down Expand Up @@ -59,7 +59,7 @@ export { Atom, Tatom };
export { AvaxC, AvaxCToken, TavaxC };
export { AvaxP, TavaxP };
export { Bch, Tbch };
export { Bera, Tbera };
export { Bera, Tbera, BeraToken };
export { Bsc, BscToken, Tbsc };
export { Bsv, Tbsv };
export { Btc, Tbtc, Tbtcsig, Tbtc4, Tbtcbgsig };
Expand Down
1 change: 1 addition & 0 deletions modules/bitgo/test/browser/browser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('Coins', () => {
OpethToken: 1,
ZkethToken: 1,
SuiToken: 1,
BeraToken: 1,
};
Object.keys(BitGoJS.Coin)
.filter((coinName) => !excludedKeys[coinName])
Expand Down
47 changes: 47 additions & 0 deletions modules/sdk-coin-bera/src/beraToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @prettier
*/
import { coins, EthLikeTokenConfig } from '@bitgo/statics';
import { BitGoBase, CoinConstructor, common, NamedCoinConstructor } from '@bitgo/sdk-core';
import { CoinNames, EthLikeToken, recoveryBlockchainExplorerQuery } from '@bitgo/abstract-eth';

import { TransactionBuilder } from './lib';

export { EthLikeTokenConfig };

export class BeraToken extends EthLikeToken {
public readonly tokenConfig: EthLikeTokenConfig;
static coinNames: CoinNames = {
Mainnet: 'bera',
Testnet: 'tbera',
};
constructor(bitgo: BitGoBase, tokenConfig: EthLikeTokenConfig) {
super(bitgo, tokenConfig, BeraToken.coinNames);
}
static createTokenConstructor(config: EthLikeTokenConfig): CoinConstructor {
return super.createTokenConstructor(config, BeraToken.coinNames);
}

static createTokenConstructors(): NamedCoinConstructor[] {
return super.createTokenConstructors(BeraToken.coinNames);
}

protected getTransactionBuilder(): TransactionBuilder {
return new TransactionBuilder(coins.get(this.getBaseChain()));
}

/**
* Make a query to Berachain explorer for information such as balance, token balance, solidity calls
* @param {Object} query key-value pairs of parameters to append after /api
* @returns {Promise<Object>} response Berachain explorer
*/
async recoveryBlockchainExplorerQuery(query: Record<string, string>): Promise<Record<string, unknown>> {
const apiToken = common.Environments[this.bitgo.getEnv()].beraExplorerApiToken;
const explorerUrl = common.Environments[this.bitgo.getEnv()].beraExplorerBaseUrl;
return await recoveryBlockchainExplorerQuery(query, explorerUrl as string, apiToken);
}

getFullName(): string {
return 'Bera Token';
}
}
1 change: 1 addition & 0 deletions modules/sdk-coin-bera/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './bera';
export * from './tbera';
export * from './beraToken';
export * from './lib';
export * from './register';
4 changes: 4 additions & 0 deletions modules/sdk-coin-bera/src/register.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { BitGoBase } from '@bitgo/sdk-core';
import { Bera } from './bera';
import { Tbera } from './tbera';
import { BeraToken } from './beraToken';

export const register = (sdk: BitGoBase): void => {
sdk.register('bera', Bera.createInstance);
sdk.register('tbera', Tbera.createInstance);
BeraToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
sdk.register(name, coinConstructor);
});
};
31 changes: 31 additions & 0 deletions modules/sdk-coin-bera/test/unit/beraToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
import { BitGoAPI } from '@bitgo/sdk-api';

import { BeraToken } from '../../src';

describe('Bera Token:', function () {
let bitgo: TestBitGoAPI;
let bgtTokenCoin;
const tokenName = 'tbera:bgt';

before(function () {
bitgo = TestBitGo.decorate(BitGoAPI, { env: 'test' });
BeraToken.createTokenConstructors().forEach(({ name, coinConstructor }) => {
bitgo.safeRegister(name, coinConstructor);
});
bitgo.initializeTestVars();
bgtTokenCoin = bitgo.coin(tokenName);
});

it('should return constants', function () {
bgtTokenCoin.getChain().should.equal('tbera:bgt');
bgtTokenCoin.getBaseChain().should.equal('tbera');
bgtTokenCoin.getFullName().should.equal('Bera Token');
bgtTokenCoin.getBaseFactor().should.equal(1e18);
bgtTokenCoin.type.should.equal(tokenName);
bgtTokenCoin.name.should.equal('Bera Testnet BGT');
bgtTokenCoin.coin.should.equal('tbera');
bgtTokenCoin.network.should.equal('Testnet');
bgtTokenCoin.decimalPlaces.should.equal(18);
});
});
100 changes: 100 additions & 0 deletions modules/statics/src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,16 @@ export class ZkethERC20Token extends ContractAddressDefinedToken {
}
}

/**
* The Bera Chain network support tokens
* Bera Chain Tokens are ERC20 tokens
*/
export class BeraERC20Token extends ContractAddressDefinedToken {
constructor(options: Erc20ConstructorOptions) {
super(options);
}
}

/**
* The Xrp network supports tokens
* Xrp tokens are identified by their issuer address
Expand Down Expand Up @@ -1998,6 +2008,96 @@ export function tzkethErc20(
);
}

/**
* Factory function for beraErc20 token instances.
*
* @param id uuid v4
* @param name unique identifier of the token
* @param fullName Complete human-readable name of the token
* @param decimalPlaces Number of decimal places this token supports (divisibility exponent)
* @param contractAddress Contract address of this token
* @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin.
* @param prefix? Optional token prefix. Defaults to empty string
* @param suffix? Optional token suffix. Defaults to token name.
* @param network? Optional token network. Defaults to bera mainnet network.
* @param features? Features of this coin. Defaults to the DEFAULT_FEATURES defined in `AccountCoin`
* @param primaryKeyCurve The elliptic curve for this chain/token
*/
export function beraErc20(
id: string,
name: string,
fullName: string,
decimalPlaces: number,
contractAddress: string,
asset: UnderlyingAsset,
features: CoinFeature[] = AccountCoin.DEFAULT_FEATURES,
prefix = '',
suffix: string = name.toUpperCase(),
network: AccountNetwork = Networks.main.bera,
primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1
) {
return Object.freeze(
new BeraERC20Token({
id,
name,
fullName,
network,
contractAddress,
prefix,
suffix,
features,
decimalPlaces,
asset,
isToken: true,
primaryKeyCurve,
baseUnit: BaseUnit.ETH,
})
);
}

/**
* Factory function for zkSync Sepolia testnet beraErc20 token instances.
*
* @param id uuid v4
* @param name unique identifier of the token
* @param fullName Complete human-readable name of the token
* @param decimalPlaces Number of decimal places this token supports (divisibility exponent)
* @param contractAddress Contract address of this token
* @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin.
* @param prefix? Optional token prefix. Defaults to empty string
* @param suffix? Optional token suffix. Defaults to token name.
* @param network? Optional token network. Defaults to the bera test network.
* @param features? Features of this coin. Defaults to the DEFAULT_FEATURES defined in `AccountCoin`
* @param primaryKeyCurve The elliptic curve for this chain/token
*/
export function tberaErc20(
id: string,
name: string,
fullName: string,
decimalPlaces: number,
contractAddress: string,
asset: UnderlyingAsset,
features: CoinFeature[] = AccountCoin.DEFAULT_FEATURES,
prefix = '',
suffix: string = name.toUpperCase(),
network: AccountNetwork = Networks.test.bera,
primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1
) {
return beraErc20(
id,
name,
fullName,
decimalPlaces,
contractAddress,
asset,
features,
prefix,
suffix,
network,
primaryKeyCurve
);
}

/**
* Factory function for xrp token instances.
*
Expand Down
6 changes: 6 additions & 0 deletions modules/statics/src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2123,6 +2123,12 @@ export enum UnderlyingAsset {
// Celo mainnet tokens
'celo:pact' = 'celo:pact',

// bera mainnet tokens
'bera:bgt' = 'bera:bgt',

// bera testnet tokens
'tbera:bgt' = 'tbera:bgt',

ERC721 = 'erc721',
ERC1155 = 'erc1155',
NONSTANDARD = 'nonstandard',
Expand Down
19 changes: 19 additions & 0 deletions modules/statics/src/coins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
algoToken,
arbethErc20,
avaxErc20,
beraErc20,
bscToken,
celoToken,
eosToken,
Expand All @@ -24,6 +25,7 @@ import {
tarbethErc20,
tavaxErc20,
tbscToken,
tberaErc20,
tceloToken,
teosToken,
terc1155,
Expand Down Expand Up @@ -17966,6 +17968,23 @@ export const coins = CoinMap.fromCoins([
'0xcccb29bac5ad81290383643c6fb38130cda9d881',
UnderlyingAsset['tzketh:link']
),
beraErc20(
'ef833f4e-7617-4c6d-8a1f-1fef0dd1dd0e',
'bera:bgt',
'BGT Token',
18,
// TODO: the mainnet contract address is still not available, adding placeholder here
'0xbda130737bdd9618301681329bf2e46a016ff9aa',
UnderlyingAsset['bera:bgt']
),
tberaErc20(
'24af5e18-ab4b-43e5-80db-0ddb9beb01b3',
'tbera:bgt',
'Bera Testnet BGT',
18,
'0xbda130737bdd9618301681329bf2e46a016ff9ad',
UnderlyingAsset['tbera:bgt']
),
txrpToken(
'8ef16158-1015-4a67-b6fe-db669c18ab2b',
'txrp:tst-rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd',
Expand Down
27 changes: 27 additions & 0 deletions modules/statics/src/tokenConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
OpethERC20Token,
ZkethERC20Token,
SuiCoin,
BeraERC20Token,
} from './account';
import { CoinFamily, CoinKind } from './base';
import { coins } from './coins';
Expand Down Expand Up @@ -135,6 +136,9 @@ export interface Tokens {
sui: {
tokens: SuiTokenConfig[];
};
bera: {
tokens: EthLikeTokenConfig[];
};
};
testnet: {
eth: {
Expand Down Expand Up @@ -191,6 +195,9 @@ export interface Tokens {
sui: {
tokens: SuiTokenConfig[];
};
bera: {
tokens: EthLikeTokenConfig[];
};
};
}

Expand Down Expand Up @@ -382,6 +389,20 @@ const formattedZkethTokens = coins.reduce((acc: EthLikeTokenConfig[], coin) => {
return acc;
}, []);

const formattedBeraTokens = coins.reduce((acc: EthLikeTokenConfig[], coin) => {
if (coin instanceof BeraERC20Token) {
acc.push({
type: coin.name,
coin: coin.network.type === NetworkType.MAINNET ? 'bera' : 'tbera',
network: coin.network.type === NetworkType.MAINNET ? 'Mainnet' : 'Testnet',
name: coin.fullName,
tokenContractAddress: coin.contractAddress.toString().toLowerCase(),
decimalPlaces: coin.decimalPlaces,
});
}
return acc;
}, []);

const formattedSolTokens = coins.reduce((acc: SolTokenConfig[], coin) => {
if (coin instanceof SolCoin) {
acc.push({
Expand Down Expand Up @@ -541,6 +562,9 @@ export const tokens: Tokens = {
sui: {
tokens: formattedSuiTokens.filter((token) => token.network === 'Mainnet'),
},
bera: {
tokens: formattedBeraTokens.filter((token) => token.network === 'Mainnet'),
},
},
// network name for test environments
testnet: {
Expand Down Expand Up @@ -598,6 +622,9 @@ export const tokens: Tokens = {
sui: {
tokens: formattedSuiTokens.filter((token) => token.network === 'Testnet'),
},
bera: {
tokens: formattedBeraTokens.filter((token) => token.network === 'Testnet'),
},
},
};

Expand Down

0 comments on commit 6dc002d

Please sign in to comment.