From 9256fcb9644a0a347ad3f8a223b772f027ff85ca Mon Sep 17 00:00:00 2001 From: Adil Iqbal Date: Fri, 28 Apr 2023 14:03:47 +0200 Subject: [PATCH] feat(rootstock): add rootstock protocol with erc20-tokens --- packages/core/src/assets/symbols/bpro.svg | 1 + packages/core/src/assets/symbols/doc.svg | 1 + packages/core/src/assets/symbols/moc.svg | 1 + packages/core/src/assets/symbols/ramlt.svg | 1 + packages/core/src/assets/symbols/rbtc.svg | 1 + packages/core/src/assets/symbols/rbund.svg | 1 + packages/core/src/assets/symbols/rdai.svg | 1 + packages/core/src/assets/symbols/rdoc.svg | 1 + packages/core/src/assets/symbols/rflixx.svg | 1 + packages/core/src/assets/symbols/rif.svg | 1 + packages/core/src/assets/symbols/rlink.svg | 1 + packages/core/src/assets/symbols/rpro.svg | 1 + packages/core/src/assets/symbols/rrfox.svg | 1 + packages/core/src/assets/symbols/rubi.svg | 1 + packages/core/src/assets/symbols/rusdc.svg | 1 + packages/core/src/assets/symbols/rusdt.svg | 1 + packages/core/src/assets/symbols/sov.svg | 1 + .../src/lib/services/protocol/defaults.ts | 28 +++- .../store/sub/sub-protocol-store.service.ts | 13 +- .../core/src/lib/services/protocol/tokens.ts | 131 ++++++++++++++++++ .../src/lib/services/token/token.service.ts | 65 ++++++++- 21 files changed, 242 insertions(+), 12 deletions(-) create mode 100644 packages/core/src/assets/symbols/bpro.svg create mode 100644 packages/core/src/assets/symbols/doc.svg create mode 100644 packages/core/src/assets/symbols/moc.svg create mode 100644 packages/core/src/assets/symbols/ramlt.svg create mode 100644 packages/core/src/assets/symbols/rbtc.svg create mode 100644 packages/core/src/assets/symbols/rbund.svg create mode 100644 packages/core/src/assets/symbols/rdai.svg create mode 100644 packages/core/src/assets/symbols/rdoc.svg create mode 100644 packages/core/src/assets/symbols/rflixx.svg create mode 100644 packages/core/src/assets/symbols/rif.svg create mode 100644 packages/core/src/assets/symbols/rlink.svg create mode 100644 packages/core/src/assets/symbols/rpro.svg create mode 100644 packages/core/src/assets/symbols/rrfox.svg create mode 100644 packages/core/src/assets/symbols/rubi.svg create mode 100644 packages/core/src/assets/symbols/rusdc.svg create mode 100644 packages/core/src/assets/symbols/rusdt.svg create mode 100644 packages/core/src/assets/symbols/sov.svg diff --git a/packages/core/src/assets/symbols/bpro.svg b/packages/core/src/assets/symbols/bpro.svg new file mode 100644 index 0000000..36f28ea --- /dev/null +++ b/packages/core/src/assets/symbols/bpro.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/doc.svg b/packages/core/src/assets/symbols/doc.svg new file mode 100644 index 0000000..541de4b --- /dev/null +++ b/packages/core/src/assets/symbols/doc.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/moc.svg b/packages/core/src/assets/symbols/moc.svg new file mode 100644 index 0000000..8136753 --- /dev/null +++ b/packages/core/src/assets/symbols/moc.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/ramlt.svg b/packages/core/src/assets/symbols/ramlt.svg new file mode 100644 index 0000000..5c66ee0 --- /dev/null +++ b/packages/core/src/assets/symbols/ramlt.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rbtc.svg b/packages/core/src/assets/symbols/rbtc.svg new file mode 100644 index 0000000..d5e7f2f --- /dev/null +++ b/packages/core/src/assets/symbols/rbtc.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rbund.svg b/packages/core/src/assets/symbols/rbund.svg new file mode 100644 index 0000000..3f26bc5 --- /dev/null +++ b/packages/core/src/assets/symbols/rbund.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rdai.svg b/packages/core/src/assets/symbols/rdai.svg new file mode 100644 index 0000000..3930f26 --- /dev/null +++ b/packages/core/src/assets/symbols/rdai.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rdoc.svg b/packages/core/src/assets/symbols/rdoc.svg new file mode 100644 index 0000000..cfa2f6c --- /dev/null +++ b/packages/core/src/assets/symbols/rdoc.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rflixx.svg b/packages/core/src/assets/symbols/rflixx.svg new file mode 100644 index 0000000..44b63f6 --- /dev/null +++ b/packages/core/src/assets/symbols/rflixx.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rif.svg b/packages/core/src/assets/symbols/rif.svg new file mode 100644 index 0000000..b11b998 --- /dev/null +++ b/packages/core/src/assets/symbols/rif.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rlink.svg b/packages/core/src/assets/symbols/rlink.svg new file mode 100644 index 0000000..78d93d5 --- /dev/null +++ b/packages/core/src/assets/symbols/rlink.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rpro.svg b/packages/core/src/assets/symbols/rpro.svg new file mode 100644 index 0000000..40c6b47 --- /dev/null +++ b/packages/core/src/assets/symbols/rpro.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rrfox.svg b/packages/core/src/assets/symbols/rrfox.svg new file mode 100644 index 0000000..8877e4a --- /dev/null +++ b/packages/core/src/assets/symbols/rrfox.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rubi.svg b/packages/core/src/assets/symbols/rubi.svg new file mode 100644 index 0000000..a991213 --- /dev/null +++ b/packages/core/src/assets/symbols/rubi.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rusdc.svg b/packages/core/src/assets/symbols/rusdc.svg new file mode 100644 index 0000000..36fcdfc --- /dev/null +++ b/packages/core/src/assets/symbols/rusdc.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/rusdt.svg b/packages/core/src/assets/symbols/rusdt.svg new file mode 100644 index 0000000..535b61b --- /dev/null +++ b/packages/core/src/assets/symbols/rusdt.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/assets/symbols/sov.svg b/packages/core/src/assets/symbols/sov.svg new file mode 100644 index 0000000..303e722 --- /dev/null +++ b/packages/core/src/assets/symbols/sov.svg @@ -0,0 +1 @@ + diff --git a/packages/core/src/lib/services/protocol/defaults.ts b/packages/core/src/lib/services/protocol/defaults.ts index 411dd28..4ad5c92 100644 --- a/packages/core/src/lib/services/protocol/defaults.ts +++ b/packages/core/src/lib/services/protocol/defaults.ts @@ -10,6 +10,7 @@ import { EthereumProtocolNetwork, EthereumERC20ProtocolConfig } from '@airgap/ethereum' +import { RskProtocol, GenericRskERC20, RskERC20ProtocolOptions, RskProtocolNetwork, RskERC20ProtocolConfig, } from '@airgap/rsk' import { GroestlcoinProtocol } from '@airgap/groestlcoin' import { MoonriverProtocol, MoonbeamProtocol } from '@airgap/moonbeam' import { PolkadotProtocol, KusamaProtocol } from '@airgap/polkadot' @@ -34,7 +35,7 @@ import { TezosKtProtocol } from '@airgap/tezos' import { Token } from '../../types/Token' -import { ethTokens } from './tokens' +import { ethTokens, rskTokens } from './tokens' export function getDefaultPassiveProtocols(): ICoinProtocol[] { return [] @@ -54,7 +55,9 @@ export function getDefaultActiveProtocols(): ICoinProtocol[] { new MoonbeamProtocol(), new BitcoinProtocol(), new AstarProtocol(), - new ShidenProtocol() + new ShidenProtocol(), + new RskProtocol(), + new GroestlcoinProtocol(), ] } @@ -65,6 +68,7 @@ export function getDefaultPassiveSubProtocols(): [ICoinProtocol, ICoinSubProtoco export function getDefaultActiveSubProtocols(): [ICoinProtocol, ICoinSubProtocol][] { const tezosProtocol = new TezosProtocol() const ethereumProtocol = new EthereumProtocol() + const rskProtocol = new RskProtocol() return [ [tezosProtocol, new TezosUUSD()], @@ -102,6 +106,24 @@ export function getDefaultActiveSubProtocols(): [ICoinProtocol, ICoinSubProtocol ) ) ] as [EthereumProtocol, GenericERC20] - ) + ), + ...rskTokens.map( + (token: Token) => + [ + rskProtocol, + new GenericRskERC20( + new RskERC20ProtocolOptions( + new RskProtocolNetwork(), + new RskERC20ProtocolConfig( + token.symbol, + token.name, + token.marketSymbol, + token.identifier as SubProtocolSymbols, + token.contractAddress, + token.decimals + ) + ) + ) + ] as [RskProtocol, GenericRskERC20] ] } diff --git a/packages/core/src/lib/services/protocol/store/sub/sub-protocol-store.service.ts b/packages/core/src/lib/services/protocol/store/sub/sub-protocol-store.service.ts index 4791f7e..b781482 100644 --- a/packages/core/src/lib/services/protocol/store/sub/sub-protocol-store.service.ts +++ b/packages/core/src/lib/services/protocol/store/sub/sub-protocol-store.service.ts @@ -10,7 +10,7 @@ import { import { getMainIdentifier } from '../../../../utils/protocol/protocol-identifier' import { getProtocolAndNetworkIdentifier } from '../../../../utils/protocol/protocol-network-identifier' import { Token } from '../../../../types/Token' -import { ethTokens } from '../../tokens' +import { ethTokens, rskTokens } from '../../tokens' import { BaseProtocolStoreService, BaseProtocolStoreConfig } from '../base-protocol-store.service' import { getProtocolOptionsByIdentifier } from '../../../../utils/protocol/protocol-options' import { ISOLATED_MODULES_PLUGIN } from '../../../../capacitor-plugins/injection-tokens' @@ -36,6 +36,7 @@ export class SubProtocolStoreService extends BaseProtocolStoreService< SubProtocolsMap, SubProtocolStoreConfig > { + private _rskTokenIdentifers: Set | undefined private _ethTokenIdentifers: Set | undefined constructor(@Inject(ISOLATED_MODULES_PLUGIN) private readonly isolatedModules: IsolatedModulesPlugin) { @@ -50,12 +51,20 @@ export class SubProtocolStoreService extends BaseProtocolStoreService< return this._ethTokenIdentifers } + private get rskTokenIdentifiers(): Set { + if (this._rskTokenIdentifers === undefined) { + this._rskTokenIdentifers = new Set(rskTokens.map((rskToken: Token) => rskToken.identifier)) + } + + return this._rskTokenIdentifers + } + public isIdentifierValid(identifier: string): boolean { const mainIdentifier = getMainIdentifier(identifier as SubProtocolSymbols) return ( Object.values(SubProtocolSymbols).includes(identifier as SubProtocolSymbols) || - this.ethTokenIdentifiers.has(identifier) || + this.ethTokenIdentifiers.has(identifier) || this.rskTokenIdentifiers.has(identifier) || (Object.values(MainProtocolSymbols).includes(mainIdentifier) && identifier !== mainIdentifier) || identifier.includes('-') ) diff --git a/packages/core/src/lib/services/protocol/tokens.ts b/packages/core/src/lib/services/protocol/tokens.ts index 26dc6ce..8d07cf9 100644 --- a/packages/core/src/lib/services/protocol/tokens.ts +++ b/packages/core/src/lib/services/protocol/tokens.ts @@ -827,3 +827,134 @@ export const ethTokens: Token[] = [ decimals: 18 } ] + +export const rskTokens: Token[] = [ + { + symbol: 'RIF', + name: 'RSK Infrastructure Framework', + marketSymbol: 'rif', + identifier: 'rbtc-erc20-rif', + contractAddress: '0x2acc95758f8b5f583470ba265eb685a8f45fc9d5', + decimals: 18 + }, + { + symbol: 'DOC', + name: 'Dollar on Chain', + marketSymbol: '', // TODO: DOC doesn't exist in the price api + identifier: 'rbtc-erc20-doc', + contractAddress: '0xE700691Da7B9851F2F35f8b8182C69C53ccad9DB', + decimals: 18 + }, + { + symbol: 'BPRO', + name: 'BitPRO', + marketSymbol: '', // TODO: BPRO doesn't exist in the price api + identifier: 'rbtc-erc20-bpro', + contractAddress: '0x440cd83c160de5c96ddb20246815ea44c7abbca8', + decimals: 18 + }, + { + symbol: 'rDAI', + name: 'Dai Stablecoin', + marketSymbol: 'dai', // TODO: rDAI doesn't exist in the price api + identifier: 'rbtc-erc20-rdai', + contractAddress: '0x6B1A73d547F4009a26B8485B63d7015d248Ad406', + decimals: 18 + }, + { + symbol: 'rDOC', + name: 'RIF Dollar on Chain', + marketSymbol: '', // TODO: rDOC doesn't exist in the price api + identifier: 'rbtc-erc20-rdoc', + contractAddress: '0x2d919F19D4892381D58edeBeca66D5642Cef1a1f', + decimals: 18 + }, + { + symbol: 'RPRO', + name: 'RIF PRO', + marketSymbol: '', // TODO: RPRO doesn't exist in the price api + identifier: 'rbtc-erc20-rpro', + contractAddress: '0xF4d27C56595eD59B66cC7f03CFF5193E4Bd74a61', + decimals: 18 + }, + { + symbol: 'rFLIXX', + name: 'Flixxo on RSK', + marketSymbol: '', // TODO: rFLIXX doesn't exist in the price api + identifier: 'rbtc-erc20-rflixx', + contractAddress: '0x73C08467E23F7DcB7DdbBc8d05041b74467A498A', + decimals: 18 + }, + { + symbol: 'rLINK', + name: 'ChainLink Token on RSK', + marketSymbol: 'link', // TODO: rLink doesn't exist in the price api + identifier: 'rbtc-erc20-rlink', + contractAddress: '0x14AdaE34beF7ca957Ce2dDe5ADD97ea050123827', + decimals: 18 + }, + { + symbol: 'rUSDC', + name: 'USD Coin on RSK', + marketSymbol: 'usdc', // TODO: rUSDC doesn't exist in the price api + identifier: 'rbtc-erc20-rusdc', + contractAddress: '0x1BDA44fda023f2aF8280A16FD1b01d1a493BA6C4', + decimals: 18 + }, + { + symbol: 'rUSDT', + name: 'Tether USD on RSK', + marketSymbol: 'usdt', // TODO: rUSDT doesn't exist in the price api + identifier: 'rbtc-erc20-rusdt', + contractAddress: '0xEf213441a85DF4d7acBdAe0Cf78004E1e486BB96', + decimals: 18 + }, + { + symbol: 'rRFOX', + name: 'RedFOX Labs on RSK', + marketSymbol: '', // TODO: rRFOX doesn't exist in the price api + identifier: 'rbtc-erc20-rrfox', + contractAddress: '0x9C3a5F8d686fadE293c0Ce989A62a34408C4e307', + decimals: 18 + }, + { + symbol: 'rBUND', + name: 'Bundles Finance on RSK', + marketSymbol: '', // TODO: rBUND doesn't exist in the price api + identifier: 'rbtc-erc20-rbund', + contractAddress: '0x4991516df6053121121274397a8c1dad608bc95b', + decimals: 18 + }, + { + symbol: 'rAMLT', + name: 'AMLT Coinfirm on RSK', + marketSymbol: '', // TODO: rAMLT doesn't exist in the price api + identifier: 'rbtc-erc20-ramlt', + contractAddress: '0xff9ea341d9ea91cb7c54342354377f5104fd403f', + decimals: 18 + }, + { + symbol: 'SOV', + name: 'Sovryn Token', + marketSymbol: 'sovryn', + identifier: 'rbtc-erc20-sov', + contractAddress: '0xefc78fc7d48b64958315949279ba181c2114abbd', + decimals: 18 + }, + { + symbol: 'MOC', + name: 'MoC Token', + marketSymbol: '', // TODO: MOC doesn't exist in the price api + identifier: 'rbtc-erc20-moc', + contractAddress: '0x9ac7fe28967b30e3a4e6e03286d715b42b453d10', + decimals: 18 + }, + { + symbol: 'rUBI', + name: 'Universal Basic Income Token', + marketSymbol: '', // TODO: rUBI doesn't exist in the price api + identifier: 'rbtc-erc20-rubi', + contractAddress: '0x70566d8541beabe984c8babf8a816ed908514ba8', + decimals: 18 + }, +] diff --git a/packages/core/src/lib/services/token/token.service.ts b/packages/core/src/lib/services/token/token.service.ts index be0b3f3..9151480 100644 --- a/packages/core/src/lib/services/token/token.service.ts +++ b/packages/core/src/lib/services/token/token.service.ts @@ -1,16 +1,19 @@ import { IAirGapTransaction, SignedTransaction, SubProtocolSymbols, UnsignedTransaction } from '@airgap/coinlib-core' import { GenericERC20, EthereumERC20ProtocolOptions, EthereumProtocolNetwork, EthereumERC20ProtocolConfig } from '@airgap/ethereum' +import { RskERC20ProtocolConfig, RskERC20ProtocolOptions, RskProtocolNetwork, GenericRskERC20 } from '@airgap/rsk' import { Injectable } from '@angular/core' import { Token } from '../../types/Token' -import { ethTokens } from '../protocol/tokens' +import { ethTokens, rskTokens } from '../protocol/tokens' @Injectable({ providedIn: 'root' }) export class TokenService { public getRecipientToken(tx: IAirGapTransaction): Token | undefined { - return ethTokens.find((token: Token) => token.contractAddress.toLowerCase() === tx.to[0].toLowerCase()) + const tokens = ethTokens.concat(rskTokens) + + return tokens.find((token: Token) => token.contractAddress.toLowerCase() === tx.to[0].toLowerCase()) } public async getTokenTransferDetailsFromSigned( @@ -19,7 +22,31 @@ export class TokenService { recipientToken?: Token ): Promise { const token: Token | undefined = recipientToken ?? this.getRecipientToken(tx) - if (token !== undefined) { + const hasMatched = rskTokens.some(rskToken => rskToken.symbol === token?.symbol) + + if (token && hasMatched) { + const genericRskERC20: GenericRskERC20 = new GenericRskERC20( + new RskERC20ProtocolOptions( + new RskProtocolNetwork(), + new RskERC20ProtocolConfig( + token.symbol, + token.name, + token.marketSymbol, + token.identifier as SubProtocolSymbols, + token.contractAddress, + token.decimals + ) + ) + ) + + const transactions: IAirGapTransaction[] = await genericRskERC20.getTransactionDetailsFromSigned(signedTransaction) + + if (transactions.length !== 1) { + throw Error('`getTransactionDetailsFromSigned` returned more than 1 transaction!') + } + + return transactions[0] + } else if (token !== undefined) { const genericErc20: GenericERC20 = new GenericERC20( new EthereumERC20ProtocolOptions( new EthereumProtocolNetwork(), @@ -42,7 +69,7 @@ export class TokenService { } return transactions[0] - } catch (error) {} + } catch (error) { } } return tx @@ -54,7 +81,31 @@ export class TokenService { recipientToken?: Token ): Promise { const token: Token | undefined = recipientToken ?? this.getRecipientToken(tx) - if (token !== undefined) { + const hasMatched = rskTokens.some(rskToken => rskToken.symbol === token?.symbol) + + if (token && hasMatched) { + const genericRskERC20: GenericRskERC20 = new GenericRskERC20( + new RskERC20ProtocolOptions( + new RskProtocolNetwork(), + new RskERC20ProtocolConfig( + token.symbol, + token.name, + token.marketSymbol, + token.identifier as SubProtocolSymbols, + token.contractAddress, + token.decimals + ) + ) + ) + + const transactions: IAirGapTransaction[] = await genericRskERC20.getTransactionDetails(unsignedTransaction) + + if (transactions.length !== 1) { + throw Error('`getTransactionDetails` returned more than 1 transaction!') + } + + return transactions[0] + } else if (token !== undefined) { const genericErc20: GenericERC20 = new GenericERC20( new EthereumERC20ProtocolOptions( new EthereumProtocolNetwork(), @@ -69,13 +120,13 @@ export class TokenService { ) ) try { - const transactions: IAirGapTransaction[] = await genericErc20.getTransactionDetails(unsignedTransaction) + const transactions: IAirGapTransaction[] = await genericErc20.getTransactionDetails(unsignedTransaction) if (transactions.length !== 1) { throw Error('`getTransactionDetails` returned more than 1 transaction!') } return transactions[0] - } catch (error) {} + } catch (error) { } }