Skip to content

Commit

Permalink
feat(sdk-coin-opeth): add opeth tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
gianchandania committed Dec 11, 2023
1 parent 490a95d commit 1e50329
Show file tree
Hide file tree
Showing 11 changed files with 238 additions and 4 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 @@ -54,6 +54,7 @@ import {
Ofc,
OfcToken,
Opeth,
OpethToken,
Osmo,
Polygon,
PolygonToken,
Expand Down Expand Up @@ -267,6 +268,10 @@ function registerCoinConstructors(globalCoinFactory: CoinFactory): void {
globalCoinFactory.register(name, coinConstructor);
});

OpethToken.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 @@ -29,7 +29,7 @@ import { Hbar, Thbar } from '@bitgo/sdk-coin-hbar';
import { Injective, Tinjective } from '@bitgo/sdk-coin-injective';
import { Islm, Tislm } from '@bitgo/sdk-coin-islm';
import { Ltc, Tltc } from '@bitgo/sdk-coin-ltc';
import { Opeth, Topeth } from '@bitgo/sdk-coin-opeth';
import { Opeth, Topeth, OpethToken } from '@bitgo/sdk-coin-opeth';
import { Osmo, Tosmo } from '@bitgo/sdk-coin-osmo';
import { Polygon, PolygonToken, Tpolygon } from '@bitgo/sdk-coin-polygon';
import { Rbtc, Trbtc } from '@bitgo/sdk-coin-rbtc';
Expand Down Expand Up @@ -73,7 +73,7 @@ export { Etc, Tetc };
export { Hash, Thash };
export { Hbar, Thbar };
export { Ltc, Tltc };
export { Opeth, Topeth };
export { Opeth, Topeth, OpethToken };
export { Osmo, Tosmo };
export { Polygon, PolygonToken, Tpolygon };
export { Rbtc, Trbtc };
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 @@ -22,6 +22,7 @@ describe('Coins', () => {
PolygonToken: 1,
BscToken: 1,
ArbethToken: 1,
OpethToken: 1,
};
Object.keys(BitGoJS.Coin)
.filter((coinName) => !excludedKeys[coinName])
Expand Down
1 change: 1 addition & 0 deletions modules/sdk-coin-opeth/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './lib';
export * from './opeth';
export * from './topeth';
export * from './opethToken';
export * from './register';
4 changes: 4 additions & 0 deletions modules/sdk-coin-opeth/src/opeth.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* @prettier
*/

import request from 'superagent';
import { BaseCoin, BitGoBase, common } from '@bitgo/sdk-core';
import { BaseCoin as StaticsBaseCoin, coins } from '@bitgo/statics';
Expand Down
35 changes: 35 additions & 0 deletions modules/sdk-coin-opeth/src/opethToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @prettier
*/
import { EthLikeTokenConfig, coins } from '@bitgo/statics';
import { BitGoBase, CoinConstructor, NamedCoinConstructor } from '@bitgo/sdk-core';
import { CoinNames, EthLikeToken } from '@bitgo/abstract-eth';

import { TransactionBuilder } from './lib';
export { EthLikeTokenConfig };

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

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

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

getFullName(): string {
return 'Opeth Token';
}
}
37 changes: 37 additions & 0 deletions modules/sdk-coin-opeth/test/unit/opethToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'should';

import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
import { OpethToken } from '../../src';
import { BitGoAPI } from '@bitgo/sdk-api';

describe('Opeth Token:', function () {
let bitgo: TestBitGoAPI;
let opethTokenCoin;
const tokenName = 'topeth:terc18dp';

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

it('should return constants', function () {
opethTokenCoin.getChain().should.equal('topeth:terc18dp');
opethTokenCoin.getBaseChain().should.equal('topeth');
opethTokenCoin.getFullName().should.equal('Opeth Token');
opethTokenCoin.getBaseFactor().should.equal(1e18);
opethTokenCoin.type.should.equal(tokenName);
opethTokenCoin.name.should.equal('Optimism Test ERC Token 18 Decimals');
opethTokenCoin.coin.should.equal('topeth');
opethTokenCoin.network.should.equal('Testnet');
opethTokenCoin.decimalPlaces.should.equal(18);
});

it('should return same token by contract address', function () {
const tokencoinBycontractAddress = bitgo.coin(opethTokenCoin.tokenContractAddress);
opethTokenCoin.should.deepEqual(tokencoinBycontractAddress);
});
});
104 changes: 102 additions & 2 deletions modules/statics/src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,16 @@ export class ArbethERC20Token extends ContractAddressDefinedToken {
}
}

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

/**
* The Xrp network supports tokens
* Xrp tokens are identified by their issuer address
Expand Down Expand Up @@ -1697,7 +1707,7 @@ export function tpolygonErc20(
* @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 Polygon main network.
* @param network? Optional token network. Defaults to Arbitrum main network.
* @param features? Features of this coin. Defaults to the DEFAULT_FEATURES defined in `AccountCoin`
* @param primaryKeyCurve The elliptic curve for this chain/token
*/
Expand Down Expand Up @@ -1744,7 +1754,7 @@ export function arbethErc20(
* @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 Polygon test network.
* @param network? Optional token network. Defaults to the Arbitrum 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
*/
Expand Down Expand Up @@ -1776,6 +1786,96 @@ export function tarbethErc20(
);
}

/**
* Factory function for opethErc20 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 Optimism main 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 opethErc20(
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.optimism,
primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1
) {
return Object.freeze(
new OpethERC20Token({
id,
name,
fullName,
network,
contractAddress,
prefix,
suffix,
features,
decimalPlaces,
asset,
isToken: true,
primaryKeyCurve,
baseUnit: BaseUnit.ETH,
})
);
}

/**
* Factory function for Optimism Sepolia testnet opethErc20 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 Optimism 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 topethErc20(
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.optimism,
primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1
) {
return opethErc20(
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 @@ -1375,6 +1375,12 @@ export enum UnderlyingAsset {
// Arbitrum testnet tokens
'tarbeth:link' = 'tarbeth:link',

// Optimism mainnet tokens
'opeth:link' = 'opeth:link',

// Optimism testnet tokens
'topeth:terc18dp' = 'topeth:terc18dp',

ERC721 = 'erc721',
ERC1155 = 'erc1155',
NONSTANDARD = 'nonstandard',
Expand Down
18 changes: 18 additions & 0 deletions modules/statics/src/coins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
hederaToken,
nonstandardToken,
polygonErc20,
opethErc20,
solToken,
stellarToken,
talgoToken,
Expand All @@ -28,6 +29,7 @@ import {
terc20,
terc721,
tpolygonErc20,
topethErc20,
tronToken,
tsolToken,
tstellarToken,
Expand Down Expand Up @@ -11388,6 +11390,22 @@ export const coins = CoinMap.fromCoins([
'0x143e1dae4f018ff86051a01d44a1b49b13704056',
UnderlyingAsset['tarbeth:link']
),
opethErc20(
'8d80fac6-4cbc-447c-b49b-4229cb8aa89d',
'opeth:link',
'Chainlink Token',
18,
'0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6',
UnderlyingAsset['opeth:link']
),
topethErc20(
'3c06bc28-1af2-4869-a632-bd081376fb46',
'topeth:terc18dp',
'Optimism Test ERC Token 18 Decimals',
18,
'0xe9df68a54bba438c8a6192e95f0f2c53ac93d997',
UnderlyingAsset['topeth:terc18dp']
),
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 @@ -15,6 +15,7 @@ import {
TronErc20Coin,
XrpCoin,
ArbethERC20Token,
OpethERC20Token,
} from './account';
import { CoinFamily, CoinKind } from './base';
import { coins } from './coins';
Expand Down Expand Up @@ -102,6 +103,9 @@ export interface Tokens {
arbeth: {
tokens: EthLikeTokenConfig[];
};
opeth: {
tokens: EthLikeTokenConfig[];
};
sol: {
tokens: SolTokenConfig[];
};
Expand Down Expand Up @@ -149,6 +153,9 @@ export interface Tokens {
arbeth: {
tokens: EthLikeTokenConfig[];
};
opeth: {
tokens: EthLikeTokenConfig[];
};
sol: {
tokens: SolTokenConfig[];
};
Expand Down Expand Up @@ -325,6 +332,20 @@ const formattedArbethTokens = coins.reduce((acc: EthLikeTokenConfig[], coin) =>
return acc;
}, []);

const formattedOpethTokens = coins.reduce((acc: EthLikeTokenConfig[], coin) => {
if (coin instanceof OpethERC20Token) {
acc.push({
type: coin.name,
coin: coin.network.type === NetworkType.MAINNET ? 'opeth' : 'topeth',
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 @@ -444,6 +465,9 @@ export const tokens: Tokens = {
arbeth: {
tokens: formattedArbethTokens.filter((token) => token.network === 'Mainnet'),
},
opeth: {
tokens: formattedOpethTokens.filter((token) => token.network === 'Mainnet'),
},
sol: {
tokens: formattedSolTokens.filter((token) => token.network === 'Mainnet'),
},
Expand Down Expand Up @@ -492,6 +516,9 @@ export const tokens: Tokens = {
arbeth: {
tokens: formattedArbethTokens.filter((token) => token.network === 'Testnet'),
},
opeth: {
tokens: formattedOpethTokens.filter((token) => token.network === 'Testnet'),
},
sol: {
tokens: formattedSolTokens.filter((token) => token.network === 'Testnet'),
},
Expand Down

0 comments on commit 1e50329

Please sign in to comment.