Skip to content

Commit

Permalink
feat: rsk integration
Browse files Browse the repository at this point in the history
  • Loading branch information
ahsan-javaiid committed Sep 13, 2022
1 parent b7c6409 commit 6acc505
Show file tree
Hide file tree
Showing 37 changed files with 269 additions and 19 deletions.
2 changes: 1 addition & 1 deletion packages/bitcore-node/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const Config = function(): ConfigType {
dbPass: process.env.DB_PASS || '',
numWorkers: cpus().length,
chains: {},
modules: ['./bitcoin', './bitcoin-cash', './ethereum'],
modules: ['./bitcoin', './bitcoin-cash', './ethereum', './rsk'],
services: {
api: {
rateLimiter: {
Expand Down
14 changes: 10 additions & 4 deletions packages/bitcore-node/src/modules/ethereum/api/csp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export class ETHStateProvider extends InternalStateProvider implements IChainSta
}

async getERC20TokenInfo(network: string, tokenAddress: string) {
const token = await ETH.erc20For(network, tokenAddress);
const token = await this.erc20For(network, tokenAddress); // Use `this` rather than ETH to make it generic for other EVM compatible chains to facilitate the class based inheritance of ETHStateProvider
const [name, decimals, symbol] = await Promise.all([
token.methods.name().call(),
token.methods.decimals().call(),
Expand Down Expand Up @@ -360,7 +360,7 @@ export class ETHStateProvider extends InternalStateProvider implements IChainSta
async streamWalletTransactions(params: StreamWalletTransactionsParams) {
const { network, wallet, res, args } = params;
const { web3 } = await this.getWeb3(network);
const query = ETH.getWalletTransactionQuery(params);
const query = this.getWalletTransactionQuery(params); // Use this rather than ETH to make it generic for other EVM compatible chains to facilitate the class based inheritance of ETHStateProvider

let transactionStream = new Readable({ objectMode: true });
const walletAddresses = (await this.getWalletAddresses(wallet._id!)).map(waddres => waddres.address);
Expand Down Expand Up @@ -572,5 +572,11 @@ export class ETHStateProvider extends InternalStateProvider implements IChainSta
};
}
}

export const ETH = new ETHStateProvider();
/*
*
* Use the ETH implementation for RSK by inheriting the ETHStateProvider class rather than making its clone
* This will reduce lot of maintenance cost and avoid code duplication
* For other EVM compatible chains like RSK below export needs to be like new ETHStateProvider('RSK')
* It's just a suggestion to use process.env.chain evn variable untill bitpay team can make it more generic for other EVM like chains
*/
export const ETH = new ETHStateProvider(process.env.chain || 'ETH');
3 changes: 2 additions & 1 deletion packages/bitcore-node/src/modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class ModuleManager extends BaseModule {
BCH: './bitcoin-cash',
DOGE: './dogecoin',
LTC: './litecoin',
XRP: './ripple'
XRP: './ripple',
RSK: './rsk'
};

loadConfigured() {
Expand Down
1 change: 1 addition & 0 deletions packages/bitcore-node/src/modules/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The modules in this table will automatically register with `bitcore-node` if you
| LTC | litecoin | ./litecoin |
| DOGE | dogecoin | ./dogecoin |
| XRP | ripple | ./ripple |
| RSK | rsk | ./rsk |

If there is a custom or third-party module you'd like to use, follow the example below.

Expand Down
18 changes: 18 additions & 0 deletions packages/bitcore-node/src/modules/rsk/api/csp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Config from '../../../config';
import { ETHStateProvider } from '../../ethereum/api/csp';

export { EventLog } from '../../ethereum/api/csp';
export class RSKStateProvider extends ETHStateProvider {
/*
* Reusing ETHStateProvider class for RSK
* Purpose is to avoid code duplication and reduce maintenance cost
*/
constructor(public chain: string = 'RSK') {
super(chain);
this.config = Config.chains[this.chain];
}

}

export const RSK = new RSKStateProvider();

36 changes: 36 additions & 0 deletions packages/bitcore-node/src/modules/rsk/api/rsk-routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Router } from 'express';
import logger from '../../../logger';
import { RSK } from './csp';
export const RskRoutes = Router();

RskRoutes.get('/api/RSK/:network/address/:address/txs/count', async (req, res) => {
let { address, network } = req.params;
try {
const nonce = await RSK.getAccountNonce(network, address);
res.json({ nonce });
} catch (err) {
logger.error('Nonce Error::' + err);
res.status(500).send(err);
}
});

RskRoutes.post('/api/RSK/:network/gas', async (req, res) => {
const { from, to, value, data, gasPrice } = req.body;
const { network } = req.params;
try {
const gasLimit = await RSK.estimateGas({ network, from, to, value, data, gasPrice });
res.json(gasLimit);
} catch (err) {
res.status(500).send(err);
}
});

RskRoutes.get('/api/RSK/:network/token/:tokenAddress', async (req, res) => {
const { network, tokenAddress } = req.params;
try {
const tokenInfo = await RSK.getERC20TokenInfo(network, tokenAddress);
res.json(tokenInfo);
} catch (err) {
res.status(500).send(err);
}
});
15 changes: 15 additions & 0 deletions packages/bitcore-node/src/modules/rsk/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { BaseModule } from '..';
import { RSKStateProvider } from './api/csp';
import { RskRoutes } from './api/rsk-routes';
import { RskP2pWorker } from './p2p/p2p';
import { RskVerificationPeer } from './p2p/RskVerificationPeer';

export default class RSKModule extends BaseModule {
constructor(services: BaseModule['bitcoreServices']) {
super(services);
services.P2P.register('RSK', RskP2pWorker);
services.CSP.registerService('RSK', new RSKStateProvider('RSK'));
services.Api.app.use(RskRoutes);
services.Verification.register('RSK', RskVerificationPeer);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { EthVerificationPeer } from '../../ethereum/p2p/EthVerificationPeer';

export class RskVerificationPeer extends EthVerificationPeer {
/*
* Reusing EthVerificationPeer class for RSK
* Purpose is to avoid code duplication and reduce maintenance cost
*/
}
12 changes: 12 additions & 0 deletions packages/bitcore-node/src/modules/rsk/p2p/p2p.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { EthP2pWorker } from '../../ethereum/p2p/p2p';
import { EthBlockStorage } from '../../ethereum/models/block';
export class RskP2pWorker extends EthP2pWorker {
/*
* Reusing EthP2pWorker class for RSK
* Purpose is to avoid code duplication and reduce maintenance cost
*/
constructor({ chain, network, chainConfig, blockModel = EthBlockStorage}) {
super({ chain, network, chainConfig, blockModel });
this.chain = 'RSK';
}
}
4 changes: 3 additions & 1 deletion packages/bitcore-wallet-client/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2964,7 +2964,9 @@ export class API extends EventEmitter {
['btc', 'livenet', true],
['bch', 'livenet', true],
['doge', 'livenet', true],
['ltc', 'livenet', true]
['ltc', 'livenet', true],
['rsk', 'livenet'],
['rbtc', 'livenet'],
];
if (key.use44forMultisig) {
// testing old multi sig
Expand Down
6 changes: 4 additions & 2 deletions packages/bitcore-wallet-client/src/lib/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const Constants = {
'btc',
'bch',
'eth',
'rsk',
'xrp',
'doge',
'ltc',
Expand All @@ -45,16 +46,17 @@ export const Constants = {
'pax', // backwards compatibility
'gusd',
'busd',
'xusd', // Sovryn token
'dai',
'wbtc',
'shib',
'ape',
'euroc'
],
UTXO_COINS: ['btc', 'bch', 'doge', 'ltc'],
CHAINS: ['btc', 'bch', 'eth', 'xrp', 'doge', 'ltc'],
CHAINS: ['btc', 'bch', 'eth', 'xrp', 'doge', 'ltc', 'rsk'],
UTXO_CHAINS: ['btc', 'bch', 'doge', 'ltc'],
EVM_CHAINS: ['eth'],
EVM_CHAINS: ['eth', 'rsk'],
TOKEN_OPTS: CWC.Constants.TOKEN_OPTS,
UNITS: CWC.Constants.UNITS
};
3 changes: 2 additions & 1 deletion packages/bitcore-wallet-client/src/lib/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const Bitcore_ = {
eth: Bitcore,
xrp: Bitcore,
doge: BitcoreLibDoge,
ltc: BitcoreLibLtc
ltc: BitcoreLibLtc,
rsk: Bitcore
};
const PrivateKey = Bitcore.PrivateKey;
const PublicKey = Bitcore.PublicKey;
Expand Down
2 changes: 2 additions & 0 deletions packages/bitcore-wallet-client/src/lib/key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,8 @@ export class Key {
coinCode = '0';
} else if (opts.coin == 'eth') {
coinCode = '60';
} else if (opts.coin == 'rsk' || opts.coin == 'rbtc') {
coinCode = '137';
} else if (opts.coin == 'xrp') {
coinCode = '144';
} else if (opts.coin == 'doge') {
Expand Down
8 changes: 8 additions & 0 deletions packages/bitcore-wallet-service/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ const Config = () => {
url: 'https://api-eth.bitcore.io'
}
},
rsk: {
livenet: {
url: 'https://api-rsk.bitcore.io'
},
testnet: {
url: 'https://api-rsk.bitcore.io'
}
},
xrp: {
livenet: {
url: 'https://api-xrp.bitcore.io'
Expand Down
4 changes: 4 additions & 0 deletions packages/bitcore-wallet-service/src/lib/blockchainexplorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const PROVIDERS = {
livenet: 'https://api-eth.bitcore.io',
testnet: 'https://api-eth.bitcore.io'
},
rsk: {
livenet: 'https://api-rsk.bitcore.io',
testnet: 'https://api-rsk.bitcore.io'
},
xrp: {
livenet: 'https://api-xrp.bitcore.io',
testnet: 'https://api-xrp.bitcore.io'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const Bitcore_ = {
btc: Bitcore,
bch: require('bitcore-lib-cash'),
eth: Bitcore,
rsk: Bitcore,
xrp: Bitcore,
doge: require('bitcore-lib-doge'),
ltc: require('bitcore-lib-ltc')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export class BlockchainMonitor {
btc: {},
bch: {},
eth: {},
rsk: {},
xrp: {},
doge: {},
ltc: {}
Expand Down
11 changes: 8 additions & 3 deletions packages/bitcore-wallet-service/src/lib/chain/eth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ function getInvoiceDecoder() {
}

export class EthChain implements IChain {
chain: string;
constructor() {
// Now RSK will inherit EthChain and override this.chain = 'RSK';
this.chain = 'ETH';
}
/**
* Converts Bitcore Balance Response.
* @param {Object} bitcoreBalance - { unconfirmed, confirmed, balance }
Expand Down Expand Up @@ -193,7 +198,7 @@ export class EthChain implements IChain {
const { data, outputs, payProUrl, tokenAddress, multisigContractAddress, isTokenSwap } = txp;
const isERC20 = tokenAddress && !payProUrl && !isTokenSwap;
const isETHMULTISIG = multisigContractAddress;
const chain = isETHMULTISIG ? 'ETHMULTISIG' : isERC20 ? 'ERC20' : 'ETH';
const chain = isETHMULTISIG ? 'ETHMULTISIG' : isERC20 ? 'ERC20' : this.chain;
const recipients = outputs.map(output => {
return {
amount: output.amount,
Expand Down Expand Up @@ -408,7 +413,7 @@ export class EthChain implements IChain {
throw new Error('Signatures Required');
}

const chain = 'ETH'; // TODO use lowercase always to avoid confusion
const chain = this.chain; // TODO use lowercase always to avoid confusion
const unsignedTxs = tx.uncheckedSerialize();
const signedTxs = [];
for (let index = 0; index < signatures.length; index++) {
Expand All @@ -426,7 +431,7 @@ export class EthChain implements IChain {
}

validateAddress(wallet, inaddr, opts) {
const chain = 'eth';
const chain = this.chain.toLowerCase();
const isValidTo = Validation.validateAddress(chain, wallet.network, inaddr);
if (!isValidTo) {
throw Errors.INVALID_ADDRESS;
Expand Down
4 changes: 3 additions & 1 deletion packages/bitcore-wallet-service/src/lib/chain/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { BchChain } from './bch';
import { BtcChain } from './btc';
import { DogeChain } from './doge';
import { EthChain } from './eth';
import { RskChain } from './rsk';
import { LtcChain } from './ltc';
import { XrpChain } from './xrp';

Expand Down Expand Up @@ -73,7 +74,8 @@ const chains: { [chain: string]: IChain } = {
ETH: new EthChain(),
XRP: new XrpChain(),
DOGE: new DogeChain(),
LTC: new LtcChain()
LTC: new LtcChain(),
RSK: new RskChain()
};

class ChainProxy {
Expand Down
11 changes: 11 additions & 0 deletions packages/bitcore-wallet-service/src/lib/chain/rsk/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { EthChain } from '../eth';

export class RskChain extends EthChain {
constructor() {
super();
// Now RSK will inherit EthChain and override this.chain = 'RSK';
this.chain = 'RSK';
}

// Rest of functions will be inherited from EthChain
}
6 changes: 5 additions & 1 deletion packages/bitcore-wallet-service/src/lib/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ module.exports = {
BTC: 'btc',
BCH: 'bch',
ETH: 'eth',
RSK: 'rsk',
RBTC: 'rbtc',
XRP: 'xrp',
DOGE: 'doge',
LTC: 'ltc'
Expand All @@ -18,6 +20,7 @@ module.exports = {
BTC: 'btc',
BCH: 'bch',
ETH: 'eth',
RSK: 'rsk',
XRP: 'xrp',
DOGE: 'doge',
LTC: 'ltc',
Expand Down Expand Up @@ -67,7 +70,8 @@ module.exports = {
},

EVM_CHAINS: {
ETH: 'eth'
ETH: 'eth',
RSK: 'rsk'
},

NETWORKS: {
Expand Down

0 comments on commit 6acc505

Please sign in to comment.