From 3ce3753c8fbb124d241ac62aa1980ce232492d8c Mon Sep 17 00:00:00 2001 From: 7alip Date: Thu, 1 Jul 2021 18:19:31 +0200 Subject: [PATCH] feat(rsk): add rsk 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 | 29 +++- .../main/main-protocol-store.service.spec.ts | 3 +- .../store/sub/sub-protocol-store.service.ts | 12 +- .../core/src/lib/services/protocol/tokens.ts | 131 ++++++++++++++++++ .../src/lib/services/token/token.service.ts | 61 +++++++- 22 files changed, 246 insertions(+), 7 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 100755 packages/core/src/assets/symbols/rusdc.svg create mode 100755 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..03cadf8 --- /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..cba3366 --- /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 100755 index 0000000..95f2705 --- /dev/null +++ b/packages/core/src/assets/symbols/rusdc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/core/src/assets/symbols/rusdt.svg b/packages/core/src/assets/symbols/rusdt.svg new file mode 100755 index 0000000..46f996c --- /dev/null +++ b/packages/core/src/assets/symbols/rusdt.svg @@ -0,0 +1 @@ + \ No newline at end of file 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 dd6958b..8851519 100644 --- a/packages/core/src/lib/services/protocol/defaults.ts +++ b/packages/core/src/lib/services/protocol/defaults.ts @@ -4,6 +4,7 @@ import { BitcoinSegwitProtocol, BitcoinProtocol, EthereumProtocol, + RskProtocol, GroestlcoinProtocol, TezosProtocol, CosmosProtocol, @@ -12,11 +13,15 @@ import { ICoinSubProtocol, TezosKtProtocol, GenericERC20, + GenericRskERC20, EthereumERC20ProtocolOptions, EthereumProtocolNetwork, EthereumERC20ProtocolConfig, TezosUUSD, TezosYOU, + RskERC20ProtocolOptions, + RskProtocolNetwork, + RskERC20ProtocolConfig, TezosBTC, TezosUSD, SubProtocolSymbols, @@ -31,7 +36,7 @@ import { TezosQUIPU, } from '@airgap/coinlib-core' import { Token } from '../../types/Token' -import { ethTokens } from './tokens' +import { ethTokens, rskTokens } from './tokens' export function getDefaultPassiveProtocols(): ICoinProtocol[] { return [] @@ -41,6 +46,8 @@ export function getDefaultActiveProtocols(): ICoinProtocol[] { return [ new BitcoinSegwitProtocol(), new EthereumProtocol(), + new RskProtocol(), + new GroestlcoinProtocol(), new TezosProtocol(), new PolkadotProtocol(), new KusamaProtocol(), @@ -68,6 +75,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()], @@ -98,6 +106,25 @@ 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/main/main-protocol-store.service.spec.ts b/packages/core/src/lib/services/protocol/store/main/main-protocol-store.service.spec.ts index a240381..0e19392 100644 --- a/packages/core/src/lib/services/protocol/store/main/main-protocol-store.service.spec.ts +++ b/packages/core/src/lib/services/protocol/store/main/main-protocol-store.service.spec.ts @@ -244,13 +244,14 @@ describe('MainProtocolStoreService', () => { MainProtocolSymbols.BTC, MainProtocolSymbols.COSMOS, MainProtocolSymbols.ETH, + MainProtocolSymbols.RBTC, MainProtocolSymbols.GRS, MainProtocolSymbols.KUSAMA, MainProtocolSymbols.POLKADOT, MainProtocolSymbols.XTZ ] - const invalidIdentifiers: string[] = ['qwerty', 'abcde', 'aeternity', 'bitcoin', 'ethereum', 'tezos', 'ksm', 'dot', 'atom'] + const invalidIdentifiers: string[] = ['qwerty', 'abcde', 'aeternity', 'bitcoin', 'ethereum', 'rsk', 'tezos', 'ksm', 'dot', 'atom'] it('should check if the identifier is valid', () => { service.init({ 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 9c3557e..dab30c3 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 @@ -11,7 +11,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' export interface SubProtocolsMap { @@ -35,6 +35,7 @@ export class SubProtocolStoreService extends BaseProtocolStoreService< SubProtocolStoreConfig > { private _ethTokenIdentifers: Set | undefined + private _rskTokenIdentifers: Set | undefined constructor() { super('SubProtocolService') @@ -48,10 +49,19 @@ 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 { return ( Object.values(SubProtocolSymbols).includes(identifier as SubProtocolSymbols) || this.ethTokenIdentifiers.has(identifier) + || this.rskTokenIdentifiers.has(identifier) || Object.values(MainProtocolSymbols).includes(getMainIdentifier(identifier as SubProtocolSymbols) as MainProtocolSymbols) ) } diff --git a/packages/core/src/lib/services/protocol/tokens.ts b/packages/core/src/lib/services/protocol/tokens.ts index d383017..2b6a578 100644 --- a/packages/core/src/lib/services/protocol/tokens.ts +++ b/packages/core/src/lib/services/protocol/tokens.ts @@ -811,3 +811,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 d0998e0..3e741d6 100644 --- a/packages/core/src/lib/services/token/token.service.ts +++ b/packages/core/src/lib/services/token/token.service.ts @@ -3,6 +3,10 @@ import { EthereumERC20ProtocolOptions, EthereumProtocolNetwork, GenericERC20, + RskERC20ProtocolConfig, + RskERC20ProtocolOptions, + RskProtocolNetwork, + GenericRskERC20, IAirGapTransaction, SignedTransaction, SubProtocolSymbols, @@ -11,14 +15,15 @@ import { 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( @@ -27,7 +32,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(), @@ -60,7 +89,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(),