diff --git a/modules/statics/src/account.ts b/modules/statics/src/account.ts index 42e6419c32..a735e876a4 100644 --- a/modules/statics/src/account.ts +++ b/modules/statics/src/account.ts @@ -8,6 +8,7 @@ import { CANTON_TOKEN_FEATURES, CELO_TOKEN_FEATURES, COSMOS_SIDECHAIN_FEATURES, + TEMPO_FEATURES, } from './coinFeatures'; /** @@ -188,6 +189,10 @@ export interface CantonTokenConstructorOptions extends AccountConstructorOptions contractAddress: string; } +export interface Tip20TokenConstructorOptions extends AccountConstructorOptions { + contractAddress: string; +} + export interface ContractAddress extends String { __contractaddress_phantom__: never; } @@ -798,6 +803,20 @@ export class CantonToken extends AccountCoinToken { } } +/** + * The Tempo network supports TIP20 tokens + * TIP20 tokens are ERC20-compatible tokens on the Tempo network + */ +export class Tip20Token extends AccountCoinToken { + public contractAddress: string; + constructor(options: Tip20TokenConstructorOptions) { + super({ + ...options, + }); + this.contractAddress = options.contractAddress; + } +} + /** * Factory function for account coin instances. * @@ -4291,3 +4310,93 @@ export function tcantonToken( primaryKeyCurve ); } + +/** + * Factory function for TIP20 token instances on Tempo network. + * + * @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 the contract address of the token + * @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 TEMPO_FEATURES + * @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 mainnet Tempo network. + * @param primaryKeyCurve The elliptic curve for this chain/token + */ +export function tip20Token( + id: string, + name: string, + fullName: string, + decimalPlaces: number, + contractAddress: string, + asset: UnderlyingAsset, + features: CoinFeature[] = TEMPO_FEATURES, + prefix = '', + suffix: string = name.toUpperCase(), + network: AccountNetwork = Networks.main.tempo, + primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1 +) { + return Object.freeze( + new Tip20Token({ + id, + name, + fullName, + decimalPlaces, + network, + contractAddress, + asset, + features, + prefix, + suffix, + isToken: true, + primaryKeyCurve, + baseUnit: BaseUnit.ETH, + }) + ); +} + +/** + * Factory function for testnet TIP20 token instances on Tempo network. + * + * @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 the contract address of the token + * @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 TEMPO_FEATURES + * @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 testnet Tempo network. + * @param primaryKeyCurve The elliptic curve for this chain/token + */ +export function ttip20Token( + id: string, + name: string, + fullName: string, + decimalPlaces: number, + contractAddress: string, + asset: UnderlyingAsset, + features: CoinFeature[] = TEMPO_FEATURES, + prefix = '', + suffix: string = name.toUpperCase(), + network: AccountNetwork = Networks.test.tempo, + primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1 +) { + return tip20Token( + id, + name, + fullName, + decimalPlaces, + contractAddress, + asset, + features, + prefix, + suffix, + network, + primaryKeyCurve + ); +} diff --git a/modules/statics/src/allCoinsAndTokens.ts b/modules/statics/src/allCoinsAndTokens.ts index fb2341d71e..18d599c2cf 100644 --- a/modules/statics/src/allCoinsAndTokens.ts +++ b/modules/statics/src/allCoinsAndTokens.ts @@ -43,6 +43,7 @@ import { tstellarToken, tsuiToken, ttaoToken, + ttip20Token, ttronToken, tvetNFTCollection, tworldErc20, @@ -2738,6 +2739,43 @@ export const allCoinsAndTokens = [ BaseUnit.ETH, TEMPO_FEATURES ), + // Tempo TIP20 testnet tokens + ttip20Token( + 'e1872fd8-14ee-4dc9-bc5e-fd52552d9c60', + 'ttempo:pathusd', + 'Testnet pathUSD', + 18, + '0x20c0000000000000000000000000000000000000', + UnderlyingAsset['ttempo:pathusd'], + TEMPO_FEATURES + ), + ttip20Token( + '3c67eaa8-f073-4e1a-9d3a-c6756a31bef0', + 'ttempo:alphausd', + 'Testnet AlphaUSD', + 18, + '0x20c0000000000000000000000000000000000001', + UnderlyingAsset['ttempo:alphausd'], + TEMPO_FEATURES + ), + ttip20Token( + 'da6d27bd-ed3b-4b59-b574-6e013e5eb55d', + 'ttempo:betausd', + 'Testnet BetaUSD', + 18, + '0x20c0000000000000000000000000000000000002', + UnderlyingAsset['ttempo:betausd'], + TEMPO_FEATURES + ), + ttip20Token( + '58cbb592-446e-4753-8c2a-c89f662135ba', + 'ttempo:thetausd', + 'Testnet ThetaUSD', + 18, + '0x20c0000000000000000000000000000000000003', + UnderlyingAsset['ttempo:thetausd'], + TEMPO_FEATURES + ), canton( '07385320-5a4f-48e9-97a5-86d4be9f24b0', 'canton', diff --git a/modules/statics/src/base.ts b/modules/statics/src/base.ts index dd350f1f6d..cbbc598635 100644 --- a/modules/statics/src/base.ts +++ b/modules/statics/src/base.ts @@ -3578,6 +3578,12 @@ export enum UnderlyingAsset { 'canton:usdcx' = 'canton:usdcx', 'canton:cbtc' = 'canton:cbtc', + // Tempo testnet tokens + 'ttempo:pathusd' = 'ttempo:pathusd', + 'ttempo:alphausd' = 'ttempo:alphausd', + 'ttempo:betausd' = 'ttempo:betausd', + 'ttempo:thetausd' = 'ttempo:thetausd', + // fiats AED = 'aed', EUR = 'eur', diff --git a/modules/statics/src/coins/ofcCoins.ts b/modules/statics/src/coins/ofcCoins.ts index b09e66505b..f2526f0238 100644 --- a/modules/statics/src/coins/ofcCoins.ts +++ b/modules/statics/src/coins/ofcCoins.ts @@ -40,6 +40,7 @@ import { tofcTonToken, ofcSuiToken, tofcSuiToken, + tofcTempoToken, } from '../ofc'; import { UnderlyingAsset, CoinKind, CoinFeature } from '../base'; @@ -3992,4 +3993,33 @@ export const ofcCoins = [ ), // New SUI OFC token ofcSuiToken('1e01eb3d-2573-4662-aa5e-4c390e4a9b38', 'ofcsui:dmc', 'DeLorean', 9, UnderlyingAsset['sui:dmc']), + // Tempo testnet OFC tokens + tofcTempoToken( + '7912e76e-5a5c-4f1b-86e9-1fc2a51f5a98', + 'ofcttempo:pathusd', + 'Testnet pathUSD', + 18, + UnderlyingAsset['ttempo:pathusd'] + ), + tofcTempoToken( + '349f887a-e764-4640-9ba1-2e29e02d5d65', + 'ofcttempo:alphausd', + 'Testnet AlphaUSD', + 18, + UnderlyingAsset['ttempo:alphausd'] + ), + tofcTempoToken( + 'dc2b6c3d-b7a4-4940-bee3-32defbeff3bf', + 'ofcttempo:betausd', + 'Testnet BetaUSD', + 18, + UnderlyingAsset['ttempo:betausd'] + ), + tofcTempoToken( + '490a65b6-e01f-4fae-9aa5-7528d1848075', + 'ofcttempo:thetausd', + 'Testnet ThetaUSD', + 18, + UnderlyingAsset['ttempo:thetausd'] + ), ]; diff --git a/modules/statics/src/ofc.ts b/modules/statics/src/ofc.ts index 9235570aab..761ad47372 100644 --- a/modules/statics/src/ofc.ts +++ b/modules/statics/src/ofc.ts @@ -2508,3 +2508,113 @@ export function tofcSuiToken( }) ); } + +/** + * Factory function for ofc tempo token 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 decimalPlaces Number of decimal places this coin supports (divisibility exponent) + * @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin. + * @param kind Differentiates coins which represent fiat assets from those which represent crypto assets + * @param prefix? Optional coin prefix. Defaults to empty string + * @param suffix? Optional coin suffix. Defaults to coin name. + * @param isToken? Whether or not this account coin is a token of another coin + * @param features? Features of this coin. Defaults to the DEFAULT_FEATURES defined in `OfcCoin` + * @param primaryKeyCurve The elliptic curve for this chain/token + */ +export function ofcTempoToken( + id: string, + name: string, + fullName: string, + decimalPlaces: number, + asset: UnderlyingAsset, + kind: CoinKind = CoinKind.CRYPTO, + features: CoinFeature[] = OfcCoin.DEFAULT_FEATURES, + prefix = '', + suffix: string = name.replace(/^ofc/, '').toUpperCase(), + network: OfcNetwork = Networks.main.ofc, + isToken = true, + addressCoin = 'tempo', + primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1 +) { + const filteredFeatures = getFilteredFeatures(suffix); + if (filteredFeatures.length > 0) { + features = filteredFeatures; + } + return Object.freeze( + new OfcCoin({ + id, + name, + fullName, + network, + prefix, + suffix, + features, + decimalPlaces, + isToken, + asset, + kind, + addressCoin, + primaryKeyCurve, + baseUnit: BaseUnit.ETH, + }) + ); +} + +/** + * Factory function for testnet ofc tempo token 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 decimalPlaces Number of decimal places this coin supports (divisibility exponent) + * @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin. + * @param kind Differentiates coins which represent fiat assets from those which represent crypto assets + * @param prefix? Optional coin prefix. Defaults to empty string + * @param suffix? Optional coin suffix. Defaults to coin name. + * @param isToken? Whether or not this account coin is a token of another coin + * @param features? Features of this coin. Defaults to the DEFAULT_FEATURES defined in `OfcCoin` + * @param primaryKeyCurve The elliptic curve for this chain/token + */ +export function tofcTempoToken( + id: string, + name: string, + fullName: string, + decimalPlaces: number, + asset: UnderlyingAsset, + kind: CoinKind = CoinKind.CRYPTO, + features: CoinFeature[] = OfcCoin.DEFAULT_FEATURES, + prefix = '', + suffix: string = name.replace(/^ofc/, '').toUpperCase(), + network: OfcNetwork = Networks.test.ofc, + isToken = true, + addressCoin = 'ttempo', + primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1 +) { + const filteredFeatures = getFilteredFeatures(suffix); + if (filteredFeatures.length > 0) { + features = filteredFeatures; + } + return Object.freeze( + new OfcCoin({ + id, + name, + fullName, + network, + prefix, + suffix, + features, + decimalPlaces, + isToken, + asset, + kind, + addressCoin, + primaryKeyCurve, + baseUnit: BaseUnit.ETH, + }) + ); +} diff --git a/modules/statics/src/tokenConfig.ts b/modules/statics/src/tokenConfig.ts index eaa96ab8b7..9acc0c978f 100644 --- a/modules/statics/src/tokenConfig.ts +++ b/modules/statics/src/tokenConfig.ts @@ -38,6 +38,7 @@ import { JettonToken, AccountCoin, CantonToken, + Tip20Token, } from './account'; import { CoinFamily, CoinKind, BaseCoin, CoinFeature } from './base'; import { coins } from './coins'; @@ -1109,16 +1110,31 @@ const getFormattedJettonTokens = (customCoinMap = coins) => }, []); /** - * Get all formatted TIP20 tokens (skeleton) - * TODO: Implement when Tip20Token coin class is added to @bitgo/statics + * Get token config for TIP-20 tokens on the Tempo network. + * TIP-20 is the native token standard for Tempo, similar to ERC-20 on Ethereum. + * If other chains need to support this token standard, the base coin can be determined + * dynamically + */ +function getTip20TokenConfig(coin: Tip20Token): Tip20TokenConfig { + return { + type: coin.name, + coin: coin.network.type === NetworkType.MAINNET ? 'tempo' : 'ttempo', + network: coin.network.type === NetworkType.MAINNET ? 'Mainnet' : 'Testnet', + name: coin.fullName, + tokenContractAddress: coin.contractAddress.toLowerCase(), + decimalPlaces: coin.decimalPlaces, + }; +} + +/** + * Get all formatted TIP20 tokens * @param customCoinMap - Coin map to search */ const getFormattedTip20Tokens = (customCoinMap = coins): Tip20TokenConfig[] => customCoinMap.reduce((acc: Tip20TokenConfig[], coin) => { - // TODO: Uncomment when Tip20Token class is added to @bitgo/statics - // if (coin instanceof Tip20Token) { - // acc.push(getTip20TokenConfig(coin)); - // } + if (coin instanceof Tip20Token) { + acc.push(getTip20TokenConfig(coin)); + } return acc; }, []); @@ -1505,10 +1521,8 @@ export function getFormattedTokenConfigForCoin(coin: Readonly): TokenC return getEthLikeERC721TokenConfig(coin); } else if (coin instanceof CantonToken) { return getCantonTokenConfig(coin); + } else if (coin instanceof Tip20Token) { + return getTip20TokenConfig(coin); } - // TODO: Add Tip20Token instance check when class is added to statics - // else if (coin instanceof Tip20Token) { - // return getTip20TokenConfig(coin); - // } return undefined; }